An AF_NETLINK socket, opened in a chosen network namespace.
A netlink socket is bound for its whole life to the network namespace it was
created in. open/2 selects that namespace:
:host— the BEAM's own network namespace.{:pid, pid}/{:path, path}— another network namespace. The BEAM cannotsetnson a scheduler thread, soLinx.Netlink.Socket.Nativedoes it on a throwaway thread and hands back the fd, which:socketadopts.
protocol is the netlink protocol number — NETLINK_ROUTE,
NETLINK_GENERIC, and so on — so one socket type serves every netlink
family.
The struct carries an :atomics sequence counter. Netlink echoes a
request's sequence number back in its reply; next_seq/1 hands out a fresh
one per request so a stale or unsolicited message can't be mistaken for the
current reply. The counter is mutable shared state, so a %Socket{} works
correctly whether driven synchronously by one process or, later, owned by a
connection process.
Close every socket with close/1 when done.
Summary
Functions
Joins a netlink multicast group on socket.
Closes a socket from open/2.
Leaves a multicast group joined via add_membership/2.
Returns the next netlink sequence number for socket.
Opens a netlink socket of protocol in network namespace netns.
Sets the socket receive buffer size (SO_RCVBUF) in bytes.
Types
@type netns() :: :host | {:pid, pos_integer()} | {:path, binary()}
@type t() :: %Linx.Netlink.Socket{ netns: netns(), protocol: non_neg_integer(), seq: :atomics.atomics_ref(), socket: :socket.socket() }
Functions
@spec add_membership(t(), pos_integer()) :: :ok | {:error, term()}
Joins a netlink multicast group on socket.
Subsequent reads will receive multicast events for group (a
protocol-family-specific group number — NFNLGRP_NFTABLES = 7
for nfnetlink ruleset events, RTNLGRP_LINK = 1 for rtnetlink
link events, etc.).
@spec close(t()) :: :ok
Closes a socket from open/2.
@spec drop_membership(t(), pos_integer()) :: :ok | {:error, term()}
Leaves a multicast group joined via add_membership/2.
@spec next_seq(t()) :: pos_integer()
Returns the next netlink sequence number for socket.
Sequence numbers start at 1; 0 is reserved for unsolicited kernel messages, so a reply bearing seq 0 is never an answer to one of our requests.
@spec open(non_neg_integer(), netns()) :: {:ok, t()} | {:error, term()}
Opens a netlink socket of protocol in network namespace netns.
Returns {:ok, socket} or {:error, reason}. Pass the socket to the rest
of Linx.Netlink, and close/1 it when done.
@spec set_rcvbuf(t(), pos_integer()) :: :ok | {:error, term()}
Sets the socket receive buffer size (SO_RCVBUF) in bytes.
For multicast monitors that may face heavy churn, a larger
buffer reduces the chance of ENOBUFS overflow. The kernel
silently clamps to its net.core.rmem_max ceiling — use
SO_RCVBUFFORCE (requires CAP_NET_ADMIN) to override.