X
Tech

Setting up a Linux bandwidth emulator

I dug up some notes from my own archives, and decided to post information on setting up a network bandwidth emulator with Linux. And what would anybody want to use this for?
Written by Chris Clay Clay, Contributor

I dug up some notes from my own archives, and decided to post information on setting up a network bandwidth emulator with Linux. And what would anybody want to use this for? Over the years, I have found it extremely useful for testing web based applications. The emulator can add a bandwidth cap as well as latency (network delay), to exactly simulate any sort of broadband connection, DSL, cable, dial-up, etc. to a test server, while being plugged in to your local network. However, this application could also be used for bandwidth throttling if there was a need. If you happen to try searching for an appliance that does what this setup does, you will find they are quite expensive, so this provides a very powerful and money saving solution. The steps provided here require knowledge of the command shell in Linux.

I recommend setting up an old PC for this with two network cards in it, and dedicate it strictly for this purpose. Thankfully, Linux can easily run on an old Pentium II or newer, which is perfect. The instructions below will enable any PC running Linux to behave as a bridge, meaning you simply set the PC between two network devices, and it will pass all traffic yet limit the bandwidth as you set it.

First, we need to set up the bridge for the two network interfaces. There is probably an easier way to do this with GUI-based tools, but these instructions are a few years old and were written for Fedora 6, so I am handling it the old fashioned way, which still should work with a new Linux installation. Do not set any static IP addresses on your network cards, leave them on DHCP.

Add these lines to the bottom of the file /etc/rc.d/rc.local :

brctl addbr br0 brctl stp br0 off brctl addif br0 eth0 brctl addif br0 eth1

ifconfig eth0 down ifconfig eth1 down ifconfig eth0 0.0.0.0 up ifconfig eth1 0.0.0.0 up

ifconfig br0 192.168.0.3 up

These lines will set up the two network interfaces (network cards) to form a bridge. The bottom line assigns an IP address to the bridge, so that you can connect to the PC with an ssh client and manage it. Be sure to select a valid IP address for your network there. Note that the individual interfaces should not have an IP address.

Now, add these additional lines to the bottom of the file /etc/rc.d/rc.local :

# eth1 (plugged in to local network) tc qdisc del dev eth1 root # packet delay (incoming) tc qdisc add dev eth1 root handle 1: netem delay 80ms # bandwidth limits (outgoing) tc qdisc add dev eth1 parent 1: handle 10: htb default 1 tc class add dev eth1 parent 10: classid 10:1 htb rate 1.54mbit ceil 1.54mbit

# eth0 (plugged in to test box) tc qdisc del dev eth0 root # packet delay (outgoing) (delay from incoming iface is added) tc qdisc add dev eth0 root handle 1: netem delay 0ms # bandwidth limits (incoming) tc qdisc add dev eth0 parent 1: handle 10: htb default 1 tc class add dev eth0 parent 10: classid 10:1 htb rate 1.54mbit ceil 1.54mbit

These lines will set the default emulation options when the PC boots, which in this case is a full T1 (1.54 mbit up, 1.54 mbit down, 80 ms latency). As you can see, the "tc" (traffic control) utility is being used to set parameters on each interface. Also, bandwidth settings that are set on each interface (eth0 and eth1) only affect traffic going out on that interface, inbound traffic on an interface is not set. Therefore, you will need to set parameters on both interfaces of your PC, if you want to limit bandwidth travelling in both directions through the PC. However, latency set on either interface will affect latency travelling through the PC, so if you were to set latency to 40 ms on eth0 and eth1, you would get a total of 80 ms through the PC. Therefore I only recommend setting latency on one interface.

Now, plug in the interface eth0 to a test box (a server is recommended). Plug eth1 to your regular local network, such as a network switch or hub. Then, I usually jump on to a test PC on my local network, and test the connection to the server, which will pass through the bridge (and emulator).

You can use some sample commands below from the command prompt, to view and modify the parameters in realtime (Linux doesn't need rebooting) on the emulator.

To view current download speeds from the test box:

tc qdisc show dev eth1 tc class show dev eth1

To view current upload speeds to the test box:

tc qdisc show dev eth0 tc class show dev eth0

To set download speeds from the test box:

tc qdisc replace dev eth1 root handle 1: netem delay DOWNLATENCYms tc qdisc replace dev eth1 parent 1: handle 10: htb default 1 tc class replace dev eth1 parent 10: classid 10:1 htb rate DOWNRATEkbit ceil DOWNCEILkbit

Where "DOWNLATENCY" is the latency or network delay in milliseconds (ms). "DOWNRATE" and "DOWNCEIL" are the bandwith cap in kilobits (kb). You can also specify the rate in megabits (mb).

To set upload speeds to the test box:

tc qdisc replace dev eth0 root handle 1: netem delay UPLATENCYms tc qdisc replace dev eth0 parent 1: handle 10: htb default 1 tc class replace dev eth0 parent 10: classid 10:1 htb rate UPRATEkbit ceil UPCEILkbit

Where "UPLATENCY" is the latency or network delay in milliseconds (ms). "UPRATE" and "UPCEIL" are the bandwidth cap in kilobits (kb). You can also specify the rate in megabits (mb).

To disable bandwidth control completely for the bridge:

tc qdisc del dev eth1 root tc qdisc del dev eth0 root

Using the commands above, download and upload speeds through the bridge can be set independently, allowing complete control of the link you are trying to emulate. Emulate a 512 kb DSL connection, or even a 56 kb dial-up connection! Also, if you reboot, the default settings in the file /etc/rc.d/rc.local will be used, so you can set your settings in that file to whatever you wish to use. What is even more amazing about this solution, is that it emulates perfectly to the real world. As a test, try pinging a host on the other side of the bridge, and then start a file transfer or transfer data to a host. Watch as the latency increases just as expected.

Due to the limited space of this post, I cannot go into much detail about what each command is doing. The documentation for the "tc" utility will explain in more detail. If you are looking for an affordable way to handle traffic control, this solution works extremely well.

Editorial standards