From 2af0e3a74c40e5df946813324574ccc18feb4761 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Tue, 20 Nov 2018 11:11:12 +0100 Subject: [PATCH] flow-hash: Add symmetric flag for flow hashing When 'Symmetric' flag is enabled, it will sort the addresses and hence, same flow hash will be calculated on both directions. Change-Id: I5d846f8d0b94ca1121e03d15b02bb56edb5887b1 Signed-off-by: Mohsin Kazmi --- src/vnet/ip/ip.api | 4 +++- src/vnet/ip/ip4.h | 18 +++++++++++++++++- src/vnet/ip/ip6.h | 18 +++++++++++++++++- src/vnet/ip/lookup.h | 4 +++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api index b08af5657fc..6ae0e023d5f 100644 --- a/src/vnet/ip/ip.api +++ b/src/vnet/ip/ip.api @@ -20,7 +20,7 @@ called through a shared memory interface. */ -option version = "1.3.0"; +option version = "1.4.0"; import "vnet/ip/ip_types.api"; import "vnet/fib/fib_types.api"; import "vnet/ethernet/ethernet_types.api"; @@ -181,6 +181,7 @@ define ip_neighbor_add_del_reply @param dport - if non-zero include dport in flow hash @param proto -if non-zero include proto in flow hash @param reverse - if non-zero include reverse in flow hash + @param symmetric - if non-zero include symmetry in flow hash */ autoreply define set_ip_flow_hash { @@ -194,6 +195,7 @@ autoreply define set_ip_flow_hash u8 dport; u8 proto; u8 reverse; + u8 symmetric; }; /** \brief IPv6 router advertisement config request diff --git a/src/vnet/ip/ip4.h b/src/vnet/ip/ip4.h index 9cb54bdfc41..31ca10feece 100644 --- a/src/vnet/ip/ip4.h +++ b/src/vnet/ip/ip4.h @@ -308,7 +308,6 @@ ip4_compute_flow_hash (const ip4_header_t * ip, a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1; b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2; - b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? ip->protocol : 0; t1 = is_tcp_udp ? tcp->src : 0; t2 = is_tcp_udp ? tcp->dst : 0; @@ -316,6 +315,23 @@ ip4_compute_flow_hash (const ip4_header_t * ip, t1 = (flow_hash_config & IP_FLOW_HASH_SRC_PORT) ? t1 : 0; t2 = (flow_hash_config & IP_FLOW_HASH_DST_PORT) ? t2 : 0; + if (flow_hash_config & IP_FLOW_HASH_SYMMETRIC) + { + if (b < a) + { + c = a; + a = b; + b = c; + } + if (t2 < t1) + { + t2 += t1; + t1 = t2 - t1; + t2 = t2 - t1; + } + } + + b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? ip->protocol : 0; c = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? (t1 << 16) | t2 : (t2 << 16) | t1; diff --git a/src/vnet/ip/ip6.h b/src/vnet/ip/ip6.h index aef24454413..6e0cfff5164 100644 --- a/src/vnet/ip/ip6.h +++ b/src/vnet/ip/ip6.h @@ -468,7 +468,6 @@ ip6_compute_flow_hash (const ip6_header_t * ip, a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1; b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2; - b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? protocol : 0; t1 = is_tcp_udp ? tcp->src : 0; t2 = is_tcp_udp ? tcp->dst : 0; @@ -476,6 +475,23 @@ ip6_compute_flow_hash (const ip6_header_t * ip, t1 = (flow_hash_config & IP_FLOW_HASH_SRC_PORT) ? t1 : 0; t2 = (flow_hash_config & IP_FLOW_HASH_DST_PORT) ? t2 : 0; + if (flow_hash_config & IP_FLOW_HASH_SYMMETRIC) + { + if (b < a) + { + c = a; + a = b; + b = c; + } + if (t2 < t1) + { + t2 += t1; + t1 = t2 - t1; + t2 = t2 - t1; + } + } + + b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? protocol : 0; c = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? ((t1 << 16) | t2) : ((t2 << 16) | t1); diff --git a/src/vnet/ip/lookup.h b/src/vnet/ip/lookup.h index 374023835f4..4c598e3a460 100644 --- a/src/vnet/ip/lookup.h +++ b/src/vnet/ip/lookup.h @@ -64,6 +64,7 @@ #define IP_FLOW_HASH_SRC_PORT (1<<3) #define IP_FLOW_HASH_DST_PORT (1<<4) #define IP_FLOW_HASH_REVERSE_SRC_DST (1<<5) +#define IP_FLOW_HASH_SYMMETRIC (1<<6) /** Default: 5-tuple without the "reverse" bit */ #define IP_FLOW_HASH_DEFAULT (0x1F) @@ -74,7 +75,8 @@ _(dst, IP_FLOW_HASH_DST_ADDR) \ _(sport, IP_FLOW_HASH_SRC_PORT) \ _(dport, IP_FLOW_HASH_DST_PORT) \ _(proto, IP_FLOW_HASH_PROTO) \ -_(reverse, IP_FLOW_HASH_REVERSE_SRC_DST) +_(reverse, IP_FLOW_HASH_REVERSE_SRC_DST) \ +_(symmetric, IP_FLOW_HASH_SYMMETRIC) /** * A flow hash configuration is a mask of the flow hash options -- 2.16.6