Linux Networking – Simulating Packet Loss on Bridged Interface Using Netem

bridgelinuxnetworking

I am trying to simulate a network loss on a bridged interface.
I have 4 network interfaces on my server eth1, eth2 and eth3 are bridged in br0 and eth0 which is currently disconnected. As a matter of fact eth2 is also disconnected (down). I have connected to eth1 a video transmitting device and eth3 is connected directly to the network switch.
A receiving device is connected to the same switch but on another port. I am using netem to simulate network impairments on the path. This is an example of my netem command:
sudo tc qdisc add dev eth1 root netem delay 100ms 50ms loss 20%.
If I ping the transmitter I am getting exactly the time delay, jitter and packet loss configured with this command but this is somehow not affecting the network transport between the transmitter and decoder. If I run the same command on eth3 the link between the transmitter and receiver starts to drop, but the question is why the transport is running fine if if I define eth1 as a network interface?

Best Answer

The reason for this behaviour is described in the tc-netem(8) (bold mine):

delay

adds the chosen delay to the packets outgoing to chosen network interface.

or

loss random

adds an independent loss probability to the packets outgoing from the chosen network interface.

So tc ... netem works only on outgoing packets and has no effect on incoming packets from eth1. Applying the rule to eth3 allows netem to have the intented effect since it's now an outgoing interface for the video traffic.

If eth3 shouldn't have such rules applied, because it should behave normally with traffic not related to eth1, and only incoming traffic from eth1 should suffer these rules, then an intermediate interface should be put between eth1 and the bridge in order to have netem applied on an outgoing side.

An easy to understand example, would be to add an other bridge enslaving eth1 and also linked with a veth pair to the first bridge: then the tc rule can be applied on the veth interface of this additional bridge: since incoming packets from eth1 would then be outgoing via this veth interface, it would work as intended.

But actually the Intermediate Functional Block device (ifb0) is designed to be used for this kind of problem by inserting an artificial internal egress interface in the network flow, right after the incoming/ingress interface. ifb0 will still be located before most other network layers and stay mostly invisible. Since it's outgoing/egress (but only internally), netem will work on it.

So here's the solution to have netem work for incoming instead of outgoing traffic on eth1 interface, using ifb0's trick adapted from an example from tc-mirred(8).:

ip link add ifb0 type ifb || :
ip link set ifb0 up
tc qdisc add dev ifb0 root netem delay 100ms 50ms loss 20%
tc qdisc add dev eth1 handle ffff: ingress
tc filter add dev eth1 parent ffff: u32 match u32 0 0 action mirred egress redirect dev ifb0

u32 match u32 0 0 is the simplest possible ANY filter to use for the filter command to be accepted.

Of course it also works when eth1 is in a bridge.