Friday, June 1, 2012

Simulate delayed and dropped packets on Linux

I would like to simulate packet delay and loss for UDP and TCP on Linux to measure the performance of an application. Is there a simple way to do this?

Source: Tips4all


  1. netem leverages functionality already built into Linux and userspace utilities to simulate networks. This is actually what Mark's answer refers to, by a different name.

    The examples on their homepage already show how you can achieve what you've asked for:


    Emulating wide area network delays

    This is the simplest example, it just adds a fixed amount of delay to all packets going out of the local Ethernet.

    # tc qdisc add dev eth0 root netem delay 100ms

    Now a simple ping test to host on the local network should show an increase of 100 milliseconds. The delay is limited by the clock resolution of the kernel (HZ). On most 2.4 systems, the system clock runs at 100hz which allows delays in increments of 10ms. On 2.6, the value is a configuration parameter from 1000 to 100 hz.

    Later examples just change parameters without reloading the qdisc

    Real wide area networks show variability so it is possible to add random variation.

    # tc qdisc change dev eth0 root netem delay 100ms 10ms

    This causes the added delay to be 100ms ± 10ms. Network delay variation isn't purely random, so to emulate that there is a correlation value as well.

    # tc qdisc change dev eth0 root netem delay 100ms 10ms 25%

    This causes the added delay to be 100ms ± 10ms with the next random element depending 25% on the last one. This isn't true statistical correlation, but an approximation.

    Delay distribution

    Typically, the delay in a network is not uniform. It is more common to use a something like a normal distribution to describe the variation in delay. The netem discipline can take a table to specify a non-uniform distribution.

    # tc qdisc change dev eth0 root netem delay 100ms 20ms distribution normal

    The actual tables (normal, pareto, paretonormal) are generated as part of the iproute2 compilation and placed in /usr/lib/tc; so it is possible with some effort to make your own distribution based on experimental data.

    Packet loss

    Random packet loss is specified in the 'tc' command in percent. The smallest possible non-zero value is:

    232 = 0.0000000232%

    # tc qdisc change dev eth0 root netem loss 0.1%

    This causes 1/10th of a percent (i.e 1 out of 1000) packets to be randomly dropped.

    An optional correlation may also be added. This causes the random number generator to be less random and can be used to emulate packet burst losses.

    # tc qdisc change dev eth0 root netem loss 0.3% 25%

    This will cause 0.3% of packets to be lost, and each successive probability depends by a quarter on the last one.

    Probn = .25 * Probn-1 + .75 * Random

  2. For dropped packets I would simply use iptables and the statistic module.

    iptables -A INPUT -m statistic --mode random --probability 0.01 -j DROP

    Above will drop an incoming packet with a 1% probability. Be careful, anything above about 0.14 and most of you tcp connections will most likely stall completely.

    Take a look at man iptables and search for "statistic" for more information.

  3. iptables(8) has a statistics module that can be used to match every nth packet. To drop this packet, just append -j DROP.

  4. This tutorial on networking physics simulations contains a C++ class in the sample code for simulating latency and packet loss in a UDP connection and may be of guidance:

  5. One of my colleagues uses tc to do this. Refer to the man page for more information. You can see an example of its usage here.

  6. Haven't tried it myself, but this page has a list of plugin modules that run in Linux' built in iptables IP filtering system. One of the modules is called "nth", and allows you to set up a rule that will drop a configurable rate of the packets. Might be a good place to start, at least.

  7. You can try
    It's quite old NIST project (last release 2005), but it works for me.