Network shaping using `tc netem` doesn't seem to work
Solution 1:
I finally figured it out. After careful studying of this and this chapters I have much better understanding of how it is supposed to work and how tc
processes packets.
So basically, what I need to do, is to build this kind of tree:
1: root qdisc
/ | \
/ | \
/ | \
1:1 1:2 1:3 classes
| | |
10: 20: 30: qdiscs qdiscs
netem sfq ---
band 0 1 2
Which means, that apart from adding netem
qdisc I needed to add sfq
to the second band and add a filter for "catch-all" case. Here are all the commands I'm using:
tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 172.19.0.2 match ip dport 6363 0xffff flowid 1:1
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:2
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match ip protocol 1 0xff flowid 1:2
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 10ms
tc qdisc add dev eth0 parent 1:2 handle 20: sfq
Here are explanations for every line above:
Add
prio
queueing discipline to the root with handle (id)1:0
(0 is not mandatory) on interfaceeth0
.prio
qdisc has three classes by default - 1:1 1:2 and 1:3. These classes will be assigned filters on the next three lines (order matters!). It is important to understand how outgoing packets are processed - they enter tree from the root and exit it from the root as well (not falling off the leaves!).Add filter for the traffic we want to slow down (it's the traffic going to
172.19.0.2
on port6363
in my case). Filter attaches to the root node (parent 1:
) - it means that all outgoing packets will be checked by this filter. Filter checks for ip and port (ip dst ... ip dport ...
) and redirects to class1:1
(flowid 1:1
).In similar fashion to the above, this is how "catch-all" filter is set (thanks this post), redirects to class
1:2
.Similarly, this filter is a "catch-all" for ICMP packets (ping packets), also redirects to
1:2
.Attach
qdisc
to class1:1
, give it a handle of10:0
and let it benetem
qdisc with delay 10ms.Attach
sfq
qdisc to class1:2
- this qdisc will handle all other packets that matched "catch-all" filter in a "stochastic fairness" fashion.
I highly recommend reading those chapters I gave links to as they clarify a lot of things and allow you to stop desperately googling for a solution and start designing network shaping on your own.
Also, I found these commands extremely useful for debugging/examining:
tc -s qdisc ls dev eth0
tc -s filter ls dev eth0