Skip to content

Instantly share code, notes, and snippets.

@devoncrouse
Last active December 16, 2015 10:09
Show Gist options
  • Save devoncrouse/5417887 to your computer and use it in GitHub Desktop.
Save devoncrouse/5417887 to your computer and use it in GitHub Desktop.
Adapted from https://gist.github.com/bradoaks/940616. Multiple port-based prioritization rules, and explicit de-prioritization for S3 CIDR ranges (long-running backups no longer impede browsing, etc.)
#!/bin/bash
# Set this to your internet-facing network interface:
WAN_INTERFACE=eth0
# Set this to your local network interface:
LAN_INTERFACE=bond0
# How fast is your downlink?
MAX_DOWNRATE=12288kbit
# How close should we get to max down? e.g. 90%
USE_DOWNPERCENT=0.95
# How fast is your uplink?
MAX_UPRATE=896kbit
# How close should we get to max up? e.g. 80%
USE_UPPERCENT=0.90
# Remove any existing qdiscs
tc qdisc del dev $WAN_INTERFACE root 2> /dev/null
tc qdisc del dev $WAN_INTERFACE ingress 2> /dev/null
tc qdisc del dev $LAN_INTERFACE root 2> /dev/null
tc qdisc del dev $LAN_INTERFACE ingress 2> /dev/null
##
# Computations
##
MAX_UPNUM=`echo $MAX_UPRATE | sed 's/[^0-9]//g'`
MAX_UPBASE=`echo $MAX_UPRATE | sed 's/[0-9]//g'`
MAX_DOWNNUM=`echo $MAX_DOWNRATE | sed 's/[^0-9]//g'`
MAX_DOWNBASE=`echo $MAX_DOWNRATE | sed 's/[0-9]//g'`
NEAR_MAX_UPNUM=`echo "$MAX_UPNUM * $USE_UPPERCENT" | bc | xargs printf "%.0f"`
NEAR_MAX_UPRATE="${NEAR_MAX_UPNUM}${MAX_UPBASE}"
NEAR_MAX_DOWNNUM=`echo "$MAX_DOWNNUM * $USE_DOWNPERCENT" | bc | xargs printf "%.0f"`
NEAR_MAX_DOWNRATE="${NEAR_MAX_DOWNNUM}${MAX_DOWNBASE}"
HALF_MAXUPNUM=$(( $MAX_UPNUM / 2 ))
HALF_MAXUP="${HALF_MAXUPNUM}${MAX_UPBASE}"
HALF_MAXDOWNNUM=$(( $MAX_DOWNNUM / 2 ))
HALF_MAXDOWN="${HALF_MAXDOWNNUM}${MAX_DOWNBASE}"
##
# Upload
##
# Install HFSC under WAN to limit upload
tc qdisc add dev $WAN_INTERFACE root handle 1: hfsc default 11
tc class add dev $WAN_INTERFACE parent 1: classid 1:1 hfsc sc rate $NEAR_MAX_UPRATE ul rate $NEAR_MAX_UPRATE
tc class add dev $WAN_INTERFACE parent 1:1 classid 1:10 hfsc sc umax 1540 dmax 5ms rate $HALF_MAXUP ul rate $NEAR_MAX_UPRATE
tc class add dev $WAN_INTERFACE parent 1:1 classid 1:11 hfsc sc umax 1540 dmax 5ms rate $HALF_MAXUP ul rate $HALF_MAXUP
# De-prioritize S3 upload
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip src 72.21.192.0/19 flowid 1:11
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dst 72.21.192.0/19 flowid 1:11
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip src 207.171.160.0/19 flowid 1:11
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dst 207.171.160.0/19 flowid 1:11
# Prioritize SSH upload
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip sport 22 0xffff flowid 1:10
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dport 22 0xffff flowid 1:10
# Prioritize HTTP upload
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip sport 80 0xffff flowid 1:10
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:10
# Prioritize SSL upload
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip sport 443 0xffff flowid 1:10
tc filter add dev $WAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dport 443 0xffff flowid 1:10
# Add SFQ
tc qdisc add dev $WAN_INTERFACE parent 1:10 handle 30: sfq perturb 10
tc qdisc add dev $WAN_INTERFACE parent 1:11 handle 40: sfq perturb 10
##
# Download
##
# Install ingress filter to limit download to 97% max
MAX_DOWNRATE_INGRESSNUM=`echo "$MAX_DOWNNUM * 0.97" | bc | xargs printf "%.0f"`
MAX_DOWNRATE_INGRESS="${MAX_DOWNRATE_INGRESSNUM}${MAX_DOWNBASE}"
tc qdisc add dev $WAN_INTERFACE handle ffff: ingress
# Prioritize SSH download
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 1 u32 match ip sport 22 0xffff flowid :1
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 1 u32 match ip dport 22 0xffff flowid :1
# Prioritize HTTP download
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 1 u32 match ip sport 80 0xffff flowid :1
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 1 u32 match ip dport 80 0xffff flowid :1
# Prioritize SSL download
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 1 u32 match ip sport 443 0xffff flowid :1
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 1 u32 match ip dport 443 0xffff flowid :1
# De-prioritize everything else
tc filter add dev $WAN_INTERFACE parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate $MAX_DOWNRATE_INGRESS burst 20k drop flowid :2
# Install HFSC under LAN to limit download
tc qdisc add dev $LAN_INTERFACE root handle 1: hfsc default 11
tc class add dev $LAN_INTERFACE parent 1: classid 1:1 hfsc sc rate 1000mbit ul rate 1000mbit
tc class add dev $LAN_INTERFACE parent 1:1 classid 1:10 hfsc sc umax 1540 dmax 5ms rate 900mbit ul rate 900mbit
tc class add dev $LAN_INTERFACE parent 1:1 classid 1:11 hfsc sc umax 1540 dmax 5ms rate $HALF_MAXDOWN ul rate $NEAR_MAX_DOWNRATE
# De-prioritize S3 download
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip src 72.21.192.0/19 flowid 1:11
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dst 72.21.192.0/19 flowid 1:11
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip src 207.171.160.0/19 flowid 1:11
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dst 207.171.160.0/19 flowid 1:11
# Prioritize SSH download
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip sport 22 0xffff flowid 1:10
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dport 22 0xffff flowid 1:10
# Prioritize HTTP download
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip sport 80 0xffff flowid 1:10
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:10
# Prioritize SSL download
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip sport 443 0xffff flowid 1:10
tc filter add dev $LAN_INTERFACE protocol ip parent 1:0 prio 1 u32 match ip dport 443 0xffff flowid 1:10
# Add SFQ
tc qdisc add dev $LAN_INTERFACE parent 1:10 handle 30: sfq perturb 10
tc qdisc add dev $LAN_INTERFACE parent 1:11 handle 40: sfq perturb 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment