An isolated Linux testbed for OSPF failover and service continuity measurement
Route Resilience Lab is a university side project developed from work in a network management class. It creates six Linux network namespaces and runs BIRD on four routers. OSPF selects a preferred path between two hosts while a higher-cost path remains available. Python then sends continuous UDP probes, disables the primary link, measures convergence to the backup path, restores the link, and verifies primary-path recovery. Every run produces machine-readable routing, latency, packet-loss and cleanup evidence.
preferred path
+--------- r2 ---------+
/ \
h1 client ------ r1 r4 ------ h2 server
\ /
+--------- r3 ---------+
backup path
The r1-r2-r4 path uses lower OSPF costs than r1-r3-r4. Host-facing networks are advertised as OSPF stub interfaces. BIRD installs learned routes only inside the router namespaces.
OSPF uses a one-second hello timer and four-second dead timer. The client sends a probe every 50 milliseconds with a 40 millisecond reply timeout. Fault and restoration timing starts immediately before the first endpoint operation. Route detection polls both forwarding directions every 20 milliseconds, so convergence values have at least that measurement uncertainty. Estimated outage is the longest interval covered by consecutive unsuccessful probes.
Five consecutive live runs completed on Arch Linux with BIRD 3.2.1. Each run established all eight directed OSPF neighbour relationships, selected the preferred path, failed the r2-r4 link, moved traffic to the backup path, restored the preferred path, and removed its tracked transient resources.
| Metric | Minimum | Median | Maximum |
|---|---|---|---|
| Failover convergence | 2.63 s | 2.75 s | 2.77 s |
| Primary-path recovery | 2.99 s | 4.02 s | 4.99 s |
| Estimated traffic outage | 2.70 s | 2.70 s | 2.70 s |
| Packet loss during experiment | 19.6% | 19.6% | 19.6% |
| Validation | Result |
|---|---|
| Experiment checks | 45 of 45 passed |
| OSPF adjacency formation | 5 of 5 runs |
| Backup route selected | 5 of 5 runs |
| Service available on backup path | 5 of 5 runs |
| Preferred route restored | 5 of 5 runs |
| Service available after recovery | 5 of 5 runs |
| Host links, routes and namespace registrations unchanged | 5 of 5 runs |
The 1,400 probes include 1,125 successful replies and 275 losses. Loss is expected while OSPF converges after the deliberate fault. The results demonstrate recovery rather than uninterrupted forwarding. A representative run is in reports/failover-validation.json and reports/failover-validation.csv. Four further JSON reports retain the other runs. The evaluator records each source hash in reports/stability-summary.json.
The lab requires Linux, Python 3.12 or newer, iproute2, BIRD 3, and sudo access. On Arch Linux:
sudo pacman -S --needed python iproute2 bird
python -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
sudo -v
scripts/setup.sh
pytest -q
scripts/integration-test.sh reports/failover-local.json reports/failover-local.csvUse new output names because reports are never overwritten. The runner refuses colliding namespace and interface names. It deliberately provides no destructive stale-cleanup command because fixed names do not prove resource ownership. If the process is forcibly killed, inspect any remaining namespaces and processes before removing them manually.
The experiment requires root privileges for namespace and virtual-link orchestration. BIRD runs with only the network capabilities it needs, and probes run as the original sudo caller without capabilities. The project does not start the host BIRD service or alter host routing policy. Experiment IP traffic is confined to the lab namespaces. Unicast links use RFC 1918 addresses, and OSPF uses its standard multicast traffic. Review the code before running it and do not adapt the failure tooling to networks you do not own.