lnstatus
lnstatus is the Reticulum status tool. It shows the interfaces of a
running daemon and their traffic, announce, path-request, and link
statistics, and is output-compatible with Python's rnstatus — fed the
same interface_stats from the same daemon, lnstatus and rnstatus
render byte-identical output, so lnstatus | diff rnstatus passes.
Reticulum Network Stack Status
Usage: lnstatus [OPTIONS] [FILTER]
Arguments:
[FILTER] only display interfaces with names including filter
Options:
--config <CONFIG>
path to alternative Reticulum config directory
-a, --all
show all interfaces
-A, --announce-stats
show announce stats
-P, --pr-stats
show path request stats
-l, --link-stats
show link stats
-B, --burst
only show interfaces with active bursts
-t, --totals
display traffic totals
-s, --sort <SORT>
sort interfaces by [rate, traffic, rx, tx, rxs, txs, announces, arx, atx, prx, ptx, held]
-r, --reverse
reverse sorting
-j, --json
output in JSON format
--tables
add the transport's internal tables and collection sizes to the JSON output (requires -j)
-R <REMOTE>
transport identity hash of remote instance to get status from
-i <IDENTITY>
path to identity used for remote management
-w <TIMEOUT>
timeout before giving up on remote queries
-d, --discovered
list discovered interfaces
-D
show details and config entries for discovered interfaces
-m, --monitor
continuously monitor status
-I, --monitor-interval <MONITOR_INTERVAL>
refresh interval for monitor mode (default: 1) [default: 1]
-v, --verbose...
verbose logging (repeatable)
--instance-name <INSTANCE_NAME>
shared-instance name to query (default: from config, else "default")
-h, --help
Print help (see more with '--help')
-V, --version
Print version
lnstatus needs a running daemon (lnsd or rnsd) on the same shared
instance to query — see the
lnsd Quickstart.
Running it against a daemon
With lnsd (or Python rnsd) running, lnstatus with no arguments
prints every up interface and its counters:
lnstatus
It resolves the daemon exactly like the other tools: the config
directory (default lookup, or --config <DIR>) gives the shared-instance
name and the RPC authkey. If no shared instance is reachable, it reports
No shared RNS instance available to get status from and exits non-zero.
Give a FILTER to restrict the output to interfaces whose name contains
it:
lnstatus eth
Common flags
Extra statistics
-A/--announce-stats and -P/--pr-stats add announce and path-request
columns; -l/--link-stats adds link counts (queried separately from the
daemon); -t/--totals appends traffic totals:
lnstatus -A -P -l -t
-a/--all also shows interfaces that are currently down, and
-B/--burst restricts the output to interfaces with active bursts.
Sorting
-s/--sort <KEY> orders the interfaces by one of rate, traffic,
rx, tx, rxs, txs, announces, arx, atx, prx, ptx, or
held; -r/--reverse flips the order:
lnstatus -s traffic -r
Monitor mode
-m/--monitor clears the screen and re-renders on each interval;
-I/--monitor-interval <SECONDS> sets the refresh period (default 1):
lnstatus -m -I 2
JSON output
-j/--json emits the status as JSON instead of the rendered table, for
scripting:
lnstatus -j
The transport's tables
--tables adds one key, transport_tables, to that JSON object. It answers
how big every table the transport maintains is — path_table,
reverse_table, link_table (relayed links), announce_table,
announce_cache, tunnels, and local_links (links this node terminates) —
as a table_sizes list of {name, entries}:
lnstatus -j --tables
The rows themselves are a separate ask, --table-rows, which names the
tables you want them from (all for every one):
lnstatus -j --tables --table-rows path_table
lnstatus -j --tables --table-rows all
The split is about what the query costs the daemon. Answering a size is a
len(); answering with rows makes the daemon build one dictionary per row
before it can send anything, which on a node with 11 000 paths and 43 000
reverse entries was measured at 83 MB of daemon memory for a single call. A
status poll that only wanted to know how full the tables were was moving the
daemon's resident set by tens of megabytes, repeatedly. Asking for sizes now
costs about 35 KB regardless of how large the tables are; the rows cost what
they cost, to whoever actually wants them.
A table you did not ask rows for is absent from the response, not present
as an empty list, because an empty list is how this key says "the table is
empty". rows_for names the tables whose rows the response does carry, so a
reader never has to infer it. --table-rows requires --tables.
Beside the tables it carries collections: one row per collection the
daemon's storage holds, with name, entries and capacity (null where
the collection has no configured ceiling). It covers all of them, not just
the seven dumped above — including the packet dedup cache, which is the
largest structure in the daemon and appears as its two generations
packet_cache and packet_cache_prev rather than as a sum, because a
rotation frees one generation whole and a sum does not move when it happens.
That is how a resident set that steps up and falls back gets attributed to a
structure instead of guessed at.
rnstatus has no counterpart, so both flags require -j and never change
what a reference flag prints. lnstatus -j on its own is exactly what it was.
Two timestamps in there answer different questions. timestamp is our
clock — when this node learned the row. announce_emitted is the announcing
node's clock — the second it stamped into its announce, which is what peers
order competing announces by.
A daemon that does not implement the query — a Python rnsd, or an lnsd
older than this flag — makes lnstatus omit the key, print why on stderr, and
exit 0; the status you asked for is still printed. So an absent
transport_tables key means "this daemon cannot answer", while a present
key means it can — and inside it, a table named in rows_for whose list is
empty really is empty. Check for the key before reading it, and do not treat
its absence as an empty table.
Full field lists are in lnstatus(1).
Remote status (-R/-i/-w)
-R <hash> queries a remote transport instance's status over a link,
the way rnstatus -R does, and feeds the result to the same renderer,
so remote and local output match (run_remote (lnstatus.rs:453)).
<hash> is the remote instance's transport identity hash (32 hex
characters). -i <file> names the management identity and is
mandatory; it is proven to the remote over the link, so the remote
daemon only answers if it has remote management enabled and lists that
identity as allowed. -w <seconds> bounds the query (default 15,
matching Python's path-request timeout). -m re-queries the remote on
the monitor interval, and -j renders the remote status as JSON:
lnstatus -R 76fe5751a56067d1e84eef3e88eab85b -i ~/.reticulum/identities/mgmt -w 30
Discovered interfaces (-d/-D)
-d lists the interfaces this daemon has discovered on the network, in
the rnstatus discovered layout; -D renders the detailed layout with
ready-to-paste config entries (run_discovered (lnstatus.rs:362)).
Both read the local daemon's discovered-interface registry over the
shared-instance RPC and honour FILTER and -j:
lnstatus -D rnode
Examples
Full picture of a local daemon
lnstatus -a -A -P -l -t
Watch one interface live
lnstatus -m -I 2 rnode
lnstatus needs a running daemon (lnsd or rnsd) on the same shared
instance to reach the mesh — see the
lnsd Quickstart.