#!/bin/bash INTERFACE=eth0 DOWNLINK_WAN=4000kbit UPLINK_WAN=250kbit LATENCY_WAN=50ms BURST=1540 UPLINK_LAN=100mbit SUDO=/usr/bin/sudo ETHTOOL=/usr/sbin/ethtool IP=/sbin/ip TC=/sbin/tc # tc uses following rules for bandwith specification: # # mbps = 1024 kbps = 1024 * 1024 bps => byte/s # mbit = 1024 kbit => kilo bit/s. # mb = 1024 kb = 1024 * 1024 b => byte # mbit = 1024 kbit => kilo bit # # kb = KByte # kbit = kbit # 1Mbit = 1024 Kbit = 1024 * 1024 bps => byte/s # 10kbit up (..KB) => 30kbit down # 20kbit up (5.2KB) => ..kbit down # 100kbit up (KB) => ..kbit down tc_reset () { $SUDO $TC qdisc del dev $INTERFACE root 2> /dev/null > /dev/null $SUDO $TC qdisc del dev $INTERFACE ingress 2> /dev/null > /dev/null } tc_status () { echo "[qdisc - $INTERFACE]" $TC -s qdisc show dev $INTERFACE echo "------------------------" echo echo "[class - $INTERFACE]" $TC -s class show dev $INTERFACE } tc_showfilter () { echo "[filter - $INTERFACE]" $TC -s filter show dev $INTERFACE } start() { # reset everything tc_reset ###### uplink # creates a root handle attached to eth0 using the HTB qdisc and classify # packets as classid 60 by default $SUDO $TC qdisc add dev $INTERFACE root handle 1: htb default 10 # LAN / WAN separation # shape everything at uplink speed - this prevents huge dsl modem queues $SUDO $TC class add dev $INTERFACE parent 1: classid 1:1 htb rate ${UPLINK_LAN} ceil ${UPLINK_LAN} burst 6k $SUDO $TC class add dev $INTERFACE parent 1: classid 1:50 htb rate ${UPLINK_WAN} ceil ${UPLINK_WAN} # LAN classes # realtime priority $SUDO $TC class add dev $INTERFACE parent 1:1 classid 1:10 htb rate ${UPLINK_LAN} burst 6k prio 1 # high prio class $SUDO $TC class add dev $INTERFACE parent 1:1 classid 1:20 htb rate ${UPLINK_LAN} burst 6k prio 2 # bulk & default class -> less traffic and lower priority $SUDO $TC class add dev $INTERFACE parent 1:1 classid 1:30 htb rate $[9 * $UPLINK / 10]kbit burst 6k prio 3 # low priority traffic class $SUDO $TC class add dev $INTERFACE parent 1:1 classid 1:40 htb rate $[8 * $UPLINK / 10]kbit burst 6k prio 4 # all get Stochastic Fairness $SUDO $TC qdisc add dev $INTERFACE parent 1:10 handle 10: sfq perturb 10 $SUDO $TC qdisc add dev $INTERFACE parent 1:20 handle 20: sfq perturb 10 $SUDO $TC qdisc add dev $INTERFACE parent 1:30 handle 30: sfq perturb 10 $SUDO $TC qdisc add dev $INTERFACE parent 1:40 handle 40: sfq perturb 10 # WAN classes $SUDO $TC class add dev $INTERFACE parent 1:1 classid 1:10 htb rate ${UPLINK_WAN} $SUDO $TC class add dev $INTERFACE parent 1:1 classid 1:20 htb rate ${UPLINK_WAN} $SUDO $TC filter add dev $INTERFACE parent 1:0 protocol ip prio 1 u32 match ip dst 10.218.1.0/24 flowid 1:60 # LAN Handles $SUDO $TC qdisc add dev $INTERFACE parent 1:60 handle 61: sfq perturb 10 $SUDO $TC qdisc add dev $INTERFACE parent 1:70 handle 71: sfq perturb 10 # WAN Handles $SUDO $TC qdisc add dev $INTERFACE parent 1:10 handle 11: sfq perturb 10 $SUDO $TC qdisc add dev $INTERFACE parent 1:20 handle 21: sfq perturb 10 #sudo tc qdisc add dev eth0 root tbf rate $UPLINK latency 50ms burst 1540 } stop() { sudo tc qdisc del dev eth0 root 2>/dev/null } status() { $SUDO $ETHTOOL $DEVICE ip route list table local ip route list table main tc qdisc ls dev eth0 tc class ls dev eth0 tc filter ls dev eth0 } usage() { echo -e "Usage: " $0 " [ start | stop | status | info ]\n" echo -e " start - start traffic shaping" echo -e " stop - stop traffic shaping" echo -e " status - display traffic-shaping information" echo -e " info - display some pre-defined shaping values" } if [ ! $1 ] ; then usage exit 1 fi if [ $1 = "start" ] ; then start exit 0 elif [ $1 = "stop" ] ; then stop exit 0 elif [ $1 = "status" ] ; then status exit 0 elif [ $1 = "info" ] ; then info exit 0 fi