Files
ferrix/docs/lab/README.md
T
Rayhaan JaufeerallyandClaude Fable 5.1 eb77090d01 feature: config zippy on statusz; drop prepend options from the UI
- 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>
2026-09-19 22:46:07 +02:00

4.0 KiB

BGP teaching lab

A small topology in which a prefix announced from the ferrix_bgp web UI is carried around a loop of two routers and arrives back, so students can watch what their path attributes and communities do.

        announce                     re-advertise
 ┌─────────┐  ──────▶  ┌────────┐  ──────▶  ┌────────┐
 │ ferrix  │           │  r1    │           │  r2    │
 │ AS65000 │           │ AS65001│           │ AS65002│
 │ web UI  │  ◀──────────────────────────────────────┘
 └─────────┘   comes back with AS path 65002 65001 65000
  • ferrix (AS65000, 10.200.0.1) dials r1 and r2 and announces whatever students enter on http://localhost:8080/statusz. It does not forward routes it learns, so the only routes it sends are the students'.
  • r1 (AS65001, FRR) applies policy to routes from ferrix based on the communities they carry, then passes them to r2. It originates 192.0.2.0/24.
  • r2 (AS65002, FRR) refuses routes directly from ferrix, so it only learns student prefixes via r1, and re-advertises everything to ferrix. It originates 198.51.100.0/24.

Running it

From the repository root:

docker compose -f docs/lab/docker-compose.yml up --build

Then open http://localhost:8080/statusz. Both peers should show Established within a few seconds and the received table should already list the two prefixes r1 and r2 originate.

Useful on the routers:

docker exec r1 vtysh -c 'show bgp ipv4 unicast'
docker exec r2 vtysh -c 'show bgp ipv4 unicast 10.100.1.0/24'
docker exec r1 vtysh -c 'show bgp neighbors 10.200.0.1 advertised-routes'

Policy on r1

Students set r1 does Visible effect in ferrix
nothing forwards to r2 prefix returns, AS path 65002 65001 65000
NO_EXPORT keeps it, does not send to r2 (RFC 1997) prefix does not return
65001:100 prepends 65001 three times returns with path 65002 65001 65001 65001 65001 65000
BLACKHOLE (65535:666) drops it on import prefix does not return

Without containers

fake_peer in crates/integration-tests/examples is enough for the core loop on one machine: it echoes every prefix back with its own ASN prepended and honours NO_EXPORT. See bin/bgp/README.md.

Caveats

These container files were written without a container runtime to hand, so they have not been executed. Things most likely to need a touch:

  • the FRR image tag, and FRR's route-map / community-list syntax if your version differs from 10.x;
  • no bgp ebgp-requires-policy is required on FRR 7.4+ or eBGP routes are silently dropped; it is present in both configs;
  • ferrix binds port 179 inside its container, which requires no special capability there. If you run it on the host instead, either run as root, grant CAP_NET_BIND_SERVICE, or change listen_endpoints and the FRR neighbor port.
  • Both ferrix and the FRR routers dial each other, so connection collisions (RFC 4271 §6.8) are normal at start-up: one of the two TCP connections is closed with a Cease / Connection Collision Resolution NOTIFICATION and the other carries the session. ferrix has the lowest BGP Identifier here, so the connection the FRR router opened is the one that survives; the "opened by" column on the status page shows which side that was.
  • ferrix does not check AS paths for its own ASN. That is what lets the looped route be accepted; a production BGP speaker would reject it.