#! /bin/sh bandwidth=2500kbit Q_ESTIMATOR="estimator 250ms 500ms" CL_ESTIMATOR="estimator 1 4" function fwhandle() { grep $1 /etc/iproute2/rt_marks | awk '{ print $1 }' } function drr_hierarchy() { parent=$1 handle=$2 classes=$3 tc qdisc add dev eth0 $Q_ESTIMATOR parent $parent handle $handle \ drr for ((i = 1; i <= $classes; i++)); do classid=$handle$(printf %x $i) tc class add dev eth0 $CL_ESTIMATOR parent $handle classid $classid \ drr tc qdisc add dev eth0 parent $classid pfifo limit 40 done } function tc_hierarchy() { # Root qdisc and class # tc qdisc add dev eth0 $Q_ESTIMATOR root handle 1: hfsc default 10 tc class add dev eth0 parent 1: classid 1:1 \ hfsc ls rate $bandwidth ul rate $bandwidth # Default leaf class # tc class add dev eth0 $CL_ESTIMATOR parent 1:1 classid 1:10 \ hfsc sc rate 1570kbit # tc qdisc add dev eth0 $Q_ESTIMATOR parent 1:10 handle 110: \ # sfq limit 128 drr_hierarchy 1:10 110: 1024 # protocol ip tc filter add dev eth0 protocol all pref 1 parent $handle handle 1 \ flow hash keys nfct divisor 1024 # SIP class # # 64000 bit/s a-Law in 51 frames a 156 bytes with an overhead of 28 (UDP) + 16 (RTP) bytes # per packet (= 200 byte), resulting in 81600 bit/s per channel. # tc class add dev eth0 $CL_ESTIMATOR parent 1:1 classid 1:20 \ hfsc sc rate 163200bit tc qdisc add dev eth0 $Q_ESTIMATOR parent 1:20 handle 120: \ pfifo limit 10 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle sip-rtp) fw classid 1:20 # High priority class # tc class add dev eth0 $CL_ESTIMATOR parent 1:1 classid 1:30 \ hfsc sc rate 750kbit tc qdisc add dev eth0 $Q_ESTIMATOR parent 1:30 handle 130: \ pfifo limit 50 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle syn) fw classid 1:30 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle ack) fw classid 1:30 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle dns) fw classid 1:30 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle ping) fw classid 1:30 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle sip-ctrl) fw classid 1:30 # FTP class # tc class add dev eth0 $CL_ESTIMATOR parent 1:1 classid 1:40 \ hfsc ls rate 10kbit tc qdisc add dev eth0 $Q_ESTIMATOR parent 1:40 handle 140: \ red min 30k max 50k burst 30 avpkt 1516 bandwidth $bandwidth limit 1 ecn # tc qdisc add dev eth0 $Q_ESTIMATOR parent 140:1 handle 1400: \ # sfq limit 128 drr_hierarchy 140:1 1400: 1024 tc filter add dev eth0 protocol ip pref 1 parent 1400: handle 1 \ flow hash keys dst divisor 1024 tc filter add dev eth0 protocol ip pref 1 parent 1: handle $(fwhandle ftp) fw classid 1:40 } function tc_hierarchy_clean() { tc qdisc del dev eth0 root 2>/dev/null } case "$1" in up) tc_hierarchy_clean tc_hierarchy & ;; down) tc_hierarchy_clean ;; esac