[ovs-dev] [PATCH] datapath: Rehash 16-bit skbuff hashes into 32 bits.

Jesse Gross jesse at nicira.com
Wed Jun 25 01:46:30 UTC 2014


Currently, if the network stack provides skb->rxhash then we use it,
otherwise we compute our own. However, on at least some versions of
RHEL/CentOS, the stack provides a hash but it is 16 bits rather than
32 bits. In cases where we use the upper most bits of the hash this
is particularly bad because we detect that a hash is present and we
use it rather than computing our own but the result is always zero.

This is particularly noticible with tunnel ports that use the hash
to generate a source port, such as VXLAN. On these kernels the source
port is always zero when using VXLAN. To solve this problem while
still taking advantage of the procomputed hash, this rehashes the
hash so that the entropy is spread throughout 32 bits.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 acinclude.m4                                 | 2 ++
 datapath/linux/compat/include/linux/skbuff.h | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/acinclude.m4 b/acinclude.m4
index 69d65f0..c761366 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -297,6 +297,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [[[^@]]proto_data_valid],
                   [OVS_DEFINE([HAVE_PROTO_DATA_VALID])])
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [rxhash])
+  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [u16.*rxhash],
+                  [OVS_DEFINE([HAVE_U16_RXHASH])])
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_dst(],
                   [OVS_DEFINE([HAVE_SKB_DST_ACCESSOR_FUNCS])])
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], 
diff --git a/datapath/linux/compat/include/linux/skbuff.h b/datapath/linux/compat/include/linux/skbuff.h
index b011396..9abd582 100644
--- a/datapath/linux/compat/include/linux/skbuff.h
+++ b/datapath/linux/compat/include/linux/skbuff.h
@@ -3,6 +3,7 @@
 
 #include_next <linux/skbuff.h>
 
+#include <linux/jhash.h>
 #include <linux/version.h>
 
 #ifndef HAVE_SKB_COPY_FROM_LINEAR_DATA_OFFSET
@@ -260,7 +261,11 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
 {
 #ifdef HAVE_RXHASH
 	if (skb->rxhash)
+#ifndef HAVE_U16_RXHASH
 		return skb->rxhash;
+#else
+		return jhash_1word(skb->rxhash, 0);
+#endif
 #endif
 	return __skb_get_hash(skb);
 }
-- 
1.9.1




More information about the dev mailing list