aboutsummaryrefslogtreecommitdiffstats
path: root/extra/iproute2-qos
diff options
context:
space:
mode:
authorIlya Strelkin <iilluzion@gmail.com>2009-02-20 12:33:44 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2009-02-20 12:33:44 +0000
commit6d38339592ed2fb7100709662971f7a2d3a060e8 (patch)
treedde7a97c8f4765827a8e91d3e674878a64609c54 /extra/iproute2-qos
parentdd17281c4c19f62892d45a792fc5d4258eaaf024 (diff)
downloadaports-6d38339592ed2fb7100709662971f7a2d3a060e8.tar.gz
aports-6d38339592ed2fb7100709662971f7a2d3a060e8.tar.bz2
aports-6d38339592ed2fb7100709662971f7a2d3a060e8.tar.xz
extra/iproute2-qos: new aport
Scripts to set up quality of service with iproute2
Diffstat (limited to 'extra/iproute2-qos')
-rw-r--r--extra/iproute2-qos/APKBUILD21
-rw-r--r--extra/iproute2-qos/qos.confd314
-rw-r--r--extra/iproute2-qos/qos.initd293
-rw-r--r--extra/iproute2-qos/setup-qos67
4 files changed, 695 insertions, 0 deletions
diff --git a/extra/iproute2-qos/APKBUILD b/extra/iproute2-qos/APKBUILD
new file mode 100644
index 0000000000..51c90b6137
--- /dev/null
+++ b/extra/iproute2-qos/APKBUILD
@@ -0,0 +1,21 @@
+# Contributor: Ilya Strelkin <iilluzion@gmail.com>
+# Maintainer: Ilya Strelkin <iilluzion@gmail.com>
+pkgname=iproute2-qos
+pkgver=0.1
+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"
+
+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
+}
+
+md5sums="024b3e5b6f6cca09a729ce265898a0c7 qos.initd
+2517182784a415ac10fca4998680df60 qos.confd
+785aff5d4284c47038a009797c576e34 setup-qos"
diff --git a/extra/iproute2-qos/qos.confd b/extra/iproute2-qos/qos.confd
new file mode 100644
index 0000000000..60d4093726
--- /dev/null
+++ b/extra/iproute2-qos/qos.confd
@@ -0,0 +1,314 @@
+###########################################################################################################
+#
+# 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
+###########################################################################################################
diff --git a/extra/iproute2-qos/qos.initd b/extra/iproute2-qos/qos.initd
new file mode 100644
index 0000000000..b543748691
--- /dev/null
+++ b/extra/iproute2-qos/qos.initd
@@ -0,0 +1,293 @@
+#!/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
+}
diff --git a/extra/iproute2-qos/setup-qos b/extra/iproute2-qos/setup-qos
new file mode 100644
index 0000000000..5d5c601268
--- /dev/null
+++ b/extra/iproute2-qos/setup-qos
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+PREFIX=
+. "$PREFIX/lib/libalpine.sh"
+
+conf="$ROOT/etc/conf.d/qos"
+
+cfgval() {
+ awk -F= "/^$1/ {print \$2}" $conf 2>/dev/null
+}
+
+setcfg() {
+ local key=$1
+ local value=$2
+ sed -i "s/^\\(\\#\\)*$key=.*/$key=$value/" "$conf"
+ if ! grep "^$key=" "$conf" >/dev/null ; then
+ echo "$key=$value" >> "$conf"
+ fi
+}
+
+apk_add iproute2
+
+if [ -f "$conf" ] ; then
+ _UPLINK_RATE=$(cfgval UPLINK_RATE)
+ _DOWNLINK_RATE=$(cfgval DOWNLINK_RATE)
+ _RATE_SUB_PERCENT=$(cfgval RATE_SUB_PERCENT)
+else
+ echo "Configuration file '$conf' not found"
+ exit 1
+fi
+
+echo "**********************************************************************"
+echo "Since ISPs tend to overestimate the speeds they offer, it would probably be best"
+echo " if you measure this on a free line to set values very precisely."
+echo "**********************************************************************"
+echo
+echon "Specify the upload speed of your internet connection (mbps, mbit, kbit, kbps, bps): [$_UPLINK_RATE] "
+ default_read _UPLINK_RATE $_UPLINK_RATE
+echo
+echon "Specify the download speed of your internet connection (mbps, mbit, kbit, kbps, bps): [$_DOWNLINK_RATE] "
+ default_read _DOWNLINK_RATE $_DOWNLINK_RATE
+echo
+echo "**********************************************************************"
+echo "In order to prevent traffic queuing at the ISP side or in your modem,"
+echo " you should set a slightly lower rate than real one."
+echo "This way the bottleneck is the router,"
+echo " not the ISP or modem, which allows to control the queue."
+echo "**********************************************************************"
+echo
+echon "Specify amount of percents: [$_RATE_SUB_PERCENT] "
+ default_read _RATE_SUB_PERCENT $_RATE_SUB_PERCENT
+
+echon "Start QoS? (y/n) [y] "
+ default_read startqos "y"
+ case "$startqos" in
+ [Yy]*) /etc/init.d/qos start;;
+ esac
+
+echon "Make QoS to be started on boot? (y/n) [y] "
+ default_read bootstartqos "y"
+ case "$bootstartqos" in
+ [Yy]*) rc_add qos;;
+ esac
+
+setcfg UPLINK_RATE $_UPLINK_RATE
+setcfg DOWNLINK_RATE $_DOWNLINK_RATE
+setcfg RATE_SUB_PERCENT $_RATE_SUB_PERCENT