Bandwidth shaping with Linux
If you have a broadband Internet connection like a cable modem or ADSL, you probably already know that an old PC running Linux makes a great firewall for your home network. But did you know that Linux also includes everything you need to manage your bandwidth and give you the most performance out of your connection?
Most Internet connections, even a 56k modem, have different upstream and downstream speeds. For example, my ADSL connection at my house has a maximum downstream speed of 1.5 megabits/s and a maximum upstream of 256 kilobits/s. My network looks like this:
The problem is that when the upstream is completely saturated, the downstream will drop to the same speed. That means that if my router is sending packets to the modem at 10mb/s but the modem can only transmit them at 256kb/s, my download speed is effectively capped at 256kb/s. This is an inherent limitation of the TCP/IP protocol, and not the fault of the provider or the modem. The most common way this situation might arise is through the use of a file sharing program like Gnutella where several files are being uploaded at once, choking off download performance. Cancelling some of the uploads will restore download to its full capacity.
<---256kb/s ADSL Linux Home
Internet <-------------> Modem <--10mb/s--> Router <--100mb/s--> Network
This is why some file sharing programs come with bandwidth throttling options to limit upload speed. But this is just a band-aid for one particular application, and does nothing to address the basic problem. The solution is to implement bandwidth management at the Linux router so that outbound traffic is capped there instead of at the modem, and the upstream connection is never allowed to reach complete saturation.
First, you need a fairly recent Linux distribution with a 2.4 kernel and iptables. You'll need to enable netfilter and QOS as modules in the networking options section of the kernel if they aren't already (most default kernels should have this already). You also need the iproute2 package and Arno's iptables firewall script package.
Arno's Firewall Script
Compile and install the iproute2 package, using Rewandythal's tutorial on compiling as a reference if necessary. The traffic shaping script needs the tc binary from this package.
Next, untar Arno's script and find the file called rc.traffic-shaper. This is the only file you'll need from the package. Open it in a text editor and edit the lines that read:
Since my upstream is 256kb/s, I set my cap at 225kb/s for a little safety margin. If you're on dial-up or ADSL, the ppp0 interface should be correct. If not, adjust it to the ethernet interface you use for your public interface. I also had to edit the location of the tc binary. The script defaults to /sbin/tc, but on my Gentoo system it is located in /usr/sbin/tc, which caused the script to choke.
Next, set the executable bit on the script and run it:
chmod +x rc.traffic-shaper
If you want to start the script automatically at boot, you can copy it to /etc/rc.d/init.d/ (Some distributions may use a different method, but this will work on Red Hat and Mandrake at least.) If you want to test it, go to www.dslreports.com and run their speed test to check your maximum upload speed.
There are much more sophisticated bandwidth shaping tools available out there, but for a home network this is perfectly adequate. If you want to investigate more complex options, you can have a look at the following documents: