Skip to main content
RunBook Academy

VyOSXXXII · BFDBFD

BFD with BGP — neighbor bfd, sub-second failure detection, and the profile that owns the timers

Advanced⏱ ~24 minset protocols bgp neighbor <ip> bfdset protocols bgp neighbor <ip> bfd profile <name>set protocols bfd profile <name> interval transmit <ms>show ip bgp summaryshow ip bgp neighbors <ip>show bfd peersshow bfd peer <ip>show configuration commands | match bfdvtyshjournalctl -u frr

What you'll learn

  • Enable BFD on a BGP peer with `set protocols bgp neighbor <ip> bfd`
  • Explain how BFD bypasses the BGP hold-time for sub-second failure detection
  • Configure a BFD profile and reference it from the BGP neighbour
  • Validate the BGP+BFD integration with show bfd peers and the BFD block of show ip bgp neighbors
  • Recognise the production failure modes — BFD flap, BGP peer down without BFD, asymmetric BFD

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling)

Not yet marked complete on this device.

BGP’s hold-time is 180 seconds by default. If the link drops, the local router does not know for up to 180 seconds. The local router keeps stale routes; traffic continues to be routed to the dead peer. The blackhole lasts up to 180 seconds. BFD solves this by detecting failures in sub-second intervals and signalling BGP to tear down the session. When BFD+BGP are integrated, the BGP session drops within ~150-300ms of the link failure — well before the 180-second hold-time.

This lesson walks the BGP+BFD integration on VyOS 1.5 LTS: how to enable BFD on a BGP peer, how BFD bypasses the hold-time, how to reference a BFD profile, and the operational commands to validate. The goal is the ability to enable BFD on any BGP peer, choose the right interval, and validate the integration is live.

Why integrate BFD with BGP

BGP without BFD has a 180-second failure detection window. For most production use cases, this is unacceptable:

  • Internet-facing peers — a 180-second blackhole on an Internet-facing link is a major incident. Customers see the outage.
  • Transit providers — a 180-second blackhole on a transit link means 180 seconds of traffic being routed into a void. The operator’s SLAs are violated.
  • Route reflectors — a 180-second blackhole on a route reflector means 180 seconds of stale routes being advertised to clients.

BFD reduces the failure detection time to sub-second intervals. The BGP session drops within ~150-300ms of the link failure. The local router removes the routes immediately. Traffic is rerouted via an alternative path within seconds.

The trade-off: BFD consumes CPU and bandwidth. The operator must balance failure-detection speed against the link’s capability.

Enabling BFD on a BGP peer

The simplest configuration:

set protocols bgp neighbor 192.0.2.2 bfd

The bfd flag registers the peer with bfdd. With no profile named, the session runs on FRR’s defaults.

To use a specific profile:

set protocols bgp neighbor 192.0.2.2 bfd profile 'FAST'

The full configuration example:

set protocols bfd profile FAST interval transmit '50'
set protocols bfd profile FAST interval receive '50'
set protocols bfd profile FAST interval multiplier '3'
set protocols bgp system-as 64512
set protocols bgp neighbor 192.0.2.2 remote-as '65001'
set protocols bgp neighbor 192.0.2.2 bfd profile 'FAST'

Note the shape of the profile, because it is the part most often written from memory and rejected: the timers sit under an interval node — interval transmit, interval receive, interval multiplier — rather than as interval / min-rx / multiplier leaves directly under the profile. The names map onto FRR’s transmit-interval, receive-interval and detect-multiplier.

Note also the BGP shape: the AS is declared once with set protocols bgp system-as 64512 and peers hang off set protocols bgp neighbor .... The older set protocols bgp 64512 neighbor ... form does not commit on 1.5.

sequenceDiagram
  participant A as Router A
  participant B as Router B
  participant BGP as BGP daemon
  participant BFD as BFD daemon

  Note over A,B: Initial — link up, BGP Established, BFD Up
  A->>B: BFD packet (interval 50ms)
  B->>A: BFD packet (interval 50ms)
  Note over A,B: Link drops
  A->>B: BFD packet — NO RESPONSE
  Note over A: BFD detects failure after 150ms (3x missed)
  BFD->>BGP: peer-down signal
  BGP->>B: NOTIFICATION 6/0 (Cease)
  Note over A,B: BGP session torn down immediately
  Note over A: Routes from peer removed

The diagram shows the failure detection and teardown sequence. When the link drops, BFD detects the failure in 150ms; BFD signals BGP; BGP tears down the session immediately. The local router removes the routes within seconds.

Per-peer timers: there are none

There is no way to override a timer on the BGP neighbour. The bfd node under set protocols bgp neighbor <ip> takes the flag itself, a profile reference, and check-control-plane-failure — and no interval or multiplier of its own. VyOS does not expose the older FRR form that took inline timers on the neighbour line.

That is a design decision rather than a gap to work around: the timers are a property of the link’s tolerance, and giving two protocols on the same link two different opinions about how fast it can be probed is a way to build a flap. If two peers need different timers, they need different profiles:

set protocols bfd profile FAST interval transmit '50'
set protocols bfd profile FAST interval receive '50'
set protocols bfd profile FAST interval multiplier '3'
set protocols bfd profile TUNNEL interval transmit '300'
set protocols bfd profile TUNNEL interval receive '300'
set protocols bfd profile TUNNEL interval multiplier '4'
set protocols bgp neighbor 192.0.2.2 bfd profile 'FAST'
set protocols bgp neighbor 203.0.113.9 bfd profile 'TUNNEL'

Naming profiles after the kind of link rather than after the speed keeps this honest — TUNNEL still means something in a year; FAST-300 stops meaning anything the first time someone edits it.

Multi-hop BFD for BGP

For BGP peers that are not directly connected (e.g., across a routed network or via IPsec tunnel), the operator uses the multihop flag on both the BFD peer and the BGP neighbour:

set protocols bfd peer 192.0.2.2 profile 'FAST'
set protocols bfd peer 192.0.2.2 multihop
set protocols bfd peer 192.0.2.2 source address '192.0.2.1'
set protocols bgp system-as 64512
set protocols bgp neighbor 192.0.2.2 remote-as '65001'
set protocols bgp neighbor 192.0.2.2 bfd profile 'FAST'

The source address is source address (there is also source interface), not the src abbreviation an older config may carry. Multi-hop is a property of the BFD peer definition; the BGP neighbour has no multihop flag of its own to set — what it has is ebgp-multihop, which is a different thing solving a different problem, as the next callout explains.

Multi-hop BFD also uses a different UDP destination port from single-hop (4784 rather than 3784), which matters the moment there is a filter anywhere in the path.

How the result is validated

show ip bgp summary
show ip bgp neighbors 192.0.2.2
show bfd peers
show bfd peer 192.0.2.2
show configuration commands | match bfd
sudo journalctl -u frr --since '-1 hour' | grep -i bfd

The first shows the BGP peer state. The second is the per-peer BGP view, and when BFD is registered for that peer its output carries a BFD block naming the type (single hop or multihop), the negotiated intervals, the detect multiplier and the current status — that block’s presence is what tells you bgpd actually registered the peer, as opposed to the configuration merely mentioning BFD. The third and fourth are bfdd’s own view: session state, the local and remote discriminators, the negotiated timers and the uptime. The fifth is the configuration side. The journal is where a session that keeps bouncing leaves its trail.

Read those two views together, because they answer different questions. show bfd peer says whether the link probe is healthy. The BFD block in show ip bgp neighbors says whether BGP is wired to it. It is entirely possible to have a perfectly healthy BFD session that no BGP peer is listening to.

What “working” looks like: show bfd peer 192.0.2.2 reports the session up, with negotiated intervals that match what you intended on both sides, and show ip bgp neighbors 192.0.2.2 carries a BFD block for the same peer with the same status. A session in down or init means the probe is not established — and BGP will keep running on its own hold timer, quite happily, with none of the protection you think you deployed.

How it fails

The production failure modes the engineer must recognise:

  • BFD up but BGP not using BFD. A protocols bfd peer block exists and its session is healthy, but no BGP neighbour has the bfd flag, so nothing signals bgpd. The evidence is a healthy show bfd peer with no BFD block in show ip bgp neighbors. The fix: add set protocols bgp neighbor <ip> bfd.
  • BFD down but BGP session still up. The BFD session is not established (firewall, peer not running BFD). BGP continues to operate with its own keepalive. The fix: resolve the BFD issue.
  • BGP session drops but BFD says up. BFD is not detecting the failure (asymmetric routing, BFD peer misconfigured). The fix: verify BFD is detecting failures.
  • BFD flap causes BGP flap. The BFD interval is too aggressive; the link cannot sustain the packet rate. The fix: increase the interval.
  • Detection is slower than the ticket claims. BFD was enabled with no profile, so the timers are FRR’s 300/300/3 defaults and detection is around 900 ms rather than the 150 ms someone wrote down. The evidence is in the negotiated intervals in show bfd peer. The fix: attach a profile, on both ends.
  • The negotiated timers are not the configured ones. The local profile asks for 50 ms but the far end will only accept 300 ms, so that is what is transmitted. The evidence, again, is the negotiated values rather than the configuration. The fix is a conversation with the peer, not another local change.

Rollback

BGP+BFD changes are configuration changes. The standard rollback paths:

  • rollback N; commit; save to revert any configuration changes.
  • delete protocols bgp neighbor <ip> bfd to disable BFD on a BGP peer.
  • delete protocols bfd profile <name> to remove a profile.
  • delete protocols bfd peer <ip> to remove a peer.

The operator who enables BFD should know how to disable it. The canonical pattern: enable BFD, validate the session is stable, then enable BFD on additional peers.

Production discipline

Cross-course references

The Linux course’s XIX-Linux-NetFoundations covers the kernel UDP stack. The OPNsense course’s XXX-OPNsense-DynamicRouting covers the equivalent FRR BGP+BFD on the firewall side. The BGP lessons vyos-xxiv-01-bgp-config and vyos-xxiv-03-bgp-timers cover the BGP configuration and hold-time. The lesson vyos-xxxii-01-bfd-concept covers the BFD protocol; vyos-xxxii-02-bfd-config covers the BFD configuration.

Quiz

Knowledge check · 4 questions

  1. Q1. An operator wants BFD on a BGP peer with a 50 ms interval and a 3x detect multiplier. Which configuration achieves it on VyOS 1.5?

  2. Q2. When BFD is enabled on a BGP peer, a link failure is detected by BFD and the session is reset long before BGP's 180-second hold timer would have expired.

  3. Q3. An operator configures BFD on a BGP peer with the `FAST` profile (50ms interval, 3x multiplier). The BGP session is in Established. The operator wants to verify that BFD is actually detecting failures. How does the operator test?

    The operator wants to verify that BFD is active and detecting failures. The available evidence: `show bfd peer <ip>` for the session state and the negotiated timers; `show ip bgp neighbors <ip>` for whether bgpd registered the session; and a destructive test that filters BFD packets and observes how fast the BGP session drops.

  4. Q4. An operator enables BFD on a BGP peer with a FAST profile (50 ms transmit, 50 ms receive, multiplier 3). The BGP session flaps every 1-2 seconds. `show ip bgp summary` shows the BGP session flapping on that cadence, and `show bfd peer 192.0.2.2` shows the BFD session flapping on the same one. What is the most likely cause and fix?

    The BFD interval is 50ms (20 packets per second per direction). The link or the peer cannot sustain this rate. The BFD session flaps; the BGP session follows. The fix is to increase the BFD interval to match the link's capability.

Passing score: 75%. Answers are checked in this browser.