From: Damjan Marion Date: Wed, 21 May 2025 09:23:41 +0000 (+0200) Subject: hash: add ipv4 and ipv6 only hash X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=87a2643014942412574abdf33b3c070c0d65d287;p=vpp.git hash: add ipv4 and ipv6 only hash Type: improvement Change-Id: Ia210a7a128521d4d81dba0fe3f09c87e0bec7dd8 Signed-off-by: Damjan Marion --- diff --git a/src/vnet/hash/crc32_5tuple.c b/src/vnet/hash/crc32_5tuple.c index 2cdb19440c6..dd0e54c3e75 100644 --- a/src/vnet/hash/crc32_5tuple.c +++ b/src/vnet/hash/crc32_5tuple.c @@ -48,17 +48,18 @@ compute_ip4_key (ip4_header_t *ip) return clib_crc32c_u64 (hash, ((u64) pr << 32) | l4hdr); } static_always_inline u32 -compute_ip_key (void *p) +compute_ip_key (void *p, int ip4, int ip6) { - if ((((u8 *) p)[0] & 0xf0) == 0x40) + if (ip4 && (((u8 *) p)[0] & 0xf0) == 0x40) return compute_ip4_key (p); - else if ((((u8 *) p)[0] & 0xf0) == 0x60) + if (ip6 && (((u8 *) p)[0] & 0xf0) == 0x60) return compute_ip6_key (p); return 0; } -void -vnet_crc32c_5tuple_ip_func (void **p, u32 *hash, u32 n_packets) +static_always_inline void +vnet_crc32c_5tuple_ip_func_inline (void **p, u32 *hash, u32 n_packets, int ip4, + int ip6) { u32 n_left_from = n_packets; @@ -69,10 +70,10 @@ vnet_crc32c_5tuple_ip_func (void **p, u32 *hash, u32 n_packets) clib_prefetch_load (p[6]); clib_prefetch_load (p[7]); - hash[0] = compute_ip_key (p[0]); - hash[1] = compute_ip_key (p[1]); - hash[2] = compute_ip_key (p[2]); - hash[3] = compute_ip_key (p[3]); + hash[0] = compute_ip_key (p[0], ip4, ip6); + hash[1] = compute_ip_key (p[1], ip4, ip6); + hash[2] = compute_ip_key (p[2], ip4, ip6); + hash[3] = compute_ip_key (p[3], ip4, ip6); hash += 4; n_left_from -= 4; @@ -81,7 +82,7 @@ vnet_crc32c_5tuple_ip_func (void **p, u32 *hash, u32 n_packets) while (n_left_from > 0) { - hash[0] = compute_ip_key (p[0]); + hash[0] = compute_ip_key (p[0], ip4, ip6); hash += 1; n_left_from -= 1; @@ -157,12 +158,32 @@ vnet_crc32c_5tuple_ethernet_func (void **p, u32 *hash, u32 n_packets) } } +static void +vnet_crc32c_5tuple_ip46_func (void **p, u32 *hash, u32 n_packets) +{ + vnet_crc32c_5tuple_ip_func_inline (p, hash, n_packets, 1, 1); +} + +static void +vnet_crc32c_5tuple_ip4_func (void **p, u32 *hash, u32 n_packets) +{ + vnet_crc32c_5tuple_ip_func_inline (p, hash, n_packets, 1, 0); +} + +static void +vnet_crc32c_5tuple_ip6_func (void **p, u32 *hash, u32 n_packets) +{ + vnet_crc32c_5tuple_ip_func_inline (p, hash, n_packets, 0, 1); +} + VNET_REGISTER_HASH_FUNCTION (crc32c_5tuple, static) = { .name = "crc32c-5tuple", .description = "IPv4/IPv6 header and TCP/UDP ports", .priority = 50, .function[VNET_HASH_FN_TYPE_ETHERNET] = vnet_crc32c_5tuple_ethernet_func, - .function[VNET_HASH_FN_TYPE_IP] = vnet_crc32c_5tuple_ip_func, + .function[VNET_HASH_FN_TYPE_IP] = vnet_crc32c_5tuple_ip46_func, + .function[VNET_HASH_FN_TYPE_IP4] = vnet_crc32c_5tuple_ip4_func, + .function[VNET_HASH_FN_TYPE_IP6] = vnet_crc32c_5tuple_ip6_func, }; #endif diff --git a/src/vnet/hash/hash.c b/src/vnet/hash/hash.c index 31693c9889b..d2942e14dbc 100644 --- a/src/vnet/hash/hash.c +++ b/src/vnet/hash/hash.c @@ -29,14 +29,16 @@ vnet_hash_fn_t vnet_hash_default_function (vnet_hash_fn_type_t ftype) { vnet_hash_function_registration_t *hash = vnet_hash_main.hash_registrations; - vnet_hash_function_registration_t *tmp_hash = hash; + vnet_hash_function_registration_t *selected = 0; + while (hash) { - if (hash->priority > tmp_hash->priority) - tmp_hash = hash; + if (hash->function[ftype] && + (!selected || hash->priority > selected->priority)) + selected = hash; hash = hash->next; } - return tmp_hash->function[ftype]; + return selected ? selected->function[ftype] : 0; } vnet_hash_fn_t diff --git a/src/vnet/hash/hash.h b/src/vnet/hash/hash.h index c1eb9475e28..d1168648eef 100644 --- a/src/vnet/hash/hash.h +++ b/src/vnet/hash/hash.h @@ -10,7 +10,9 @@ #define foreach_vnet_hash_fn_types \ _ (ETHERNET, 0, "hash-fn-ethernet") \ - _ (IP, 1, "hash-fn-ip") + _ (IP4, 1, "hash-fn-ip4") \ + _ (IP6, 2, "hash-fn-ip6") \ + _ (IP, 3, "hash-fn-ip") typedef enum {