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?
-
I was thinking that this might be connected with the OSI layer on which the video traffic and the network bridge is operating and that this could be the reason why when applied to the interface connected to the encoder the network impairments don't affect the video traffic and when applied to the interface connected to the switch it affects it.– Georgi StoyanovFeb 5, 2018 at 12:00
1 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.