TTR Networks

Intermediate · BFD on VyOS: fast failover for quiet failures · section 1 of 7

Quiet failures, and the lab

✓ Lab-tested 21 October 2026 on VyOS 2026.10.16-0024-rolling, FRR 10.2.1

Measure how long OSPF and BGP take to notice a link that fails without going down (35 and 159 seconds in the lab), then cut it to about a second with BFD: profiles, BFD for OSPF and BGP, multihop sessions between loopbacks, and choosing timers.

By the end you will be able to:

  • Explain why a link that fails quietly takes OSPF and BGP tens of seconds or minutes to notice
  • Configure BFD profiles and attach them to OSPF interfaces and BGP neighbours
  • Measure failover with and without BFD, and read the BFD session state
  • Use multihop BFD between loopbacks, with timers slower than the network's reconvergence
  • Choose BFD timers, and troubleshoot sessions that don't come up or flap

Prerequisites: OSPF on VyOS: costs and OSPFv3, BGP Fundamentals

When a cable is unplugged, both routers see the link go down and reroute in a moment. The failures that hurt are the quiet ones: the link stays up, but packets stop. A switch in the middle hangs, a provider's circuit fails somewhere you can't see, a fibre fails in one direction only. The interface says up, so nothing notices.

Nothing, that is, except the routing protocol's own keepalives, and they're slow on purpose:

ProtocolHellos / keepalivesDeclared dead after
OSPF (defaults)every 10 s40 s without one
BGP (FRR and VyOS defaults)every 60 s180 s without one

In Why not keep it simple? a quiet failure took far too long to notice. This lesson measures it on VyOS, then fixes it with Bidirectional Forwarding Detection (BFD): a tiny protocol whose only job is to answer "is the path to my neighbour still forwarding?", many times a second.

What the lab measured

Without BFDWith BFD (300 ms × 3)
OSPFabout 35 s of lost trafficunder 1 s
eBGPabout 159 sabout 1 s

The lab

R1 is a VyOS VM, and R2 runs FRR (the same routing suite VyOS uses underneath). They're joined by two links: link A, the primary, and link B, the backup. Each has a LAN with one host, and h1 pings h2 ten times a second throughout, so every lost ping is a tenth of a second of outage.

To fail link A quietly, the lab unplugs it in the middle: inside R1's QEMU container, the wire is detached from the bridge that connects the VM to the Docker network. R1's interface and R2's interface both stay up, with carrier, exactly like a dead switch between them.

Diagram: Two links, one quiet failure — Two routers joined by two links. Link A fails in the middle while both interfaces stay up.
  1. Normal: link A carries everything. OSPF (cost 10 vs 100) or BGP (weight 100) prefers link A. h1 pings h2 ten times a second.
  2. A quiet failure in the middle. Link A stops forwarding between the routers, but both of their interfaces stay up, with carrier. Nothing tells R1 or R2.
  3. Without BFD: wait for the protocol. OSPF waits for its 40 s dead timer, BGP for its 180 s hold timer. Traffic is black-holed meanwhile: about 35 s and 159 s in the lab.
  4. With BFD: under a second. BFD packets every 300 ms stop arriving. After three are missed (900 ms), BFD tells OSPF or BGP, and traffic moves to link B.
How the lab cuts link A quietly
#!/bin/sh
# ./fail-test.sh OUTFILE SECS: ping h1 -> h2 ten times a second for SECS, quietly cut link A after 5 s,
# then put it back. Writes a transcript to out/OUTFILE.
cd "$(dirname "$0")"
f=out/$1; secs=$2; mkdir -p out
x() { docker compose exec -T "$@"; }
x h1 sh -c "setsid ping -i 0.1 -c $((secs * 10)) -q 198.51.100.130 > /tmp/ping.txt 2>&1 < /dev/null &"
sleep 5
printf 'root@r1-container:~# date +%%T; ip link set eth0 nomaster   # cut link A in the middle; carrier stays up\n' >> $f
x r1 sh -c 'date +%T; ip link set eth0 nomaster' >> $f
printf '\nroot@h1:~# ping -i 0.1 -c %s -q 198.51.100.130   # started 5 s before the cut\n' "$((secs * 10))" >> $f
sleep $((secs - 3))
x h1 sh -c 'until grep -q statistics /tmp/ping.txt; do sleep 1; done; sleep 1; cat /tmp/ping.txt' | grep -v '^$' >> $f
x r1 sh -c 'ip link set eth0 master br0 && bridge link set dev eth0 learning off'
echo >> $f
  • Line 7: Ten pings a second, in the background, for the whole test.
  • Lines 9–10: Detach link A from the bridge inside R1's QEMU container: no packets cross, but every interface stays up.
  • Line 13: Wait for ping's summary.
  • Line 14: Plug link A back in.

Check your understanding

Why doesn't R1 reroute immediately when link A fails in the middle?

  • Its interface is still up, so only the routing protocol's own keepalives can reveal the failure.
  • OSPF prefers link A because of its cost.
  • Link B is too slow.
  • VyOS doesn't support fast rerouting.