Skip to content

Monitoring

Abdul Wasey edited this page Oct 2, 2026 · 6 revisions

Monitoring

The engine writes a JSON snapshot of everything it knows when it receives SIGUSR1, to the path given by --stats-dump:

sudo pkill -USR1 -x xdp-bfd     # bfd_tx if you built from source
python3 -m json.tool /tmp/bfd_tx_stats.json

It is written on the signal, not continuously, so always check the file's age before trusting it.

Whole-engine fields

field meaning
kernel_tx false means no XDP attach; everything is running in software
sessions_configured / sessions_up what bfdd has handed over, and how much of it is Up
xdp_ifindex the interface the program is attached to
deadman_us the bound actually in force, not what was asked for
demand_poll_us how long a demanding session may go unverified
loop_gap_us histogram of how long the userspace loop went between passes; the right-hand buckets are what starve detection

Per-session fields worth knowing

last_ktx_us is the one to look at first: it is when the program last transmitted for that session. Zero on an Up session means userspace is answering and the offload is not doing its job.

last_reason carries why the last transition happened, and last_overshoot_us how far past the detection budget the engine was when it declared a timeout, which is the number that tells you the box was too busy rather than the link being bad.

Counters

These are per-CPU totals from the XDP program, so they count what the driver saw, not what reached userspace.

counter what it means
seen every packet the program looked at
well-formed parsed as a BFD control packet
malformed header did not parse, or the envelope lied about its length; dropped
rejected GTSM, demux or fragment; dropped
unknown-session well-formed, for an address pair nothing is configured for, and not naming one of our discriminators; dropped
v6-exthdr UDP to a BFD port behind an IPv6 extension header; dropped
auth-mismatch the A bit and the session disagree in either direction
auth-bad key, digest or sequence failed
auth-ratelimited dropped before the digest, because too many failures landed this interval
reflected echo bounced back to its originator
echo-returns our own echo came back
declined echo from something that is not a peer of an echo-active session
not-self echo neither self-addressed nor sent to us for one of our sessions
deadman-hold a reply withheld because the engine had stopped making progress
ip-options UDP carrying IPv4 header options to a BFD port; dropped
echo-ttl an echo that did not arrive at the hop limit it must
unsupported-flags a flag the session cannot honour, such as the multipoint bit
sweep-init-fail the kernel sweeper never armed, which means detection is not running in the program
moved-ratelimited naming one of our discriminators from a pair we do not know, over this CPU's budget of 256 per 100ms; dropped
echo-ratelimited echo from a known peer past its budget, four times our Required Min Echo RX plus 16 per 100ms; dropped
too-fast a session's packet sooner than half our Required Min RX after the last, or a Poll or Final past 32 per 100ms; counted for liveness, then dropped
verify-limited a good-looking authenticated packet over the session's digest verify budget (one per half our Required Min RX, a burst of two); dropped before the HMAC. Only a peer that holds the key, or a broken one, should move it
changes-lost the program's change ring was full; the engine then reads every session's state each pass until it catches up

A healthy engine under normal traffic moves seen, well-formed and, if echo is on, reflected and echo-returns. Everything else should be flat. malformed, rejected and unknown-session climbing steadily is traffic aimed at the BFD ports that is not yours; see Security model for what that costs.

Clone this wiki locally