nlink
A Rust library for Linux network configuration via netlink. Async/tokio-native,
type-safe, owns its wire format end-to-end (no rtnetlink / netlink-packet-*
dependency). CLI binaries (ip, tc, ss, nft, wg, bridge, devlink,
ethtool, wifi) ship as proof-of-concept demonstrations of the library.
Install
= "0.19"
Feature flags: sockdiag, tuntap, tuntap-async, output, namespace_watcher,
syscall_batch (recvmmsg/sendmmsg batching), serde, lab (test harness),
full. Full list in the docs.rs feature table.
MSRV: Rust 1.95, edition 2024.
Quick start
use ;
use StreamExt;
async
What's in the box
Networking core — links (20+ types: dummy, veth, bridge, bond, VLAN, VXLAN, GRE, IPIP, SIT, VTI, Geneve, netkit, IFB, VRF, MACsec, MACVLAN, IPVLAN, GTP, tun/tap), addresses, routes, neighbors, routing rules, nexthop objects + ECMP groups, MPLS, SRv6, bridge FDB + VLAN filtering, network namespaces.
Traffic control — 18 typed qdisc kinds, typed classes (HTB, HFSC, DRR, QFQ),
9 typed filter kinds, 14 typed action kinds, filter chains, BPF program attachment.
Every typed config has a parse_params(&[&str]) so tc CLI syntax round-trips
through the typed API. Strongly-typed units: Rate (bytes/sec internally,
parses 100mbit / 1gbit), Bytes, Percent, TcHandle, FilterPriority.
Generic Netlink families — WireGuard, MACsec, MPTCP, ethtool, nl80211 (WiFi), devlink, DPLL (clock synchronization — SyncE/PTP/GNSS, kernel 6.7+), net_shaper (TX hardware shaping, kernel 6.13+).
Firewall — nftables tables/chains/rules/sets/NAT/match expressions,
flowtables (Expr::FlowOffload), multicast event subscription, atomic
single-batch commits via Transaction.
Diagnostics & observability — socket diagnostics (SockDiag),
connection tracking (Netfilter/ctnetlink), Linux audit, SELinux events,
FIB lookups, ethtool statistics + monitor, kobject uevent (device hotplug),
process connector lifecycle events.
Cross-cutting — XFRM IPsec SA/SP management + hardware offload
(XFRMA_OFFLOAD_DEV), 30-second default per-Connection timeout (override or
opt out), NETLINK_EXT_ACK TLV parsing (kernel error messages with offset +
attribute name), NETLINK_GET_STRICT_CHK opt-in.
High-level APIs
The lower-level imperative API is the foundation; these declarative layers collapse common configuration patterns.
// Declarative network state — diff against kernel, apply changes idempotently.
use NetworkConfig;
new
.link
.link
.address?
.apply.await?;
// Declarative nftables ruleset — atomic batch commit.
use NftablesConfig;
let cfg = new
.table;
cfg.diff.await?.apply.await?;
// Rate limiting — typed Rate, no bits-vs-bytes confusion.
use ;
new.egress.ingress
.apply.await?;
// Per-peer impairment — netem per destination on shared L2.
use PerPeerImpairer;
new
.impair_dst_ip
.apply.await?;
// Network diagnostics — find issues, score bottlenecks.
let report = new.scan.await?;
Building blocks for downstream code
ConnectionPool<P>— bounded async pool of typed connections; each lease gets its own kernel-side socket, so the kernel processes them in parallel.DumpStream<T>—Streamadapter over netlink dumps; O(1) memory on BGP/conntrack/IPsec-scale tables instead of buffering the full response.ResyncStream<T>— wraps multicast subscriptions with ENOBUFS recovery (ResyncedEvent::Marker(ResyncStart)→ snapshot replay →ResyncEnd).nlink-macros— declare a custom Generic Netlink family in ~30 lines via#[genl_family]+#[derive(GenlMessage)]; consume throughconn.send_typed(req).await?/dump_typed_stream. The in-tree DPLL and net_shaper families are the canonical dogfoods.
Documentation
- Library guide — detailed examples: namespaces, TC, WireGuard, error handling, concurrency.
- Cookbook recipes — end-to-end walkthroughs (per-peer impairment, VLAN-aware bridges, bidirectional rate limiting, WireGuard mesh in namespaces, ENOBUFS-resync loops, define-your-own-GENL-family).
- CLI reference —
ipandtccommand coverage. - Migration guides — per-release upgrade notes.
- Examples — 40+ runnable demos.
- docs.rs/nlink — full API reference.
Project status
API stable and used in production. Wire format pinned by build-time
sizeof(struct …) CI gates; concurrent shared-Arc<Connection> use is safe
(serialized via internal mutex — use ConnectionPool for parallel throughput).
14 CI gates on every push (build × 2 feature sets, tests × 2, clippy
--deny warnings, doc with strict intra-doc links, semver-checks, public-api
diff, machete, msrv, plus 5 nlink-specific audit scripts) + a privileged
integration job that runs the root-gated kernel round-trip suite.
Building from source
License
Apache 2.0 OR MIT, at your option.