diff options
Diffstat (limited to 'main/iproute2-qos/qos.initd')
-rw-r--r-- | main/iproute2-qos/qos.initd | 417 |
1 files changed, 286 insertions, 131 deletions
diff --git a/main/iproute2-qos/qos.initd b/main/iproute2-qos/qos.initd index b54374869..825ef07cf 100644 --- a/main/iproute2-qos/qos.initd +++ b/main/iproute2-qos/qos.initd @@ -8,17 +8,23 @@ # Distributed under GPL-2 ########################################################################################################### -PROGRAM=qos -CONFIG=/etc/conf.d/qos +PROGRAM=$SVCNAME +CONFIG=/etc/conf.d/$SVCNAME DEBUG=0 #1 -opts="compile" +opts="describe compile" +########################################################################################################### +# +# depend() { need net } +########################################################################################################### +# +# checkconfig() { if [ ! -e $CONFIG ] ; then eerror "You need to create $CONFIG first." @@ -26,33 +32,125 @@ checkconfig() { fi } -usage() +########################################################################################################### +# +# +bits() { - 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" + 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, kbps, bps)" + fi + + echo "$R_RATE" } +########################################################################################################### +# +# +expand_leaf_qdisc() +{ + case "$1" in + pfifo) echo "pfifo limit 5";; + sfq) echo "sfq perturb 10";; + red) echo "red min $RED_MIN max $RED_MAX burst $RED_BURST limit $RED_LIMIT probability $RED_PROB avpkt $RED_AVPKT";; + esac +} + +########################################################################################################### +# +# configure() { - source $CONFIG $1 + if [ ! -z $1 ]; then + eval WAN_RATE="\$$1"_RATE + WAN_RATE=`bits $WAN_RATE` + + # Calculaton of WAN classes rates + 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)) + + DEV_RATE=${DEV_RATE:-$EGRESS_RATE} + DEV_RATE=`bits $DEV_RATE` + if [ $DEV_RATE -lt $WAN_RATE ]; then + DEV_RATE=$WAN_RATE + fi + OUT_OF_WAN_RATE=$((DEV_RATE - WAN_RATE)) + + # 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 + + # 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 + + 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)) + + # Setting leaf Queuing Disciplines parameters + INTERACTIVE_LEAF_QDISC=`expand_leaf_qdisc $INTERACTIVE_LEAF_QDISC` + PRIVILEGED_LEAF_QDISC=`expand_leaf_qdisc $PRIVILEGED_LEAF_QDISC` + BESTEFFORT_LEAF_QDISC=`expand_leaf_qdisc $BESTEFFORT_LEAF_QDISC` + LAN_LEAF_QDISC=`expand_leaf_qdisc $LAN_LEAF_QDISC` + fi } +########################################################################################################### +# +# 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 + # Supported Queuing Disciplines + QDISCS="prio|tbf|htb|hfsc|sfq|red|pfifo" + + 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 + + if [ "$INGRESS_ALG" = "ifb" ] && [ ! -z $IFB_DEV ]; then + $ECHO ip link set dev $IFB_DEV down + fi } +########################################################################################################### +# +# set_leaf_qdisc() { - DEV=$1 - PARENT_CLASSID=$2 + PARENT_CLASSID=$1 PARENT_CLASSID=${PARENT_CLASSID:-1} if [ ! "$QDISC_CMD" = "prio" ]; then @@ -62,170 +160,217 @@ set_leaf_qdisc() $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 + if [ $OUT_OF_WAN_RATE -gt 0 ]; 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 + if [ $OUT_OF_WAN_RATE -gt 0 ]; then CLASS_TYPES=$CLASS_TYPES" LAN" - fi + 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 + 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 - - $ECHO done + + $ECHO } +########################################################################################################### +# +# 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 qdisc add dev $DEV root handle 1 htb default 60 + $ECHO tc class add dev $DEV parent 1: classid 1:2 htb rate $DEV_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 [ $OUT_OF_WAN_RATE -gt 0 ]; 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 + set_leaf_qdisc - $ECHO - done + $ECHO 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 qdisc add dev $DEV root handle 1 hfsc default 60 + $ECHO tc class add dev $DEV parent 1: classid 1:2 hfsc sc rate $DEV_RATE ul rate $DEV_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 [ $OUT_OF_WAN_RATE -gt 0 ]; 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 + set_leaf_qdisc - $ECHO - done + $ECHO 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 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 [ $OUT_OF_WAN_RATE -gt 0 ]; then $ECHO tc class add dev $DEV parent 10:1 classid $PARENT_CLASSID:70 htb rate $OUT_OF_WAN_RATE prio 7 - fi + fi - set_leaf_qdisc $DEV $PARENT_CLASSID + set_leaf_qdisc $PARENT_CLASSID - $ECHO - done + $ECHO set_filters $PARENT_CLASSID } +########################################################################################################### +# +# +set_ifb() +{ + $ECHO ip link set dev $IFB_DEV up + $ECHO tc qdisc add dev $DEV ingress handle ffff: + $ECHO tc filter add dev $DEV parent ffff: protocol ip prio 10 u32 match u32 0 0 action mirred egress redirect dev $IFB_DEV > /dev/null 2>&1 +} + +########################################################################################################### +# +# set_police() { + +# Calculation of policing bursts +# burst = rate / 17 (taken basing on experemental results) + + POLICE_BURST_SCALE=17 + WAN_POLICE_BURST=$((WAN_RATE / POLICE_BURST_SCALE)) + + WAN_POLICE_FLOWID=1 + + $ECHO tc qdisc add dev $DEV handle ffff: ingress + $ECHO tc filter add dev $DEV parent ffff: protocol ip prio 999 u32 match ip src 0.0.0.0/0 police rate $WAN_RATE burst $WAN_POLICE_BURST drop flowid :$WAN_POLICE_FLOWID + + $ECHO +} + +########################################################################################################### +# +# +set_cpolice() +{ + + # 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)) + 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 + $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 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 + $ECHO } +########################################################################################################### +# +# 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 $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 + echo + echo " INGRESS Policing Filters:" + echo "--------------------------" + $ECHO tc -s filter show dev $DEV parent ffff: + + echo } +########################################################################################################### +# +# compile() { DEBUG=1 @@ -233,6 +378,9 @@ compile() start } +########################################################################################################### +# +# start() { checkconfig || return 1 @@ -240,29 +388,29 @@ start() if [ $DEBUG -gt 0 ]; then ECHO="echo" else - ebegin "Starting QoS" + ebegin "Starting QoS at $DEV" 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 + reset - eval INGRESS_CMD="\$$LINK_DIRECTION"LINK_INGRESS - if [ ! "$INGRESS_CMD" = "none" ]; then - set_$INGRESS_CMD + for LINK_DIRECTION in EGRESS INGRESS; do + configure $LINK_DIRECTION + eval ALG_CMD="\$$LINK_DIRECTION"_ALG + if [ ! "$ALG_CMD" = "none" ]; then + set_$ALG_CMD fi done +describe > /tmp/$$ + if [ $DEBUG -eq 0 ]; then eend $? fi } +########################################################################################################### +# +# stop() { checkconfig || return 1 @@ -270,10 +418,9 @@ stop() if [ $DEBUG -gt 0 ]; then ECHO="echo" else - ebegin "Stopping QoS" + ebegin "Stopping QoS at $DEV" fi - configure ALL reset if [ $DEBUG -eq 0 ]; then @@ -281,13 +428,21 @@ stop() fi } +########################################################################################################### +# +# restart() { stop start } -status() +########################################################################################################### +# +# +describe() { + checkconfig || return 1 + get_stats -} +}
\ No newline at end of file |