Skip to content

Commit 5640cbd

Browse files
committed
datapath: Rehash 16-bit skbuff hashes into 32 bits.
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 that is 16 bits rather than 32 bits. In cases where we use the uppermost 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 tunnel source port is always the minimum value. To solve this problem while still taking advantage of the precomputed hash, this rehashes the hash so that the entropy is spread throughout 32 bits. Signed-off-by: Jesse Gross <jesse@nicira.com> Acked-by: Thomas Graf <tgraf@noironetworks.com>
1 parent 210ba96 commit 5640cbd

2 files changed

Lines changed: 7 additions & 0 deletions

File tree

acinclude.m4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
297297
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [[[^@]]proto_data_valid],
298298
[OVS_DEFINE([HAVE_PROTO_DATA_VALID])])
299299
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [rxhash])
300+
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [u16.*rxhash],
301+
[OVS_DEFINE([HAVE_U16_RXHASH])])
300302
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_dst(],
301303
[OVS_DEFINE([HAVE_SKB_DST_ACCESSOR_FUNCS])])
302304
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h],

datapath/linux/compat/include/linux/skbuff.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include_next <linux/skbuff.h>
55

6+
#include <linux/jhash.h>
67
#include <linux/version.h>
78

89
#ifndef HAVE_SKB_COPY_FROM_LINEAR_DATA_OFFSET
@@ -260,7 +261,11 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
260261
{
261262
#ifdef HAVE_RXHASH
262263
if (skb->rxhash)
264+
#ifndef HAVE_U16_RXHASH
263265
return skb->rxhash;
266+
#else
267+
return jhash_1word(skb->rxhash, 0);
268+
#endif
264269
#endif
265270
return __skb_get_hash(skb);
266271
}

0 commit comments

Comments
 (0)