Hi,
On 2021-01-18 6:29 a.m., Phil Sutter wrote:
Hi!
Playing with u32 filter's hash table I noticed it is not possible to use
'sample' option with keys larger than 8bits to calculate the hash
bucket.
I have mostly used something like: ht 2:: sample ip protocol 1 0xff
Hoping this is continuing to work.
I feel i am missing something basic in the rest of your email:
Sample is a user space concept i.e it is used to instruct the
kernel what table/bucket to insert the node into. This computation
is done in user space. The kernel should just walk the nodes in
the bucket and match.
Reminder: you can only have 256 buckets (8 bit representation).
Could that be the contributing factor?
Here's an example of something which is not 8 bit that i found in
an old script that should work (but I didnt test in current kernels).
ht 2:: sample u32 0x00000800 0x0000ff00 at 12
We are still going to extract only 8 bits for the bucket.
Can you provide an example of what wouldnt work?
cheers,
jamal
Turns out key hashing in kernel and iproute2 differ:
* net/sched/cls_u32.c (kernel) basically does:
hash = ntohl(key & mask);
hash >>= ffs(ntohl(mask)) - 1;
hash &= 0xff;
hash %= divisor;
* while tc/f_u32.c (iproute2) does:
hash = key & mask;
hash ^= hash >> 16;
hash ^= hash >> 8;
hash %= divisor;
In iproute2, the code changed in 2006 with commit 267480f55383c
("Backout the 2.4 utsname hash patch."), here's the relevant diff:
hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
- uname(&utsname);
- if (strncmp(utsname.release, "2.4.", 4) == 0) {
- hash ^= hash>>16;
- hash ^= hash>>8;
- }
- else {
- __u32 mask = sel2.sel.keys[0].mask;
- while (mask && !(mask & 1)) {
- mask >>= 1;
- hash >>= 1;
- }
- hash &= 0xFF;
- }
+ hash ^= hash>>16;
+ hash ^= hash>>8;
htid = ((hash%divisor)<<12)|(htid&0xFFF00000);
The old code would work if key and mask weren't in network byteorder. I
guess that also changed since then.
I would simply send a patch to fix iproute2, but I don't like the
kernel's hash "folding" as it ignores any bits beyond the first eight.
So I would prefer to "fix" the kernel instead but would like to hear
your opinions as that change has a much larger scope than just
iproute2's 'sample' option.
Thanks, Phil