How to match port range using u32 filter

tc

with "u32 match ip sport 80" in Linux tc I can match port 80, but how can I match a port range 10000 – 20000 ?

Best Answer

You can use mask, but it difficult:

 u32 match ip sport 4096 0xf000 = sport 4096-8191
 u32 match ip sport 8192 0xe000 = sport 8192-16383

0xf000/0xe000 is the mask. The word extracted from the packet is bit-wise with this mask before comparison.

value = 0001000000000000
mask  = 1111000000000000

start = 0001000000000000
end   = 0001111111111111

Also you can create many filter for one classid:

tc filter add dev eth0 parent 1:0 prio 3 protocol ip u32 match ip protocol 6 0xff match ip sport 10000 0xffff classid 1:13
tc filter add dev eth0 parent 1:0 prio 3 protocol ip u32 match ip protocol 6 0xff match ip sport 10001 0xffff classid 1:13
tc filter add dev eth0 parent 1:0 prio 3 protocol ip u32 match ip protocol 6 0xff match ip sport 10002 0xffff classid 1:13

For your example, your need create several 'tc filter':

first: sport 10000 0xfff0 (10000-10015)
second: sport 10016 0xffe0 (10016-10047)
.............

etc.

10000=10011100010000

0010011100010000
           |
     first not zero
1111111111111111
mask
1111111111110000=0xfff0

[Basically take the first number in the range (in this example 10,000) and convert it to binary ( 0010011100010000 ); then scan this binary number from right to left until you encounter the 1st non 0 bit; then make the bits from the left of that bit all into 1's inclusive, and all the bits to the right of it to zeros. That is how you come out to 0xfff0 as the mask.]

Related Topic