Matching range of values using tc u32
Very few people realize that Linux's tc u32 filter allows you to match range of values. Basicly the logic is very similar to IP address/netmask matching.
For example, this u32 rule will match all source ports in the port range 0-1023: match ip sport 0x0 0xfc00
All you need is some simple binary arithmetic. Remember that u32 does an AND operation of the parameter against the mask, and then compares it with the target value. 1023 is 0x3FF in hex, after inversion (XOR 0xffff) we get 0xfc00. So, 0xfc00 is 1111110000000000 in binary, and if we use it as a mask it will mean that any bits with values below 1024 will be discarded. 0x0 (zero) is the target value that u32 will compare against. Any port values above or equal 1024 will not have a zero value after "[port] AND 0xfc00" binary arithmetic operation is done, so the filter will match only the ports below 1024.
For example, this u32 rule will match all source ports in the port range 0-1023: match ip sport 0x0 0xfc00
All you need is some simple binary arithmetic. Remember that u32 does an AND operation of the parameter against the mask, and then compares it with the target value. 1023 is 0x3FF in hex, after inversion (XOR 0xffff) we get 0xfc00. So, 0xfc00 is 1111110000000000 in binary, and if we use it as a mask it will mean that any bits with values below 1024 will be discarded. 0x0 (zero) is the target value that u32 will compare against. Any port values above or equal 1024 will not have a zero value after "[port] AND 0xfc00" binary arithmetic operation is done, so the filter will match only the ports below 1024.