- The status page has a collapsible "Configuration" section showing the
config file as read at startup, with its path. Served by the new
GET /api/config; RouterInfo::with_config carries the text.
- Removed the AS-path prepends field and the SwissIX prepend presets
(42476:101..103) from the form to keep the exercise focused. The API
still accepts `prepend`.
- Docs follow: the handout loses its prepending exercise, the lab README
its prepend row, and the BIRD config notes that the 42476 namespace is
still admitted for hand-typed values.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Hovering (or focusing) a byte segment opens a popup that decodes it:
header fields, the two length fields, and each path attribute with its
flags spelled out and its value in readable form. AS_PATH shows segment
type, ASNs, path length and ASN width; COMMUNITIES shows well-known
names; LARGE_COMMUNITIES shows the SwissIX meaning of known values;
MP_REACH/UNREACH show address family, next hop and prefixes; NLRI and
withdrawn routes list prefixes. Decoding happens on hover from the bytes
themselves. /api/routes/local/wire gains four_octet_asn so the AS_PATH
width is known.
- The page is now a snapshot by default. ?refresh=<seconds> (1..3600)
turns on reloading of all tables at that interval and connects the
event log; the header offers 2s / 5s / 30s, "turn off" and "reload now".
Events only feed the log, so the tables never change faster than asked.
The reader's own announce / withdraw still shows its effect at once.
- Removed the "tables refresh on every event" footer text.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Modelled on Vitess's servenv status page and golang.org/x/net/trace, both
written by Google engineers to mirror the internal pages: plain sans-serif
HTML, default links and native form controls, dense bordered tables, and a
full-width centred light blue (#eef) heading bar per section. Header shows
"Status for ferrix_bgp" with start time, uptime, version, router ID and AS
on the left and host, "View:" links and live-update state on the right.
The dark theme is dropped on purpose.
Behaviour is unchanged (live updates, owner-gated withdraw, per-session
UPDATE bytes, looped-route highlight, peers polling). Additions:
- a SwissIX large-community picker next to the field; presets with a peer
AS ask for the number
- event log lines include prepend and MED
- /api/status gains hostname and started_at_unix (RouterInfo::new)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Phase 3 of the teaching demo.
- crates/web serves an embedded, dependency-free status page at /statusz
(/ redirects there). Sections: router header with live indicator, peers,
announce form (owner remembered locally, well-known community picker,
prepend / MED / large communities), local routes with per-session UPDATE
bytes segmented into header / lengths / attributes / NLRI, received
routes with rows highlighted when a locally announced prefix has come
back, and a live event log. Tables refresh on every SSE event. Light
and dark themes.
- fake_peer example in crates/integration-tests: connects, announces,
prints received UPDATEs and with --echo re-announces everything back
with its ASN prepended (dropping NO_EXPORT), so one daemon plus one
process demonstrates the full loop without lab routers.
- README for the binary documents the endpoints and the demo setup.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Phase 2 of the teaching demo: everything the status page will need is now
reachable over HTTP.
- New crate crates/web (axum). JSON endpoints for status, peers, local
routes (announce / withdraw), received routes, the exact UPDATE bytes a
local route produces per session, and well-known community names.
Communities are accepted as ASN:VALUE or by name (NO_EXPORT, BLACKHOLE,
...); large communities as A:B:C. Policy errors map to 403/409/422.
- GET /api/events is a server-sent event stream merging session up/down,
local route and Adj-RIB-In changes, with lag notifications.
- GET /metricz serves Prometheus metrics; the server crate now counts
messages sent/received by type and sessions established.
- The runnable main moves from crates/server to bin/bgp so it can depend
on both server and web without a cycle. `cargo run -- config.textpb`.
- Config gains http_endpoint; unset disables the API.
- Integration tests drive the API against a live server with a real BGP
peer, including verifying the wire view matches the bytes the peer got.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>