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.

Later examples just change parameters without reloading the qdisc.

Variable delay

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 a 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. (See Eric W. Weisstein. "Normal Distribution." From MathWorld--A Wolfram Web Resource.) 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:
1/232 = .0000000232%

# tc qdisc change dev eth0 root netem loss .1%

A correlation value can also be specified.

Packet duplication

Packet duplication is specified the same way as packet loss.

# tc qdisc change dev eth0 root netem duplicate 1%

Packet re-ordering

Packet re-ordering causes 1 out of N packets to be delayed.

# tc qdisc change dev eth0 root netem gap 5 delay 10ms

So the 5th (10th, 15th, ...) packet will get delayed by 10ms and the others will pass straight out.

Rate control

There is no rate control built-in to the netem discpline, instead use one of the other disciplines that does do rate control. In this example, we use Token Bucket Filter (TBF) to limit output.

# tc qdisc add dev eth0 root handle 1:0 netem delay 100ms
# tc qdisc add dev eth0 parent 1:1 handle 10: tbf rate 256kbit buffer 1600 limit 3000

# tc -s qdisc ls dev eth0
qdisc netem 1: limit 1000 delay 100.0ms
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0 )
qdisc tbf 10: rate 256Kbit burst 1599b lat 26.6ms
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0 )

For more explanation about how to use classful queuing disciplines see: Linux Advanced Routing HOWTO - classes

Non FIFO queuing

Just like the previous example, any of the other queuing disciplines (GRED, CBQ, etc) can be used.

Delaying only some traffic

Here is a simple example that only controls traffic to one IP address.

# tc qdisc add dev eth0 root handle 1: prio
# tc qdisc add dev eth0 parent 1:3 handle 30: netem \
    delay 200ms 10ms distribution normal
# tc qdisc add dev eth0 parent 30:1 tbf rate 20kbit buffer 1600 limit 3000
# tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
    match ip dst 65.172.181.4/32 flowid 10:3

The commands makes a simple priority queueing discipline, then attaches a basic netem to the priority 3 hook. Then a TBF is added to do rate control. Finally, a filter classifies all packets going to 65.172.181.4 as being priority 3.

See the Linux Advanced Routing HOWTO - filters about how to classify traffic.