###########################################################################################################
#
# Traffic Control configuration
#
# Copyright (c) 2009 iilluzion
#
# Distributed under GPL-2
#
###########################################################################################################
##### MAIN CONFIGURATION PARAMETERS
####
###	uplink and downlink rates should be set very precisely
##	RATE_SUB_PERCENT should be set to allow the Router to control a queue
#
###########################################################################################################
# Specify the upload speed of your internet connection (kbit, mbit).
# 	Since ISPs tend to overestimate the speeds they offer, it would
#	 probably be best if you measure this on a free line.
#
### UPLINK_RATE=128kbit
### UPLINK_RATE=256kbit
UPLINK_RATE=512kbit


###########################################################################################################
# Specify the download speed of your internet connection (kbit, mbit).
#
### DOWNLINK_RATE=256kbit
### DOWNLINK_RATE=512kbit
DOWNLINK_RATE=1024kbit


###########################################################################################################
# In order to prevent traffic queuing at the ISP side or in your modem,
# we shape to a slightly lower rate. This way the bottleneck is the router,
# not the ISP or modem, which allows us more direct control of shaping.
#
### RATE_SUB_PERCENT=20
### RATE_SUB_PERCENT=15
RATE_SUB_PERCENT=10


###########################################################################################################
# Specify the local network speed (kbit, mbit)
#
LAN_RATE=9mbit


###########################################################################################################
##### ADVANCED CONFIGURATION PARAMETERS
####
###
##
#
###########################################################################################################
# Helper Functions
#
# Convert rate to bites per second format (bits)
bits()
{
	RATE=0
	R_RATE=$1
	R_NUMBER=`echo "$R_RATE" | sed -e "s/[^0-9]//g"`
	R_UNIT=`echo "$R_RATE" | sed -e "s/[0-9]//g"`

	if [ "$R_UNIT" == "" ]; then
		R_UNIT="kbit"
	fi

	if [ "$R_UNIT" == "kbps" ]; then   R_RATE=$(($R_NUMBER * 1024 * 8))
	elif [ "$R_UNIT" == "mbps" ]; then R_RATE=$(($R_NUMBER * 1024 * 1024 * 8))
	elif [ "$R_UNIT" == "mbit" ]; then R_RATE=$(($R_NUMBER * 1024 * 1024))
	elif [ "$R_UNIT" == "kbit" ]; then R_RATE=$(($R_NUMBER * 1024))
	elif [ "$R_UNIT" == "bps" ]; then  R_RATE=$(($R_NUMBER * 8))
	else
		echo "Unknown unit '$R_UNIT' (mbps, mbit, kbit, bps)"
	fi

	echo "$R_RATE"
}

###########################################################################################################
# Define supported Queuing Disciplines
#
QDISCS="prio|tbf|htb|hfsc|sfq|red|pfifo"


###########################################################################################################
# Traffic Control parameters will be calculated depending on link directions
#
DIRECTION=$1


###########################################################################################################
# Specify the network devices that are connected to the internet.
# If you are a dialup or PPPoE user, you have to re-run the QoS script
# every time you connect.
#
### WAN_DEVICES="ppp0"
WAN_DEVICES="$(ip route show 0.0.0.0/0 | grep dev | sed 's/.*dev //' | awk '{print $1}')"
	WAN_DEVICES="$WAN_DEVICES $(ip addr | grep gre | egrep -v "gre0" | awk '/^[0-9]/ { gsub(":", ""i, $2); print $2}' |  cut -f 1 -d'@')"


###########################################################################################################
# Specify the network devices which are connected with your local network segments.
#
### LAN_DEVICES="eth1"
LAN_DEVICES=`awk -F: 'NR > 2 { print $1 }' /proc/net/dev | egrep -v "lo|gre0|$(echo $WAN_DEVICES | sed s/" "/"|"/g)"`


###########################################################################################################
# Calculaton of WAN up/down link rates
#
DIRECTION=${DIRECTION:-ALL}
	if [ $DIRECTION = "ALL" ]; then
		DEVICES="$WAN_DEVICES $LAN_DEVICES"
	fi

	if [ $DIRECTION = "UP" ]; then 
		WAN_RATE=`bits $UPLINK_RATE`
		DEVICES=$WAN_DEVICES
	fi

	if [ $DIRECTION = "DOWN" ]; then 
		WAN_RATE=`bits $DOWNLINK_RATE`
		DEVICES=$LAN_DEVICES
	fi

		WAN_SUB_RATE=$((WAN_RATE - (RATE_SUB_PERCENT * WAN_RATE / 100)))
			INTERACTIVE_RATE=$((WAN_SUB_RATE / 5))
			PRIVILEGED_RATE=$((WAN_SUB_RATE / 2))
			BESTEFFORT_RATE=$((WAN_SUB_RATE / 3))

		OUT_OF_WAN_RATE=`bits $LAN_RATE`
			OUT_OF_WAN_RATE=$((OUT_OF_WAN_RATE - WAN_RATE))


###########################################################################################################
# Specify root Queuing Disciplines
#
# Recommendations:
#	htb:    if link is not congested or you want to control busrts of traffic; recommended for downstream.
#	hfsc:   if link is congested and you need to control guarantees of delay; recommended for upstream.
#			dmax = 50-100 [ms] = 50000-100000 [microsec]
#			umax = MIN (rate * (dmax / 1000), 1500) [b]
#	prio:   if rate is variable and you want to be sure that interactive traffic has ultimate priority
#	none:   if no egress shaping is desired 
#		(in this case you may want to setup only ingress policing)
#
DOWNLINK_QDISC=htb
### DOWNLINK_QDISC=hfsc  
### DOWNLINK_QDISC=prio
### DOWNLINK_QDISC=none
#
UPLINK_QDISC=hfsc
### UPLINK_QDISC=htb
### UPLINK_QDISC=prio
### UPLINK_QDISC=none


###########################################################################################################
# Calculation of Queuing Discipline parameters
#
INTERACTIVE_PRIO_LATENCY=50000
INTERACTIVE_PRIO_BURST=$((INTERACTIVE_RATE / 100 / 8))
#
INTERACTIVE_HFSC_DMAX=50000
INTERACTIVE_HFSC_UMAX=$((INTERACTIVE_RATE * INTERACTIVE_HFSC_DMAX / 1000 / 1000))
	[ $INTERACTIVE_HFSC_UMAX -gt 1500 ] && INTERACTIVE_HFSC_UMAX=1500
#
PRIVILEGED_HFSC_DMAX=100000
PRIVILEGED_HFSC_UMAX=$((PRIVILEGED_RATE * PRIVILEGED_HFSC_DMAX / 1000 / 1000))
	 [ $PRIVILEGED_HFSC_UMAX -gt 1500 ] && PRIVILEGED_HFSC_UMAX=1500


###########################################################################################################
# Specify INGRESS policing
#
# Recommendations:
#	none:   if link is not congested 
#	police: if link is constantly congested
#
### DOWNLINK_INGRESS=police
DOWNLINK_INGRESS=none
### UPLINK_INGRESS=police
UPLINK_INGRESS=none


###########################################################################################################
# Calculation of policing bursts
#	burst = rate / 17 (taken basing on experemental results)
#
POLICE_BURST_SCALE=17 
	INTERACTIVE_POLICE_BURST=$((INTERACTIVE_RATE / POLICE_BURST_SCALE))
	PRIVILEGED_POLICE_BURST=$((PRIVILEGED_RATE / POLICE_BURST_SCALE))
	BESTEFFORT_POLICE_BURST=$((BESTEFFORT_RATE / POLICE_BURST_SCALE))


###########################################################################################################
# Specify leaf Queuing Disciplines
# Recommendations:
#	"pfifo limit 5":	Interactive, Priviledged (real-time streams, IPSEC)
#	"sfq perturb 10":	Best-Effort (TCP sessions or best-effort class traffic)
#	"red <parameters>":		Best-Effort (hightly congested links or high-speed Internet [> 10Mbit/sec])
#					Random Early Detect (RED) parameters calculation:
#  						min         = maximum delay * rate (dalay ~ 200ms = 0.2sec) [b]
# 						max         = 3 * min [b]
#						avpkt       = 1000 (MTU 1500)
#						limit       = 8 * max [b]
#						burst       = (min + min + max)/(3 * avpkt) [b]
#						probability = 0.02
INTERACTIVE_LEAF_QDISC="pfifo limit 5"
PRIVILEGED_LEAF_QDISC="pfifo limit 5"
### BESTEFFORT_LEAF_QDISC="sfq perturb 10"
#
RED_DELAY=200
RED_MIN=$((RED_DELAY * BESTEFFORT_RATE / 1000 / 8)) # devided on 8 since rate given in bit/s so we get bytes
RED_MAX=$((3 * RED_MIN))
RED_AVPKT=1000
RED_PROB=0.02
RED_BURST=$(((RED_MIN + RED_MIN + RED_MAX) / (3 * RED_AVPKT)))
RED_LIMIT=$((8 * RED_MAX))
#
	BESTEFFORT_LEAF_QDISC="red min $RED_MIN max $RED_MAX burst $RED_BURST limit $RED_LIMIT probability $RED_PROB avpkt $RED_AVPKT"
#
LAN_LEAF_QDISC="sfq perturb 10"


###########################################################################################################
# Specify filter rules (see tc, tc-filters man page). 
#	You may have multiple <CLASS-NAME>_FILTER_<n> items.
# 	Maximum 100 filter items are allowed for each class
#
# Interactive Class Traffic Filters
#
# UDP
#
INTERACTIVE_FILTER_1="protocol ip prio 100 u32 match ip protocol 0x11 0xff"
#
# ICMP
#
INTERACTIVE_FILTER_2="protocol ip prio 100 u32 match ip protocol 0x1 0xff"
#
# ACK with payload < 64 bytes (32-bit version)
#
INTERACTIVE_FILTER_3="protocol ip prio 100 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33"
#
# ACK with payload < 64 bytes
#
INTERACTIVE_FILTER_4="protocol ip prio 100 u32 match ip protocol 6 0xff match u8 0x10 0xff at nexthdr+13 match u16 0x0000 0xffc0 at 2"
#
# TOS: 0x10, 0x18, 0xb8(ef)
#
INTERACTIVE_FILTER_5="protocol ip prio 100 u32 match ip tos 0x10 0xff"
INTERACTIVE_FILTER_6="protocol ip prio 100 u32 match ip tos 0x18 0xff"
INTERACTIVE_FILTER_7="protocol ip prio 100 u32 match ip tos 0xb8 0xff"


###########################################################################################################
# Priviledged Class Traffic Filters
#
# SSH
#
PRIVILEGED_FILTER_1="protocol ip prio 100 u32 match ip dport 22 0xffff"
PRIVILEGED_FILTER_2="protocol ip prio 100 u32 match ip sport 22 0xffff"
#
# Remote Desktop
#
PRIVILEGED_FILTER_3="protocol ip prio 100 u32 match ip dport 3389 0xffff"
PRIVILEGED_FILTER_4="protocol ip prio 100 u32 match ip sport 3389 0xffff"
#
# ESP
#
PRIVILEGED_FILTER_5="protocol ip prio 100 u32 match ip protocol 0x32 0xff"
#
# AH
#
PRIVILEGED_FILTER_6="protocol ip prio 100 u32 match ip protocol 0x33 0xff"
#
# TOS: 0x88(af41)
#
PRIVILEGED_FILTER_7="protocol ip prio 100 u32 match ip tos 0x88 0xff"
#
# IPSEC-NAT
#
PRIVILEGED_FILTER_8="protocol ip prio 90 u32 match ip protocol 0x11 0xff match ip dport 4500 0xffff"
PRIVILEGED_FILTER_9="protocol ip prio 90 u32 match ip protocol 0x11 0xff match ip sport 4500 0xffff"


###########################################################################################################
# Best-Effort Class Traffic Filters
#	By default ALL unclassified traffic is being assined to Best-Effort class
#	You may specify additional filters here
#
# Examples: Any traffic from/to 192.168.1.0/24 network will be unconditionally classified as best-effort
#
### BESTEFFORT_FILTER_1="protocol ip prio 3 u32 match ip src 192.168.1.0/24"
### BESTEFFORT_FILTER_2="protocol ip prio 4 u32 match ip dst 192.168.1.0/24"
#

###########################################################################################################
# LAN Class Traffic Filters
#
# Traffic Originated from router
#
# Example:
###LAN_FILTER_1="protocol ip prio 10 u32 match ip src 192.168.1.10"

#
##
###
####
##### END OF GENERIC ALPINE SETUP
###########################################################################################################