Netlink Sockets Tutorial: Asynchronous Kernel to User Space Messaging
Free Linux Kernel Development Course • Free Linux Device Drivers Course
What You Will Learn
- Why netlink sockets exist and how they differ from procfs, sysfs, and debugfs
- The basic anatomy of a netlink message
- How a kernel module creates a netlink socket and sends data to user space
- Where netlink is used in real systems today, such as udev and network configuration
Why Netlink? What Is Missing From File-Based Interfaces
procfs, sysfs, and debugfs all share one limitation: they are pull-based. A user-space program has to open a file and read it to find out the current state; the kernel cannot push a notification the instant something changes. Many real-world use cases need the opposite: the kernel should tell interested processes immediately when a network interface goes up, when a USB device is plugged in, or when routing state changes. That is exactly the gap netlink sockets fill. A netlink socket behaves like a regular socket, but it connects a user-space process to the kernel (or to another user-space process) instead of to a remote host, and it naturally supports multicast-style broadcast to every subscriber at once.
| sysfs / procfs User space must poll |
vs | netlink Kernel pushes events |
Anatomy of a Netlink Message
Every netlink message starts with a fixed struct nlmsghdr header describing the message length, type, flags, sequence number, and sender’s port ID, followed by a payload. The kernel side typically uses a generic netlink family or a custom protocol number registered with NETLINK_* constants; user-space udev and networking tools commonly use NETLINK_ROUTE for interface and routing events.
Creating a Kernel Netlink Socket
Here is a minimal kernel module that opens a netlink socket and can send a message to a listening user-space process, using a custom protocol number:
#include <linux/module.h>
#include <net/sock.h>
#include <net/netlink.h>
#define NETLINK_MYDRIVER 25
static struct sock *nl_sk;
static void nl_recv_msg(struct sk_buff *skb)
{
struct nlmsghdr *nlh = nlmsg_hdr(skb);
int pid = nlh->nlmsg_pid;
struct sk_buff *skb_out;
const char *msg = "hello from kernel";
int msg_size = strlen(msg);
skb_out = nlmsg_new(msg_size, GFP_KERNEL);
nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
memcpy(nlmsg_data(nlh), msg, msg_size);
nlmsg_unicast(nl_sk, skb_out, pid);
}
static int __init my_init(void)
{
struct netlink_kernel_cfg cfg = {
.input = nl_recv_msg,
};
nl_sk = netlink_kernel_create(&init_net, NETLINK_MYDRIVER, &cfg);
if (!nl_sk)
return -ENOMEM;
return 0;
}
static void __exit my_exit(void)
{
netlink_kernel_release(nl_sk);
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
The matching user-space side opens a standard AF_NETLINK socket with the same protocol number, sends an initial message so the kernel learns the sending process’s port ID, and then waits on recv() for a reply, exactly the same way you would use a regular socket.
Real-World Use Cases
- udev uses a netlink socket to receive uevent notifications whenever a device is added or removed.
- iproute2 tools such as
ip linkandip routeuseNETLINK_ROUTEto configure and query network interfaces and routing tables. - wpa_supplicant and NetworkManager rely on netlink events for real-time link state changes.
Common Mistakes
- Choosing a
NETLINK_*protocol number that collides with an existing kernel subsystem. - Forgetting to release the socket with
netlink_kernel_release()on module exit. - Assuming netlink messages arrive in order across different sockets when only per-socket ordering is guaranteed.
- Not validating the message length before copying payload data, which can lead to buffer overruns.
Performance Considerations
Netlink is efficient for event-driven, moderate-frequency messaging. It is not designed for high-throughput bulk data transfer; for streaming large amounts of data, a character device with mmap or a dedicated ring buffer is usually a better fit.
FAQ
Q1: How is netlink different from a regular character device?
Netlink is socket-based and naturally supports asynchronous, multicast-style event delivery, while a character device is a synchronous, request-response file interface.
Q2: Can netlink be used purely between two user-space processes?
Yes, netlink sockets can also be used for inter-process communication without any kernel component involved.
Q3: What is generic netlink?
A framework built on top of netlink that lets subsystems register a dynamic family instead of consuming a fixed protocol number, which reduces the risk of collisions.
Q4: Is netlink reliable, like TCP?
Netlink itself does not guarantee delivery under memory pressure; applications that need reliability typically implement acknowledgements at their own protocol layer.
Q5: Do I need root privileges to open a netlink socket?
It depends on the specific netlink family; some, like NETLINK_ROUTE read access, are available to unprivileged users, while others require CAP_NET_ADMIN.

2 Comments