External sources Linx draws on — kernel documentation, prior-art libraries in C and other languages, and the Elixir conventions that shaped the API. Anything cited in a moduledoc or referenced in a design discussion should appear here.
A living doc — add to it when new sources inform a decision.
Netlink protocol (the kernel side)
The wire format Linx speaks and the message families it knows come from the kernel:
netlink(7)man page — the protocol overview.rtnetlink(7)man page —NETLINK_ROUTE's message families.libnetlink(3)man page —rtnl_talkand friends; the C conventionLinx.Netlink.Request.talk/4is named after.
UAPI headers (the authoritative wire definitions; cited inline wherever a struct appears):
linux/netlink.h—nlmsghdr,nlmsgerr,NLM_F_*,NLMSG_*.linux/rtnetlink.h—ifinfomsg,rtmsg,RTM_*,RTA_*.linux/if_link.h—IFLA_*link attributes, kind-specific data (IFLA_MACVLAN_MODE,IFLA_IPVLAN_MODE,IFLA_VLAN_*,VETH_INFO_PEER).linux/if_addr.h—ifaddrmsg,IFA_*.linux/neighbour.h—ndmsg,NDA_*,NUD_*.linux/fib_rules.h—fib_rule_hdr,FRA_*,FR_ACT_*.linux/if.h—IFF_*interface flags.
Kernel YAML netlink specs
The kernel ships machine-readable descriptions of netlink protocols. The target of the future YAML-driven codegen path for genl families.
- Netlink protocol specifications — the format.
- Intro to writing netlink specs
- The
netlink-rawschema — for rtnetlink and other pre-genl protocols. - Netlink docs index
Documentation/netlink/specs/— the YAML files themselves.tools/net/ynl/— the C and Python (pyynl) codegen tooling; the reference for spec semantics.
Prior-art C libraries
Studied for the layering Linx adopts (Socket → Message → Attr → Request → Codec → per-family resources):
- libmnl — minimalistic netlink helpers; the model for Linx's pure-codec layer.
- libnl — the larger object/cache library; the model for the high-level resource pattern.
libnl-routeadds typed object support around the core. - iproute2's
libnetlink.c—rtnl_talk,rtnl_dump_filter. The reference C client.
Prior-art bindings in other languages
Cross-checked Linx's API shape against these:
- vishvananda/netlink (Go) — top-level
LinkAdd/AddrAdd/RouteAddverbs plus annl/low-level split. - pyroute2 (Python) (docs) — the low-level
IPRouteand high-levelNDB. The schema-driven message classes (fields+nla_map) were the most interesting comparison point. - rust-netlink — the deliberate crate split (
netlink-sys/netlink-packet-core/netlink-packet-route/netlink-proto/rtnetlink). The clearest layering reference; Linx's module groups mirror it. - Feuerlabs/netlink (Erlang) — the cautionary example:
gen_server-IS-the-socket, twin hand-written codecs, dated C port driver. Its multicast-diff idea (subscribe to link / addr / route events) is genuinely useful and is the seed of the plannedLinx.Netlink.Monitor— rebuilt as a clean layer on top ofConnection, not baked into the socket.
Elixir conventions and ecosystem
The API shape — {:ok, _} | {:error, %Struct{}}, the ~IP sigil, error
structs as defexception — follows what's established in modern Elixir.
Libraries that use {:error, %Struct{}}:
Ecto.Repo.insert/2—{:error, %Ecto.Changeset{}}, the dominant Elixir error-struct pattern.- Req —
{:error, exception}(%Req.TransportError{},%Req.HTTPError{}). - Jason —
{:error, %Jason.DecodeError{}}. - Postgrex —
{:error, %Postgrex.Error{}}. Finch —
{:error, %Finch.HTTPError{} | %Finch.TransportError{}}.- Mint.TransportError —
defexceptioncarrying a structured:reason.
Background reading on error-handling conventions:
- Michał Muskała — Error Handling in Elixir Libraries — recommends
{:error, exception}, citing Andrea Leopardi. - Leandro Pereira — Leveraging Exceptions to handle errors in Elixir
- Moxley Stratton — Best Practices For Error Values
- Elixir code anti-patterns — official guide; "normalise errors for
with". - christopheradams/elixir_style_guide — naming conventions.