I cannot get HTB to function properly. Most classes transmit more than
their ceiling, more than any reasonable burst would allow. I have
reviewed my script several times but I can''t find anything out of
place.
The setup is as standard as it gets: one HTB root qdisc, a small tree of
HTB classes, one SFQ qdisc for each leaf HTB class.
To illustrate the problem, here is non-leaf HTB class 1:30, the one that
exhibits the worst behaviour:
| tc class add dev eth0 parent 1:1 classid 1:30 htb prio 30 rate 149kbit
Here are the statistic after a few hours:
| class htb 1:30 parent 1:1 rate 149000bit ceil 149000bit burst 1617b cburst
1617b
| Sent 344497902 bytes 513804 pkts (dropped 0, overlimits 0)
| rate 226304bit 74pps
| lended: 0 borrowed: 0 giants: 0
| tokens: -59999999 ctokens: -59999999
As you can see, the class has been transmitting at a 226kbit rate, when
its ceil is 149kbit! I let tc choose burst/cburst and they seem ok.
I am concerned by the tokens and ctokens numbers, because they seem
quite out of place. What is happening here?
Here are the statistics for the root qdisc and class:
| qdisc htb 1: r2q 10 default 20 direct_packets_stat 1090
| Sent 415742014 bytes 1523439 pkts (dropped 35052, overlimits 1693102)
| backlog 230p
| class htb 1:1 root rate 224000bit ceil 224000bit burst 1627b cburst 1627b
| Sent 413505692 bytes 1522121 pkts (dropped 0, overlimits 0)
| rate 285200bit 162pps
| lended: 0 borrowed: 0 giants: 0
| tokens: -59946694 ctokens: -59946694
Why does the qdisc show millions of overlimit packets and only thousands
of dropped ones? Why are those numbers zero in ALL the classes?
The OS is Debian Sarge with a vanilla 2.6.9 kernel and the iproute (tc)
package that comes with Debian, version 20041019-3.
The eth0 device which is being shaped is part of Ethernet bridge br0.
Am I missing something or is this a bug? Has it already been fixed in a
new version of any of the software I am using?
I can send the full tc script, kernel config or anything else by mail.
I have attached an excerpt of the script below.
Tobia
Relevant (IMHO) part of the tc script, after variable substitution:
| tc qdisc add dev eth0 root handle 1: htb
|
| tc class add dev eth0 parent 1: classid 1:1 htb rate 224kbit
| tc class add dev eth0 parent 1:1 classid 1:10 htb prio 1 rate 224kbit
| tc class add dev eth0 parent 1:1 classid 1:20 htb prio 20 rate 200kbit
| tc class add dev eth0 parent 1:1 classid 1:30 htb prio 30 rate 149kbit
| tc class add dev eth0 parent 1:20 classid 1:21 htb prio 21 rate 178kbit
| tc class add dev eth0 parent 1:20 classid 1:22 htb prio 22 rate 178kbit
| tc class add dev eth0 parent 1:30 classid 1:31 htb prio 31 rate 112kbit
| tc class add dev eth0 parent 1:30 classid 1:32 htb prio 32 rate 112kbit
|
| for i in 10 21 22 31 32; do
| tc qdisc add dev eth0 parent 1:$i handle $i: sfq perturb 10
| done
The rest of the script are filters and a trivial ingress policer.