* Fwd: Working HTB Script for traffic control
@ 2013-12-16 11:54 Ian Macintosh
0 siblings, 0 replies; only message in thread
From: Ian Macintosh @ 2013-12-16 11:54 UTC (permalink / raw)
To: lartc
Hi.
I've run the below script on my servers for a while now and thought I
would submit it for comment or use by others. Also to elicit
improvements.
Basically it creates a number of HTB streams and sub-streams for one
of our 100mb networks.
Logically important is to understand that this is for a gateway
server. ie, it is between the internet and the various LAN's and all
traffic goes via it. Why is this important? Because it does not
police the traffic (ie, drop packets) but queues the traffic both
inbound and outbound on two separate interfaces. As a result, it
makes sure that incoming traffic obeys the configured traffic rules
without policing.
Also note that the script is written for synchronous traffic, where
the incoming and outgoing rates are equal. In other words, it is not
written to handle 30mb download and 1mb upload.
The logical structure is:
.--------------.---------.
| Root | Filters |
'--------------'---------'
|
v
.--------------.
| HTB Limit |-----------------------------------------------.
'--------------' |
| |
v v
.--------------------. .--------------------.
| HTB Stream | | HTB Stream |
| Guaranteed/Ceiling |---------. | Guaranteed/Ceiling |
'--------------------' | '--------------------'
| | |
v v |
.-------------. .-------------. v
| Optionally | | Optionally | .-----------.
| other HTB | | other HTB |-------------------->| ditto.... |
| sub streams | | sub streams | '-----------'
'-------------' '-------------'
|
v
.----------------.
| Prio qdisc |-----------------------.
'----------------' | |
| | |
v v v
.------------. .------------. .------------.
| prio 0 | | prio 1 | | prio 2 |
'------------' '------------' '------------'
| | |
v v v
.-----------. .-----------. .-----------.
| qdisc sfq | | qdisc sfq | | qdisc sfq |
'-----------' '-----------' '-----------'
Textually, there is a main HTB limiting the traffic to 0.5mbit below
the rated line speed (adjustable to suit your config), which is then
broken into HTB streams which can be optionally broken into further
HTB sub-streams.
Finally, the base of each HTB receive a standard prio qdisc and each
of the prio qdisc's receive a sfq qdisc to stop any one system from
hogging all the bandwidth within that stream.
It works very well for us.
Note that as per usual the IP addresses are bogus and that the 'names'
are just invented to protect the innocent.
Here is the script:
#!/bin/bash
# Debugging
#set -x
# Traffic Shaping
# (c) 2012 KCS Total Solutions Ltd
# Released 2013-12-16 AGPL 3.0
# Contact: Ian Macintosh
# email address is ian.macintosh at the domain kcsts.co.uk
# 2012-03-13 - IGM: Initial version
# 2013-02-20 - IGM: Updates for LAN2
# 2013-05-01 - IGM: Added PRIO & SFQ
# 2013-12-16 - IGM: Refactored - changed to variables & loops
# Interfaces - Inside and Outside
IFACE_OUTSIDE=eth0
IFACE_INSIDE=eth1
# Maximum mbit rate on forwarding
MAX_IRATE™.9
MAX_ORATE™.9
# mbit Guaranteed Rates (GRate) & Ceiling Rates (CRate)
declare -a Names # Bucket Names (human understanding only)
declare -a GRate # Guaranteed rate
declare -a CRate # Ceiling rate
declare -a SubDv # Is this bucket subdivided?
declare -a FiltI # Filter IP address
declare -a FiltP # Filter Priority - generally /32 IP filters
or dead accurate /XX filters can be prio 1
# but other 'over-broad' filters should be a
lower priority, eg, prio 2
DefaultFilter\x11 # Default classify, (Main is #1, and it is
subdivided with sub #1=Firewall
Names=(Main Linus Bill Larry Sergey Peter James )
GRate=(87 2 2 2 2 2 2 )
CRate=(99 20 20 20 20 20 20 )
SubDv=(y n n n n n n )
# The filters to extract put the right IP's into the correct streams
# Note that any subdivided (SubDv="y") stream does not use this filter
# but instead use the filter given in the array SubFI below
FiltI=( \
XXXXXXXXXXXXXXX \
141.0.56.105/32 \
141.0.56.104/29 \
141.0.56.117/32 \
141.0.56.100/32 \
141.0.56.120/32 \
141.0.56.103/32 \
)
# The filter priority. Any overbroad filter should receive a lower
(higher number) priority
FiltP=( \
X \
1 \
2 \
1 \
1 \
1 \
1 \
)
# SubDivided rates (SubD)
declare -a SubDN # SubD Names
declare -a SubDG # SubD Guaranteed rates
declare -a SubDC # SubC Ceiling rates
declare -a SubFi # Subdivided Filters
SubDN=( 'subn=(LAN Backup Web Other )' )
SubDG=( 'subg=(46.5 10 10 20 )' )
SubDC=( 'subc=(99 99 99 99 )' )
# IP filter specs for each class, in sequence
SubFi=( \
'subf=( \
"" \
"101.10.16.99/32" \
"101.10.16.97/32 101.10.16.112/32 111.10.16.113/32 101.10.16.114/32
101.10.16.116/32 101.10.16.118/32 101.10.16.124/32" \
"101.10.16.98/32" \
)' \
)
if [ "$1" = "status" ]; then
echo
echo "INSIDE"
echo "==="
tc -s -d -p -iec qdisc show dev $IFACE_INSIDE
tc -s -d -p -iec class show dev $IFACE_INSIDE
echo
echo "OUTSIDE"
echo "===="
tc -s -d -p -iec qdisc show dev $IFACE_OUTSIDE
tc -s -d -p -iec class show dev $IFACE_OUTSIDE
echo
exit 0
fi
# Start fresh
tc qdisc del dev $IFACE_OUTSIDE root &> /dev/null
tc qdisc del dev $IFACE_INSIDE root &> /dev/null
# If we're stopping, we're done
if [ "$1" = "stop" ]; then
exit
fi
# abbreviations
TCQI="tc qdisc add dev $IFACE_INSIDE"
TCQO="tc qdisc add dev $IFACE_OUTSIDE"
TCCI="tc class add dev $IFACE_INSIDE"
TCCO="tc class add dev $IFACE_OUTSIDE"
TCFI="tc filter add dev $IFACE_INSIDE protocol ip"
TCFO="tc filter add dev $IFACE_OUTSIDE protocol ip"
$TCQI root handle 1: htb default $DefaultFilter
$TCCI parent 1: classid 1:1 htb rate ${MAX_IRATE}mbit
$TCQO root handle 1: htb default $DefaultFilter
$TCCO parent 1: classid 1:1 htb rate ${MAX_ORATE}mbit
for i in $(seq 0 $((${#Names[@]} - 1)) ); do
ClassID=$((i + 1))
#echo "Creating HTB class for ${Names[i]} at rates G/C=${GRate[i]}/${CRate[i]}"
$TCCI parent 1:1 classid 1:${ClassID}0 htb rate ${GRate[i]}mbit ceil
${CRate[i]}mbit
$TCCO parent 1:1 classid 1:${ClassID}0 htb rate ${GRate[i]}mbit ceil
${CRate[i]}mbit
if [ ${SubDv[i]} = "y" ]; then
eval ${SubDN[i]}; eval ${SubDG[i]}; eval ${SubDC[i]}; eval ${SubFi[i]}
for j in $(seq 0 $((${#subn[@]} - 1)) ); do
ClassSuff=$((j + 1))
$TCCI parent 1:${ClassID}0 classid 1:${ClassID}${ClassSuff} htb
rate ${subg[j]}mbit ceil ${subc[j]}mbit
$TCCO parent 1:${ClassID}0 classid 1:${ClassID}${ClassSuff} htb
rate ${subg[j]}mbit ceil ${subc[j]}mbit
for ks in ${subf[j]}; do
if [ ${#ks} -gt 0 ]; then
$TCFI parent 1: prio 1 u32 match ip dst $ks flowid 1:${ClassID}${ClassSuff}
$TCFO parent 1: prio 1 u32 match ip src $ks flowid 1:${ClassID}${ClassSuff}
fi
done
$TCQI parent 1:${ClassID}${ClassSuff} handle ${ClassID}0${ClassSuff}: prio
$TCQO parent 1:${ClassID}${ClassSuff} handle ${ClassID}0${ClassSuff}: prio
for k in $(seq 1 3); do
$TCQI parent ${ClassID}0${ClassSuff}:$k handle
${ClassID}${ClassSuff}$k: sfq perturb 10
$TCQO parent ${ClassID}0${ClassSuff}:$k handle
${ClassID}${ClassSuff}$k: sfq perturb 10
done
done
else
$TCFI parent 1: prio 1 u32 match ip dst ${FiltI[i]} flowid 1:${ClassID}0
$TCFO parent 1: prio 1 u32 match ip src ${FiltI[i]} flowid 1:${ClassID}0
$TCQI parent 1:${ClassID}0 handle ${ClassID}0: prio
$TCQO parent 1:${ClassID}0 handle ${ClassID}0: prio
for j in $(seq 1 3); do
$TCQI parent ${ClassID}0:$j handle ${ClassID}0$j: sfq perturb 10
$TCQO parent ${ClassID}0:$j handle ${ClassID}0$j: sfq perturb 10
done
fi
done
exit 0
Comments, flames, critique and improvements accepted - either to the
list or in the case of flames preferably me directly :-)
Regards,
Ian.
-------------------
Ian Macintosh
Technical Director - KCS Total Solutions Ltd
Tel: +44 (0)1442 251-514 Web: www.kcsts.co.uk
Registered in England and Wales, No. 3792344 at 3 Kensworth Gate,
200-204 High Street South, Dunstable, LU6 3HS
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2013-12-16 11:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-16 11:54 Fwd: Working HTB Script for traffic control Ian Macintosh
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.