#!/bin/bash # Bryggenet QoS script # ------------------------------------- # Author: Jesper Dangaard Brouer CEIL=390000 if [ -z "$IFACE" ]; then echo "WARN: This script should be run from /etc/network/interfaces" if [ -n "$1" ]; then DEV=$1 echo " Using arg1 as device name: $DEV" else echo "ERROR: Bailing out!" exit 1 fi else DEV=$IFACE fi # Bryggenet # eth1 - world being NAT'ted # eth2 - LAN with 10.0.0.0/8 # # We need a different hash in each direction, to assign a # DRR queue to each user/customer behind the shaper. # if [ "$DEV" = "eth1" ]; then FLOW_HASH=nfct-src elif [ "$DEV" = "eth2" ]; then FLOW_HASH=dst else FLOW_HASH=src fi # Determining the 'tc' command location, if not specified # and verify the location if the $tc variable is set. # # Have installed the latest iproute2 in /usr/local/stow/ tc=/usr/local/sbin/tc if [ -z "$tc" ]; then which tc > /dev/null 2>&1 if [ $? -eq 0 ]; then tc=tc elif [ -x /sbin/tc ]; then tc=/sbin/tc else echo "" echo "ERROR: Linux traffic control command 'tc' not found!" exit 1 fi else # Verify $tc exists and is executable if [ ! -x $tc ]; then echo "" echo "ERROR: Linux traffic control command '$tc' not found/executable!" exit 1 fi fi ########################################## # Functions ########################################## VERBOSE=yes function fun_tc() { $tc $@ result=$? if [ $result -gt 0 ]; then echo "WARNING -- Error ($result) when executing the tc command:" echo " \"$tc $@\"" else if [ -n "$VERBOSE" ]; then echo "$tc $@" fi fi } function drr_hierarchy() { # Thanks to Patrick McHardy parent=$1 handle=$2 classes=$3 fun_tc qdisc replace dev $DEV parent $parent handle $handle \ drr for ((i = 1; i <= $classes; i++)); do classid=$handle$(printf %x $i) fun_tc class replace dev $DEV parent $handle classid $classid \ drr #fun_tc qdisc replace dev $DEV parent $classid pfifo limit 40 fun_tc qdisc replace dev $DEV parent $classid \ sfq perturb 120 limit 1024 done # Filter: # FLOW_HASH is set above # We need a different hash in each direction, to assign a # DRR queue to each user/customer behind the shaper. # fun_tc filter add dev $DEV protocol ip pref 1 parent $handle handle 1 \ flow hash keys $FLOW_HASH divisor 256 perturb 60 # Filter EXAMPLES: # ---------------- # SRC matching has a problem due to NAT #fun_tc filter add dev $DEV protocol ip pref 1 parent 20: handle 1 \ # flow hash keys src divisor 256 perturb 60 # NFCT-SRC should be the source before NAT #fun_tc filter add dev $DEV protocol ip pref 1 parent 20: handle 1 \ # flow hash keys nfct-src divisor 256 perturb 60 # NFCT-SRC source before NAT and the dst #fun_tc filter add dev $DEV protocol ip pref 1 parent 20: handle 1 \ # flow hash keys nfct-src,dst divisor 256 perturb 60 # Direct mapping #fun_tc filter replace dev $DEV protocol ip pref 1 parent 20: handle 1 \ # flow map key src and 0xfff divisor 256 if [ -n "$VERBOSE" ]; then fun_tc filter show dev $DEV parent 20: fi } #drr_hierarchy 140:1 1400: 1024 # #tc filter add dev $DEV protocol ip pref 1 parent 1400: handle 1 \ # flow hash keys src divisor 1024 perturb 30 #drr_hierarchy 1:30 300: 1024 #tc filter add dev $DEV protocol ip pref 1 parent 300: handle 1 \ # flow hash keys src divisor 1024 perturb 60 function classify_iptables_stop() { ### STOP Classification of subnets using iptables iptables -t mangle -F FORWARD } function classify_iptables_start() { ### Classification of subnets using iptables # Match all 10.0.0.0/8 will/SHOULD be rematched below iptables -t mangle -A FORWARD -s 10.0.0.0/8 -j CLASSIFY --set-class 1:77 iptables -t mangle -A FORWARD -d 10.0.0.0/8 -j CLASSIFY --set-class 1:77 # Lille iptables -t mangle -A FORWARD -s 10.16.0.0/15 -j CLASSIFY --set-class 1:30 iptables -t mangle -A FORWARD -d 10.16.0.0/15 -j CLASSIFY --set-class 1:30 # Stor iptables -t mangle -A FORWARD -s 10.20.0.0/15 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -d 10.20.0.0/15 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -s 10.12.0.0/16 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -d 10.12.0.0/16 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -s 194.255.87.0/24 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -d 194.255.87.0/24 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -s 194.255.112.0/24 -j CLASSIFY --set-class 1:20 iptables -t mangle -A FORWARD -d 194.255.112.0/24 -j CLASSIFY --set-class 1:20 } # Deletes previous classification (if any) # ---------------------------------------- # Suppress output, because no classes/qdiscs result # in an error message, which is expected... fun_tc qdisc del dev $DEV root > /dev/null 2>&1 # Stop the classification during building the queues classify_iptables_stop # Create the root of tree # ----------------------- # (default class: 1:50) # fun_tc qdisc add dev ${DEV} root handle 1: htb default 50 r2q 1 fun_tc class add dev ${DEV} parent 1: classid 1:1 htb \ rate ${CEIL}kbit ceil ${CEIL}kbit ########################################## # Class: 1:50 # Mark : 50 # Description: Default fallthrough traffic ########################################## procent=20 ceil_procent=95 fun_tc class add dev ${DEV} parent 1:1 classid 1:50 htb \ rate $[${procent}*${CEIL}/100]kbit \ ceil $[${ceil_procent}*${CEIL}/100]kbit \ prio 4 \ burst 10000 cburst 5000 fun_tc qdisc add dev ${DEV} parent 1:50 handle 4250: \ sfq perturb 10 limit 256 fun_tc filter add dev ${DEV} parent 1:0 protocol ip \ prio 50 handle 0x50 fw classid 1:50 ########################################## # Class: 1:20 # Mark : 20 # Description: Big Internet ########################################## rate_stor=290000 ceil_stor=$CEIL fun_tc class add dev ${DEV} parent 1:1 classid 1:20 htb \ rate ${rate_stor}kbit \ ceil ${ceil_stor}kbit \ prio 1 \ burst 10000 cburst 5000 # Can be replaced by DRR #fun_tc qdisc add dev ${DEV} parent 1:20 handle 4220: \ # sfq perturb 10 limit 256 # drr_hierarchy 1:20 20: 256 fun_tc filter add dev ${DEV} parent 1:0 protocol ip \ prio 20 handle 0x20 fw classid 1:20 ########################################## # Class: 1:30 # Mark : 30 # Description: Small Internet ########################################## rate_lille=100000 ceil_lille=100000 fun_tc class add dev ${DEV} parent 1:1 classid 1:30 htb \ rate ${rate_lille}kbit \ ceil ${ceil_lille}kbit \ prio 4 \ burst 10000 cburst 5000 # Can be replaced by DRR #fun_tc qdisc add dev ${DEV} parent 1:30 handle 4230: \ # sfq perturb 10 limit 256 drr_hierarchy 1:30 30: 256 fun_tc filter add dev ${DEV} parent 1:0 protocol ip \ prio 30 handle 0x30 fw classid 1:30 ########################################## # Class: 1:77 # Mark : 77 # Description: Should not occur ########################################## rate_lille=100000 ceil_lille=100000 fun_tc class add dev ${DEV} parent 1:1 classid 1:77 htb \ rate ${rate_lille}kbit \ ceil ${ceil_lille}kbit \ prio 6 \ burst 10000 cburst 5000 fun_tc qdisc add dev ${DEV} parent 1:77 handle 4277: \ sfq perturb 10 limit 128 fun_tc filter add dev ${DEV} parent 1:0 protocol ip \ prio 77 handle 0x77 fw classid 1:77 ############ # DRR setup ############ #drr_hierarchy 1:77 777: 1024 #fun_tc filter add dev $DEV protocol ip pref 1 parent 777: handle 1 \ # flow hash keys src divisor 1024 perturb 60 #fun_tc filter show dev $DEV parent 777: ##fun_tc filter del dev $DEV protocol ip pref 1 parent 777: #################### # DDR on Class 1:20 #################### # drr_hierarchy 1:20 20: 256 ### Classification using iptables rules classify_iptables_start