Created
August 28, 2010 17:25
-
-
Save bartvandendriessche/555363 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/ash | |
| # Modified to run under DD-WRT | |
| # http://www.morph3ous.net/2009/11/20/beta-hfsc-traffic-shaping-for-qos-on-dd-wrt/ | |
| # Go to Administration and then commands | |
| # Paste script in and click on the save firewall button | |
| # Reboot router and test | |
| # References: | |
| # http://www.voip-info.org/wiki/view/QoS+Linux+with+HFSC | |
| # http://www.nslu2-linux.org/wiki/HowTo/EnableTrafficShaping | |
| # http://www.cs.cmu.edu/~hzhang/HFSC/main.html | |
| # Specify the uplink as 85 or 90 percent of your actual upload speed | |
| # Uplink and downlink speeds | |
| # removed throttling downlink | |
| UPLINK=300 | |
| ###### From original script, but code has been disabled further below | |
| # IP addresses of the VoIP phones, | |
| # if none, set VOIPIPS="" | |
| VOIPIPS="" | |
| ###### | |
| # Interactive class: SSH Terminal, DNS, RDP | |
| INTERACTIVEPORTS="22 23 53 3389 27960:27980" | |
| # VoIP telephony | |
| #VOIPPORTS="5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731" | |
| VOIPPORTS="" | |
| # WWW, jabber and IRC | |
| BROWSINGPORTS="80 443 3000 8080" | |
| # The lowest priority traffic: IMAP, SMTP, FTP, IMAP, IMAP/S, high port numbers likely to be P2P | |
| P2PPORTS="110 25 21 143 993 1024:65535" | |
| # Device that connects you to the Internet | |
| DEV=$(nvram get wan_ifname) | |
| # clean up in case re-running | |
| # Reset everything to a known state (cleared) | |
| tc qdisc del dev $DEV root > /dev/null 2>&1 | |
| tc qdisc del dev $DEV ingress > /dev/null 2>&1 | |
| # Flush and delete tables | |
| iptables -t mangle --delete POSTROUTING -o $DEV -j THESHAPER > /dev/null 2>&1 | |
| iptables -t mangle --flush THESHAPER 2> /dev/null > /dev/null | |
| iptables -t mangle --delete-chain THESHAPER 2> /dev/null > /dev/null | |
| # start setting up QOS | |
| # Traffic classes: | |
| # 1:2 Interactive (SSH, DNS, ACK, Quake) | |
| # 1:3 Low latency (VoIP) < - currently being used for Netflix movie streaming from Roku box | |
| # 1:4 Browsing (HTTP, HTTPs) | |
| # 1:5 Default | |
| # 1:6 Low priority (p2p, pop3, smtp, etc) | |
| # add HFSC root qdisc | |
| tc qdisc add dev $DEV root handle 1: hfsc default 5 | |
| # add main rate limit class | |
| tc class add dev $DEV parent 1: classid 1:1 hfsc \ | |
| sc rate ${UPLINK}kbit ul rate ${UPLINK}kbit | |
| # Interactive traffic | |
| tc class add dev $DEV parent 1:1 classid 1:2 hfsc sc umax 1500b dmax 30ms rate $((5*$UPLINK/10))kbit ul rate ${UPLINK}kbit | |
| # Netflix | |
| tc class add dev $DEV parent 1:1 classid 1:3 hfsc sc umax 1500b dmax 75ms rate $((2*$UPLINK/10))kbit ul rate ${UPLINK}kbit | |
| # Browsing | |
| tc class add dev $DEV parent 1:1 classid 1:4 hfsc sc rate $((1*$UPLINK/10))kbit ul rate ${UPLINK}kbit | |
| # Default traffic | |
| tc class add dev $DEV parent 1:1 classid 1:5 hfsc sc rate $((1*$UPLINK/20))kbit ul rate ${UPLINK}kbit | |
| # Low priority/Bulk | |
| tc class add dev $DEV parent 1:1 classid 1:6 hfsc sc rate 500bit ul rate ${UPLINK}kbit | |
| # add THESHAPER chain to the mangle table in iptables | |
| iptables -t mangle --new-chain THESHAPER | |
| iptables -t mangle --insert POSTROUTING -o $DEV -j THESHAPER | |
| # had to change all iptables rules below to use mark instead of classify. tc filters then pick these up and move to the proper queue | |
| # in the future this should all be done with tc filters as this is somewhat of a hack and there is presumably at least slightly more overhead | |
| # put packets marked by iptables in the right queues using tc filters | |
| tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 2 fw flowid 1:2 | |
| tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 3 fw flowid 1:3 | |
| tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 4 fw flowid 1:4 | |
| tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 5 fw flowid 1:5 | |
| tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 6 fw flowid 1:6 | |
| ## Note that iptables rules are being appended to the end of the chain. It appears that in the mangle | |
| ## table when using mark, all rules are processed | |
| ## put more specific rules lower down in the script otherwise more general rules below them may | |
| ## re-mark them and cause unexpected behavior | |
| ### UNLESS ## | |
| ## You add another rule with -j RETURN | |
| ## I'm doing this with some rules because I want them to be processed first. It also | |
| ## helps keep the packet statistics cleaner when issuing the iptables -t mangle -L -v command (otherwise some traffic is double-counted) | |
| # To speed up downloads while an upload is going on, put short ACK | |
| # packets in the interactive class: | |
| iptables -t mangle -A THESHAPER -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK ACK -m length --length :64 -j MARK --set-mark 2 | |
| iptables -t mangle -A THESHAPER -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK ACK -m length --length :64 -j RETURN | |
| # put large (512+) icmp packets in browsing category | |
| iptables -t mangle -A THESHAPER -p icmp -m length --length 512: -j MARK --set-mark 4 | |
| iptables -t mangle -A THESHAPER -p icmp -m length --length 512: -j RETURN | |
| # ICMP (ip protocol 1) in the interactive class | |
| iptables -t mangle -A THESHAPER -p icmp -m length --length :512 -j MARK --set-mark 2 | |
| iptables -t mangle -A THESHAPER -p icmp -m length --length :512 -j RETURN | |
| setclassbyport() { | |
| port=$1 | |
| CLASS=$2 | |
| iptables -t mangle -A THESHAPER -p udp --sport $port -j MARK --set-mark $CLASS | |
| iptables -t mangle -A THESHAPER -p udp --dport $port -j MARK --set-mark $CLASS | |
| iptables -t mangle -A THESHAPER -p tcp --sport $port -j MARK --set-mark $CLASS | |
| iptables -t mangle -A THESHAPER -p tcp --dport $port -j MARK --set-mark $CLASS | |
| } | |
| for port in $INTERACTIVEPORTS; do setclassbyport $port 2; done | |
| for port in $VOIPPORTS; do setclassbyport $port 3; done | |
| for port in $BROWSINGPORTS; do setclassbyport $port 4; done | |
| for port in $P2PPORTS; do setclassbyport $port 6; done | |
| for VOIP in $VOIPIPS | |
| do | |
| iptables -t mangle -A THESHAPER --src $VOIP -j MARK --set-mark 3 | |
| iptables -t mangle -A THESHAPER --dst $VOIP -j MARK --set-mark 3 | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment