The top-level netfilter value type — a netns-shaped collection of tables (and everything inside them) as plain data.
A %Ruleset{} is what push/2 writes to the kernel, what
pull/1..2 reads back, and what diff/2 takes pairs of. The
pipeline DSL — new/0, add_table/3, add_chain/4,
add_rule/4, add_set/3, add_map/3, add_object/3,
add_flowtable/3 — is how authoring-time code builds one. The
~NFT sigil compiles to the same DSL calls.
Fields
:tables—%{{family, name} => %Linx.Netfilter.Table{}}. Tables are uniquely identified by(family, name)at the kernel level —inet mytableandip mytablecoexist as distinct tables.
Pipeline DSL
Two flavours of every mutator:
Plain (e.g.
add_table/3) — returns{:ok, Ruleset.t()} | {:error, {:bad_X, reason}}. Validator- setter shape; compose viawith.Bang (e.g.
add_table!/3) — returnsRuleset.t()or raisesArgumentError. Pipeline-friendly for inline construction.ruleset = Ruleset.new() |> Ruleset.add_table!(:inet, "myapp") |> Ruleset.add_chain!("myapp", "input",
type: :filter, hook: :input, priority: 0, policy: :drop)|> Ruleset.add_rule!("myapp", "input",
Rule.build!([Expr.immediate(:accept)], tag: :allow_all))
Table references
Most mutators accept either a bare name string (when unambiguous)
or a {family, name} tuple. A bare name raises / errors with
:ambiguous_table_name if the ruleset has multiple tables of
that name across families.
add_chain!(rs, "myapp", "input", ...) # name → unambiguous
add_chain!(rs, {:inet, "myapp"}, "input", ...) # tuple → explicitErrors
Validator-setter functions return tagged-tuple errors so callers can pattern-match on the kind of failure:
{:bad_table, _}— bad family / flag / duplicate name.{:bad_chain, _}— bad hook/type, missing device on ingress, etc. (fromChain.new/2andChain.validate_for_family/2).{:bad_rule, _}— bad expression list, duplicate tag.{:bad_set, _}/{:bad_set_element, _}— set shape / element type mismatch.{:bad_map, _}/{:bad_map_element, _}— map shape / element shape (including non-verdict data in vmaps).{:bad_object, _}/{:bad_flowtable, _}.{:no_such_table, ref}/{:no_such_chain, ref}/{:ambiguous_table_name, name}— navigation failures.
Kernel-rejection errors come back as %Linx.Netfilter.Error{} —
always distinct from the value-type errors above.
Summary
Functions
Adds a chain to a table, building it inline via Chain.new/2.
Bang variant.
Adds a flowtable to a table.
Bang variant.
Adds a map (or vmap) to a table.
Bang variant.
Adds an object to a table.
Bang variant.
Appends a rule to a chain inside a table.
Adds a set to a table.
Bang variant.
Adds a new table to the ruleset. Builds the table via
Table.new/3, checks (family, name) uniqueness, inserts.
Bang variant of add_table/4.
Removes a table from the ruleset by reference. Returns
{:error, {:no_such_table, ref}} if absent.
Bang variant of delete_table/2.
Fetches a table by reference.
An empty ruleset.
Inserts a pre-built %Chain{} into a table.
Bang variant.
Lists tables — [{family, name, %Table{}}, ...].
Types
@type t() :: %Linx.Netfilter.Ruleset{ tables: %{ optional({Linx.Netfilter.Table.family(), String.t()}) => Linx.Netfilter.Table.t() } }
@type table_ref() :: String.t() | {Linx.Netfilter.Table.family(), String.t()}
Functions
Adds a chain to a table, building it inline via Chain.new/2.
table_ref is a bare name string (unambiguous case) or a
{family, name} tuple.
Bang variant.
@spec add_flowtable(t(), table_ref(), Linx.Netfilter.Flowtable.t()) :: {:ok, t()} | {:error, term()}
Adds a flowtable to a table.
@spec add_flowtable!(t(), table_ref(), Linx.Netfilter.Flowtable.t()) :: t()
Bang variant.
@spec add_map(t(), table_ref(), Linx.Netfilter.Map.t()) :: {:ok, t()} | {:error, term()}
Adds a map (or vmap) to a table.
@spec add_map!(t(), table_ref(), Linx.Netfilter.Map.t()) :: t()
Bang variant.
@spec add_object(t(), table_ref(), Linx.Netfilter.Object.t()) :: {:ok, t()} | {:error, term()}
Adds an object to a table.
@spec add_object!(t(), table_ref(), Linx.Netfilter.Object.t()) :: t()
Bang variant.
@spec add_rule( t(), table_ref(), String.t(), Linx.Netfilter.Rule.t() | [Linx.Netfilter.Rule.expression_input()], keyword() ) :: {:ok, t()} | {:error, term()}
Appends a rule to a chain inside a table.
rule_or_exprs is either a pre-built %Rule{} or a list of
expressions (passed to Rule.build/2). When rule_or_exprs is a
list, opts are forwarded to Rule.build/2 (tag / comment /
handle).
Tag uniqueness within the chain is enforced — a rule with a
duplicate tag returns {:error, {:bad_rule, {:duplicate_tag, _}}}.
Untagged rules are always accepted.
@spec add_rule!( t(), table_ref(), String.t(), Linx.Netfilter.Rule.t() | [Linx.Netfilter.Rule.expression_input()], keyword() ) :: t()
Bang variant.
@spec add_set(t(), table_ref(), Linx.Netfilter.Set.t()) :: {:ok, t()} | {:error, term()}
Adds a set to a table.
@spec add_set!(t(), table_ref(), Linx.Netfilter.Set.t()) :: t()
Bang variant.
@spec add_table(t(), Linx.Netfilter.Table.family(), String.t(), keyword()) :: {:ok, t()} | {:error, {:bad_table, term()}}
Adds a new table to the ruleset. Builds the table via
Table.new/3, checks (family, name) uniqueness, inserts.
@spec add_table!(t(), Linx.Netfilter.Table.family(), String.t(), keyword()) :: t()
Bang variant of add_table/4.
Removes a table from the ruleset by reference. Returns
{:error, {:no_such_table, ref}} if absent.
Bang variant of delete_table/2.
@spec fetch_table(t(), table_ref()) :: {:ok, Linx.Netfilter.Table.t()} | {:error, term()}
Fetches a table by reference.
@spec new() :: t()
An empty ruleset.
@spec put_chain(t(), table_ref(), Linx.Netfilter.Chain.t()) :: {:ok, t()} | {:error, term()}
Inserts a pre-built %Chain{} into a table.
@spec put_chain!(t(), table_ref(), Linx.Netfilter.Chain.t()) :: t()
Bang variant.
@spec tables(t()) :: [ {Linx.Netfilter.Table.family(), String.t(), Linx.Netfilter.Table.t()} ]
Lists tables — [{family, name, %Table{}}, ...].