[MLB-WIRELESS] Rate shaping using HTB and SFQ

Fenn Bailey fenn_b at smktech.com.au
Mon Dec 12 17:49:13 EST 2005


Hey Steve (and all),

Without looking in very much detail (I got a sudden burst of laziness), I'm
fairly certain as to the general problem that's happening here.

Unfortunately, it's not quite as easy for doing in and outbound traffic
shaping as putting in the iptables hooks to classify traffic in the
INPUT/OUTPUT/FORWARD tables - shaping isn't quite this easy.

In fact, it's fairly hideous in some ways - linux traffic shaping can only
shape (usefully) on egress, not ingress - that is, you can only
shape/control traffic usefully when it's being OUTPUT from an interface you
control.

So, to do inbound shaping (at least usefully with HTB), you have to control
it as it LEAVES your downlink interface - ie: download shaping would happen
on your LAN interface and upload shaping on your WAN interface.

Each one needs it's own set of qdiscs/classes setup on their own interface
(which is why you pass the dev arg to tc).

The second part, is kernel packet traversal with QoS is VERY confusing. The
most useful thing you'll ever see to help understand this is this diagram:

http://www.docum.org/docum.org/kptd/

Glancing at Steve's example below, packets would be classified multiple
times as they traverse the iptables tables and finally in the default rule,
which is why all are classified as the default class.

It's a bit of a learning curve, but I recommend everyone interested to have
a good read of http://lartc.org/. The docum.org site is also good, as is
checkout out other basic traffic shaping scripts (ie: wondershaper/etc).

Good luck all!

	Fenn.

> -----Original Message-----
> From: melbwireless-bounces at wireless.org.au 
> [mailto:melbwireless-bounces at wireless.org.au] On Behalf Of 
> Steven Haigh
> Sent: Monday, 12 December 2005 12:36 PM
> To: Melbourne Wireless Mailing List
> Subject: [MLB-WIRELESS] Rate shaping using HTB and SFQ
> 
> HI all,
> 
> This is slightly OT, but could be very handy for traffic 
> flows on wireless interfaces... I'm using it on ppp0 which is 
> my DSL link to my ISP, however it could very easily be 
> changed to use a wifi interface... The problem I am having is 
> that the classifications that I am setting via iptables don't 
> seem to be hitting the actual leaf for shaping - meaning it 
> doesn't get it's guaranteed bandwidth.
> 
> The commands:
>          $TC qdisc add dev $INTERFACE root handle 1: htb default 70
>          $TC class add dev $INTERFACE parent 1: classid 1:1 
> htb rate 256kbit
>          $TC class add dev $INTERFACE parent 1:1 classid 1:10 
> htb rate 128kbit ceil 256kbit prio 0
>          $TC class add dev $INTERFACE parent 1:1 classid 1:20 
> htb rate 64kbit ceil 256kbit prio 1
>          $TC class add dev $INTERFACE parent 1:1 classid 1:30 
> htb rate 40kbit ceil 256kbit prio 2
>          $TC class add dev $INTERFACE parent 1:1 classid 1:40 
> htb rate 22kbit ceil 256kbit prio 3
>          $TC class add dev $INTERFACE parent 1:1 classid 1:50 
> htb rate 20kbit ceil 256kbit prio 4
>          $TC class add dev $INTERFACE parent 1:1 classid 1:60 
> htb rate 18kbit ceil 256kbit prio 5
>          $TC class add dev $INTERFACE parent 1:1 classid 1:70 
> htb rate 10kbit ceil 256kbit prio 6
> 
>          $TC qdisc add dev $INTERFACE parent 1:10 handle 10: 
> sfq perturb 10
>          $TC qdisc add dev $INTERFACE parent 1:20 handle 20: 
> sfq perturb 10
>          $TC qdisc add dev $INTERFACE parent 1:30 handle 30: 
> sfq perturb 10
>          $TC qdisc add dev $INTERFACE parent 1:40 handle 40: 
> sfq perturb 10
>          $TC qdisc add dev $INTERFACE parent 1:50 handle 50: 
> sfq perturb 10
>          $TC qdisc add dev $INTERFACE parent 1:60 handle 60: 
> sfq perturb 10
>          $TC qdisc add dev $INTERFACE parent 1:70 handle 70: 
> sfq perturb 10
> 
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 0 handle 10 fw flowid 1:10
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 1 handle 20 fw flowid 1:20
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 2 handle 30 fw flowid 1:30
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 3 handle 40 fw flowid 1:40
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 4 handle 50 fw flowid 1:50
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 5 handle 60 fw flowid 1:60
>          $TC filter add dev $INTERFACE parent 1:0 protocol ip 
> prio 6 handle 70 fw flowid 1:70
> 
> What we do here is create a root class with an ID of 1:0 - 
> then we create sub classes of that with various guaranteed 
> bandwidth amounts (128kbit, 64kbit, 40kbit, 22kbit, 20kbit, 
> 18kbit, and 10kbit) of various priorities (0 is highest, 6 is 
> lowest). We have the specified kbit amount as a minimum, 
> however if nothing of a higher priority exists, then it can 
> take up to the highest speed specified (in the root class) 
> which in my case is 256kbit.
> 
> We then use iptables to mark packets to match the various classes:
> 
>          # Catch all the small stuff... SYN/ACK/etc
>          $IPTABLES -t mangle -I OUTPUT -p tcp -m length 
> --length :64 - o $INTERFACE -j CLASSIFY --set-class 1:10
>          $IPTABLES -t mangle -I FORWARD -p tcp -m length 
> --length :64 -o $INTERFACE -j CLASSIFY --set-class 1:10
> 
>          # VoIP Stuff rated min 64kbit to max 256kbit
>          $IPTABLES -t mangle -A FORWARD -p udp --dport 5060 
> -o $INTERFACE -j CLASSIFY --set-class 1:20
>          $IPTABLES -t mangle -A FORWARD -p udp --dport 
> 10000:20000 -o $INTERFACE -j CLASSIFY --set-class 1:20
> 
>          # Outgoing mail gets minimum 40kbit if needed.
>          $IPTABLES -t mangle -A OUTPUT -p tcp --dport 25 -o 
> $INTERFACE -j CLASSIFY --set-class 1:30
> 
>          # Catchall to lowest
>          $IPTABLES -t mangle -A OUTPUT -o $INTERFACE -j 
> CLASSIFY -- set-class 1:70
>          $IPTABLES -t mangle -A FORWARD -o $INTERFACE -j 
> CLASSIFY -- set-class 1:70
> 
> Now this part doesn't seem to be working - as I can see the 
> classifications matching via iptables:
> # iptables -t mangle -L -n -v
> Chain FORWARD (policy ACCEPT 51745 packets, 13M bytes)
> pkts bytes target     prot opt in     out     source                
> destination
>    155  7380 CLASSIFY   tcp  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           length 0:64 CLASSIFY set 1:10
>     54 31992 CLASSIFY   udp  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           udp dpt:5060 CLASSIFY set 1:20
>      0     0 CLASSIFY   udp  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           udp dpts:10000:20000 CLASSIFY set 1:20
>    356 82776 CLASSIFY   all  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           CLASSIFY set 1:70
> 
> Chain INPUT (policy ACCEPT 55467 packets, 8606K bytes)
> pkts bytes target     prot opt in     out     source                
> destination
> 
> Chain OUTPUT (policy ACCEPT 59199 packets, 12M bytes)
> pkts bytes target     prot opt in     out     source                
> destination
>    113  5660 CLASSIFY   tcp  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           length 0:64 CLASSIFY set 1:10
>      0     0 CLASSIFY   tcp  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           tcp dpt:25 CLASSIFY set 1:30
>    231 34802 CLASSIFY   all  --  *      ppp0    0.0.0.0/0             
> 0.0.0.0/0           CLASSIFY set 1:70
> 
> HOWEVER, it is not matching the actual classes:
> # tc -s qdisc show dev ppp0
> qdisc htb 1: r2q 10 default 70 direct_packets_stat 0 Sent 
> 145439 bytes 798 pkt (dropped 0, overlimits 0 requeues 0) 
> rate 0bit 0pps backlog 0b 0p requeues 0 qdisc sfq 10: parent 
> 1:10 limit 128p quantum 1492b perturb 10sec Sent 0 bytes 0 
> pkt (dropped 0, overlimits 0 requeues 0) rate 0bit 0pps 
> backlog 0b 0p requeues 0 qdisc sfq 20: parent 1:20 limit 128p 
> quantum 1492b perturb 10sec Sent 0 bytes 0 pkt (dropped 0, 
> overlimits 0 requeues 0) rate 0bit 0pps backlog 0b 0p 
> requeues 0 qdisc sfq 30: parent 1:30 limit 128p quantum 1492b 
> perturb 10sec Sent 0 bytes 0 pkt (dropped 0, overlimits 0 
> requeues 0) rate 0bit 0pps backlog 0b 0p requeues 0 qdisc sfq 
> 40: parent 1:40 limit 128p quantum 1492b perturb 10sec Sent 0 
> bytes 0 pkt (dropped 0, overlimits 0 requeues 0) rate 0bit 
> 0pps backlog 0b 0p requeues 0 qdisc sfq 50: parent 1:50 limit 
> 128p quantum 1492b perturb 10sec Sent 0 bytes 0 pkt (dropped 
> 0, overlimits 0 requeues 0) rate 0bit 0pps backlog 0b 0p 
> requeues 0 qdisc sfq 60: parent 1:60 limit 128p quantum 1492b 
> perturb 10sec Sent 0 bytes 0 pkt (dropped 0, overlimits 0 
> requeues 0) rate 0bit 0pps backlog 0b 0p requeues 0 qdisc sfq 
> 70: parent 1:70 limit 128p quantum 1492b perturb 10sec Sent 
> 145439 bytes 798 pkt (dropped 0, overlimits 0 requeues 0) 
> rate 0bit 0pps backlog 0b 0p requeues 0
> 
> As you can see above, there are - bytes hitting any other 
> classes - so the only class getting used is 1:70 - which is 
> out catchall non- priority, lowest guaranteed throughput...
> 
> Can anyone shed some light on what I've missed on this?
> 
> --
> Steven Haigh
> 
> Email: netwiz at crc.id.au
> Web: http://www.crc.id.au
> Phone: (03) 9017 0597 - 0412 935 897
> 
> 
> 
> 
> _______________________________________________
> Melbwireless mailing list
> Melbwireless at wireless.org.au
> http://wireless.org.au/mailman/listinfo/melbwireless
> 




More information about the Melbwireless mailing list