BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
ipv6_flow.c
00001 /* 00002 * Copyright (c) 2016-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "nsconfig.h" 00019 00020 #include "randLIB.h" 00021 #include "Service_Libs/fnv_hash/fnv_hash.h" 00022 00023 #include "ipv6_flow.h" 00024 00025 bool ipv6_flow_auto_label = true; 00026 00027 /* Flow label hash computation for RFC 6347, but using algorithm 8 as 00028 * suggested by "Comparing Hash Function Algorithms for the IPv6 Flow Label" 00029 * (Anderson, Brownlee, Carpenter 2012). 00030 */ 00031 00032 static inline uint_fast24_t fold_32_to_flow(uint32_t val32) 00033 { 00034 uint_fast24_t flow = (uint_fast24_t) ((val32 ^ (val32 >> 20)) & 0xFFFFF); 00035 if (flow == 0) { 00036 flow = 1; 00037 } 00038 return flow; 00039 } 00040 00041 /* Compute a flow from the traditional (src-IP,dst-IP,proto,src-port,dst-port) 00042 * 5-tuple. To be used when building our own IP headers from a transport module. 00043 */ 00044 uint_fast24_t ipv6_flow_5tuple(const uint8_t src_addr[static 16], 00045 const uint8_t dst_addr[static 16], 00046 uint8_t protocol, 00047 uint16_t src_port, 00048 uint16_t dst_port) 00049 { 00050 uint32_t hash; 00051 const uint8_t bytes[] = { dst_port >> 8, dst_port, src_port >> 8, src_port, protocol }; 00052 00053 /* Hash algorithms suggest starting with the low-order bytes, as they're 00054 * most likely to vary, increasing potential dispersion. This means using 00055 * the "reverse" function on the IP addresses, and we use the same reverse 00056 * for the other 3 tuple members to re-use the code. 00057 */ 00058 hash = fnv_hash_1a_32_reverse_block(src_addr, 16); 00059 hash = fnv_hash_1a_32_reverse_block_update(hash, dst_addr, 16); 00060 hash = fnv_hash_1a_32_reverse_block_update(hash, bytes, sizeof bytes); 00061 00062 return fold_32_to_flow(hash); 00063 } 00064 00065 /* Compute a flow from a basic (src-IP,dst-IP) 2-tuple, plus an existing flow 00066 * label. To be used on tunnel entry, using fields from inner header. 00067 */ 00068 uint_fast24_t ipv6_flow_2tuple_flow(const uint8_t src_addr[static 16], 00069 const uint8_t dst_addr[static 16], 00070 uint_fast24_t flow) 00071 { 00072 uint32_t hash; 00073 00074 flow &= 0xFFFFF; 00075 const uint8_t bytes[] = { flow >> 16, flow >> 8, flow }; 00076 00077 hash = fnv_hash_1a_32_reverse_block(bytes, sizeof bytes); 00078 hash = fnv_hash_1a_32_reverse_block_update(hash, src_addr, 16); 00079 hash = fnv_hash_1a_32_reverse_block_update(hash, dst_addr, 16); 00080 00081 return fold_32_to_flow(hash); 00082 } 00083 00084 /* Compute a random flow label. To be used on a connected socket. */ 00085 uint_fast24_t ipv6_flow_random(void) 00086 { 00087 uint32_t rand32 = randLIB_get_32bit(); 00088 00089 return fold_32_to_flow(rand32); 00090 }
Generated on Tue Jul 12 2022 12:21:57 by
