#!/bin/sh # # Seminal release by Bert Hubert # Copyright 2002, licensed under the GPL # Originally part of the Linux Advanced Routing & Shaping HOWTO # # Modified version by Robert Koch (aka akbor) published in October 2007 # found at http://wiki.wl500g.info/index.php/PackageWondershaper # # Some additions on June 1st 2008 by Jean-Marc Liotier # cf. http://serendipity.ruwenzori.net/index.php/2008/06/01/modified-wondershaper-for-better-voip-qos # Example integration in Debian's /etc/network/interfaces # ## auto eth1 ## iface eth1 inet dhcp ## up /usr/local/bin/wondershaper eth1 17408 1187 # # where usage is 'wondershaper device downlink_rate uplink_rate' # with values expressed in Kilobits per second DEV=$1 DOWNLINK=$2 UPLINK=$3 # low priority OUTGOING traffic - you can leave this blank if you want # low priority source netmasks NOPRIOHOSTSRC="" # low priority destination netmasks NOPRIOHOSTDST="" # low priority source ports NOPRIOPORTSRC="20 25 989 1080 1194 1214 1412 2086 2234 3364 4444 4662 4666 4672 4949 6346 6347 6699 6881 6882 8436 9001 9030 9050 9100 9999 44646" # 20 ftp-data # 25 smtp # 989 ftps-data # 1080 gnunet # 1194 openvpn # 1214 fasttrack # 1412 directconnect # 2086 gnunet # 2234 soulseek # 3364 mldonkey # 4444 directconnect # 4662 edonkey # 4666 edonkey # 4672 edonkey # 4949 openvpn # 6346 gnutella # 6347 gnutella 2 # 6699 opennapster # 6881 bittorrent # 6882 bittorrent # 8436 freenet # 9001 tor # 9030 tor # 9050 tor # 9100 tor # 9999 opennapster # 44646 openvpn # Source : http://mldonkey.sourceforge.net/WhatFirewallPortsToOpen # low priority destination ports #NOPRIOPORTDST="" # I'm lazy so sources and destinations are set to be the same. NOPRIOPORTDST=$NOPRIOPORTSRC # high priority source ports - meant to only be VOIP but # could also be the small set of source ports that you consider the highest priority HIGHPRIOPORTSRC="2427 4569 5004 5060 5061 27015 27030" # 2427 mgcp # 4569 iax # 5004 rtp # 5060 sip # 5061 sip-tls # 27015 valve source game engine # 27030 valve source game engine # high priority destination ports - meant to only be VOIP but # could also be the small set of source ports that you consider the highest priority #HIGHPRIOPORTDST="" # I'm lazy so sources and destinations are set to be the same. HIGHPRIOPORTDST=$HIGHPRIOPORTSRC if [ "$1" = "dumpconf" ] then echo NOPRIOHOSTSRC echo $NOPRIOHOSTSRC echo NOPRIOHOSTDST echo $NOPRIOHOSTDST echo NOPRIOPORTSRC echo $NOPRIOPORTSRC echo NOPRIOPORTDST echo $NOPRIOPORTDST echo HIGHPRIOPORTSRC echo $HIGHPRIOPORTSRC echo HIGHPRIOPORTDST echo $HIGHPRIOPORTDST exit fi if [ "$2" = "status" ] then tc -s qdisc ls dev $DEV tc -s class ls dev $DEV exit fi if [ "$1" = "help" ] then echo usage : wondershaper device downlink_rate uplink_rate echo example : wondershaper eth1 17408 1187 echo Values are expressed in Kilobits per second echo echo Set the downlink_rate and uplink_rate to somewhat less than actual capacity. echo You may need to experiment to find the highest values that do not saturate the link. echo echo Low priority netmask and ports, both source and destination, can be set my modifying the relevant values in the script itself. echo echo status usage : wondershaper device status echo status example : wondershaper eth1 status echo echo configuration dump usage : wondershaper dumpconf exit fi # clean existing down- and uplink qdiscs, hide errors tc qdisc del dev $DEV root 2> /dev/null > /dev/null tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null if [ "$1" = "stop" ] then exit fi ########## uplink ########## # install root HTB, point default traffic to 1:20: tc qdisc add dev $DEV root handle 1: htb default 20 # shape everything at $UPLINK speed - this prevents huge queues in your # DSL modem which destroy latency: tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit \ ceil ${UPLINK}kbit burst 6k # high prio class 1:10 - gets 50 to 100% traffic and highest priority: tc class add dev $DEV parent 1:1 classid 1:10 htb rate $((5*$UPLINK/10))kbit \ ceil ${UPLINK}kbit burst 6k prio 1 # bulk & default class 1:20 - gets 40 to 100% traffic and lower priority: tc class add dev $DEV parent 1:1 classid 1:20 htb rate $((4*$UPLINK/10))kbit \ ceil ${UPLINK}kbit burst 6k prio 2 # lowest priority class 1:30 - gets 10 to 100% traffic and lowest priority: tc class add dev $DEV parent 1:1 classid 1:30 htb rate $((1*$UPLINK/10))kbit \ ceil ${UPLINK}kbit burst 6k prio 3 # all get Stochastic Fairness: tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10 # 'match ip protocol 0x11 0xff' means UDP U32rootfilter="tc filter add dev $DEV parent 1: protocol ip" # high priority for VoIP traffic (by TOS) $U32rootfilter prio 1 u32 \ match ip tos 0x68 0xff \ match ip protocol 0x11 0xff \ flowid 1:10 $U32rootfilter prio 1 u32 \ match ip tos 0xb8 0xff \ match ip protocol 0x11 0xff \ flowid 1:10 # high priority for VoIP traffic (by source port) for port in $HIGHPRIOPORTSRC do $U32rootfilter prio 1 u32 \ match ip sport $port 0xffff \ match ip protocol 0x11 0xff \ flowid 1:10 done # high priority for VoIP traffic (by destination port) for port in $HIGHPRIOPORTDST do $U32rootfilter prio 1 u32 \ match ip dport $port 0xffff \ match ip protocol 0x11 0xff \ flowid 1:10 done # TOS Minimum Delay (ssh, NOT scp) in 1:10: $U32rootfilter prio 1 u32 \ match ip tos 0x10 0xff \ flowid 1:10 # ICMP (ip protocol 1) in the interactive class 1:10 so we # can do measurements & impress our friends: $U32rootfilter prio 1 u32 \ match ip protocol 1 0xff \ flowid 1:10 # To speed up downloads while an upload is going on, put ACK packets in # the interactive class: $U32rootfilter prio 2 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:10 # some traffic however suffers a worse fate # we could distinguish between TCP and UDP for those no priority filters, but we don't. for port in $NOPRIOPORTDST do $U32rootfilter prio 1 u32 \ match ip dport $port 0xffff flowid 1:30 done for port in $NOPRIOPORTSRC do $U32rootfilter prio 1 u32 \ match ip sport $port 0xffff flowid 1:30 done for port in $NOPRIOHOSTSRC do $U32rootfilter prio 1 u32 \ match ip src $port flowid 1:30 done for port in $NOPRIOHOSTDST do $U32rootfilter prio 1 u32 \ match ip dst $port flowid 1:30 done # rest is 'non-interactive' ie 'bulk' and ends up in 1:20 $U32rootfilter prio 1 u32 \ match ip dst 0.0.0.0/0 flowid 1:20 ########## downlink ########## # slow downloads down to somewhat less than the real speed to prevent # queuing at our ISP. Tune to see how high you can set it. # ISPs tend to have *huge* queues to make sure big downloads are fast # # attach ingress policer: tc qdisc add dev $DEV handle ffff: ingress # filter *everything* to it (0.0.0.0/0), drop everything that's # coming in too fast: tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src \ 0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1