Netlink sockets are Linux’s answer to a problem that files can’t solve well: asynchronous, event-driven communication between kernel and user space. This lecture in our free Linux kernel programming course explains netlink sockets in plain terms, including why udev and the network stack rely on them so heavily.
Files like those in sysfs and procfs are great for request-response style data: user space asks, kernel answers. But some events — a network link going down, a new USB device appearing, a routing table change — need to be pushed to user space the moment they happen, potentially to many listeners at once. Netlink sockets solve exactly this with a socket-based API that supports both point-to-point messages and multicast broadcasts to groups of interested listeners.
| Kernel Netlink Socket | → | udev |
| → | NetworkManager | |
| → | Your monitoring script |
- rtnetlink — routing table and network interface changes.
- uevent — the mechanism udev listens on for device add/remove events.
- nl80211 — wireless configuration and events.
- Generic netlink (genl) — a framework many custom subsystems build on, including parts of Bluetooth management.
Here is an original, minimal sketch of how a kernel module opens a netlink socket for a custom protocol number:
#include <net/sock.h>
#include <linux/netlink.h>
#define MY_NETLINK_PROTO 25
static struct sock *nl_sock;
static void nl_recv_msg(struct sk_buff *skb)
{
struct nlmsghdr *nlh = nlmsg_hdr(skb);
pr_info("mydrv: received netlink message, len=%d\n", nlh->nlmsg_len);
}
static int __init mydrv_init(void)
{
struct netlink_kernel_cfg cfg = {
.input = nl_recv_msg,
};
nl_sock = netlink_kernel_create(&init_net, MY_NETLINK_PROTO, &cfg);
if (!nl_sock)
return -ENOMEM;
return 0;
}
| Mistake | Fix |
|---|---|
| Picking a netlink protocol number already in use | Prefer generic netlink (genl) to avoid number clashes |
| Blocking inside the receive callback | Keep input handlers fast; defer heavy work to a workqueue |
| Not releasing the socket on module unload | Call netlink_kernel_release() in your exit function |
- Use generic netlink (genl) for new subsystems instead of allocating a raw protocol number.
- Design multicast groups around logical event categories, not individual messages.
- Validate every incoming netlink message length and format before parsing it.
Netlink messages from user space should always be treated as untrusted input: validate lengths, check capabilities where privileged actions are involved, and never assume a well-formed message just because it arrived on a netlink socket.
Netlink’s multicast model is efficient because the kernel sends one message that fanout-delivers to every subscribed listener, avoiding the overhead of separate per-listener polling that file-based interfaces would require for the same use case.
- Netlink sockets enable asynchronous, event-driven kernel-to-user communication.
- Multicast groups let one event reach many interested listeners efficiently.
- Generic netlink is the recommended foundation for new custom protocols.
- Always validate incoming netlink data as untrusted input.
Q1. How is netlink different from a regular socket?
Netlink uses the standard socket API but is designed specifically for kernel-to-user and user-to-user communication within Linux, with built-in support for multicast delivery.
Q2. What is generic netlink?
Generic netlink (genl) is a framework built on top of netlink that lets subsystems register commands and attributes without needing a dedicated protocol number.
Q3. Does udev use netlink?
Yes, udev listens on the kernel’s uevent netlink multicast group to learn about device addition and removal events.
Q4. Is netlink suitable for simple driver attributes?
Not usually — sysfs is simpler and better suited for straightforward attribute exposure; netlink is best reserved for asynchronous or event-based data.
Q5. Do I need special privileges to use netlink sockets?
Some netlink operations require elevated capabilities, particularly those that can modify kernel state such as routing tables.

2 Comments