Configuring BFD with FRRouting on Linux: Sub-Second Link Failure Detection for OSPF and BGP

Network tutorial - IT technology blog
Network tutorial - IT technology blog

Real-World Scenario: When the Physical Link Stays Up but Traffic Completely Drops

At 2:00 AM, PagerDuty blared incessantly due to widespread backend API timeouts. I scrambled to SSH into the Ubuntu gateway in the datacenter. Both BGP and OSPF sessions in FRRouting still showed green, reporting Established and Full states. Yet, actual throughput had plummeted to 0 Mbps.

The culprit turned out to be an optical media converter on an intermediate switch with a frozen microcontroller. The network port connected to the server NIC still had power and the link light was solid green. As a result, the Linux kernel had no idea the upstream fiber link was dead. Traffic was blindly forwarded straight into a black hole.

The bottleneck lies in the default health-check mechanisms of standard routing protocols:

  • OSPF: A 10-second Hello timer with a Dead timer of up to 40 seconds. It takes nearly a full minute for the network to reroute.
  • BGP: Default Keepalive is 60 seconds with a Hold timer of 180 seconds. That means traffic drops for three whole minutes before the BGP router realizes the neighbor is dead.

Can you reduce the OSPF Hello timer to 1 second? Yes, but router CPU usage will spike significantly with dozens of neighbors. OSPF simply wasn’t designed for sub-second, millisecond-level reaction times. That is where BFD (Bidirectional Forwarding Detection – RFC 5880) comes in.

BFD operates independently in the data plane over UDP (port 3784 for single-hop, 3785 for echo). BFD packets are lightweight—only a few dozen bytes—and consume less than 0.1% CPU. Its sole purpose is periodic handshaking at millisecond intervals. If three consecutive packets are dropped, BFD immediately tears down the OSPF/BGP neighbor adjacency. The entire routing table reconverges onto the backup path in under 300ms.

Installing FRRouting and Enabling the BFD Daemon

FRRouting (FRR) is the industry-standard routing suite on Linux and the modern successor to Quagga. To access all the latest bfdd features, install it from the official FRR repository rather than Ubuntu’s default apt repository:

# 1. Add official FRR repository
sudo apt update && sudo apt install -y curl gnupg2 lsb-release
curl -s https://deb.frrouting.org/frr/keys.asc | sudo gpg --dearmor -o /usr/share/keyrings/frrouting.gpg
echo "deb [signed-by=/usr/share/keyrings/frrouting.gpg] https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable" | sudo tee /etc/apt/sources.list.d/frr.list

# 2. Install FRR package
sudo apt update
sudo apt install -y frr frr-pythontools

By default, FRR only activates the core zebra daemon. Open /etc/frr/daemons to enable BFD, OSPF, and BGP:

sudo nano /etc/frr/daemons

Update the respective flags:

zebra=yes
bgpd=yes
ospfd=yes
ospf6d=no
ripd=no
bfdd=yes

Restart the service and enable it to start on boot:

sudo systemctl restart frr
sudo systemctl enable frr

Step-by-Step BFD Configuration for OSPF and BGP

The lab topology consists of two gateways: Router-A (IP: 10.10.10.1/30 on eth1) connected to Router-B (IP: 10.10.10.2/30 on eth1) through an intermediate L2 switch.

1. Access vtysh

Launch the unified FRR configuration shell:

sudo vtysh

2. Configure the BFD Peer

On Router-A, configure a 100ms transmit/receive interval with a detect multiplier of 3. If the router misses 3 consecutive packets (300ms), the connection is declared down:

configure terminal
bfd
 peer 10.10.10.2 interface eth1
  detect-multiplier 3
  receive-interval 100
  transmit-interval 100
 exit
exit

3. Bind BFD to the OSPF Interface

Add the ip ospf bfd command directly to the interface connected to the neighbor:

configure terminal
interface eth1
 ip address 10.10.10.1/30
 ip ospf area 0
 ip ospf bfd
exit

router ospf
 router-id 1.1.1.1
 network 10.10.10.0/30 area 0
exit

With just a single ip ospf bfd statement, the OSPF process automatically registers with bfdd to monitor neighbors on interface eth1.

4. Integrate BFD into BGP

For BGP (eBGP or iBGP), attach BFD directly to each designated neighbor:

configure terminal
router bgp 65001
 neighbor 10.10.10.2 remote-as 65002
 neighbor 10.10.10.2 bfd
exit

5. Synchronize Equivalent Configuration on Router-B

Apply the reciprocal configuration on Router-B to establish a two-way BFD handshake:

configure terminal
bfd
 peer 10.10.10.1 interface eth1
  detect-multiplier 3
  receive-interval 100
  transmit-interval 100
 exit
exit

interface eth1
 ip address 10.10.10.2/30
 ip ospf area 0
 ip ospf bfd
exit

router ospf
 router-id 2.2.2.2
 network 10.10.10.0/30 area 0
exit

router bgp 65002
 neighbor 10.10.10.1 remote-as 65001
 neighbor 10.10.10.1 bfd
exit

# Don't forget to save the configuration to disk
write memory

Note: The write memory command writes the entire running configuration to /etc/frr/frr.conf. If you skip this step, all changes will be lost upon reboot.

Verification & Real-World Failure Testing

After saving the configuration, verify that the BFD session has established successfully before deploying to production.

1. Verify the BFD Session

Inside vtysh, check the peer status summary:

show bfd peers

Expected output:

FRR-Router-A# show bfd peers

BFD Peers:
	peer 10.10.10.2 interface eth1
		ID: 219481023
		Remote ID: 198302194
		Status: up
		Uptime: 0 hour(s), 12 minute(s), 18 second(s)
		Diagnostic: ok
		Remote diagnostics: ok
		Receive Interval: 100ms
		Transmit Interval: 100ms
		Remote Receive Interval: 100ms
		Remote Transmit Interval: 100ms

The Status: up state and negotiated 100ms intervals confirm that both routers are actively exchanging BFD packets.

2. Verify OSPF and BGP Integration with BFD

Check the OSPF neighbor details:

show ip ospf neighbor detail

You should see the line: BFD enabled: status is Up. Next, verify BGP:

show ip bgp neighbors 10.10.10.2

Look for the expected output line: BFD enabled: yes, status: Up.

3. Failure Simulation (Chaos Testing)

How can you verify system behavior when an intermediate fiber link drops? Use iptables to block BFD UDP port 3784 on Router-B to simulate connectivity loss:

# Drop inbound BFD packets on Router-B
sudo iptables -I INPUT -p udp --dport 3784 -j DROP

Immediately monitor logs on Router-A:

show log monitor

The log messages appear almost instantaneously:

%BFD_PEER_DOWN: BFD peer 10.10.10.2 down
%OSPF-5-ADJCHANGE: Nbr 2.2.2.2 on eth1: Reset (BFD down)
%BGP-5-ADJCHANGE: neighbor 10.10.10.2 Down BFD session down

Exactly 300ms after the drop rule was applied, both OSPF and BGP immediately tore down the neighbor sessions. The routing table automatically rerouted traffic to the backup path. No more prolonged 40-second or 3-minute traffic outages. Once you remove the iptables rule (sudo iptables -D INPUT 1), BFD re-establishes within milliseconds, seamlessly restoring primary routes.

Share: