Skip to content

Flow Visualizer

Render the live nftables packet pipeline — hooks, chains, sets, and counters — as a left-to-right diagram so you can see exactly how a DHCP packet is routed and enforced inside the kernel.

The Flow Visualizer is the read-only sibling of the Firewall Manager (chapter 20). The manager lets you edit the ruleset; the visualizer lets you understand it. Reach it from the sidebar under Operations > Flow Visualizer (route /firewall-flow).

You will use this page to answer two recurring questions:

  • Where is a packet being dropped? Walk the diagram from the entry point to the exit, follow the colour-coded actions, and look at live counter values.
  • Which set has this device? Open the Sets panel, find the relevant llm_*_marks set, and inspect its current entries.

A horizontal flow of chain boxes for the currently selected hook, optional side panels for rule detail and sets, and a legend.

The page is divided into:

  1. Header with the page title, a data-source badge, and toolbar buttons.
  2. Hook tabs — one tab per kernel hook (prerouting, input, forward, output, postrouting). Each tab carries a chain count badge.
  3. Flow area — the entry packet node, a chain of ChainBoxes connected by arrows, vmap group nodes where applicable, and an exit node. Scrolls horizontally for long pipelines.
  4. Side panel (only visible when needed) — Rule Detail panel or Sets & Maps panel docked to the right of the flow area.
  5. Legend strip at the bottom listing action colour codes.

Switch between the live kernel ruleset and any saved snapshot from the Firewall Manager.

The data source badge next to the page title shows the current source. Click it for a dropdown:

  • Live Running Config — fetched directly from the kernel via nft -j list ruleset. Reflects exactly what is enforcing traffic right now. Marked with a green radio icon.
  • Stored snapshots — every saved configuration from Firewall Manager (chapter 20), listed by name. The active snapshot is annotated (active). Useful for previewing a saved configuration before applying it, or comparing two side by side (open the page in two tabs).

The Refresh button re-fetches the current data source. Live config caches for 30 seconds; counter samples refresh every 30 seconds independently.


One tab per kernel hook. Each shows the chains registered at that hook in priority order.

HookPosition in the packet path
PreroutingBefore the routing decision — the hook DHCP DPI uses for inbound packet inspection. Most chains in the shipped ruleset live here.
InputPackets destined for a local process.
ForwardPackets being forwarded through the appliance.
OutputPackets generated by a local process.
PostroutingAfter the routing decision — used by the shipped ruleset for outbound DHCP enforcement (OFFER, ACK, NAK, REPLY).

The badge next to each tab name shows the chain count. Switching tabs reloads the flow area; the selected rule and any expanded vmap groups reset.


The diagram reads left to right: PACKET → first chain → arrow → next chain → … → CONTINUE.

The leftmost box shows the hook entry point as <HOOK> PACKET. Every packet reaching this hook enters here.

Each chain registered at the hook appears as a ChainBox. The header shows:

  • Chain name in bold.
  • Type (filter, nat, route, etc.) when set.
  • Priority (e.g. pri:-100) — chains are drawn left to right in priority order; lower priority numbers run first.
  • Family, table, and hook in a metadata line.
  • Counter badges when counters are enabled (see Counters).

The body lists each rule as a RuleNode, in declaration order, top to bottom. Long chains scroll inside the box. An empty chain shows “No rules in this chain”.

Each rule node summarises its expr array as a row of badges:

Badge familyColourMeaning
Acceptgreenaccept verdict
Dropreddrop verdict
Queueprimary bluequeue verdict (sends to userspace inspector)
Counter / Limityellowcounter increment or limit test
Jump / Gotopurpletransfer to another chain
VMap dispatchpurplevmap lookup that dispatches into one of several chains
NAT / Markcyanmangle of meta mark or NAT action

The same colours appear in the legend strip at the bottom. Comments on rules are shown as italic text under the badges.

Click a rule node to open the Rule Detail panel (described below).

When a chain ends with a vmap or a jump whose target is one of the user-defined per-msg-type chains, a VMap Group node appears immediately after the chain. It groups the target chains (e.g. v4_discover_chain, v4_request_chain, v6_solicit_chain, …) into a single collapsible node.

Click the node header to expand it and show each target chain as its own ChainBox. Click again to collapse. Each hook switch collapses every group on the page.

Black arrows between nodes indicate the packet’s left-to-right traversal. A packet visits chains in the order shown unless a rule changes the flow (jump, goto, vmap, drop, or accept).

The rightmost box shows the chain policy outcome — typically continue, meaning the packet leaves this hook and proceeds in the kernel.


Click any rule node to open a docked panel with that rule’s full information.

The side panel shows two views toggled by an icon button in the header:

  • Parsed view (default) — Location (family + table + chain), comment, the list of match clauses, and the list of actions. Each action is rendered as a coloured badge, the same as in the rule node.
  • Raw JSON view — the exact JSON object for that rule, indented and copyable.

Buttons in the header:

  • Toggle view (between code and document icons) — switch between parsed and raw.
  • Copy — copy the raw JSON to the clipboard.
  • Close — dismiss the panel.

The panel persists across counter refreshes and hook switches (the rule disappears if the new hook does not contain it).


Toggle the Sets button in the header to dock a panel listing every set and map in the loaded configuration.

The Sets button shows the total set count (Sets (12) for instance) and is disabled when no sets are present.

Each set is rendered as a card with:

  • Name prefixed with @ (@llm_blocked_marks, @tracked_marks, …).
  • Kind — set or map.
  • Family and table.
  • Element typemark, ipv4_addr, ifname, etc.
  • Timeout (when set) with a clock icon.
  • Size cap (when set) with a hash icon.
  • Element count with a show / hide toggle.

Expanding a set lists its current elements. For the LLM enforcement sets (llm_blocked_marks, llm_denied_marks, llm_throttled_marks, llm_allowed_marks, llm_monitored_marks) this is the answer to “is this device’s mark in the set right now?”.

The shipped seven enforcement sets — what they mean and their default timeouts — are documented in Key Concepts (chapter 03).

Tip: to confirm an automation rule has actually placed a mark in llm_blocked_marks, open Flow Visualizer, click Sets, expand llm_blocked_marks, and look for the device’s low-24-bit mark. If the mark is present, the kernel is enforcing.


Toggle the Counters button to overlay live packet/byte counts on every chain that defines one.

When Counters is off, the diagram is static — it shows structure only. When Counters is on:

  • A coloured counter badge appears in each chain header listing packets and bytes, with the counter’s name when the chain has more than one.
  • Values refresh every 30 seconds.
  • Newly-incremented counters animate briefly so you can spot active rules at a glance.

A small orange ! superscript on the Counters button warns when one or more counters are defined in the configuration but not present in the latest counter snapshot — typically because the counter was added more recently than the latest snapshot run. Hover the warning for the missing counter names.

Counter data comes from the appliance’s stored snapshot of nftables counters; live values come from the kernel and are captured periodically. The snapshot endpoint is the same one used by other Statistics pages — see Statistics & Reports (chapter 19) for the snapshot history viewer.

ObservationLikely meaning
Drop counter on a per-msg-type chain incrementing fastDevices being blocked or throttled in that chain
Counter on dhcp_block safety net incrementingPackets bypassing the per-msg-type vmap, hitting the fallback chain
Zero counts on a chain you expected traffic inMisconfigured priority, wrong hook, or no matching packets reaching that chain
Queue counter on the inspection chain low or zeroUserspace inspector not receiving packets — check nft list table for the queue rule

Counters take a moment to populate after a fresh apply. If a brand-new chain shows zero traffic, give it one or two counter refresh cycles before concluding the chain is dead.


A strip at the bottom names every colour used in the diagram.

BadgeColour
Acceptgreen
Dropred
Queueprimary blue
Counter / Limityellow
Jump / Gotopurple
VMap dispatchpurple
NAT / Markcyan

These match exactly the colours used in rule node badges and the rule detail panel.


Three concrete uses of the page.

  1. Switch to the prerouting tab (or whichever hook the packet enters at).
  2. Walk the chains in priority order — leftmost first.
  3. For each chain that the packet reaches, look at its rules: any drop badge will catch the packet if the matches succeed.
  4. Enable Counters; the drop counter that incremented since the packet appeared is your culprit.
  5. Click the dropping rule to see its match expression in the Rule Detail panel.
  1. Compute the device’s 24-bit mark from the last three bytes of its MAC (see Key Concepts, chapter 03).
  2. Open the Sets panel.
  3. Expand each llm_*_marks set in turn. Mark values are listed in hex (e.g. 0xddeeff).
  4. Cross-check against Firewall Decisions (chapter 10) for the higher-level view.
  1. Find the mark in llm_blocked_marks to confirm kernel enforcement is in place.
  2. Open the corresponding device’s Device Details (chapter 14) page — Enforcement Status will show which mac_actions row owns the entry and the source (rule name, LLM analysis, or operator).

The page is empty. Check the data-source dropdown. Live Running Config requires the appliance to have a loaded nftables ruleset. If nothing is loaded, the diagram is empty even though the page renders.

No chains for this hook. Not every hook is populated. The shipped ruleset uses prerouting and postrouting heavily; input, forward, and output are usually empty.

Counters refuse to turn on. Counter collection requires a counter snapshot row in the database. Counter snapshots are captured on a schedule by the appliance; on a fresh install give the first snapshot a minute or two. The orange ! badge will list any counters defined in the ruleset but missing from the snapshot.

A chain in the diagram does not match nft list ruleset. Re-fetch with the Refresh button; the page caches for 30 seconds. If the mismatch persists, you may be viewing a saved snapshot rather than Live Running — check the data-source badge.