Dear reader, I'm not updating these pages anymore. If you have tc or ip related questions, you can post them on the LARTC mailing list.



What I wanna do

These are the results of the tests I did with CBQ classes, subclasses and filters.

Basic setup

Used script (download)

RATE_TOT=140kbps
IP=kriek
RATE1=100kbps
PRIO1="prio 3"
 
DEV="dev eth0"
OPTION="allot 1514 maxburst 20 avpkt 1000"
 
tc qdisc del $DEV root
tc qdisc add $DEV root handle 10: cbq bandwidth 10mbit avpkt 1000
tc class add $DEV parent 10:0 classid 10:1 cbq bandwidth 10mbit rate $RATE_TOT $OPTION bounded prio 3
 
tc class add $DEV parent 10:1 classid 10:10 cbq bandwidth $RATE_TOT rate $RATE1 $WEIGHT1 $OPTION $PRIO1 bounded

tc filter add $DEV parent 10: protocol ip prio 3 handle 1 fw classid 10:1 # red filter
tc filter add $DEV parent 10:1 protocol ip prio 3 handle 1 fw classid 10:10 # green filter
 

iptables -F
iptables -X
iptables -N acc_0
iptables -N acc_1
iptables -A OUTPUT -t mangle -p tcp --dport 2000 -j MARK --set-mark 1
iptables -A OUTPUT -p tcp --dport 2000 -j acc_0

This is the basic setup of my tests. The red, green and blue lines represent the different filters. I use fw filters based on marking packets with ipchains.

The first tests I did, was trying to understand the different filters. These are the results (100kbps gives a real bandwidth of 75kbps.

filterclass 10:10
boundedbounded + isolated
red 157 kbps157 kbps
red + green109 kbps109 kbps
blue 109 kbps109 kbps
green Full Full

Next test (1)

For the next test, I removed the bounded parameter of class 10:10.

Used script (download)

RATE_TOT=140kbps        # In KiloBytes/Sec
IP=kriek
RATE1=100kbps
PRIO1="prio 3"
RATE2=30kbps
PRIO2="prio 3"
 
DEV="dev eth0"
OPTION="allot 1514 maxburst 20 avpkt 1000"
 
tc qdisc del $DEV root
tc qdisc add $DEV root handle 10: cbq bandwidth 10mbit avpkt 1000
tc class add $DEV parent 10:0 classid 10:1 cbq bandwidth 10mbit rate $RATE_TOT $OPTION isolated bounded prio 3
 
tc class add $DEV parent 10:1 classid 10:10 cbq bandwidth $RATE_TOT rate $RATE1 $WEIGHT1 $OPTION $PRIO1 isolated

tc filter add $DEV parent 10: protocol ip prio 3 handle 1 fw classid 10:1
tc filter add $DEV parent 10:1 protocol ip prio 3 handle 1 fw classid 10:10
 
iptables -F
iptables -X
iptables -N acc_0
iptables -N acc_1
iptables -A OUTPUT -t mangle -p tcp --dport 2000 -j MARK --set-mark 1
iptables -A OUTPUT -p tcp --dport 2000 -j acc_0

filterclass 10:10
 isolated
red 157 kbps157 kbps
red + green157 kbpsFull
blue 157 kbpsFull
green Full Full

When class 10:10 is not bounded, the results are like expected. But when you isolated class 10:10 and create some traffic in it with a filter, the bandwidth is totally used like there is no QOS.

Next test (2)

I add a second class as a subclass of 10:1. I want to put the traffic in the different classes, but I want the most traffic in class 10:10. So I give class 10:10 a rate of 130kbps and class 10:20 10kbps.

Used script (download)

RATE_TOT=140kbps
IP=kriek
RATE1=130kbps
PRIO1="prio 3"
RATE2=10kbps
PRIO2="prio 3"
 
DEV="dev eth0"
OPTION="allot 1514 maxburst 20 avpkt 1000"
 
tc qdisc del $DEV root
tc qdisc add $DEV root handle 10: cbq bandwidth 10mbit avpkt 1000
tc class add $DEV parent 10:0 classid 10:1 cbq bandwidth 10mbit rate $RATE_TOT $OPTION bounded prio 3
 
tc class add $DEV parent 10:1 classid 10:10 cbq bandwidth 10mbit rate $RATE1 $WEIGHT1 $OPTION $PRIO1 isolated
tc class add $DEV parent 10:1 classid 10:20 cbq bandwidth 10mbit rate $RATE2 $WEIGHT2 $OPTION $PRIO2

tc filter add $DEV parent 10:0 protocol ip prio 3 handle 1 fw classid 10:1
tc filter add $DEV parent 10:0 protocol ip prio 3 handle 2 fw classid 10:1
tc filter add $DEV parent 10:1 protocol ip prio 3 handle 1 fw classid 10:10
tc filter add $DEV parent 10:1 protocol ip prio 3 handle 2 fw classid 10:20
 
iptables -F
iptables -X
iptables -N acc_0
iptables -N acc_1
iptables -A OUTPUT -t mangle -p tcp --dport 2000 -j MARK --set-mark 1
iptables -A OUTPUT -t mangle -p tcp --dport 2001 -j MARK --set-mark 2
iptables -A OUTPUT -p tcp --dport 2000 -j acc_0
iptables -A OUTPUT -p tcp --dport 2001 -j acc_1

filterclass 10:10/class 10:20
 isolated1/2 isolated
red 79 + 79 79 + 79 79 + 79
red + green145 + 13Full Full (X)
blue 145 + 13Full Full (X)
green Full Full Full

Full (X): Non-isolated alone: 157 kbps
Isolated class alone: Full
2 classes together: Full with class 10:10 72%

Next test (3)

To have better results than with the tests 2 and 3, I attached a second qdisc to class 10:1. This has the advantage that I don't have to attach a filter to a class and don't have subclasses.

Used script (download)

RATE_TOT=140kbps
IP=kriek
RATE1=130kbps
PRIO1="prio 3"
RATE2=10kbps
PRIO2="prio 3"
 
DEV="dev eth0"
OPTION="allot 1514 maxburst 20 avpkt 1000"
 
tc qdisc del $DEV root
tc qdisc add $DEV root handle 10: cbq bandwidth 10mbit avpkt 1000
tc class add $DEV parent 10:0 classid 10:1 cbq bandwidth 10mbit rate $RATE_TOT $OPTION prio 3 bounded
 
tc qdisc add $DEV parent 10:1 handle 20: cbq bandwidth $RATE_TOT allot 1514 avpkt 1000

tc class add $DEV parent 20: classid 20:10 cbq bandwidth $RATE_TOT rate $RATE1 $WEIGHT1 $OPTION $PRIO1 bounded
tc class add $DEV parent 20: classid 20:20 cbq bandwidth $RATE_TOT rate $RATE2 $WEIGHT2 $OPTION $PRIO2 isolated bounded

tc filter add $DEV parent 10: protocol ip prio 3 handle 1 fw classid 10:1
tc filter add $DEV parent 10: protocol ip prio 3 handle 2 fw classid 10:1
tc filter add $DEV parent 20: protocol ip prio 3 handle 1 fw classid 20:10
tc filter add $DEV parent 20: protocol ip prio 3 handle 2 fw classid 20:20
 
iptables -F
iptables -X
iptables -N acc_0
iptables -N acc_1
iptables -A OUTPUT -t mangle -p tcp --dport 2000 -j MARK --set-mark 1
iptables -A OUTPUT -t mangle -p tcp --dport 2001 -j MARK --set-mark 2
iptables -A OUTPUT -p tcp --dport 2000 -j acc_0
iptables -A OUTPUT -p tcp --dport 2001 -j acc_1

filterclass 10:10/class 10:20
isolated 1/2 isolated
red 145 + 13145 + 13145 + 13
blueFull Full Full

Conclusion

You get the same results if you use a filter that points directly to the good subclass (blue filter) as if you use different filters to get there (red filters).

When you use an isolated class, the traffic is not putted in the classes like you would expect. Just don't use the isolated parameter and everything will be fine.