I am having some issues with tcqdisc commands, more specifically netemdelay and bfifolimit. They work as intended when I use them separately, but I cannot figure out a way to use them simultaneously.
I deployed a virtual network using Linux namespaces that looks like the following: Topology
My goal with this work is to do some experiments with regards to congestion control. More specifically by introducing some congestion in various "Router_x". To do so, I want to be able to add delay and packet loss on some routers. In top of that, although it doesn't matter for this post, I will be using the buffers occupancy of said routers to perform some operations, it is therefore important that the buffers of my Router_x have a limit (at least the transmission buffer).
In a perfect world, the following code should to what I want:
#!/bin/bash
for i in $(seq 1 "$1")
do
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" root handle 1:0 htb default 20
sudo ip netns exec Router_"$i" tc class add dev eth1-rtr_"$i" parent 1:0 classid 1:1"$i" htb rate 1gbit
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 1:1"$i" handle 10: netem delay 100ms loss 5%
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 10: handle 20: bfifo limit 500000
sudo ip netns exec Router_"$i" tc filter add dev eth1-rtr_"$i" protocol ipv6 parent 1:0 prio 1 flower dst_ip fd05::1 action classid 1:1"$i"
done
But it does not. Actually, neither the delay, nor the buffer limit are applied. In top of that, even the htbrate stops to be applied properly.
What bothers me even more is that only setting the delay and loss as follow:
#!/bin/bash
for i in $(seq 1 "$1")
do
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" root handle 1:0 htb default 20
sudo ip netns exec Router_"$i" tc class add dev eth1-rtr_"$i" parent 1:0 classid 1:1"$i" htb rate 1gbit
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 1:1"$i" handle 10: netem delay 100ms loss 5%
sudo ip netns exec Router_"$i" tc filter add dev eth1-rtr_"$i" protocol ipv6 parent 1:0 prio 1 flower dst_ip fd05::1 action classid 1:1"$i"
done
works perfectly as intended and doing the exact opposite, by only setting the buffers limitations by replacing:
#!/bin/bash
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 1:1"$i" handle 10: netem delay 100ms loss 5%
with:
#!/bin/bash
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 1:1"$i" handle 10: bfifo limit 500000
also work as intended and I can clearly observe the buffer occupancy never crossing this limit.
I have tested several alternatives to make it work, but in vain... Note that I don't mind switching from bytes limits to packet limits, I don't mind either to switch from htb to tbf for instance, nor to try something totally, as long as my links are limited in bandwidth, I have buffer size limitation, and that I'm able to add delay/loss.
To facilitate your precious help, here are some potentially useful additional data on my setup:
The traffic is generated using iperf3 as follows:
#!/bin/bash
sudo ip netns exec Sender iperf3 --version6 -J -t 30 --set-mss 256B -c fd05::1 -P 128
My Linux version is: Linux myVM 5.18.0 #1 SMP PREEMPT_DYNAMIC Wed Feb 22 14:16:07 CET 2023 x86_64 x86_64 x86_64 GNU/Linux
I may have missed a few key elements to help and solve my issue, do not hesitate to ask addition information that could help you to solve this problem.
Here is a non exhaustive list of attempts made to solve this problem:
- Using the embedded limit option in netem
#!/bin/bash
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" root netem limit 500000 delay 100ms
Directly setting txqueuelen to internally fix the buffer size while only using tc for delay/loss
Trying to chain the rules by adding an additional tcc class
#!/bin/bash
for i in $(seq 1 "$1")
do
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" root handle 1:0 htb default 30
sudo ip netns exec Router_"$i" tc class add dev eth1-rtr_"$i" parent 1:0 classid 1:1"$i" htb rate 1gbit
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 1:1"$i" handle 10: bfifo limit 500000
sudo ip netns exec Router_"$i" tc class add dev eth1-rtr_"$i" parent 1:1"$i" classid 1:2"$i" htb rate 1gbit
sudo ip netns exec Router_"$i" tc qdisc add dev eth1-rtr_"$i" parent 1:2"$i" handle 20: netem delay 100ms loss 5%
sudo ip netns exec Router_"$i" tc filter add dev eth1-rtr_"$i" protocol ipv6 parent 1:0 prio 1 flower dst_ip fd05::1 action classid 1:2"$i"
done
Thank you very much for your help.