Call traffic control (tc) from within Linux kernel

1.2k views Asked by At

There is a userspace util called tc(8) for traffic shaping, i.e.

tc qdisc add dev eth0 root tbf rate 10mbit latency 100ms burst 5000.

The internal implementation of the tc command uses netlink to send specific messages to the kernel which in turn will change things accordingly. However, there is no public interface for the kernel code for this specific procedure - as in, there is no public API like tc_qdisc_add(x,y,z) - as everything is depending on the data from the netlink message itself.

So, is there a trick to simplify the process and simulate a message from the kernel? Is there a way to bypass the userspace call to tc and get the same outcome just from a kernel context?

1

There are 1 answers

5
red0ct On

is there a trick to simplify the process and simulate a message from the kernel?

I don't see any way to make it simple.

If we do not go into the details of the implementation of specific tc-commands, just to contemplate an existing API inside kernel, we can see that all the related to netlink talking and qdiscs adding code is located in /net/sched subdirectory. The main function for registering qdisc is located in /net/sched/sch_api.c and called register_qdisc(). Also we can see registering basic qdiscs and netlink ops in pktsched_init().

Qdisc operations are described via struct Qdisc_ops and comprise such like init, enqueue, change, etc.

Knowing this we can take a look at how is this implemented in tbf module (net/sched/sch_tbf.c). It has several operations described with tbf_qdisc_ops. Here there is operation to change called which normally is invoked like tc_modify_qdisc() -> qdisc_change() -> tbf_change().

So depending on what exactly you want to tune, you can somehow obtain the particular qdisc, build an appropriate netlink message (struct nlmsghdr, as it is done in usermode) and invoke e.g. ->change(...) method of qdisc.

The answer does not claim to be correct. I just tried to clarify the situation a little bit.