A small DSL for defining netlink message codecs.
Every netlink message body has the same shape — a fixed C-struct header
followed by a stream of type-length-value attributes. A module that uses
this one declares that shape in a codec block, and gets a struct plus an
encode/1 and a decode/1 generated for it:
defmodule MyMessage do
use Linx.Netlink.Codec
codec do
header do
field :family, :u8
pad 1
field :index, :s32
end
attr 1, :name, :string
attr 2, :mtu, :u32
end
# hand-written verbs may follow — the struct is already defined
endencode/1 turns a %MyMessage{} into a message body; decode/1 turns a
body back into a struct. Header fields default to 0; an attribute field is
nil when absent, and a nil field is omitted on encode.
The whole definition is one codec block so the struct is defined right
there, before any hand-written functions below it can refer to it.
This module is the reference codec backend: the generated encode/1 and
decode/1 are thin wrappers over one shared engine driven by the declared
schema. The schema is also exposed as data through the generated
__codec__/0 — the seam a future kernel-YAML-driven front end would target.
Field and attribute types
Scalars :u8, :u16, :u32, :u64, :s8, :s16, :s32; :string (a
NUL-terminated string); :binary (raw bytes).
The escape hatches
An attribute's type may also be:
- a module that exports
encode/1anddecode/1. Pointed at anotherLinx.Netlink.Codecmodule it covers a nested attribute set; pointed at a hand-written module it covers any value whose wire form a primitive cannot express. - a dispatch table:
{:dispatch, :other_field, %{"k1" => Mod1, "k2" => Mod2, …}}. The sub-codec is chosen at encode and decode time from the current value of:other_field— a sibling attribute on the same struct. The dispatching field must be declared before the dispatched one, so its value is in hand by the time the latter is processed.
Both let the DSL handle the regular case and step aside, to module-level code, for the rest.
Summary
Functions
Declares a message codec: a header block of field/2 and pad/1 calls,
and attr/3 declarations. Generates the struct, encode/1 and decode/1.