I'm trying to rate-limit all incoming traffic on ports 8128-8191. I've read everything I found, checked everything ten times, it still doesn't work.
The commands:
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb default 1
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1kbit ceil 1kbit
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 match ip dport 8128 0xFFC0 classid 1:1
This is how I calculated the mask:
expected = lowest port = 0b_0001_1111_1100_0000 = 0x1FC0 = 8128d
mask = highest port = 0b_1111_1111_1100_0000 = 0xFFC0
highest port = 0b_0001_1111_1111_1111 = 0x1FFF = 8191d
The output:
#tc -s class show dev eth0
class htb 1:1 root prio 0 rate 1000bit ceil 1000bit burst 1600b cburst 1600b
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: 200000000 ctokens: 200000000
# tc filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
match 00001fc0/0000ffc0 at 20
I send a flow of bytes from my workstation with:
cat /dev/urandom | pv -L 3k | nc -nvv ${SERVER_ADDRESS} 8128
On the server I receive them with:
nc -nvvl -p 8128 > /dev/null
I check usage of eth1 with the excellent iptraf and the throughput remains stuck to 3 kbit/s and more, and there is no increase in the counters of class htb 1:1
.
I believe I'm good with the masks. I also tried something simpler with dport 8128 0xFFFF
with no more results.
When displaying the filter, the at 20
seems correct because IP header is 20 byte long. The source and the destination ports are the first 4 bytes, so 32-bit match is correct. I don't understand the other values.
I'm using Debian 7:
# uname -a
Linux node-1 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u5 x86_64 GNU/Linux
I also cleared everything in iptables before trying the above.
Maybe I messed up something in the manner I connect the filter to a class. Maybe there is some kernel option I forgot to activate.
Any insights?