Skip to content

Latest commit

 

History

History
210 lines (153 loc) · 4.32 KB

File metadata and controls

210 lines (153 loc) · 4.32 KB

14. Appendix A — Linux Netlink Primer

14.1 What Is Netlink?

Netlink is a Linux kernel IPC mechanism used for communication between:

  • User space processes
  • The Linux kernel networking stack

It is used to deliver:

  • Interface up/down events
  • IP address additions/removals
  • Neighbor (ARP/ND) updates
  • FDB events (for Linux bridges)
  • Route updates
  • VLAN notifications

SONiC daemons such as:

  • portsyncd
  • neighsyncd
  • intfmgrd

use netlink to detect real-time changes.


14.2 Netlink Socket Basics

A netlink socket is created with:

socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

Key Types

  • RTM_NEWLINK / RTM_DELLINK – interface state
  • RTM_NEWADDR / RTM_DELADDR – IP address
  • RTM_NEWNEIGH / RTM_DELNEIGH – ARP/ND
  • RTM_NEWROUTE / RTM_DELROUTE – kernel routes

14.3 Netlink Multicast Groups

Processes subscribe to specific event groups:

  • RTNLGRP_LINK
  • RTNLGRP_NEIGH
  • RTNLGRP_IPV4_IFADDR
  • RTNLGRP_IPV6_IFADDR
  • RTNLGRP_IPV4_ROUTE
  • RTNLGRP_IPV6_ROUTE
  • RTNLGRP_BRVLAN
  • RTNLGRP_BRIDGE

Can a process subscribe to more than one group?

Yes.

Example:

nl_groups = RTNLGRP_LINK | RTNLGRP_NEIGH | RTNLGRP_IPV4_IFADDR;

14.4 Binding a Netlink Socket

struct sockaddr_nl addr = {0};
addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid();   // unique for user process
addr.nl_groups = RTNLGRP_LINK | RTNLGRP_NEIGH;

bind(nl_sock, (struct sockaddr*)&addr, sizeof(addr));

14.5 Receiving Netlink Messages

Netlink messages arrive via recvmsg():

char buf[8192];
struct iovec iov = { buf, sizeof(buf) };

struct sockaddr_nl kernel = {0};
struct msghdr msg = {
    .msg_name = &kernel,
    .msg_namelen = sizeof(kernel),
    .msg_iov = &iov,
    .msg_iovlen = 1,
};

int len = recvmsg(nl_sock, &msg, 0);

What does recvmsg() do?

  • Blocks until a message is ready
  • Retrieves one or more nlmsghdr structures
  • Returns size of received data
  • Writes sender address (kernel) into msg_name

14.6 Parsing Messages

for (struct nlmsghdr *nh = (struct nlmsghdr*)buf;
     NLMSG_OK(nh, len);
     nh = NLMSG_NEXT(nh, len))
{
    if (nh->nlmsg_type == RTM_NEWLINK) {
        struct ifinfomsg *ifi = NLMSG_DATA(nh);
        // ifi->ifi_index, flags, oper state, etc.
    }

    if (nh->nlmsg_type == RTM_NEWNEIGH) {
        struct ndmsg *nd = NLMSG_DATA(nh);
        // nd->ndm_state, nd->ndm_ifindex, etc.
    }
}

14.7 Typical SONiC Daemon Netlink Subscriptions

Daemon Events Subscribed To
portsyncd RTNLGRP_LINK
neighsyncd RTNLGRP_NEIGH
intfmgrd LINK + ADDR
teamsyncd LINK + TEAM events

14.8 Example C Code

int nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

// Subscribe to multiple groups
int groups = RTNLGRP_LINK | RTNLGRP_NEIGH | RTNLGRP_IPV4_IFADDR;

struct sockaddr_nl addr = {0};
addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid();
addr.nl_groups = groups;

bind(nl_sock, (struct sockaddr*)&addr, sizeof(addr));

while (1) {
    char buf[8192];
    struct iovec iov = { buf, sizeof(buf) };
    struct sockaddr_nl kernel = {0};

    struct msghdr msg = {
        .msg_name = &kernel,
        .msg_namelen = sizeof(kernel),
        .msg_iov = &iov,
        .msg_iovlen = 1,
    };

    int len = recvmsg(nl_sock, &msg, 0);
    if (len <= 0) continue; // error or no data

    // Walk each netlink message in the buffer
    for (struct nlmsghdr *nh = (struct nlmsghdr*)buf;
         NLMSG_OK(nh, len);
         nh = NLMSG_NEXT(nh, len))
    {
        switch (nh->nlmsg_type)
        {
            case RTM_NEWLINK:
            case RTM_DELLINK:
                // Interface state change
                break;

            case RTM_NEWADDR:
            case RTM_DELADDR:
                // IP address assigned/removed
                break;

            case RTM_NEWNEIGH:
            case RTM_DELNEIGH:
                // ARP or ND update
                break;
        }
    }
}

14.9 Summary

Netlink is the backbone of SONiC kernel interaction. It allows daemons to:

  • Detect interface up/down
  • Track IP address changes
  • Learn ARP/ND updates
  • Receive Linux FDB/bridge events
  • Synchronize kernel state with Redis and SAI