Friday, November 27, 2020

Linux: Comparison of netlink vs ioctl mechnaisms for configuration control in kernel space

Why bother?

If you are writing a new kernel module or adding configurability to an existing one, typically you need some means by which you can communicate with the kernel module from user space.

I came across this discussion on an internet message board and had saved it for offline reading. Unfortunately, I am not able to find the website to refer it. If you find it please send me a note. Here are the key points that were made for the comparison:

  • Polling vs direct: Kernel services can send information directly to user applications over Netlink, while you’d have explicitly poll the kernel with ioctl functions, a relatively expensive operation.

  • Synchronous vs offline: Netlink communication is fairly asynchronous, with each side receiving messages at some point after the other side sends them. ioctls are purely synchronous: “Hey kernel, WAKE UP and do this now”

  • Multicast support: Netlink supports multicast communications between the kernel and multiple user-space processes, while ioctls are strictly one-to-one.

  • Reliability: Netlink messages can be lost for various reasons (e.g. out of memory), while ioctls are generally more reliable due to their immediate-processing nature.

  • OS support: Netlink is effectively Linux-only; there’s an RFC that extends its utility to the software-defined networking (SDN) world, but I don’t know of anyone who’s actually implemented it for widespread adoption. In contrast, code written to use common ioctls (e.g. the terminal I/O series) is largely portable across platforms.

You will find multiple discussions on the internet which might have more comparisons, but the above ones concisely capture the most important aspects.

Pro tip:
At a high level - use these simple guide-lines.
For sending control info: ioctl should be your first choice, unless there’s an overriding reason, due to its immediacy and reliable delivery.
For sending data: For occasional data passing, ioctl should work fine. For bulk data, and especially if you’re look at asynchronous operation, Netlink is preferred.