[kwlug-disc] tc and traffic shaping

Fernando Duran liberosec at yahoo.ca
Wed Sep 8 21:49:34 EDT 2010


(since my name was invoked he)

Hi Andrew,

It's been 10 years since I touched tc (and at that time the code was not 
being maintained for several years, the htb algorithm by a different developer 
was the only new thing) so I'm sure you know more about the scripts but I'll try 
to make a couple of not-totally-useless comments.


- The general policy (traffic order) is sound: VoIP first, interactive traffic 
and then the rest, mail etc.
- It never occurred to me to prioritize particular packets, like ACKs. If you 
found some reliable documentation or tests about this then it may make sense but 
my first instinct is that prioritizing just packets is not going to work or make 
much difference.
- Regarding UDP probably I'm not understanding your situation: most of your UDP 
traffic is going to be VoIP, why would you want to throttle that?
- You may want to optimize DNS traffic too (as part of "interactive")
- As you said it doesn't make any sense to prioritize incoming traffic
- Does it work? If you're not sure I suggest you use a bandwidth logging tool 
(or at worst logging iptables) to find out if the rules are doing what they 
should. There are traffic generators you can use and set up a few scenarios.
- An option instead of tc is to use the Tomato 
firmware http://www.polarcloud.com/tomato which has traffic shaping / QoS 
capabilities with nice GUI and graphics, I haven't tried it myself but I keep 
hearing good things about it.

Cheers,
---------------------
Fernando Duran
http://www.fduran.com



----- Original Message ----
> From: Andrew Kohlsmith (mailing lists account) <aklists at mixdown.ca>
> To: KWLUG discussion <kwlug-disc at kwlug.org>
> Sent: Wed, September 8, 2010 5:28:09 PM
> Subject: [kwlug-disc] tc and traffic shaping
> 
> Given that at least two people have openly commented that they're experienced 
> traffic shapers and one in particular (Frernando) has even admitted to using  
>tc, 
>
> I thought I'd share my traffic shaping script and ask some  questions.
> 
> I'm on DSL and have an internal modem. Linux has direct  control over the 
> outgoing message queue and thus I don't have to worry as  much about saturating 
>
> an 800kbit upstream with a 100mbit ethernet port  sourcing it.
> 
> I also run VOIP, and do not have a "real" telephone line.  Haven't for years. 
> In order to keep the Wife Acceptance Factor (WAF) high,  I've implemented 
>traffic 
>
> shaping and policing on the ADSL line.
> 
> I've  tried wondershaper and the various other ones out there (in fact mine is 

> based largely on wondershaper and the lartc manual online) but they were all 
> lacking in some way.
> 
> What I've pasted below is what I'm using. It's  almost perfect, and I'm hoping 

> that those with a little more tc  understanding than me can help me perfect 
it.
> 
> What the script does:
> 5  classes for outgoing traffic, in order of priority:
> - VOIP
> - ICMP ECHO,  TCP ACK, interactive traffic
> - default (bulk) traffic
> - mail
> - lowest  priority traffic
> 
> I set up the system so that VOIP traffic is sent via  FIFO, and the streams in 

> the other classes are handled in a fair queuing  manner. I guarantee bandwidth 

> for individual classes, and the total  guaranteed (576kbit) isn't close to my 
> maximum (800kbit).
> 
> >From an  downstream (data to me) perspective, I tried playing with priority 
> maps and  policing some of the bulk traffic in an effort to have the 
>application 
>
> layer  throttle back the UDP traffic.
> 
> I set up upstream traffic shaping/policing  on the DSL network interface, and 
>the 
>
> downstream traffic shaping/policing on  the LAN network interface; it doesn't 
> make any sense to try to do things  with the data coming IN to the firewall in 

> either direction.
> 
> So,  given all of this, and given the script below... would anyone care to 
> comment, give some tips or guidance?  What do you use to monitor  traffic 
>shaping 
>
> performance?
> 
> -A.
> 
> 
> # cat  /etc/rc.d/rc.tc
> #!/bin/bash
> 
> DSLDEV=ppp0
> LANDEV=eth0
> UPRATE=700
> DOWNRATE=4400
> 
> 
> tc_upstatus()  {
>   tc -s qdisc ls dev $DSLDEV
>   echo
>   tc -s class ls  dev $DSLDEV
> }
> 
> 
> tc_downstatus() {
>   tc -s qdisc ls dev  $LANDEV
>   echo
>   tc -s class ls dev  $LANDEV
> }
> 
> 
> tc_stop() {
> # clean existing down- and uplink qdiscs,  hide errors
>   tc qdisc del dev $DSLDEV root    2> /dev/null  > /dev/null
>   tc qdisc del dev $DSLDEV ingress 2> /dev/null >  /dev/null
> 
>   tc qdisc del dev $LANDEV root    2>  /dev/null > /dev/null
>   tc qdisc del dev $LANDEV ingress 2>  /dev/null > /dev/null
> 
> #  iptables -D FORWARD -p tcp --tcp-flags  SYN,RST SYN -j TCPMSS 
>--clamp-mss-to-
> pmtu 2> /dev/null
> #   iptables -t mangle -D PREROUTING -m p2p -j CONNMARK --set-mark 1 2> 
> /dev/null 2> /dev/null
> #  iptables -t mangle -D PREROUTING -m  connmark --mark 1 -j CONNMARK --
> restore-mark 2> /dev/null >  /dev/null
> }
> 
> 
> tc_start() {
> # *** UPSTREAM (SENDING) CONFIG  ***
> 
>   CEIL=$[90*$UPRATE/100]
>    MISCRATE=$[90*$CEIL/100]
> 
> # set packet queue much smaller than default  (100):
>   ip link set dev $DSLDEV qlen 100
> 
> # install root HTB,  point default traffic to 1:30:
>   tc qdisc add dev $DSLDEV root handle 1:  htb r2q 1 default 30
>   tc class add dev $DSLDEV parent 1: classid 1:1  htb rate ${MISCRATE}kbit ceil 
>
> ${CEIL}kbit
> 
> # 1:10 - VOIP
> # 1:20 -  ICMP ECHO, TCP ACK, interactive traffic
> # 1:30 - default (bulk) traffic
> #  1:40 - mail
> # 1:50 - lowest priority traffic
> 
>   tc class add dev  $DSLDEV parent 1:1 classid 1:10 htb rate 256kbit ceil 
> ${MISCRATE}kbit prio  1
>   tc class add dev $DSLDEV parent 1:1 classid 1:20 htb rate 64kbit  ceil 
> ${MISCRATE}kbit prio 2
>   tc class add dev $DSLDEV parent 1:1  classid 1:30 htb rate 128kbit ceil 
> ${MISCRATE}kbit prio 3
>   tc class  add dev $DSLDEV parent 1:1 classid 1:40 htb rate 64kbit ceil 
> ${MISCRATE}kbit  prio 4
>   tc class add dev $DSLDEV parent 1:1 classid 1:50 htb rate  64kbit ceil 
> ${MISCRATE}kbit prio 5
> 
> # VOIP gets FIFO, the rest get  Stochastic Fairness:
>   tc qdisc add dev $DSLDEV parent 1:10 handle 10:  pfifo limit 50
>   tc qdisc add dev $DSLDEV parent 1:20 handle 20: sfq  perturb 10
>   tc qdisc add dev $DSLDEV parent 1:30 handle 30: sfq perturb  10
>   tc qdisc add dev $DSLDEV parent 1:40 handle 40: sfq perturb  10
>   tc qdisc add dev $DSLDEV parent 1:50 handle 50: sfq perturb  10
> 
> # now set up filters to toss packets into the appropriate  class:
> #a) VOIP
>   tc filter add dev $DSLDEV protocol ip prio 1 u32  match ip dst 208.68.91.47 
> match ip protocol 17 0xff flowid 1:10
>   tc  filter add dev $DSLDEV protocol ip prio 2 u32 match ip dst 208.68.89.134 

> match ip protocol 17 0xff flowid 1:10
> 
> #b) Interactive stuff, ICMP  ECHO and TCP ACKs
>   tc filter add dev $DSLDEV protocol ip prio 10 u32  match ip tos 0x10 0xff 
>flowid 
>
> 1:20
>   tc filter add dev $DSLDEV  protocol ip prio 11 u32 match ip protocol 1 0xff 
> flowid 1:20
>   tc  filter add dev $DSLDEV protocol ip prio 12 u32 match ip protocol 47 0xff 

> flowid 1:20
>   tc filter add dev $DSLDEV protocol ip prio 13 u32  match ip protocol 50 0xff 

> flowid 1:20
>   tc filter add dev $DSLDEV  protocol ip prio 14 u32 match ip sport 53 0xffff 
> flowid 1:20
>   tc  filter add dev $DSLDEV protocol ip prio 15 u32 match ip dport 53 0xffff 
> flowid 1:20
>   tc filter add dev $DSLDEV protocol ip prio 16 u32  \
>      match ip protocol 6 0xff \
>      match u8 0x05  0x0f at 0 \
>      match u16 0x0000 0xffc0 at 2 \
>       match u8 0x10 0xff at 33 \
>      flowid 1:20
> 
> #c)  mail:
>   tc filter add dev $DSLDEV protocol ip prio 40 u32 match ip dport  25 0xffff 
> flowid 1:40
>   tc filter add dev $DSLDEV protocol ip prio  41 u32 match ip sport 25 0xffff 
> flowid 1:40
>   tc filter add dev  $DSLDEV protocol ip prio 42 u32 match ip sport 110 0xffff 

> flowid  1:40
>   tc filter add dev $DSLDEV protocol ip prio 43 u32 match ip sport  143 0xffff 

> flowid 1:40
> 
>   tc filter add dev $DSLDEV protocol ip  prio 50 u32 match ip dst 208.68.91.47 

> flowid 1:50
> 
> # any traffic that  the p2p match module for iptables finds (it marks with 
>--set-
> mark  1):
> #  tc filter add dev $DSLDEV protocol ip prio 59 handle 1 fw flowid  1:50
> 
> # LAN ingress handler; drop any NON-VOIP traffic >  rate
> #  tc qdisc add dev $DSLDEV handle ffff: ingress
> #  tc  filter add dev $DSLDEV parent ffff: protocol ip prio 90 u32 match ip src 
>
> 208.68.91.47 match ip protocol 17 0xff flowid :1
> #  tc filter add  dev $DSLDEV parent ffff: protocol ip prio 91 u32 match ip src 
>
> 208.68.89.134  match ip protocol 17 0xff flowid :1
> #  tc filter add dev $DSLDEV parent  ffff: protocol ip prio 99 u32 match ip src 
>
> 0.0.0.0/0 police rate  $[90*$DOWNRATE/100]kbit buffer 8k drop flowid :1
> 
> # *** DOWNSTREAM  (RECEIVING) CONFIG ***
> 
>   CEIL=$DOWNRATE
>    MISCRATE=$[98*$CEIL/100]
> 
> # set packet queue much smaller than default  (100):
>   ip link set dev $LANDEV qlen 100
> 
> # default priomap  -------------------------------------------> 1 2 1 1 2 2 2 2 
>
> 0 0 0 0 1 1  1 1
> #  tc qdisc add dev $LANDEV root handle 1: prio bands 5 priomap 2 2  2 2 2 2 2 

> 2 1 1 1 1 2 2 2 2 
> 
> # install root HTB, point default  traffic to 1:30:
>   tc qdisc add dev $LANDEV root handle 1: htb r2q 5  default 30
>   tc class add dev $LANDEV parent 1: classid 1:1 htb rate  ${MISCRATE}kbit ceil 
>
> ${CEIL}kbit
> 
> # 1:10 - VOIP
> # 1:20 - ICMP ECHO,  TCP ACK, interactive traffic
> # 1:30 - default (bulk) traffic
> # 1:40 -  mail
> # 1:50 - lowest priority traffic
> 
>   tc class add dev $LANDEV  parent 1:1 classid 1:10 htb rate 256kbit ceil 
> ${MISCRATE}kbit prio  1
>   tc class add dev $LANDEV parent 1:1 classid 1:20 htb rate 64kbit  ceil 
> ${MISCRATE}kbit prio 2
>   tc class add dev $LANDEV parent 1:1  classid 1:30 htb rate 128kbit ceil 
> ${MISCRATE}kbit prio 3
>   tc class  add dev $LANDEV parent 1:1 classid 1:40 htb rate 64kbit ceil 
> ${MISCRATE}kbit  prio 4
>   tc class add dev $LANDEV parent 1:1 classid 1:50 htb rate  64kbit ceil 
> ${MISCRATE}kbit prio 5
> 
> # VOIP gets FIFO, the rest get  Stochastic Fairness:
>   tc qdisc add dev $LANDEV parent 1:10 handle 10:  pfifo limit 50
>   tc qdisc add dev $LANDEV parent 1:20 handle 20: sfq  perturb 10
>   tc qdisc add dev $LANDEV parent 1:30 handle 30: sfq perturb  10
>   tc qdisc add dev $LANDEV parent 1:40 handle 40: sfq perturb  10
>   tc qdisc add dev $LANDEV parent 1:50 handle 50: sfq perturb  10
> 
> # now set up filters to toss packets into the appropriate  class:
> #a) VOIP
>   tc filter add dev $LANDEV protocol ip prio 1 u32  match ip src 208.68.91.47 
> match ip protocol 17 0xff flowid 1:10
>   tc  filter add dev $LANDEV protocol ip prio 2 u32 match ip src 208.68.89.134 

> match ip protocol 17 0xff flowid 1:10
> 
> #b) Interactive stuff, ICMP  ECHO and TCP ACKs
>   tc filter add dev $LANDEV protocol ip prio 10 u32  match ip tos 0x10 0xff 
>flowid 
>
> 1:20
>   tc filter add dev $LANDEV  protocol ip prio 11 u32 match ip protocol 1 0xff 
> flowid 1:20
>   tc  filter add dev $LANDEV protocol ip prio 12 u32 match ip protocol 47 0xff 

> flowid 1:20
>   tc filter add dev $LANDEV protocol ip prio 13 u32  match ip protocol 50 0xff 

> flowid 1:20
>   tc filter add dev $LANDEV  protocol ip prio 14 u32 match ip sport 53 0xffff 
> flowid 1:20
>   tc  filter add dev $LANDEV protocol ip prio 15 u32 match ip dport 53 0xffff 
> flowid 1:20
>   tc filter add dev $LANDEV protocol ip prio 16 u32  \
>      match ip protocol 6 0xff \
>      match u8 0x05  0x0f at 0 \
>      match u16 0x0000 0xffc0 at 2 \
>       match u8 0x10 0xff at 33 \
>      flowid 1:20
> 
> #c)  mail:
>   tc filter add dev $LANDEV protocol ip prio 40 u32 match ip dport  25 0xffff 
> flowid 1:40
>   tc filter add dev $LANDEV protocol ip prio  41 u32 match ip sport 25 0xffff 
> flowid 1:40
>   tc filter add dev  $LANDEV protocol ip prio 42 u32 match ip sport 110 0xffff 

> flowid  1:40
>   tc filter add dev $LANDEV protocol ip prio 43 u32 match ip sport  143 0xffff 

> flowid 1:40
> 
>   tc filter add dev $LANDEV protocol ip  prio 50 u32 match ip src 208.68.91.47 

> flowid 1:50
> 
> # any traffic that  the p2p match module for iptables finds (it marks with 
>--set-
> mark  1):
> #  tc filter add dev $LANDEV protocol ip prio 59 handle 1 fw flowid  2:50
> 
> # p2p detection
> #  iptables -t mangle -A PREROUTING -m p2p  -j CONNMARK --set-mark 1
> #  iptables -t mangle -A PREROUTING -m connmark  --mark 1 -j CONNMARK --
> restore-mark
> }
> 
> case "$1"  in
> 'start')
>   tc_start
>   ;;
> 'stop')
>    tc_stop
>   ;;
> 'restart')
>   tc_stop
>   sleep 1
>    tc_start
>   ;;
> 'upstatus')
>   tc_upstatus
>    ;;
> 'downstatus')
>   tc_downstatus
>   ;;
> *)
>   echo  "usage $0  start|stop|restart"
> esac
> 
> _______________________________________________
> kwlug-disc_kwlug.org  mailing list
> kwlug-disc_kwlug.org at kwlug.org
> http://astoria.ccjclearline.com/mailman/listinfo/kwlug-disc_kwlug.org
> 







More information about the kwlug-disc mailing list