#!/bin/bash

TC="/home/craig/bin/tc"

if [ -z $1 ] ; then
	echo "Usage: "
	echo " del          disable QoS"
	echo " init         init QoS"
	echo " noact        show commands used to init QoS"
	echo " show         show current status"		
	echo " stats        display statistics"
	exit 0
fi

#=============================================
#	Configuration
#=============================================
INBANDWIDTH="440kbit"
OUTBANDWIDTH="120kbit"
ETHBWIDTH="95mbit"
INHOSTBANDWIDTH="90kbit"
OUTHOSTBANDWIDTH="25kbit"
#HOSTBURST="50b"
#HOSTCBURST="1500b"
#R2Q="r2q 1"
DEFAULTBANDWIDTH="56kbit"
INDEV="dev eth0"
EXDEV="dev ppp0"
ACTION="add"


#=============================================
#	Execution
#=============================================

if [ $1 == "noact" ] ; then 
	TC="echo $TC"
elif [ $1 == "init" ] ;  then 
	TC=$TC 
elif [ $1 == "del" ] ; then
	$TC qdisc del $INDEV root
	$TC qdisc del $EXDEV root
	exit 0
elif [ $1 == "show" ] ; then
	$TC qdisc ls $INDEV
	$TC class ls $INDEV
	exit 0
elif [ $1 == "stats" ] ; then
	$TC -s qdisc ls $INDEV
	$TC -s class ls $INDEV
	exit 0
else
	echo "bad command"
	exit 1
fi



# Add root htb qdiscs:
$TC  qdisc $ACTION $INDEV root handle 1: htb default 99 $R2Q
$TC  qdisc $ACTION $EXDEV root handle 1: htb default 99 $R2Q

# Add a "master" class for all routed traffic that's not lan<->lan
$TC  class $ACTION $INDEV parent 1: classid 1:1 htb rate $INBANDWIDTH ceil $INBANDWIDTH
$TC  class $ACTION $EXDEV parent 1: classid 1:1 htb rate $OUTBANDWIDTH ceil $OUTBANDWIDTH

# Add a "master" class for all lan<->lan traffic that isn't speed-limited.
$TC class $ACTION $INDEV parent 1: classid 1:2 htb rate $ETHBWIDTH ceil $ETHBWIDTH quantum 2000

# Add the "other" class as specified in root init command
# This class gets all P2P traffic
$TC  class $ACTION $INDEV parent 1:1 classid 1:99 htb rate $DEFAULTBANDWIDTH ceil 250kbit quantum 1550
$TC  class $ACTION $EXDEV parent 1:1 classid 1:99 htb rate $DEFAULTBANDWIDTH ceil 50kbit quantum 1550

# ok, now comes the fun. 
# We init the machine classes and proto subclasses
HOST_CLASSES="12 13 14 15"
for HOST_CLASS in $HOST_CLASSES
do
	# Add the htb classes for each host...
	$TC class $ACTION $INDEV parent 1:1 classid 1:${HOST_CLASS} htb rate $INHOSTBANDWIDTH ceil $INBANDWIDTH $HOSTBURST $HOSTCBURST
	$TC class $ACTION $EXDEV parent 1:1 classid 1:${HOST_CLASS} htb rate $OUTHOSTBANDWIDTH ceil $OUTBANDWIDTH $HOSTBURST $HOSTCBURST

	# Add a single sfq bucket to put traffic in
	$TC qdisc $ACTION $INDEV parent 1:${HOST_CLASS} handle $HOST_CLASS: sfq
	$TC qdisc $ACTION $EXDEV parent 1:${HOST_CLASS} handle $HOST_CLASS: sfq

done

# ok filtering discipline time. Make sure all traffic originating at the
# firewall goes out to the LAN at $ENETBWIDTH speeds (full iface speed):

$TC filter add $INDEV protocol ip parent 1: prio 3 u32 match ip src 192.168.0.1    match ip dst 192.168.0.0/24 flowid 1:2
$TC filter add $INDEV protocol ip parent 1: prio 3 u32 match ip src 192.168.0.0/24 match ip dst 192.168.0.0/24 flowid 1:2

# Filter BitTorrent traffic to low-priority queue
$TC filter add $INDEV protocol ip parent 1: prio 2 u32 match ip dport 6881 0xffff flowid 1:99
$TC filter add $INDEV protocol ip parent 1: prio 2 u32 match ip dport 6882 0xffff flowid 1:99
$TC filter add $INDEV protocol ip parent 1: prio 2 u32 match ip sport 6881 0xffff flowid 1:99
$TC filter add $INDEV protocol ip parent 1: prio 2 u32 match ip sport 6882 0xffff flowid 1:99

# Filter other traffic into by-host classes
HOST_FILTER="$TC filter add $INDEV protocol ip parent 1: prio 4 u32 match ip"
$HOST_FILTER dst 192.168.0.2 flowid 1:12
$HOST_FILTER dst 192.168.0.3 flowid 1:13
$HOST_FILTER dst 192.168.0.4 flowid 1:14
$HOST_FILTER dst 192.168.0.5 flowid 1:15

HOST_FILTER="$TC filter add $EXDEV protocol ip parent 1: prio 4 u32 match ip"
$HOST_FILTER src 192.168.0.2 flowid 1:12
$HOST_FILTER src 192.168.0.3 flowid 1:13
$HOST_FILTER src 192.168.0.4 flowid 1:14
$HOST_FILTER src 192.168.0.5 flowid 1:15
