Monday, September 6, 2010

traffic shaping a dsl line with linux

The case is like this:
[code]
Internet < --> [dsl modem] < --> [linux box] < --> [Lan]
[/code]
DSL modem is connected on eth2 on linux box and the rest of the Lan on eth0. I had a serious problem with people leaving edonkey clients opens all night..limiting the download speed to 20kb/sec but forgetting to limit the upload. The current dsl line is 384/128 so having the uploads unlimited…is like killing the line.
The solution was to setup a QOS script. And here it is:
[code]
#!/bin/bash
DEV="eth2"
LOCALIF="eth2"
# Reset everything to a known state (cleared)
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev imq0 root 2> /dev/null > /dev/null
iptables -t mangle -F POSTROUTING 2> /dev/null > /dev/null
iptables -t mangle -Z POSTROUTING 2> /dev/null > /dev/null
iptables -t mangle -X POSTROUTING 2> /dev/null > /dev/null
iptables -t mangle -F tosfix
iptables -t mangle -F ack
ip link set imq0 down 2> /dev/null > /dev/null
rmmod imq 2> /dev/null > /dev/null
if [ "$1" = "stop" ]
then
echo "Shaping removed on $DEV."
exit
fi
tc qdisc add dev $DEV root handle 1: tbf rate 85kbit burst 1600 limit 1
tc qdisc add dev $DEV parent 1:1 handle 2: prio bands 4
tc qdisc add dev $DEV parent 2:1 handle 10: sfq perturb 10
tc qdisc add dev $DEV parent 2:2 handle 20: sfq perturb 10
tc qdisc add dev $DEV parent 2:3 handle 30: sfq perturb 10
tc qdisc add dev $DEV parent 2:4 handle 40: tbf rate 40kbit burst 1600 limit 3000
tc qdisc add dev $DEV parent 40:1 handle 41: pfifo limit 10
iptables -t mangle -N tosfix
iptables -t mangle -A tosfix -p tcp -m length --length 0:64 -j RETURN
iptables -t mangle -A tosfix -m limit --limit 2/s --limit-burst 10 -j RETURN
iptables -t mangle -A tosfix -j TOS --set-tos Maximize-Throughput
iptables -t mangle -A tosfix -j RETURN
iptables -t mangle -N ack
iptables -t mangle -A ack -m tos ! --tos Normal-Service -j RETURN
iptables -t mangle -A ack -p tcp -m length --length 0:64 \
-j TOS --set-tos Minimize-Delay
iptables -t mangle -A ack -p tcp -m length --length 64: \
-j TOS --set-tos Maximize-Throughput
iptables -t mangle -A ack -j RETURN
# Is our TOS broken? Fix it for TCP ACK and OpenSSH.
iptables -t mangle -A POSTROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j ack
iptables -t mangle -A POSTROUTING -p tcp -m tos --tos Minimize-Delay -j tosfix
# Here we deal with ACK, SYN, and RST packets
# Match SYN and RST packets
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp -m tcp --tcp-flags ! SYN,RST,ACK ACK \
-j CLASSIFY --set-class 2:1
# Match ACK packets
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK \
-m length --length :128 -m tos --tos Minimize-Delay \
-j CLASSIFY --set-class 2:1
# Match packets with TOS Minimize-Delay
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp -m tos --tos Minimize-Delay \
-j CLASSIFY --set-class 2:1
### Actual traffic shaping classifications with CLASSIFY
# ICMP (ping)
iptables -t mangle -A POSTROUTING -o $LOCALIF -p icmp -j CLASSIFY --set-class 2:1
# Outbound client requests for HTTP, IRC and AIM (dport matches)
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp --dport 80 -j CLASSIFY --set-class 2:2
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp --dport 6667 -j CLASSIFY --set-class 2:2
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp --dport 5190 -j CLASSIFY --set-class 2:2
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp --sport 80 -j CLASSIFY --set-class 2:3
iptables -t mangle -A POSTROUTING -o $LOCALIF -p tcp --dport 1024: -j CLASSIFY --set-class 2:4
[/code]

It WORKS for me…I don’t know whether it will work for you though. I take no responsibility. I will explain it no further because comments do exists and it’s really easy to understand what’s going on if you read a couple of tc tutorials from the net. Many ideas about this script were “stolen” from other scripts I studied while trying to make mine.
Have fun with it…

Source : http://www.void.gr/kargig/blog/2005/07/27/traffic-shaping-a-dsl-line-with-linux/