Linux – Why doesn’t this “tc filter” rule classify the traffic at intended

linuxnetworkingqostc

I'm trying to configure some basic traffic classification to limit the maximum ingress bandwidth for every machine in my local network to 3 Mbps. I'm operating the gateway 192.168.2.1, where the interface eth1 is attached to a switch to provide Internet connection for hosts at 192.168.2.0/24.

The classification is simple: ingress traffic is classified info two classes, the first class 1:20 is for the unclassified traffic by default as fallback, the second class 1:30 would limit the ingress bandwidth to 3 Mbps. Then I use a tc filter to classify the traffic originated from every host as class 1:30.

# Clear the qdisc first.
tc qdisc del root dev eth1

# Set a HTB qdisc on the root, and use class 1:20 by default
tc qdisc add dev eth1 root handle 1: htb default 20

# Create class 1:1, limit the total ingress bandwidth to 8 Mbps.
tc class add dev eth1 parent 1: classid 1:1 htb rate 8mbit burst 15k

# Class 1:20
tc class add dev eth1 parent 1:1 classid 1:20 htb rate 5mbit ceil 5.5mbit burst 15k

# Class 1:30
tc class add dev eth1 parent 1:1 classid 1:30 htb rate 3mbit ceil 4mbit burst 15k

# Attach fq_codel w/ ECN on each class to control latency / bufferbloat.
tc qdisc add dev eth1 parent 1:20 handle 20: fq_codel ecn
tc qdisc add dev eth1 parent 1:30 handle 30: fq_codel ecn

# Match the LAN range and classify them as class 1:30
tc filter add dev eth1 parent 1: protocol ip prio 2 u32 match ip src 192.168.2.0/24 flowid 1:30

However, the rule doesn't work as intended. The download speed for hosts is still the higher bandwidth specified in 1:20, not 1:30. What is my mistake?

Best Answer

Whats Your kernel version?

I'm trying to configure similar thing, and becoming to have strong feeling that kernel debian 4.15.0-23-generic is broken. Problem is not with HTB itself, but with classifying packets fo correct classid flow.

Even this educational example fails:

tc qdisc add dev int0 root handle 1:0 htb r2q 100000 default 13
tc class add dev int0 parent 1:0 classid 1:1 htb rate 10Gbit
tc class add dev int0 parent 1:1 classid 1:11 htb rate 1Gbit ceil 2Gbit
tc class add dev int0 parent 1:1 classid 1:12 htb rate 1Gbit ceil 2Gbit
tc class add dev int0 parent 1:1 classid 1:13 htb rate 1Gbit ceil 2Gbit

when do

tc -s -d filter show dev int0

You see, that all packets go correctly through 1:13

but if You do

iptables -t mangle -A POSTROUTING -j MARK --set-mark 11
tc filter add dev int0 parent 1:0 protocol ip handle 11 fw flowid 1:12

works in strange way, only few packets every few minutes goes as expected, other still go through default

next example of try to classify:

ipset create SHAPER4 hash:net family inet skbinfo
ipset add SHAPER4 10.0.0.0/8 skbprio 1:12
iptables -t mangle -A POSTROUTING -j SET --map-set SHAPER4 src,dst --map-prio

works same (it seems that statistically more packets goes right than in previous example)

There is no errors or warning in logs, just work like this

tc -s -d class show dev int0

class htb 1:13 parent 1:1 prio 0 quantum 1250 rate 1Gbit ceil 10Gbit 
linklayer ethernet burst 1375b/1 mpu 0b overhead 0b cburst 0b/1 mpu 0b 
overhead 0b level 0
 Sent 74139067325 bytes 53655936 pkt (dropped 0, overlimits 48986938 requeues 0)
backlog 0b 0p requeues 0
lended: 41808373 borrowed: 11847563 giants: 0
tokens: -81 ctokens: -4

class htb 1:11 parent 1:1 prio 0 quantum 1000 rate 10Mbit ceil 100Mbit 
linklayer ethernet burst 1600b/1 mpu 0b overhead 0b cburst 1600b/1 mpu 0b overhead 0b level 0
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
lended:  borrowed: 0 giants: 0
tokens: 20000 ctokens: 20000

class htb 1:12 parent 1:1 prio 0 quantum 1000 rate 5Mbit ceil 30Mbit 
linklayer ethernet burst 1600b/1 mpu 0b overhead 0b cburst 1593b/1 mpu 0b 
overhead 0b level 0
Sent 4704 bytes 48 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
lended: 48 borrowed: 0 giants: 0
tokens: 37550 ctokens: 6247

Some kernel networking developer here?

I will try other versions before report it :)