Linux networking evolves through incremental mainline releases rather than separate subsystem releases. The milestones below identify the first stable kernel containing each feature; later kernels may add protocol coverage, drivers, offloads, or userspace interfaces.
Network Feature Quick Facts #
| Feature | Kernel | Release Date | Maintainer Page | Quick Fact |
|---|---|---|---|---|
| Netfilter and iptables | 2.4.0 | January 4, 2001 | netfilter.org | Netfilter introduced extensible packet-processing hooks, while iptables exposed filtering, NAT, and packet-mangling rules to userspace. |
| NAPI | 2.6.0 | December 17, 2003 | NAPI combined interrupt notification with polling, thus reducing interrupt overhead when interfaces receive packets at high rates. | |
| CUBIC TCP congestion control | 2.6.13 | August 28, 2005 | CUBIC selects the congestion window from a cubic function of time since the previous congestion event. Linux 2.6.19 later made it the default TCP congestion-control algorithm. | |
| Network namespaces | 2.6.24 | January 24, 2008 | Initial support isolated network devices, protocol stacks, routing tables, firewall rules, and sockets. Subsequent releases expanded device and protocol coverage. | |
| Generic Receive Offload (GRO) | 2.6.29 | March 23, 2009 | GRO aggregates related packets before upper-layer processing, thus amortizing per-packet costs without requiring NIC-specific receive offload. | |
| Receive Packet Steering and Receive Flow Steering | 2.6.35 | August 1, 2010 | RPS distributes receive processing across CPUs in software, while RFS adds flow locality so packet processing can follow the consuming application. | |
| TCP Fast Open client support | 3.6 | September 30, 2012 | TFO can carry application data in the opening SYN when the client has a valid cookie. Server support followed in Linux 3.7. | |
| nftables | 3.13 | January 20, 2014 | nftables project | nftables added a programmable packet-classification engine and a Netlink API intended to replace the separate iptables, ip6tables, arptables, and ebtables interfaces. |
| Extended BPF | 3.18 | December 7, 2014 | eBPF project | The bpf() system call and eBPF virtual machine provided the foundation for verified, JIT-compiled programs used by socket filters, traffic control, tracing, and later XDP. |
| Virtual Routing and Forwarding (VRF) | 4.3 | November 2, 2015 | The VRF device lets interfaces share a network namespace while using separate routing tables, which supports route isolation without creating another namespace. | |
| eXpress Data Path (XDP) | 4.8 | October 2, 2016 | XDP project | XDP runs eBPF programs before the kernel allocates a socket buffer, enabling early packet drop, redirection, and load balancing. |
| BBR congestion control | 4.9 | December 11, 2016 | Google BBR | BBR models bottleneck bandwidth and round-trip propagation time instead of treating packet loss as the primary congestion signal. |
| Kernel TLS transmit offload | 4.13 | September 3, 2017 | kTLS moved TLS record encryption and framing for transmitted data into the kernel. Receive support followed in Linux 4.17. | |
| AF_XDP sockets | 4.18 | August 12, 2018 | XDP project | AF_XDP connects XDP programs to userspace through shared-memory rings, supporting copy and zero-copy operation depending on the driver. |
| Multipath TCP | 5.6 | March 29, 2020 | MPTCP upstream project | Initial upstream MPTCP support allowed one logical transport connection to use multiple TCP subflows across different paths. |
| WireGuard | 5.6 | March 29, 2020 | WireGuard | WireGuard added an in-kernel encrypted layer-3 tunnel with a small protocol and cryptographic surface. |
| IPv6 BIG TCP | 5.19 | July 31, 2022 | BIG TCP allows larger non-GSO packet sizes inside the host stack, thus reducing per-packet overhead on high-speed links. IPv4 support followed in Linux 6.3. |
Release dates follow the mainline tags in the Linux kernel Git history. Feature versions are cross-referenced with the KernelNewbies release summaries and the kernel networking documentation.
Kernel-Userspace Boundary #
Linux does not provide a syscall such as add_route() or create_veth(). Instead,
userspace selects a kernel control interface and reaches it through general-purpose
syscalls. Netlink, in particular, is a family of socket protocols rather than a
syscall.
| Syscalls | Control Interface | Network Configuration Role | Current Guidance |
|---|---|---|---|
socket(), bind(), sendmsg(), and recvmsg() | Netlink | A process opens an AF_NETLINK socket and exchanges structured messages with a Netlink family. NETLINK_ROUTE configures links, addresses, routes, neighbours, traffic control, and related objects. Generic Netlink and subsystem protocols cover nftables, nl80211, ethtool, devlink, WireGuard, and other facilities. | Prefer the relevant Netlink family for system-wide network configuration. Use a maintained library or tool because message attributes, acknowledgements, multipart replies, and API evolution require careful handling. |
ioctl() | Socket and device ioctls | Requests such as SIOCSIFFLAGS, SIOCSIFADDR, and SIOCSIFMTU configure interfaces. Private device ioctls and the older ethtool and wireless-extension ABIs use the same syscall. | Retain ioctl support for compatibility, but use a Netlink API when the subsystem provides one. An ioctl command has a fixed request structure and is harder to extend safely. |
setsockopt() and getsockopt() | Socket options | Socket options configure per-socket behavior such as marks, buffer sizes, device binding, multicast membership, TCP parameters, and attached filters. Legacy iptables also uploads and reads rules through protocol-specific socket options. | Continue using socket options for settings that belong to one socket. Use nftables over Netlink instead of the legacy iptables socket-option ABI for new firewall integrations. |
bpf() | eBPF object API | bpf() loads programs, creates and updates maps, queries objects, and creates supported BPF links. Networking programs may run at socket, traffic-control, cgroup, XDP, and other hooks. Some attachment paths still use Netlink or socket options. | Use libbpf rather than issuing raw bpf() commands. Prefer BPF links where a hook supports them because a link gives the attachment an explicit lifetime; use the hook’s established Netlink API where required. |
openat(), read(), and write() | procfs and sysfs | Files under /proc/sys/net expose network sysctls, while selected files under /proc/net and /sys/class/net expose state or narrowly scoped controls. The calls operate on virtual files, but the data is supplied or consumed by the kernel. | Use documented sysctls for host or namespace tunables. Do not parse procfs when a structured Netlink dump exists, because procfs formats are primarily text interfaces and may omit attributes. |
clone(), clone3(), unshare(), and setns() | Network namespaces | CLONE_NEWNET creates a network namespace or moves execution into a namespace setup path; setns() joins an existing one. Configuration commands then operate on the network stack selected by the calling thread’s namespace. | Establish the namespace first, then configure it through Netlink. Treat namespace switching as thread-scoped state and avoid changing it concurrently from an uncontrolled multithreaded process. |
Most administrative operations require CAP_NET_ADMIN in the user namespace that
governs the target network namespace. eBPF operations may additionally require
CAP_BPF, CAP_PERFMON, or other capabilities depending on the program type,
attachment point, and kernel version.
How the Recommended Interface Changed #
- Early Linux used ioctls, socket options, and virtual files. Programs such as
ifconfig,route, andarpissued network-device and routing ioctls./proc/sys/netsupplied global tunables, while firewall generations through legacy iptables used protocol-specific socket options. - Rtnetlink became the extensible network control plane. Linux 2.2 exposed
links, multiple addresses, routes, neighbours, and traffic-control objects
through
NETLINK_ROUTE. The iproute2 tools (ip,bridge, andtc) therefore replaced the ioctl-oriented net-tools commands for new configuration. - Subsystem-specific Netlink families replaced fixed private ABIs. Generic Netlink and related protocols allowed commands and type-length-value attributes to evolve without changing a syscall. nl80211 replaced Wireless Extensions, nftables replaced the legacy iptables rule ABI, and newer ethtool operations use Netlink instead of device ioctls.
- eBPF added a programmable data-plane boundary. The
bpf()syscall manages programs and maps, but configuration remains split by attachment point: rtnetlink configures traffic-control and established XDP attachments, socket options attach classic socket filters, and BPF links provide file-descriptor lifetime management for supported hooks. - New control planes favor described Netlink APIs. Kernel networking development now documents Netlink families with machine-readable specifications. Applications should use those APIs, request acknowledgements and extended acknowledgements, and reserve ioctls or text-file parsing for interfaces without a supported structured replacement.
See the kernel’s Netlink introduction,
rtnetlink(7),
netdevice(7), and
bpf(2) documentation
for the corresponding UAPI details.
Rtnetlink #
The rt in rtnetlink means routing, but the interface has grown into the
kernel’s general network-control protocol. A process opens
socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) and sends RTM_* messages. Each
message contains struct nlmsghdr, an object-specific fixed header, and aligned
type-length-value attributes.
Rtnetlink supports three interaction patterns:
- Do request: create, replace, change, or delete one object and receive an acknowledgement.
- Dump request: enumerate an object class, such as all links or all routes.
The kernel returns a multipart response terminated by
NLMSG_DONE. - Multicast notification: subscribe to groups for link, address, route, neighbour, rule, traffic-control, and other changes. Notifications use the same object messages as replies, which lets a program maintain a local cache.
Managed Objects #
| Object | Principal Messages | Operations and State |
|---|---|---|
| Network links | RTM_NEWLINK, RTM_SETLINK, RTM_DELLINK, RTM_GETLINK | Create and remove virtual devices supported by registered link kinds, including veth pairs, bridges, bonds, VLAN devices, VRFs, macvlan/macvtap, VXLAN, Geneve, and dummy devices. Change administrative state, MTU, name, MAC address, queue counts, group, alias, master relationship, namespace placement, and protocol-specific link options. Query carrier state, operational state, queue configuration, physical identifiers, VF settings, statistics, and XDP attachment information. |
| Link properties | RTM_NEWLINKPROP, RTM_DELLINKPROP, RTM_GETLINKPROP | Add, remove, and list auxiliary link properties, principally alternative interface names. |
| Protocol addresses | RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR | Add, replace, delete, and enumerate IPv4, IPv6, and supported non-IP addresses. Attributes describe local and peer addresses, prefix length, scope, broadcast or anycast address, flags, labels, preferred lifetime, and valid lifetime. |
| Address-selection labels | RTM_NEWADDRLABEL, RTM_DELADDRLABEL, RTM_GETADDRLABEL | Manage IPv6 source- and destination-address selection labels independently of interface addresses. |
| Routes | RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE | Manage unicast, local, broadcast, multicast, blackhole, unreachable, prohibit, and throw routes in multiple tables. A route can select input and output interfaces, gateway, preferred source, metric, MTU, congestion-control parameters, expiry, realms, marks, multipath nexthops, or lightweight tunnel encapsulation. RTM_GETROUTE supports both table dumps and route lookups for a supplied flow key. |
| Policy-routing rules | RTM_NEWRULE, RTM_DELRULE, RTM_GETRULE | Select a routing table or action by priority and selectors such as source, destination, input or output interface, firewall mark, UID range, IP protocol, ports, DSCP, flow label, or layer-3 master device. Actions include table lookup, goto, blackhole, unreachable, and prohibit. |
| Nexthop objects | RTM_NEWNEXTHOP, RTM_DELNEXTHOP, RTM_GETNEXTHOP | Create reusable nexthops and nexthop groups, including resilient groups, rather than embedding every path in each route. Objects carry gateway, device, group membership, weights, protection flags, and encapsulation state. |
| Resilient nexthop buckets | RTM_NEWNEXTHOPBUCKET, RTM_DELNEXTHOPBUCKET, RTM_GETNEXTHOPBUCKET | Inspect and, where supported, control the bucket-to-nexthop mapping used by resilient nexthop groups so membership changes disturb fewer flows. |
| Neighbours | RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH | Manage and inspect ARP, IPv6 NDP, and related neighbour-cache entries. State includes the protocol address, link-layer address, interface, reachability state, router and proxy flags, probe data, offload state, and cache timestamps. Bridge forwarding-database entries also use neighbour messages with bridge-specific attributes. |
| Neighbour tables | RTM_NEWNEIGHTBL, RTM_SETNEIGHTBL, RTM_GETNEIGHTBL | Read table statistics and tune garbage-collection thresholds, reachable time, retransmission time, probe counts, queue limits, stale time, and proxy behaviour for neighbour discovery. |
| Traffic-control queueing disciplines | RTM_NEWQDISC, RTM_DELQDISC, RTM_GETQDISC | Attach, configure, replace, inspect, and remove root, ingress, egress, and child qdiscs. Examples include fq, fq_codel, htb, tbf, netem, cake, clsact, and hardware-offloaded qdiscs when a driver supports them. |
| Traffic classes | RTM_NEWTCLASS, RTM_DELTCLASS, RTM_GETTCLASS | Manage class hierarchies below classful qdiscs, including rates, ceilings, priorities, parent handles, and implementation-specific parameters. |
| Traffic-control filters and chains | RTM_NEWTFILTER, RTM_DELTFILTER, RTM_GETTFILTER, RTM_NEWCHAIN, RTM_DELCHAIN, RTM_GETCHAIN | Classify packets and select classes or actions. Filters include flower, u32, route, matchall, and BPF; chains divide a block into ordered stages. Attributes can request hardware offload and report whether offload succeeded. |
| Traffic-control actions | RTM_NEWACTION, RTM_DELACTION, RTM_GETACTION | Create and inspect reusable actions such as drop, redirect, mirror, police, tunnel-key manipulation, VLAN operations, packet editing, connection tracking, sampling, and BPF execution. |
| Bridge multicast database | RTM_NEWMDB, RTM_DELMDB, RTM_GETMDB | Manage bridge and switchdev multicast forwarding entries, including group, port, VLAN, source-specific multicast state, router-port state, timers, and hardware-offload information. |
| Bridge VLAN state | RTM_NEWVLAN, RTM_DELVLAN, RTM_GETVLAN | Manage VLAN membership and per-VLAN bridge options on bridge ports. The interface differs from creating a VLAN network device, which uses RTM_NEWLINK with link kind vlan. |
| Network-namespace identifiers | RTM_NEWNSID, RTM_DELNSID, RTM_GETNSID | Assign and resolve namespace-local numeric IDs for peer network namespaces. Rtnetlink attributes use these IDs when an object refers to another namespace. |
| Per-interface protocol configuration | RTM_NEWNETCONF, RTM_DELNETCONF, RTM_GETNETCONF | Read and receive changes to selected IPv4, IPv6, and MPLS interface settings, including forwarding, reverse-path filtering, multicast forwarding, proxy-neighbour behaviour, and handling of routes whose links are down. Coverage is narrower than /proc/sys/net. |
| Data Center Bridging | RTM_GETDCB, RTM_SETDCB | Exchange Data Center Bridging configuration such as priorities, priority groups, Priority Flow Control, application priorities, and DCB capabilities with capable drivers. |
| Prefix and IPv6 ND information | RTM_NEWPREFIX, RTM_NEWNDUSEROPT | Deliver information learned from IPv6 Router Advertisements, including prefixes and user options. These message classes primarily report kernel-observed state rather than acting as general setters. |
| Multicast and anycast address reports | RTM_GETMULTICAST, RTM_GETANYCAST and corresponding notification types | Enumerate or report multicast and anycast address state for address families that implement the operations. Support is family-dependent. |
| Link and offload statistics | RTM_NEWSTATS, RTM_GETSTATS, RTM_SETSTATS | Retrieve standard link counters, extended per-link statistics, and selected offload statistics. Setter support is limited to attributes implemented by the target subsystem. |
| Cache and tunnel reports | RTM_NEWCACHEREPORT, RTM_NEWTUNNEL, RTM_DELTUNNEL, RTM_GETTUNNEL | Report address-family cache events and manage or report tunnel state implemented by an address family. Availability and accepted attributes depend on the protocol module. |
RTM_NEW* does not always mean “create only.” Flags determine the mutation
semantics:
| Flag | Meaning |
|---|---|
NLM_F_CREATE | Create the object if it does not exist. |
NLM_F_EXCL | Fail if the object already exists. |
NLM_F_REPLACE | Replace an existing object. |
NLM_F_APPEND | Add the object at the end of an ordered collection when supported. |
NLM_F_ACK | Return success or an NLMSG_ERROR acknowledgement. |
NLM_F_DUMP | Request a multipart enumeration; equivalent to `NLM_F_ROOT |
Applications should also enable NETLINK_EXT_ACK. Extended acknowledgements can
identify the rejected attribute, include a human-readable kernel message, and
report policy constraints. A successful acknowledgement means that the kernel
processed that message; it does not make a sequence of separate rtnetlink requests
transactional.
Namespace and Consistency Model #
An rtnetlink socket operates in the network namespace with which it is associated. Most requests therefore see and modify only that namespace’s links, routes, rules, neighbours, and traffic-control objects. Link attributes can move a device to another namespace, while namespace-ID messages create references to peer namespaces.
Mutating requests generally require CAP_NET_ADMIN in the user namespace that owns
the target network namespace. Read requests may still be restricted when they
expose sensitive device or protocol information.
A dump is not an atomic snapshot. Objects can change while a multipart dump is in progress, and multicast notifications can be lost when the receive buffer overflows. A state synchronizer should:
- Open and bind the socket to the required multicast groups.
- Request a dump with a unique sequence number.
- Match unicast replies by sequence number and sender port ID.
- Process notifications arriving during the dump.
- Detect
ENOBUFS, interrupted dumps, and malformed attributes. - Discard the cache and repeat the dump when synchronization cannot be proven.
Scope Boundaries #
Rtnetlink controls network topology, addressing, forwarding, neighbours, and traffic control, but it is not the interface for every network subsystem:
| Facility | Control Interface |
|---|---|
| nftables and connection tracking | NETLINK_NETFILTER families |
| Wi-Fi configuration | nl80211 over Generic Netlink |
| Modern NIC settings | ethtool over Generic Netlink |
| devlink devices, ports, resources, and health reporters | devlink over Generic Netlink |
| WireGuard peer and key configuration | wireguard over Generic Netlink |
| MPTCP path-manager configuration | mptcp_pm over Generic Netlink |
| Per-socket TCP, UDP, multicast, and device-binding options | setsockopt() |
| Network sysctls not represented by netconf messages | /proc/sys/net |
| eBPF program and map lifecycle | bpf(); attachment may additionally use rtnetlink |
The authoritative operation list is defined in
include/uapi/linux/rtnetlink.h.
The kernel also publishes
machine-readable specifications
for links, addresses, routes, rules, neighbours, and traffic control. Higher-level
programs should use maintained libraries or iproute2 rather than reproducing UAPI
structure layout and attribute validation manually.
Userspace Network Utilities #
Linux has no single userspace networking stack. Command-line tools, policy daemons, configuration renderers, routing daemons, and container plugins reach different kernel control interfaces. A higher-level command may therefore control a daemon instead of contacting the kernel.
| Software | Primary Role | Path to the Kernel |
|---|---|---|
| iproute2 | ip manages links, addresses, routes, rules, neighbours, and network namespaces; bridge manages bridge state; tc manages traffic control; ss inspects sockets. | The programs use iproute2’s internal Netlink support directly. Most configuration goes through rtnetlink; socket inspection uses diagnostic Netlink families. iproute2 is a suite of executables, not a daemon required by other network managers. |
| NetworkManager | Maintains connection profiles and policy for Ethernet, Wi-Fi, mobile broadband, VPNs, IP configuration, and DNS integration. nmcli, nmtui, desktop applets, and applications are clients. | nmcli uses libnm to call the NetworkManager daemon over D-Bus. The daemon’s Linux platform layer opens Netlink sockets directly for normal link, address, route, rule, and traffic-control operations; it does not send those operations through the ip executable. Optional helpers handle facilities such as Wi-Fi authentication, PPP, DHCP, DNS, and firewall integration. |
| systemd-networkd | Applies declarative .network, .netdev, and .link configuration, runs DHCP and router-discovery clients, and maintains network state. networkctl is its inspection and control CLI. | systemd-networkd uses systemd’s internal Netlink implementation to configure the kernel. networkctl uses networkd APIs and state rather than invoking iproute2 for managed configuration. |
| Netplan | Converts distribution-level YAML into a backend configuration and coordinates application of that configuration. | Netplan selects NetworkManager or systemd-networkd as its renderer. The selected daemon, not Netplan’s YAML parser, performs the continuing kernel configuration. |
| nftables | nft creates firewall, NAT, packet-classification, and set or map rules. libnftables exposes the same engine to applications. | nft uses libnftables and libnftnl to exchange batched messages with the nftables subsystem through NETLINK_NETFILTER; it does not use rtnetlink or iproute2. |
| firewalld | Maintains dynamic firewall zones, services, policies, and separate runtime and persistent configuration. firewall-cmd is its principal CLI. | firewall-cmd calls the firewalld daemon over D-Bus. The daemon normally applies rules through its nftables backend rather than asking NetworkManager or iproute2 to install them. |
| ethtool | Reads and changes driver and NIC properties such as link modes, channels, rings, coalescing, offloads, RSS, statistics, and firmware data. | Newer operations use the ethtool Generic Netlink family. Older or not-yet-converted operations use SIOCETHTOOL ioctls, so the selected path depends on the command and kernel support. |
iw | Inspects and configures 802.11 physical devices, virtual interfaces, channels, stations, scans, powersave, and regulatory state. | iw sends commands to the nl80211 Generic Netlink family. It does not invoke ip, although ip remains responsible for ordinary link and IP-layer configuration of the resulting interface. |
| wpa_supplicant and iwd | Perform Wi-Fi scanning, authentication, association, roaming, and key management. | Each daemon controls cfg80211/mac80211 through nl80211. NetworkManager can control either daemon over D-Bus; the Wi-Fi daemon then talks to the kernel. |
| conntrack-tools | Lists, modifies, monitors, and replicates Netfilter connection-tracking state. | conntrack and conntrackd use ctnetlink over NETLINK_NETFILTER, independently of rtnetlink. |
| bpftool | Loads and inspects eBPF programs, maps, links, BTF, cgroups, and selected networking attachments. | Most object lifecycle operations use libbpf and the bpf() syscall. Some networking operations also inspect or modify rtnetlink-managed XDP and traffic-control state. |
| FRRouting and BIRD | Implement routing protocols such as BGP, OSPF, IS-IS, and RIP and reconcile learned routes with the kernel FIB. | FRRouting protocol daemons submit routes to its zebra daemon, which programs the kernel through rtnetlink. BIRD performs its own kernel-protocol synchronization through routing sockets or Netlink on Linux. Neither requires the ip executable for steady-state route installation. |
| Open vSwitch | Implements programmable virtual switching for virtualization, containers, overlays, and software-defined networking. | ovs-vsctl changes the OVS database; ovs-vswitchd consumes that configuration and controls the Linux OVS datapath through OVS Generic Netlink families. Auxiliary link and tunnel setup may also involve rtnetlink. |
| CNI plugins | Configure a container network namespace when a compatible runtime invokes a plugin. Common plugins create veth pairs, bridges, routes, policy, and overlays. | Plugins execute as short-lived programs and commonly use Go Netlink libraries directly. A plugin may additionally call or link firewall, eBPF, IPAM, or datastore components; CNI specifies invocation and result formats rather than one kernel backend. |
| net-tools | Supplies the legacy ifconfig, route, arp, and netstat commands. | The tools primarily use network-device and routing ioctls and parse procfs. iproute2 and structured Netlink interfaces supersede them for new automation. |
Control and Dependency Paths #
The arrows describe runtime control flow, not package ownership. NETLINK_ROUTE,
NETLINK_NETFILTER, and nl80211 are kernel protocols reached through
AF_NETLINK sockets.
The diagram answers the common nmcli dependency question directly:
nmcliconstructs a request through libnm.- libnm sends the request over D-Bus to the NetworkManager daemon.
- NetworkManager applies ordinary kernel network state through its own Netlink implementation.
- iproute2 is an independent administrative client of the same kernel APIs, not an intermediate layer between NetworkManager and the kernel.
Calling ip, nft, or another CLI from a program remains useful for shell
automation, but a long-running manager generally uses a library or implements the
kernel protocol directly. Direct access avoids parsing command output and lets the
manager subscribe to asynchronous state notifications.
Comments
Read or comment on GitHub (sign-in required to comment)