Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ndn-fwd

ndn-fwd is the standalone forwarder binary. This page covers day-2 operation: starting, inspecting state, applying changes, shutting down cleanly.

For first-run setup see Running the forwarder. For containerised deployment see Self-hosting.

Lifecycle

ndn-fwd --config /etc/ndn-fwd/ndn-fwd.toml

ndn-fwd reads --config (or $NDN_CONFIG, or ./ndn-fwd.toml), opens its listeners, restores strategy and route pins from ~/.ndn/strategy-choice.toml and ~/.ndn/routes.toml, and starts serving.

Ctrl-C (or SIGTERM) triggers a clean shutdown: open faces drain, the PIT is allowed to empty (up to a grace window), strategy and route pins are persisted, the process exits 0.

The systemd unit at deploy/systemd/ndn-fwd.service (when using the deploy stack) handles restart and journal capture.

Inspecting state

ndn-ctl is the operator CLI. It speaks the TLV management protocol against the running forwarder.

VerbWhat it shows
ndn-ctl statusForwarder summary: NFD-compatible status, version, timestamps, uptime, table counts, and packet counters.
ndn-ctl face listEvery face with kind, scope, persistency, byte/packet counters.
ndn-ctl fib listFIB entries by prefix with nexthops.
ndn-ctl rib listRIB entries (registered prefixes, origin, expiry).
ndn-ctl strategy listPer-prefix strategy choice.
ndn-ctl cs infoContent store size, hits, misses, eviction count.
ndn-ctl routing statusActive routing protocol and its typed status.
ndn-ctl neighbor listDiscovery-protocol neighbour table.

Full verb catalogue: Management verbs.

The graphical equivalent is ndn-dashboard; see Running the dashboard.

Applying changes

Most knobs can be set at runtime via the mgmt protocol; restart is only needed for [engine] and [face.*] listener changes.

ChangeRestart?
Add/remove a routeNo — ndn-ctl route add / route remove.
Pin a strategyNo — ndn-ctl strategy set.
Adjust CS capacityNo (LRU resize) / Yes (variant change).
Add a new face listenerYes — re-read [face.*].
Change pipeline depthYes — [engine] knobs.
Change log filterNo — ndn-ctl log set <filter>.

Management trust & bootstrap

Privileged management commands (adding a trust anchor, importing a key, editing the trust schema or routes) are always signed and validated by the forwarder — even when require_signed_commands = false. A fresh forwarder with no configured trust anchor therefore refuses them with 403 … no validator is configured. This is intentional: forwarder trust cannot be bootstrapped over the unauthenticated management channel (anyone with socket access could otherwise install anchors).

Bootstrap trust out-of-band, once per forwarder:

# 1. Create the operator identity + a self-signed trust anchor.
ndn-sec --pib /etc/ndn/mgmt-pib keygen --anchor /op/alice

# 2. Point the forwarder at that anchor PIB and restart.
#    [security.mgmt]
#    require_signed_commands = true
#    trust_anchor_pib = "/etc/ndn/mgmt-pib"

# 3. Export the operator identity to carry into the dashboard / another host.
ndn-sec --pib /etc/ndn/mgmt-pib export /op/alice -o op-alice.safebag

Now the operator can issue signed commands: ndn-ctl reads the PIB directly, and the dashboard signs after you import op-alice.safebag (its key is loaded into the dashboard keyring; commands validate against the anchor configured in step 2). Read-only datasets (*/list, status/general, cs/info) stay unsigned and work without any of this.

Mind the section. trust_anchor_pib lives under [security.mgmt] — it configures who may manage this forwarder. It is not the same as [security] identity, which is the forwarder’s own signing key (a separate role; you don’t need it just to accept operator commands). A misplaced key is now rejected at startup with an unknown field error rather than being silently ignored.

Faces and prefixes

Apps register their own prefixes via the IPC face. The operator adds static routes for cross-host paths:

ndn-ctl face create udp://10.0.0.1:6363
ndn-ctl route add /lab faceid:<id>

The face ID comes from face create’s output; it is monotonic and never recycled (project memory feedback_face_id_no_recycle).

Per-face NDNLPv2 options are toggled with face update (the faces/update flag bits — 0 = LocalFields, 1 = LpReliability, 2 = CongestionMarking):

ndn-ctl face update <id> --flags 0x2   # enable LpReliability on a lossy link

Bits outside --mask (default: the bits in --flags) are preserved. See Per-face NDNLPv2 local fields.

Logs

ndn-fwd writes structured logs to stderr (or the journal under systemd). Filter and target taxonomy: Logging.

State that survives a restart

PathContents
~/.ndn/pib.dbKeyChain identities, keys, certs.
~/.ndn/strategy-choice.tomlPer-prefix strategy pins.
~/.ndn/routes.tomlStatic route pins added via ndn-ctl route add --persist.
~/.ndn/measurements/ (optional)Strategy measurement state.

Move or back these up via deploy/backup.sh. Restore by copying back before starting ndn-fwd.

See also