Do you experience some lag when you are talking to someone on Skype or
Gizmo whilst surfing the internet? How about having your streaming
video or audio stall and reconnect to the source when you are
downloading a huge file using BitTorrent? I am sure that most of you
who are using a broadband connection experience these problems.
Although more bandwidth is definitely a welcome addition but given the
limited bandwidth, how can you make sure that interactive internet
traffic is given more priority over others? I sure wish that we will
get the 3Mbps or higher broadband connection soon but only the telco's
can tell when we will achieve that bandwidth. So for the meantime, we
will see how we can make do with what bandwidth we have and maximize
it.
What do you need to be able to do this? First of all, you need a
broadband router. There are plenty of make and models available in the
market today but most of these do not allow you to tweak the way it
routes or handles your internet traffic. What most of these routers do
is to forward the internet-bound traffic to the telco as is - with no
priority.
In my quest to find a solution, I found the Linksys WRT54G broadband
router to be the most flexible make and model. Although I am not
getting paid to endorse it (there are other make and models available
but some are not available here), the Linksys is the most affordable
and readily available locally. What makes it special is that its
firmware is based on Linux. Being Linux, it is open - meaning you can
see the source, modify, compile and re-distribute it even. Just a word
of warning, though, using third-party firmware on these equipment
voids its warranty - so this is not for the faint-hearted.
The next step is to find a suitable firmware for the Linksys router.
There are several available at wrt54g.com or wrt54g.net. Select one
that comes with traffic control and iptables such as OpenWRT.
Incidentally, if you do not have a broadband router, you can get a
Linux box with two network interfaces as your router.
Scouring the internet for basic how-to's in prioritizing traffic will
lead you to the Linux Advanced Routing and Traffic Control How-To at
I will be summarizing it here.
Most of these commands are executed on the command-line, so it is
essential that you are familiar with this interface. Anyway, you may
create a script or simply run these on the shell:
tc qdisc add dev eth0 root handle 1: htb default 15<enter>
tc class add dev eth0 parent 1: classid 1:1 htb rate 240kbit ceil 240kbit<enter>
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80kbit ceil
80kbit prio 0<enter>
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 80kbit ceil
240kbit prio 1<enter>
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 20kbit ceil
240kbit prio 2<enter>
tc class add dev eth0 parent 1:1 classid 1:13 htb rate 20kbit ceil
240kbit prio 2<enter>
tc class add dev eth0 parent 1:1 classid 1:14 htb rate 10kbit ceil
240kbit prio 3<enter>
tc class add dev eth0 parent 1:1 classid 1:15 htb rate 30kbit ceil
240kbit prio 3<enter>
tc qdisc add dev eth0 parent 1:12 handle 120: sfq perturb 10<enter>
tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10<enter>
tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10<enter>
tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10<enter>
You basically have to type each line and hit <enter> to execute the
command. Here, the maximum bandwidth limit is set to 240 kbps. You may
change this depending on the upstream bandwidth you have. The
interface eth0 is the network interface or card that is connected to
your broadband modem. This interface is normally assigned a valid IP
address by the telco.
Each classid represents a different type of traffic. Prioritization is
done by classifying network data accordingly. For instance, classid
1:10 is considered as the highest priority class, whilst classid 1:14
is considered as the one of the lower priority classes.
Next thing to setup is the filter. This will allow iptables to
classify the packets. Here're the commands:
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1 fw
classid 1:10<enter>
tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw
classid 1:11<enter>
tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw
classid 1:12<enter>
tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 4 fw
classid 1:13<enter>
tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 5 fw
classid 1:14<enter>
tc filter add dev eth0 parent 1:0 protocol ip prio 6 handle 6 fw
classid 1:15<enter>
These commands allow iptables to mark each packet according to type by
assigning it a handle number (handle 1 for class 1:10, 2 for 1:11 and
so on), which corresponds to a specific traffic class.
Next is to enable IP forwarding and then run iptables. In the example
below, the IP address 202.92.128.111 is the router's telco supplied IP
address and 192.168.1.0/24 is your local network:
echo 1 > /proc/sys/net/ipv4/ip_forward<enter>
iptables -t nat -A POSTROUTING -s 192.168.1.0/255.255.255.0 -o eth0 -j
SNAT --to-source 212.170.21.172<enter>
Try to "ping" a site such as google.com and then run
tc -s class show dev eth0<enter>
Invoke the command several times for you to notice that traffic is
indeed flowing through 1:15.
Start marking or classifying the packets.
iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 0x1<enter>
iptables -t mangle -A PREROUTING -p icmp -j RETURN<enter>
This classifies your "ping requests" to class 1:10. The "-j RETURN"
option prevents the system from proceeding to the next iptables
entries.
Issue another "tc -s class show dev eth0" and you will notice that
traffic is coursed through 1:10.
Some applications have their IP Type-of-Service (TOS) bits set. To
handle these, run the following:
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK
--set-mark 0x1<enter>
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN<enter>
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK
--set-mark 0x5<enter>
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN<enter>
iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j
MARK --set-mark 0x6<enter>
iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j
RETURN<enter>
You may now prioritize other types of packets by following the
conventions above. You may classify packets according to the port it
uses. For example, ssh uses port 22. To classify it and give it
priority, just run:
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j MARK
--set-mark 0x1<enter>
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j RETURN<enter>
When you are done with your rules, just terminate the PREROUTING with
iptables -t mangle -A PREROUTING -j MARK --set-mark 0x6<enter>
to classify all other traffic to the default 1:15.
It is often more convenient to bunch all of these commands into a
script and have the system run it on boot. I leave it to you as an
exercise or you may check out the URL I have mentioned on how the
author did it.