Netlink Sockets Tutorial: Asynchronous Kernel to User Space Messaging-Free Linux Device Driver Course Online

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
Prerequisites: basic socket programming concepts, and the earlier lectures in this series on procfs, sysfs, and debugfs.

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.

Push vs Pull Interfaces
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 link and ip route use NETLINK_ROUTE to 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.

netlink sockets tutorial linux kernel networking free linux kernel development course free embedded systems course

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *