#!/bin/sh # Use tc to generate traffic queues for shaping traffic. # Many thanks to Steve Gran for the majority of this. OUTIF=ethe # This layout makes this kind of tree: # $OUTIF # | # htb # / \ # 1:10 1:11 # | | # htb htb # / / | \ # pfifo 1:20 1:30 1:40 # | | | # htb htb htb # | | | # sfq sfq sfq # First set up the root of the tree. This is the core of the shaping # and is the overall limit we're setting on our link. # Delete everything to give us a clean sheet tc qdisc del dev $OUTIF root 2>/dev/null || true # Set the root to have the 1: handle and to default to 30: for anything we don't filter tc qdisc add dev $OUTIF root handle 1: htb default 30 # Create a token bucket 448kbps wide to contain everything tc class add dev $OUTIF parent 1: classid 1:1 htb rate 448kbit ceil 448kbit burst 2560 # At the top level we create two queing disciplines, one for VOIP traffic, one for everything else # VOIP (1:10) has 192kbps which is a theoretical three simultaneous calls. tc class add dev $OUTIF parent 1:1 classid 1:10 htb rate 192kbit ceil 448kbit quantum 1200 burst 2560 cburst 1280 prio 0 # Everything else (1:11) has 256kbps but can borrow up to the 448 limit if the voip is inactive. tc class add dev $OUTIF parent 1:1 classid 1:11 htb rate 256kbit ceil 448kbit quantum 1200 burst 2560 cburst 1280 prio 0 # We then create three traffic buckets in the 1:11 class which we will use to shape traffic further. # System services (1:20) are guaranteed 128kbps and can borrow up to the max. tc class add dev $OUTIF parent 1:11 classid 1:20 htb rate 128kbit ceil 448kbit quantum 1200 burst 2560 cburst 1280 prio 2 # Generic services (1:30) such as HTTP are guaranteed 96kbps and can borrow up to the max. tc class add dev $OUTIF parent 1:11 classid 1:30 htb rate 96kbit ceil 448kbit quantum 1200 burst 2560 cburst 1280 prio 4 # Lower priority services (1:40) such as bittorrent are given 32kbps and can borrow up to 128kbps only. tc class add dev $OUTIF parent 1:11 classid 1:40 htb rate 32kbit ceil 128kbit quantum 1200 burst 2560 cburst 1280 prio 6 # Handles are now created, setting the leaf qdisc for each of the classes above # VOIP is 10: and is a pfifo tc qdisc add dev $OUTIF parent 1:10 handle 10: pfifo limit 10 # System services are 20: and are a stochastic fairness queue tc qdisc add dev $OUTIF parent 1:20 handle 20: sfq perturb 10 # Generic services are 30: and are a stochastic fairness queue tc qdisc add dev $OUTIF parent 1:30 handle 30: sfq perturb 10 # Low priority services are 40: and are a stochastic fairness queue tc qdisc add dev $OUTIF parent 1:40 handle 40: sfq perturb 10 # Now the following filters stuff into the various buckets... # VOIP is IAX2 and is port 4569 in either direction. tc filter add dev $OUTIF protocol ip parent 1: prio 3 u32 match ip dport 4569 0xffff flowid 1:10 tc filter add dev $OUTIF protocol ip parent 1: prio 3 u32 match ip sport 4569 0xffff flowid 1:10 # System services such as DNS, SSH, SMTP, etc come next. tc filter add dev $OUTIF protocol ip parent 1: prio 3 u32 match ip dport 53 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 3 u32 match ip dport 123 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 1194 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 1194 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 22 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 22 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 25 0xffff flowid 1:20 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 25 0xffff flowid 1:20 # The following are explicitly derated services such as bittorrent tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 6881 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 6881 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 6882 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 6882 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 16881 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 16881 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip sport 16882 0xffff flowid 1:40 tc filter add dev $OUTIF protocol ip parent 1: prio 4 u32 match ip dport 16882 0xffff flowid 1:40 # This rule matches ICMP and gives it the same priority as VOIP so that it doesn't break things. tc filter add dev $OUTIF protocol ip parent 1: prio 2 u32 match ip protocol 1 0xff flowid 1:10 # # experimental - should match contentless ack's # tc filter add dev $1 protocol ip parent 1: prio 6 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