Network emulator tool for Linux

I have finally decided to blog about my netem tool that I wrote a couple of months ago.
First, the introductions, netem is a kernel component for controlling QoS, rate control and various network properties that allows you to emulate a network by modifying the kernel’s IP stack’s queue disciplines. You can read more about it here : http://www.linuxfoundation.org/collaborate/workgroups/networking/netem

The issue I had with the netem queue was that it was hard/complicated to use and required a fair bit of reading and understanding of how the Linux IP stack worked in order to even use it properly. I needed an easy to use tool in order to test multiple network properties quickly. I looked around for a tool that would help me with that and only found phpnetemgui which is a very old piece of code, not even compatible with the latest php versions and which requires you to run a server on localhost and give sudo access to the web server… I didn’t like that, so I wrote my own tool for easy netem configuration (thanks to the phpnetemgui code, it was helpful in providing some of the commands).

You can find my netem tool here : http://cgit.collabora.com/git/user/kakaroto/netem.git/

The README has all the information you need in order to use it, so make sure you read it, but let me summarize a bit how it works.
Netem uses a CSV file in which you can set multiple rules, each with its own set of properties (10% packet loss, 5% duplicated packets, 100ms delay with 25ms of jitter, limit bandwidth to 256Kbps, etc..). Each rule has a name and you can have multiple rules with the same name (limit bandwidth to 256Kbps for IP 1.2.3.4, and 512Kbps to IP 1.2.3.5). All these sub-rules with the same name will be considered as being a single rule. You can run netem on an interface, giving it the CSV filename and the name of the rule that you want to activate and it will output all the commands you need to execute in order to emulate the network as specified in the rules from the CSV file.

To actually run the network emulation, just pipe the output to ‘sh’, for example : ./netem eth0 my_rules.csv 256kbps | sudo sh

The reason I did this was to help my colleague Olivier Crete who was working on TFRC (Tcp-Friendly Rate Control) for RTP in Farsight. He needed to be able to emulate various network configurations, change the bandwidth limitations, introduce packet drop, etc.. and see how TFRC would react to make sure that the video/audio stream’s quality stays acceptable and the bitrate calculation adapts correctly to changing network conditions. I’ve also been recently working on HLS (HTTP Live Streaming) support in GStreamer and I’ve used the tool to make sure that the HLS stream correctly adapts to the network bandwidth and switches the bitrate/resolution correctly. This tool has been a great help in doing all these tests, so it’s time now to share it with whoever it might interest.

I’ll conclude with these example outputs for three different rules (taken from the provided test.csv in git) :

  • Limit inbound and outbound bandwidth to 1024Kbps (2 sub-rules)

kakaroto@kakaroto:~/coding/netem$ ./netem wlan0 test.csv 1024kbps
modprobe ifb
ip link set dev ifb0 up
tc qdisc del dev wlan0 ingress
tc qdisc add dev wlan0 ingress
tc filter add dev wlan0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
tc qdisc del dev ifb0 root
tc qdisc add dev ifb0 root handle 1: prio bands 10
tc qdisc del dev wlan0 root
tc qdisc add dev wlan0 root handle 1: prio bands 10
tc qdisc add dev ifb0 parent 1:1 handle 10: htb default 1
tc class add dev ifb0 parent 10: classid 0:1 htb rate 1024kbit ceil 1024kbit burst 0 cburst 0
tc qdisc add dev wlan0 parent 1:1 handle 10: htb default 1
tc class add dev wlan0 parent 10: classid 0:1 htb rate 1024kbit ceil 1024kbit burst 0 cburst 0
tc filter add dev wlan0 protocol ip parent 1:0 prio 1 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 10:1
tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 10:1

  • A rule to add 100ms of delay with 25ms of jitter using a normal distribution with 25% of correlation

kakaroto@kakaroto:~/coding/netem$ ./netem wlan0 test.csv delay
tc qdisc del dev wlan0 root
tc qdisc add dev wlan0 root handle 1: prio bands 10
tc qdisc add dev wlan0 parent 1:1 handle 10: netem delay 100ms 25ms 25% distribution normal
tc filter add dev wlan0 protocol ip parent 1:0 prio 1 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 10:1

  • A rule that emulates various packet loss, delay, duplication, packet reordering, rate control, for both inbound and outbound connection with IP and port matching (3 sub-rules)

kakaroto@kakaroto:~/coding/netem$ ./netem wlan0 test.csv test1
modprobe ifb
ip link set dev ifb0 up
tc qdisc del dev wlan0 ingress
tc qdisc add dev wlan0 ingress
tc filter add dev wlan0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
tc qdisc del dev ifb0 root
tc qdisc add dev ifb0 root handle 1: prio bands 10
tc qdisc del dev wlan0 root
tc qdisc add dev wlan0 root handle 1: prio bands 10
tc qdisc add dev wlan0 parent 1:1 handle 10: htb default 1
tc class add dev wlan0 parent 10: classid 0:1 htb rate 256kbit ceil 256kbit burst 0 cburst 0
tc qdisc add dev wlan0 parent 10:1 handle 11: netem loss 0.5% 25% duplicate 5% delay 100ms 50ms 25% distribution pareto reorder 1% limit 1000
tc qdisc add dev wlan0 parent 1:2 handle 20: netem loss 0.5% 50% limit 1000
tc qdisc add dev ifb0 parent 1:1 handle 10: netem loss 5% reorder 5% limit 1000
tc filter add dev wlan0 protocol ip parent 1:0 prio 1 u32 match ip dst 1.2.3.4/32 match ip dport 1234 0xffff flowid 10:1
tc filter add dev wlan0 protocol ip parent 1:0 prio 2 u32 match ip sport 4321 0xffff flowid 10:1
tc qdisc add dev wlan0 parent 1:3 handle 30: pfifo
tc filter add dev wlan0 protocol ip parent 1:0 prio 3 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 30:3
tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4/32 match ip sport 1234 0xffff flowid 10:1
tc qdisc add dev ifb0 parent 1:2 handle 20: pfifo
tc filter add dev ifb0 protocol ip parent 1:0 prio 2 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 20:2

This entry was posted in Development, Farsight and tagged , , , , , , , , , , , . Bookmark the permalink.

5 Responses to Network emulator tool for Linux

  1. Pingback: Links 2/9/2011: 11.10 ‘Oneiric Ocelot’ Beta, Cablegate is Out in Full | Techrights

  2. alexandernst says:

    :O !
    How cool is that, sensei!! 😀
    I must test it, but I’d suggest something that *imho* is easy to implement (correct me if I’m wrong) and that’ll make that tool even cooler!
    After opening the CSV file, keep an eye on it, and if something gets changed, apply the new changes.

    Regards 😉

    • kakaroto says:

      Thanks alex, but no need to keep an eye on the csv, first of all, it’s not a daemon, the only way to do that is for the app to run forever, secondly it’s not even running the commands, it’s purpose is just to simply the generation of the commands needed to do the network emulation, you still need to pipe it through sh for it to actually execute them.
      Also, the purpose of this was not to create a full fledged application with a UI and everything.. just a quick tool to more easily generate the tc commands needed.

  3. Very nice. I’ve also found very hard to figure out how to use netem.

    Anyway, I wonder if a json file would be more appropriate instead of csv.

    • kakaroto says:

      Thanks!
      I don’t know about json files, only heard the name a couple of times. Using csv was simply because it was the easiest to parse and mostly because it can be opened in gnumeric/openoffice and present the data in a spreadsheet.
      Is there a UI for editing json files that would present it as a spreadsheet or something like that, which would be easy to edit ?

Comments are closed.