Linx.Netfilter.Log (Linx v0.1.0)

Copy Markdown View Source

NFLOG listener — receives per-packet events from the kernel's NFNL_SUBSYS_ULOG (sub-subsystem 4) for rules that include Linx.Netfilter.Expr.log/1.

Lifecycle

{:ok, listener} = Linx.Netfilter.log_listen(self(),
  group: 5000,
  copy_mode: {:packet, 256},
  flags: [:seq])

receive do
  {:linx_netfilter, :log, %Linx.Netfilter.Log.Event{} = ev} ->
    IO.inspect(ev.prefix, label: "log")
end

:ok = Linx.Netfilter.unlog_listen(listener)

Group binding

Each NFLOG group is independent. On start, the listener sends:

  • NFULNL_CFG_CMD_BIND for the chosen group.
  • NFULNL_CFG_CMD_PF_BIND for each address family in :families (default [:ipv4, :ipv6]). Required so the kernel actually invokes the NFLOG hook for matching packets.
  • NFULA_CFG_MODE for the copy mode.
  • NFULA_CFG_FLAGS for the flag bitmask.
  • Optional NFULA_CFG_TIMEOUT and NFULA_CFG_QTHRESH for batching.

Linx convention: group 5000

Group ids 1..65535 are caller-supplied. Linx reserves group 5000 as the recommended default for "I don't care which group as long as it's mine" — documented as convention, not a hard-coded default for the API.

ENOBUFS recovery

Same shape as Linx.Netfilter.Monitor: a :resync_needed message tells the owner that messages were dropped at the kernel-socket boundary. The owner can choose to ignore (the next event will still arrive) or re-bind for a clean slate.

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts a Log listener linked to the caller.

Stops the listener (also sends NFULNL_CFG_CMD_UNBIND).

Types

opt()

@type opt() ::
  {:owner, pid()}
  | {:group, 1..65535}
  | {:netns, Linx.Netlink.Socket.netns()}
  | {:copy_mode, :none | :meta | :packet | {:packet, non_neg_integer()}}
  | {:qthresh, 1..1024}
  | {:timeout_ms, non_neg_integer()}
  | {:flags, [:seq | :seq_global | :conntrack]}
  | {:families, [:ipv4 | :ipv6 | :bridge | :arp]}
  | {:rcvbuf, pos_integer()}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

@spec start_link([opt()]) :: GenServer.on_start()

Starts a Log listener linked to the caller.

Required:

  • :owner — pid that receives {:linx_netfilter, :log, %Event{}}
  • :group — NFLOG group (1..65535)

Optional:

  • :netns — namespace; default :host
  • :copy_mode:none | :meta | :packet (full packet, up to default snaplen) | {:packet, snaplen_bytes}. Default :meta.

  • :qthresh — kernel-side queue threshold (1..1024). Default 1 (forward each packet immediately).
  • :timeout_ms — kernel-side batching timeout in ms; 0 means no time-based batching. Default 0.
  • :flags:seq / :seq_global / :conntrack.
  • :families — protocol families to bind via PF_BIND; default [:ipv4, :ipv6].
  • :rcvbuf — SO_RCVBUF size in bytes; default 4 MiB.

stop(listener)

@spec stop(pid()) :: :ok

Stops the listener (also sends NFULNL_CFG_CMD_UNBIND).