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

I want to know how you can divide the traffic in different classes. So I created two classes, changes the weight parameter for different rates, generated some traffic and noted the bandwidth the two classes gets.

Used script

I used a second qdisc so the two classes are attached to a qdisc and not to another class.

Used script (download)

WEIGHT1=80

WEIGHT2=`expr 100 - $WEIGHT1`

WEIGHT1="weight $WEIGHT1"
echo $WEIGHT1
WEIGHT2="weight $WEIGHT2"
echo $WEIGHT2

RATE_TOT=140kbps        # In KiloBytes/Sec
IP=kriek
RATE1=112kbps
PRIO1="prio 3"
RATE2=28kbps
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:2 cbq bandwidth 10mbit rate $RATE_TOT $OPTION isolated bounded prio 3
 
tc qdisc add $DEV parent 10:2 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
tc class add $DEV parent 20: classid 20:20 cbq bandwidth $RATE_TOT rate $RATE2 $WEIGHT2 $OPTION $PRIO2

tc filter add $DEV parent 10: protocol ip prio 3 handle 1 fw classid 10:2
tc filter add $DEV parent 10: protocol ip prio 3 handle 2 fw classid 10:2
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

Results

TESTA : RATE_TOT = 140kbps 
        RATE1 = RATE2 = 70 kbps

TESTB: RATE_TOT = 140kbps 
       RATE1 = 84 kbps (60%)
       RATE2 = 56 kbps (40%)

TESTC: RATE_TOT = 140kbps 
       RATE2 = 112 kbps (80%)
       RATE1 = 28  kbps (40%)

TESTD: RATE_TOT = 140kbps 
       RATE2 = 126 kbps (90%)
       RATE1 = 14  kbps (10%)

TESTE: RATE_TOT = 140kbps 
       RATE2 = 133 kbps (95%)
       RATE1 = 7   kbps (5%)
WEIGTH1WEIGTH2TESTATESTBTESTCTESTDTESTE
50 50 50 %50 %50 %  
60 40 54.9%60 %60 %  
70 30 59.3%60.7%70.3% 70%
75 25 61.2%62.7%75.4%  
80 20 62.8%63.9%79.6%  
85 15 64.2%64.5%79.9% 85.6%
90 10 66.1%66.3%80 %89.2%90%
95 5 69.3%69.5%81.3%90 %94.2%
97 3 70.8%70.5%81.2% 94.4%
98 2 73.4%72.9%82.5%  
99 1 78.2%78.1%85.8%  
100 (X)0 7.4% 8.2% 14.1%  

(X)

Giving one class 0 as weight is a bad idea. It disturbes the internal sharing and results in very strange results (TODO: test again).

I tried also to generate 10 streams in class 1 and 1 stream in class 1. But the results were the same (TODO).

Conclusion

At first sight, the results don't look good. But when you have the same proportion for the rates and the weights, the result looks good (red results). So as a rule, take the weight proportional the rate and everything will be fine. But when you choose the weight for one class a lot bigger, also the smaller proportionals in rates are very accurate.

Extra tests

When you remove qdisc 20: and attach the 2 subclasses to class 10:2, then is the weight parameter total ignored. The traffic is divided to the two sublcasses proportional to the rate of the two subclasses.

If you use a filter to put the traffic in 10:2 and then two filters to put the traffic in 10:10 and 10:20, each class get 50%.

I tried also to generate 10 streams in class 1 and 1 stream in class 2. But the results were the same (TODO: extra tests results).

I tested it with this script :

Used script (download)