diff options
author | Florian Pritz <bluewind@xinu.at> | 2016-07-23 13:29:07 +0200 |
---|---|---|
committer | Florian Pritz <bluewind@xinu.at> | 2016-07-23 13:29:07 +0200 |
commit | 38ad80b8672a7ecce6bd9f607900c77dfd70da07 (patch) | |
tree | 37fd22f76e8a1babbbd4e6dd41fa13055f71aa25 /hfsc_shaper.sh | |
download | qos-38ad80b8672a7ecce6bd9f607900c77dfd70da07.tar.gz qos-38ad80b8672a7ecce6bd9f607900c77dfd70da07.tar.xz |
Initial commit
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Diffstat (limited to 'hfsc_shaper.sh')
-rwxr-xr-x | hfsc_shaper.sh | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/hfsc_shaper.sh b/hfsc_shaper.sh new file mode 100755 index 0000000..3504c68 --- /dev/null +++ b/hfsc_shaper.sh @@ -0,0 +1,274 @@ +#!/bin/bash +#---------------------------------------------------- +# File: hfsc_shaper.sh +# Version: 0.2 +# Edited: Florian "Bluewind" Pritz <bluewind@xinu.at> +# Author: Maciej Bliziński, http://automatthias.wordpress.com/ +#---------------------------------------------------- +# +# Special Thanks to +# Maciej Bliziński, http://automatthias.wordpress.com/ +# +# 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 + +######################################################################## +# CONFIGURATION +######################################################################## + +# Uplink and downlink speeds +# Normally use a bit lower values than your real speed, but +# you should experiment a bit +# downlink is unused +#DOWNLINK=75000 +UPLINK=7400 + +# Device that connects you to the Internet +DEV="extern0" + +# Traffic classes: +# 1:2 Interactive (SSH, DNS, ACK, Quake) +# 1:3 Low latency (VoIP) +# 1:4 Browsing (HTTP, HTTPs) +# 1:5 Default +# 1:6 Middle-low priority +# 1:7 Lowest priority + +# Interactive class: SSH Terminal, DNS and gaming (Quake) +INTERACTIVEPORTS="22 23 53 3389 5900 22222 6667 7000 44400 7776 4949 11030 11239 143 445 25765" + +# VoIP telephony +#VOIPPORTS="5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731" +VOIPPORTS="7977 9987" +# IP addresses of the VoIP phones, +# if none, set VOIPIPS="" +VOIPIPS="" + + +# WWW, jabber and IRC +BROWSINGPORTS="80 443 8080 993" + +# Everything unspecified will be here (inbetween Browsing and Data) + +# FTP, Mail... +DATAPORTS="110 25 21 137:139 4662 4664 " + +# The lowest priority traffic: eDonkey, Bittorrent, etc. +#P2PPORTS="6881:6999 36892 8333" +P2PPORTS="" + +######################################################################## +# CONFIGURATION ENDS HERE +######################################################################## + +if [ -z "$DEV" ] ; then + echo "$0: device not set, aborting." + exit -1 +fi + +function stop() { + # Reset everything to a known state (cleared) + tc qdisc del dev $DEV root &> /dev/null + tc qdisc del dev $DEV ingress &> /dev/null + + # Flush and delete tables + iptables -t mangle --delete POSTROUTING -o $DEV -j THESHAPER &> /dev/null + iptables -t mangle --flush THESHAPER &> /dev/null + iptables -t mangle --delete-chain THESHAPER &> /dev/null +} + +function start() { + #if [ -z "$DOWNLINK" ] ; then + #echo "$0: start requires a downlink speed, aborting." + #exit -1 + #fi + if [ -z "$UPLINK" ] ; then + echo "$0: start requires an uplink speed, aborting." + exit -1 + fi + + # 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: guarantee full uplink for 50ms, then + # 5/10 of the uplink + tc class add dev $DEV parent 1:1 classid 1:2 hfsc \ + sc m1 ${UPLINK}kbit d 50ms m2 $((5*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit + + # VoIP: guarantee full uplink for 200ms, then 3/10 + tc class add dev $DEV parent 1:1 classid 1:3 hfsc \ + sc m1 ${UPLINK}kbit d 200ms m2 $((3*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit + + # Browsing: guarantee 3/10 uplink for 200ms, then + # guarantee 1/10 + tc class add dev $DEV parent 1:1 classid 1:4 hfsc \ + sc m1 $((3*$UPLINK/10))kbit d 200ms m2 $((1*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit + + # Default traffic: guarantee 1/10 uplink for 100ms, + # then guarantee 3/20 + tc class add dev $DEV parent 1:1 classid 1:5 hfsc \ + sc m1 $((1*$UPLINK/10))kbit d 100ms m2 $((3*$UPLINK/20))kbit \ + ul rate ${UPLINK}kbit + + # Middle-low taffic: don't guarantee anything for the first 5 seconds, + # then guarantee 1/10 + tc class add dev $DEV parent 1:1 classid 1:6 hfsc \ + sc m1 0 d 5s m2 $((1*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit + + # Lowest taffic: don't guarantee anything for the first 10 seconds, + # then guarantee 1/20 + #ls m2 $((1*$UPLINK/200))kbit \ + tc class add dev $DEV parent 1:1 classid 1:7 hfsc \ + sc m1 0 d 5s m2 10kbit \ + ul rate $((UPLINK-200))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 + + # Type of service filters (see /etc/iproute2/rt_dsfield) + iptables -t mangle -A THESHAPER \ + -m tos --tos 0x10 \ + -j CLASSIFY --set-class 1:2 + + iptables -t mangle -A THESHAPER \ + -m tos --tos 0x08 \ + -j CLASSIFY --set-class 1:7 + + # 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 CLASSIFY --set-class 1:2 + + # put large (512+) icmp packets in default category + iptables -t mangle -A THESHAPER \ + -p icmp \ + -m length --length 512: \ + -j CLASSIFY --set-class 1:5 + + # small ICMP in the interactive class + iptables -t mangle -A THESHAPER \ + -p icmp \ + -m length --length :512 \ + -j CLASSIFY --set-class 1:2 + + setclassbyport() { + port=$1 + CLASS=$2 + iptables -t mangle -A THESHAPER -p udp --sport $port -j CLASSIFY --set-class $CLASS + iptables -t mangle -A THESHAPER -p udp --dport $port -j CLASSIFY --set-class $CLASS + iptables -t mangle -A THESHAPER -p tcp --sport $port -j CLASSIFY --set-class $CLASS + iptables -t mangle -A THESHAPER -p tcp --dport $port -j CLASSIFY --set-class $CLASS + } + + for port in $INTERACTIVEPORTS; do setclassbyport $port 1:2; done + for port in $VOIPPORTS; do setclassbyport $port 1:3; done + for port in $BROWSINGPORTS; do setclassbyport $port 1:4; done + for port in $DATAPORTS; do setclassbyport $port 1:6; done + for port in $P2PPORTS; do setclassbyport $port 1:7; done + + for VOIP in $VOIPIPS; do + iptables -t mangle -A THESHAPER --src $VOIP -j CLASSIFY --set-class 1:3 + iptables -t mangle -A THESHAPER --dst $VOIP -j CLASSIFY --set-class 1:3 + done + + # put large (1024+) https packets in default category + iptables -t mangle -A THESHAPER \ + -p tcp --dport 443 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:6 + + # put large (1024+) http packets in default category + iptables -t mangle -A THESHAPER \ + -p tcp --dport 80 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:6 + + # put large (1024+) packets in default category + #iptables -t mangle -A THESHAPER \ + #-p tcp \ + #-m length --length 1024: \ + #-j CLASSIFY --set-class 1:6 + + # put large (1024+) ssh packets in default category + iptables -t mangle -A THESHAPER \ + -p tcp --dport 22 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:6 + + # put all traffic from user torrent into p2p category (only works for the host this script runs on) + #iptables -t mangle -A THESHAPER \ + #--match owner --uid-owner 169 -j CLASSIFY --set-class 1:7 + + # Try to control the incoming traffic as well. + # Set up ingress qdisc + #tc qdisc add dev $DEV handle ffff: ingress + + # Filter everything that is coming in too fast + # It's mostly HTTP downloads that keep jamming the downlink, so try to restrict + # them to 95/100 of the downlink. + + # FIXME: slows down too much + #tc filter add dev $DEV parent ffff: protocol ip prio 50 \ + #u32 match ip src 0.0.0.0/0 \ + #match ip protocol 6 0xff \ + #match ip sport 80 0xffff \ + #police rate $((95*${DOWNLINK}/100))kbit \ + #burst 10k drop flowid :1 + + #tc filter add dev $DEV parent ffff: protocol ip prio 50 \ + #u32 match ip src 0.0.0.0/0 \ + #police rate $((95*${DOWNLINK}/100))kbit \ + #burst $((95*${DOWNLINK}/100*2)) drop flowid :1 +} + +function status() { + echo "[qdisc]" + tc -s qdisc show dev $DEV + + echo "" + echo "[class]" + tc -s class show dev $DEV + + echo "" + echo "[filter]" + tc -s filter show dev $DEV + + echo "" + echo "[iptables]" + iptables -n -t mangle -L THESHAPER -v -x +} + +case "$1" in + status) + status + ;; + stop) + stop + ;; + start) + start + ;; + restart) + stop + start + ;; + *) + echo "$0 [ACTION] [device]" + echo "ACTION := { start | stop | status | restart }" + exit + ;; +esac |