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?
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 calledregister_qdisc()
. Also we can see registering basic qdiscs and netlink ops inpktsched_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 liketc_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.