Traffic shaping and iptables

Someone just asked something on be.comp.os.linux for which I spent quite some time on reading relevant documentation to find a working solution. It's not hard if you know it, but since it's hidden in a lot of documentation, some of which only partially relevant, I thought it'd be nice to show it here.

The question was about how to do some traffic shaping based on the process which is sending out the data. This is not directly possible; however, it is possible to match packets based on the PID by using iptables' -m owner. The nice thing about this solution is that it doesn't have to be the PID you're selecting on; you can really use anything (yes, anything) in iptables to decide on traffic shaping later on.

The trick is to use the -j MARK stuff from iptables. In our example:

iptables -t mangle -A PREROUTING -m owner --owner-pid <some PID> -j MARK --set-mark 1

Now our packets are marked based on what PID is sending them out. Next, we'll have to make sure those packets are given lower priority over other packets:

tc qdisc add dev $OUTIF root handle 1: htb default 10

tc class add dev $OUTIF parent 1: classid 1:1 htb rate 256kbit burst 15k

tc class add dev $OUTIF parent 1:1 classid 1:10 htb rate 100kbit burst 15k
tc class add dev $OUTIF parent 1:1 classid 1:20 htb rate 50kbit burst 15k

tc qdisc add dev $OUTIF parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $OUTIF parent 1:20 handle 20: sfq perturb 10

tc filter add dev $OUTIF protocol ip parent 1:0 prio 1 u32 match mark 1 0xffff flowid 1:20

Et voila, you have traffic shaping based on the iptables -J MARK stuff. Nice, huh?