Skip to content

Instantly share code, notes, and snippets.

@nickpegg
Created July 5, 2017 00:31
Show Gist options
  • Save nickpegg/f4b21f45dc695adb50ea2488c33e9f4c to your computer and use it in GitHub Desktop.
Save nickpegg/f4b21f45dc695adb50ea2488c33e9f4c to your computer and use it in GitHub Desktop.
#!/bin/bash
set -x
set -e
# This sets up QoS using HTB, which is a simplified algorithm. How it works is
# that I set up three classes, each class gets a guaranteed rate ('rate') and
# a maximum-usable rate ('ceil'). The ceiling is set to my uplink rate, so
# any class can use the full pipe assuming no better class trumps it.
#
# The classes are:
# Class 10 - high prio (interactive, SSH, etc.)
# Guaranteed 90% of the uplink rate
# Class 20 - default
# Guaranteed 50% of the uplink rate
# Class 30 - bulk (torrent, usenet)
# Guaranteed 10% of the uplink rate
#
# Largely based on the info here:
# http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm
#
# Remember that we can only control what we _send_, not what we receive.
# I'm crossing my fingers that inbound hogs will get throttled if their
# TCP ACKs are getting throttled.
UPLINK_IFACE=eth0
UP_KBPS=3000
# Calculated rates for each class
CLASS10_RATE=$(echo "scale=0; $UP_KBPS * 0.9 / 1" | bc)
CLASS20_RATE=$(echo "scale=0; $UP_KBPS * 0.5 / 1" | bc)
CLASS30_RATE=$(echo "scale=0; $UP_KBPS * 0.1 / 1" | bc)
tc qdisc del dev $UPLINK_IFACE root || true
tc qdisc add dev $UPLINK_IFACE root handle 1: htb default 20
# Handle - the parent of each of the classes. Gotta have at least one of these in the tree.
# If you don't have a handle that the classes child off of, then the classes won't be able
# to 'borrow' from other classes and won't use the full available bandwidth when no one
# else is using it.
tc class add dev $UPLINK_IFACE parent 1: classid 1:1 htb rate "${UP_KBPS}kbit" burst 15k
# Set up each of the classes
tc class add dev $UPLINK_IFACE parent 1:1 classid 1:10 htb rate "${CLASS10_RATE}kbit" ceil "${UP_KBPS}kbit" burst 15k
tc class add dev $UPLINK_IFACE parent 1:1 classid 1:20 htb rate "${CLASS20_RATE}kbit" ceil "${UP_KBPS}kbit" burst 10k
tc class add dev $UPLINK_IFACE parent 1:1 classid 1:30 htb rate "${CLASS30_RATE}kbit" ceil "${UP_KBPS}kbit" burst 5k
# Use SFQ (fair queueing) for all traffic within a particular class
tc qdisc add dev $UPLINK_IFACE parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $UPLINK_IFACE parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $UPLINK_IFACE parent 1:30 handle 30: sfq perturb 10
# Finally add some basic filters to match packets to classes
FILTER_PRE="tc filter add dev $UPLINK_IFACE parent 1:0 prio 1 u32"
# SSH
$FILTER_PRE match ip dport 22 0xffff flowid 1:10
# BitTorrent
$FILTER_PRE match ip dport 6881 0xffff flowid 1:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment