nflog

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package nflog observes the packets the terminal rule of the owned table logs: what the policy did not permit. Under enforcement each logged packet was dropped and becomes a BLOCKED observation; under simulation it was accepted and becomes a WOULD_BLOCK observation. Because a dropped packet never becomes a tracked connection, this is the only path by which blocked traffic reaches the flow map. It is enforcement and simulation only, by decision: a visibility table logs nothing, because in visibility the agent decides nothing and there is no verdict for a log to witness. What visibility reports is what connection tracking reports (ADR-0020).

Index

Constants

This section is empty.

Variables

View Source
var ErrUnparseable = errors.New("nflog: packet is not a parseable IPv4 or IPv6 packet")

ErrUnparseable is returned for a payload that is not an IPv4 or IPv6 packet of a protocol the flow model knows.

Functions

This section is empty.

Types

type Packet

type Packet struct {
	Src      netip.Addr
	Dst      netip.Addr
	DstPort  uint16
	Protocol innerwallv1.Protocol
	Length   uint64
}

Packet is what a logged packet's headers say about the flow it belongs to.

func Parse

func Parse(payload []byte) (Packet, error)

Parse reads the network and transport headers of a logged packet. The payload starts at the IP header, as the input hook delivers it. IPv6 extension headers are not walked: a packet carrying one is reported as unparseable rather than misattributed.

type Source

type Source struct {
	// Group is the log group the terminal rule logs to.
	Group uint16
	// Decide returns the decision a logged packet represents under the
	// installed mode: BLOCKED when enforced, WOULD_BLOCK when simulated.
	// A packet whose decision is OBSERVED or unspecified is dropped.
	Decide func() innerwallv1.PolicyDecision
	Log    *slog.Logger
	// Gaps records the evidence this source knows it lost; nil records
	// nothing.
	Gaps *collect.Gaps
	// ReadBuffer is the socket's receive buffer in bytes, set at every
	// subscribe; the kernel's default when zero.
	ReadBuffer int
}

Source subscribes to one netlink log group and emits an observation per logged packet: one connection attempt, with the packet's length as its bytes. The decision is asked of Decide at each event, so a mode change takes effect on the next packet; because the decision is part of the aggregation key, records before and after the change stay apart.

func (*Source) EvidenceGaps

func (s *Source) EvidenceGaps() (*collect.Gaps, collect.GapSource)

EvidenceGaps implements collect.Gapped.

func (*Source) Run

func (s *Source) Run(ctx context.Context, emit func(collect.Observation)) error

Run implements collect.Source. An overrun is recovered in place: the kernel reports it once and the subscription stays bound, so reading simply continues, and the interval the kernel dropped packets in is recorded as a gap. This matters more here than anywhere: these are the would-block and blocked counts, and a lost would-block packet would push a simulation's verdict toward safe. Any other failure returns, and the collector restarts the source with backoff.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL