summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2021-08-04 11:18:28 +0200
committerStephen Hemminger <stephen@networkplumber.org>2021-08-10 20:02:43 -0700
commit9b7ea92b9e3feff2876f772ace01148b7406839c (patch)
treedf0e2a95757358fe8b588d56b6c69e52c09f535c
parentd1eacf12b58eb9907dc071f32238388ef3e254c0 (diff)
downloadiproute2-9b7ea92b9e3feff2876f772ace01148b7406839c.tar.gz
tc: u32: Fix key folding in sample option
In between Linux kernel 2.4 and 2.6, key folding for hash tables changed in kernel space. When iproute2 dropped support for the older algorithm, the wrong code was removed and kernel 2.4 folding method remained in place. To get things functional for recent kernels again, restoring the old code alone was not sufficient - additional byteorder fixes were needed. While being at it, make use of ffs() and thereby align the code with how kernel determines the shift width. Fixes: 267480f55383c ("Backout the 2.4 utsname hash patch.") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
-rw-r--r--tc/f_u32.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/tc/f_u32.c b/tc/f_u32.c
index 2ed5254a..a5747f67 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -978,6 +978,13 @@ show_k:
goto show_k;
}
+static __u32 u32_hash_fold(struct tc_u32_key *key)
+{
+ __u8 fshift = key->mask ? ffs(ntohl(key->mask)) - 1 : 0;
+
+ return ntohl(key->val & key->mask) >> fshift;
+}
+
static int u32_parse_opt(struct filter_util *qu, char *handle,
int argc, char **argv, struct nlmsghdr *n)
{
@@ -1110,9 +1117,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
}
NEXT_ARG();
}
- hash = sel2.keys[0].val & sel2.keys[0].mask;
- hash ^= hash >> 16;
- hash ^= hash >> 8;
+ hash = u32_hash_fold(&sel2.keys[0]);
htid = ((hash % divisor) << 12) | (htid & 0xFFF00000);
sample_ok = 1;
continue;