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…

Here’s an mrtg graph to see how it’s working. Watch the blue line which is the uploads. It never goes beyond a reasonable limit and download stays unaffected: