aboutsummaryrefslogblamecommitdiffstats
path: root/extra/iproute2-qos/qos.initd
blob: b543748691e7a09a9034ece10b41b5d870a0b7d0 (plain) (tree)




































































































































































































































































































                                                                                                                                                                                                             
#!/sbin/runscript
#
###########################################################################################################
# Traffic Control startup script
#
# Copyright (c) 2009 iilluzion
#
# Distributed under GPL-2
###########################################################################################################

PROGRAM=qos
CONFIG=/etc/conf.d/qos
DEBUG=0 #1

opts="compile"

depend() 
{
	need net
}

checkconfig() {
	if [ ! -e $CONFIG ] ; then
		eerror "You need to create $CONFIG first."
	return 1
	fi
}

usage()
{
	echo "usage: $PROGRAM [status|compile|start|stop|restart]"
	echo "   status:  View statistics"
	echo "   compile: Generate traffic control commands"
	echo "   start:   Start traffic control"
	echo "   stop:    Stop traffic control"
	echo "   restart: Restart traffic control"
}

configure()
{
	source $CONFIG $1
}

reset()
{
	for DEV in $DEVICES; do
		tc qdisc show dev $DEV | grep -v "pfifo_fast" | egrep -q "$QDISCS" && $ECHO tc qdisc del dev $DEV root
		tc qdisc show dev $DEV | grep -v "pfifo_fast" | grep  -q ingress && $ECHO tc qdisc del dev $DEV ingress
	done
}

set_leaf_qdisc()
{
	DEV=$1
	PARENT_CLASSID=$2
		PARENT_CLASSID=${PARENT_CLASSID:-1}

	if [ ! "$QDISC_CMD" = "prio" ]; then 
		$ECHO tc qdisc add dev $DEV parent $PARENT_CLASSID:40 handle 40 $INTERACTIVE_LEAF_QDISC
	fi

	$ECHO tc qdisc add dev $DEV parent $PARENT_CLASSID:50 handle 50 $PRIVILEGED_LEAF_QDISC
	$ECHO tc qdisc add dev $DEV parent $PARENT_CLASSID:60 handle 60 $BESTEFFORT_LEAF_QDISC

	if [ $DIRECTION = "DOWN" ]; then 
		$ECHO tc qdisc add dev $DEV parent $PARENT_CLASSID:70 handle 70 $LAN_LEAF_QDISC
	fi

	$ECHO
}

set_filters()
{
	CLASS_TYPES="INTERACTIVE PRIVILEGED BESTEFFORT"
		if [ $DIRECTION = "DOWN" ]; then
			CLASS_TYPES=$CLASS_TYPES" LAN"
		fi 

		PRIVILEGED_FILTER_FLOWID=50
		BESTEFFORT_FILTER_FLOWID=60
		LAN_FILTER_FLOWID=70

	for DEV in $DEVICES; do
		for CLASS_TYPE in $CLASS_TYPES; do
			if [ "$QDISC_CMD" = "prio" -a "$CLASS_TYPE" = "INTERACTIVE" ]; then
				PARENT_CLASSID=1
				INTERACTIVE_FILTER_FLOWID=1
			else
				PARENT_CLASSID=$1
					PARENT_CLASSID=${PARENT_CLASSID:-1}
				INTERACTIVE_FILTER_FLOWID=40
			fi

			for FILTER_NUM in `seq 1 100`; do
				eval FILTER="\$$CLASS_TYPE"_FILTER_$FILTER_NUM
					[ -z "$FILTER" ] && break
				eval FILTER_FLOWID="\$$CLASS_TYPE"_FILTER_FLOWID
					$ECHO tc filter add dev $DEV parent $PARENT_CLASSID:0 $FILTER flowid $PARENT_CLASSID:$FILTER_FLOWID
			done
		done

		$ECHO
	done
}

set_htb()
{
	for DEV in $DEVICES; do
		$ECHO tc qdisc add dev $DEV root handle 1 htb default 60
			$ECHO tc class add dev $DEV parent 1: classid 1:2 htb rate $LAN_RATE
				$ECHO tc class add dev $DEV parent 1:2 classid 1:30 htb rate $WAN_SUB_RATE
					$ECHO tc class add dev $DEV parent 1:30 classid 1:40 htb rate $INTERACTIVE_RATE prio 1
					$ECHO tc class add dev $DEV parent 1:30 classid 1:50 htb rate $PRIVILEGED_RATE ceil $WAN_SUB_RATE prio 3
		    			$ECHO tc class add dev $DEV parent 1:30 classid 1:60 htb rate $BESTEFFORT_RATE ceil $WAN_SUB_RATE prio 6

				if [ $DIRECTION = "DOWN" ]; then 
					$ECHO tc class add dev $DEV parent 1:2 classid 1:70 htb rate $OUT_OF_WAN_RATE prio 7
				fi
	
		set_leaf_qdisc $DEV

		$ECHO
	done

	set_filters
}

set_hfsc()
{
	for DEV in $DEVICES; do
		$ECHO tc qdisc add dev $DEV root handle 1 hfsc default 60
 			$ECHO tc class add dev $DEV parent 1: classid 1:2 hfsc sc rate $LAN_RATE ul rate $LAN_RATE
				$ECHO tc class add dev $DEV parent 1:2 classid 1:30 hfsc sc rate $WAN_SUB_RATE ul rate $WAN_SUB_RATE
					$ECHO tc class add dev $DEV parent 1:30 classid 1:40 hfsc sc umax $INTERACTIVE_HFSC_UMAX dmax $INTERACTIVE_HFSC_DMAX rate $INTERACTIVE_RATE ul rate $INTERACTIVE_RATE
					$ECHO tc class add dev $DEV parent 1:30 classid 1:50 hfsc sc umax $PRIVILEGED_HFSC_UMAX dmax $PRIVILEGED_HFSC_DMAX rate $PRIVILEGED_RATE ul rate $WAN_SUB_RATE
					$ECHO tc class add dev $DEV parent 1:30 classid 1:60 hfsc sc rate $BESTEFFORT_RATE ul rate $WAN_SUB_RATE

				if [ $DIRECTION = "DOWN" ]; then
					$ECHO tc class add dev $DEV parent 1:2 classid 1:70 hfsc sc rate $OUT_OF_WAN_RATE ul rate $OUT_OF_WAN_RATE
				fi

		set_leaf_qdisc $DEV

		$ECHO
	done

	set_filters
}

set_prio()
{
	PARENT_CLASSID=10
	for DEV in $DEVICES; do
		$ECHO tc qdisc add dev $DEV root handle 1 prio bands 2 priomap 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # by default unclassified traffic goes to flowid 1:2
			$ECHO tc qdisc add dev $DEV parent 1:1 handle 40: tbf rate $INTERACTIVE_RATE burst $INTERACTIVE_PRIO_BURST latency $INTERACTIVE_PRIO_LATENCY
			$ECHO tc qdisc add dev $DEV parent 1:2 handle $PARENT_CLASSID: htb default 60
				$ECHO tc class add dev $DEV parent $PARENT_CLASSID: classid $PARENT_CLASSID:30 htb rate $WAN_SUB_RATE
					$ECHO tc class add dev $DEV parent $PARENT_CLASSID:30 classid $PARENT_CLASSID:50 htb rate $PRIVILEGED_RATE ceil $WAN_SUB_RATE prio 3
					$ECHO tc class add dev $DEV parent $PARENT_CLASSID:30 classid $PARENT_CLASSID:60 htb rate $BESTEFFORT_RATE ceil $WAN_SUB_RATE prio 6

				if [ $DIRECTION = "DOWN" ]; then
					$ECHO tc class add dev $DEV parent 10:1 classid $PARENT_CLASSID:70 htb rate $OUT_OF_WAN_RATE prio 7
					fi

		set_leaf_qdisc $DEV $PARENT_CLASSID

		$ECHO
	done

	set_filters $PARENT_CLASSID
}

set_police()
{
	CLASS_TYPES="INTERACTIVE PRIVILEGED"
		INTERACTIVE_POLICE_FLOWID=1
		PRIVILEGED_POLICE_FLOWID=2

	for DEV in $DEVICES; do
		$ECHO tc qdisc add dev $DEV handle ffff: ingress

		for CLASS_TYPE in $CLASS_TYPES; do
			for FILTER_NUM in `seq 1 100`; do
				eval FILTER="\$$CLASS_TYPE"_FILTER_$FILTER_NUM
					[ -z "$FILTER" ] && break
				eval FILTER_FLOWID="\$$CLASS_TYPE"_POLICE_FLOWID
				eval FILTER_RATE="\$$CLASS_TYPE"_RATE
				eval FILTER_BURST="\$$CLASS_TYPE"_POLICE_BURST
					$ECHO tc filter add dev $DEV parent ffff: $FILTER police rate $FILTER_RATE burst $FILTER_BURST continue flowid $FILTER_FLOWID:
			done
		done

		$ECHO tc filter add dev $DEV parent ffff: protocol ip prio 999 u32 match ip src 0.0.0.0/0 police rate $BESTEFFORT_RATE burst $BESTEFFORT_POLICE_BURST drop flowid :3
 
		$ECHO
	done
}

get_stats()
{
	for DEV in $WAN_DEVICES $LAN_DEVICES; do
		echo $DEV Statistics
		echo
		echo "   Classes:"
		echo "--------------------------"
			$ECHO tc -s class show dev $DEV

		echo
		echo "   Leaf Queuing Disciplines:"
		echo "--------------------------"
			$ECHO tc -s qdisc show dev $DEV

		echo
		echo "   EGRESS Filters:"
		echo "--------------------------"
			$ECHO tc -s filter show dev $DEV
			$ECHO tc -s filter show dev $DEV parent 10: # if PRIO qdisc is applied
		
		echo
		echo "   INGRESS Policing Filters:"
		echo "--------------------------"
			$ECHO tc -s filter show dev $DEV parent ffff:

 		echo
		echo
 	done
}

compile()
{
	DEBUG=1
	
	start
}

start()
{
	checkconfig || return 1

	if [ $DEBUG -gt 0 ]; then 
		ECHO="echo"
	else
		ebegin "Starting QoS"
	fi

	for LINK_DIRECTION in UP DOWN; do
		configure $LINK_DIRECTION
			reset

			eval QDISC_CMD="\$$LINK_DIRECTION"LINK_QDISC
				if [ ! "$QDISC_CMD" = "none" ]; then
					set_$QDISC_CMD
				fi

			eval INGRESS_CMD="\$$LINK_DIRECTION"LINK_INGRESS
				if [ ! "$INGRESS_CMD" = "none" ]; then
 					set_$INGRESS_CMD
				fi
	done

	if [ $DEBUG -eq 0 ]; then
	 	eend $?
	fi
}

stop()
{
	checkconfig || return 1

	if [ $DEBUG -gt 0 ]; then
		ECHO="echo"
	else
		ebegin "Stopping QoS"
	fi

	configure ALL
	reset

	if [ $DEBUG -eq 0 ]; then
		eend $?
	fi
}

restart()
{
	stop
	start
}

status()
{
	get_stats
}