diff options
Diffstat (limited to 'main/iproute2-qos')
-rw-r--r-- | main/iproute2-qos/APKBUILD | 14 | ||||
-rw-r--r-- | main/iproute2-qos/qos.eth0.sample | 130 | ||||
-rw-r--r-- | main/iproute2-qos/qos.ifb0.sample | 131 | ||||
-rw-r--r-- | main/iproute2-qos/qos.initd | 417 |
4 files changed, 556 insertions, 136 deletions
diff --git a/main/iproute2-qos/APKBUILD b/main/iproute2-qos/APKBUILD index 902ff0c1ae..7851e63d24 100644 --- a/main/iproute2-qos/APKBUILD +++ b/main/iproute2-qos/APKBUILD @@ -1,21 +1,25 @@ # Contributor: Ilya Strelkin <iilluzion@gmail.com> # Maintainer: Ilya Strelkin <iilluzion@gmail.com> pkgname=iproute2-qos -pkgver=0.1 +pkgver=0.2 pkgrel=0 pkgdesc="Scripts to set up quality of service with iproute2" url="http://git.alpinelinux.org/cgit/aports" license="GPL" depends="iproute2" makedepends="" -source="qos.initd qos.confd setup-qos" +source="qos.initd qos.eth0.sample qos.ifb0.sample setup-qos" build() { install -m755 -D "$srcdir"/setup-qos "$pkgdir"/usr/sbin/setup-qos install -m755 -D "$srcdir"/qos.initd "$pkgdir"/etc/init.d/qos - install -m644 -D "$srcdir"/qos.confd "$pkgdir"/etc/conf.d/qos + install -m644 -D "$srcdir"/qos.eth0.sample \ + "$pkgdir"/etc/conf.d/qos.eth0.sample + install -m644 -D "$srcdir"/qos.ifb0.sample \ + "$pkgdir"/etc/conf.d/qos.ifb0.sample } -md5sums="024b3e5b6f6cca09a729ce265898a0c7 qos.initd -d4cc8ff1e36312cbe816c1540c4f2d92 qos.confd +md5sums="d4f225300dab94078e0c51f292bf558c qos.initd +aeb793e4e1e7219bf245c06e29212048 qos.eth0.sample +d9bbf66187a62485450397c4e93d1293 qos.ifb0.sample 785aff5d4284c47038a009797c576e34 setup-qos" diff --git a/main/iproute2-qos/qos.eth0.sample b/main/iproute2-qos/qos.eth0.sample new file mode 100644 index 0000000000..a8d1d38567 --- /dev/null +++ b/main/iproute2-qos/qos.eth0.sample @@ -0,0 +1,130 @@ +# Device being configured +DEV=eth0 + +# IFB device is used to mirror ingress traffic from $DEV (see INGRESS_ALG) +IFB_DEV=ifb0 # Leave blank if $DEV is ifbX + +# Internet EGRESS/INGRES rates in kbit or mbit. Measure this on a free line to gain precise value +EGRESS_RATE=1000kbit # 128kbit, 256kbit, 512kbit +INGRESS_RATE=1000kbit # 256kbit, 512kbit, 1024kbit + +# In order to control a queue at the router/bridge side we will downgrade a real link speed on purpose +RATE_SUB_PERCENT=5 # 20, 10 + +# Device physical speed in kbit or mbit +DEV_RATE=50mbit + +# EGRESS root Classfull Disciplins +# +# 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 link is not congested +# +EGRESS_ALG=hfsc + +# EGRESS leaf Queuing Disciplines +# +# pfifo: real-time streams or IPSEC +# sfq: TCP sessions or best-effort class traffic +# red: hightly congested links or high-speed Internet [> 10Mbit/sec]) +# +INTERACTIVE_LEAF_QDISC=pfifo +PRIVILEGED_LEAF_QDISC=pfifo +BESTEFFORT_LEAF_QDISC=red +LAN_LEAF_QDISC=sfq + +# INGRESS treatment +# +# police: if link is constantly heavy congested set simple traffic policing +# cpolice: if link is constantly heavy congested but you need certain dedicated rates then set classfull traffic policiing +# ifb: shape INGRESS traffic as EGRESS of intermediate IFB device (aka imq) +# none: if link is not congested +# +INGRESS_ALG=ifb + +# Filter rules (see tc, tc-filters man pages). +# You may have multiple <CLASS-NAME>_FILTER_<n> items. +# Maximum 100 filter items are allowed for each class. +# By default ALL unclassified traffic is being assined to Best-Effort class. + +# 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" + +# PHB TOS HEX +# -------------------------- +# 0x10 +# 0x18 +# CS1 PRIORITY 0x20 +# AF11 0x28 +# AF12 0x30 +# AF13 0x38 +# +# CS2 IMMEDIATE 0x40 +# AF21 0x48 +# AF22 0x50 +# AF23 0x58 +# +# CS5 CRITICAL 0xA0 +# EF 0xB8 +# +# CS6 INTERNETWORKCONTROL 0xC0 +# CS7 NETWORKCONTROL 0xE0 + +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 0xa0 0xff" +INTERACTIVE_FILTER_8="protocol ip prio 100 u32 match ip tos 0xb8 0xff" + +# 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" + +# PHB TOS HEX +# -------------------------- +# CS3 FLASH 0x60 +# AF31 0x68 +# AF32 0x70 +# AF33 0x78 +# +# CS4 FLASHOVERRIDE 0x80 +# AF41 0x88 +# AF42 0x90 +# AF43 0x98 + +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" + + +# Example: Any traffic from/to 192.168.1.0/24 network will be 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" + +# Example: Traffic Originated from router +# +###LAN_FILTER_1="protocol ip prio 10 u32 match ip src 192.168.1.10"
\ No newline at end of file diff --git a/main/iproute2-qos/qos.ifb0.sample b/main/iproute2-qos/qos.ifb0.sample new file mode 100644 index 0000000000..2f382b27f5 --- /dev/null +++ b/main/iproute2-qos/qos.ifb0.sample @@ -0,0 +1,131 @@ +# Device being configured +DEV=ifb0 + +# IFB device is used to mirror ingress traffic from $DEV (see INGRESS_ALG) +IFB_DEV= # Leave it blank if $DEV is ifbX + +# Internet EGRESS/INGRES rates in kbit or mbit. Measure this on a free line to gain precise value +EGRESS_RATE=1000kbit # 128kbit, 256kbit, 512kbit +INGRESS_RATE=1000kbit # 256kbit, 512kbit, 1024kbit + +# In order to control a queue at the router/bridge side we will downgrade a real link speed on purpose +RATE_SUB_PERCENT=5 # 20, 10 + +# Device physical speed in kbit or mbit. +DEV_RATE=50mbit + +# EGRESS root Classfull Disciplins +# +# 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 link is not congested +# +EGRESS_ALG=htb + +# EGRESS leaf Queuing Disciplines +# +# pfifo: real-time streams or IPSEC +# sfq: TCP sessions or best-effort class traffic +# red: hightly congested links or high-speed Internet [> 10Mbit/sec]) +# +INTERACTIVE_LEAF_QDISC=pfifo +PRIVILEGED_LEAF_QDISC=pfifo +BESTEFFORT_LEAF_QDISC=red +LAN_LEAF_QDISC=sfq + +# INGRESS treatment +# +# police: if link is constantly heavy congested set simple traffic policing +# cpolice: if link is constantly heavy congested but you need certain dedicated rates then set classfull traffic policiing +# ifb: shape INGRESS traffic as EGRESS of intermediate IFB device (aka imq) +# none: if INGRESS traffic already is being shaped or if IFB device is being configured +# +INGRESS_ALG=none + +# Filter rules (see tc, tc-filters man pages). +# You may have multiple <CLASS-NAME>_FILTER_<n> items. +# Maximum 100 filter items are allowed for each class. +# By default ALL unclassified traffic is being assined to Best-Effort class. + +# 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" + +# PHB TOS HEX +# -------------------------- +# 0x10 +# 0x18 +# CS1 PRIORITY 0x20 +# AF11 0x28 +# AF12 0x30 +# AF13 0x38 +# +# CS2 IMMEDIATE 0x40 +# AF21 0x48 +# AF22 0x50 +# AF23 0x58 +# +# CS5 CRITICAL 0xA0 +# EF 0xB8 +# +# CS6 INTERNETWORKCONTROL 0xC0 +# CS7 NETWORKCONTROL 0xE0 + +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 0xa0 0xff" +INTERACTIVE_FILTER_8="protocol ip prio 100 u32 match ip tos 0xb8 0xff" + + +# 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" + +# PHB TOS HEX +# -------------------------- +# CS3 FLASH 0x60 +# AF31 0x68 +# AF32 0x70 +# AF33 0x78 +# +# CS4 FLASHOVERRIDE 0x80 +# AF41 0x88 +# AF42 0x90 +# AF43 0x98 + +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" + + +# Example: Any traffic from/to 192.168.1.0/24 network will be 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" + +# Example: Traffic Originated from router +# +###LAN_FILTER_1="protocol ip prio 10 u32 match ip src 192.168.1.10"
\ No newline at end of file diff --git a/main/iproute2-qos/qos.initd b/main/iproute2-qos/qos.initd index b543748691..825ef07cfd 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 |