BFD for BGP
BGP is where BFD matters most, because its defaults are the slowest: a keepalive every 60 seconds, and a hold time of 180 seconds.
The lab replaces OSPF with eBGP: one session over each link, each side announcing its LAN. Two settings keep the measurement honest:
maximum-paths ebgp 1: VyOS would otherwise install both links as equal paths (ECMP), and a single ping flow could happen to hash onto the healthy one.- A weight of 100 on link A's session, on both routers, so both directions prefer link A. Without it, R2 picked link B for the return path, because FRR prefers the older of two otherwise equal eBGP routes.
Without BFD
Link A was cut at 08:45:33. h1 lost 1,506 of 2,100 pings: about 159 seconds of outage. R1 records why the session finally reset: Hold Timer Expired. On a real network that's nearly three minutes of black-holed traffic, during which nobody's monitoring sees an interface down.
The ping also counted errors: once R1's ARP entry for R2 expired, R1 started answering h1 with host unreachable.
With BFD
bfd profile FAST on each BGP neighbour (and neighbor … bfd profile FAST on R2). show bgp neighbors then shows the BFD session attached to the neighbour.
The same cut cost 10 pings: about a second. This time the session's last reset says BFD down initiated: BFD told BGP, and BGP tore the session down and switched to link B straight away.
Unlike OSPF's, BGP's BFD session stays listed while it's down, because the BGP neighbour still exists and keeps trying.
delete protocols ospf
set protocols bgp system-as '64501'
set protocols bgp parameters router-id '192.0.2.1'
set protocols bgp address-family ipv4-unicast network '198.51.100.0/25'
set protocols bgp neighbor 10.0.12.2 description 'R2 over link A'
set protocols bgp neighbor 10.0.12.2 remote-as '64502'
set protocols bgp neighbor 10.0.12.2 address-family ipv4-unicast
set protocols bgp neighbor 10.0.12.6 description 'R2 over link B'
set protocols bgp neighbor 10.0.12.6 remote-as '64502'
set protocols bgp neighbor 10.0.12.6 address-family ipv4-unicast
set protocols bgp address-family ipv4-unicast maximum-paths ebgp '1'
set protocols bgp neighbor 10.0.12.2 address-family ipv4-unicast weight '100'
set protocols bgp parameters log-neighbor-changes- Line 1: OSPF out, BGP in.
- Lines 5–10: One session per link, to the same neighbouring AS.
- Line 11: One path at a time, so the measurement doesn't depend on ECMP hashing.
- Line 12: Prefer link A.
- Line 13: Log session changes.
vyos@R1:~$ show bgp neighbors 10.0.12.2 | match "Hold time"
Hold time is 180 seconds, keepalive interval is 60 seconds- Line 2: A keepalive every minute; the session dies after three minutes of silence.
root@r1-container:~# date +%T; ip link set eth0 nomaster # cut link A in the middle; carrier stays up
08:45:33
root@h1:~# ping -i 0.1 -c 2100 -q 198.51.100.130 # started 5 s before the cut
PING 198.51.100.130 (198.51.100.130) 56(84) bytes of data.
--- 198.51.100.130 ping statistics ---
2100 packets transmitted, 594 received, +138 errors, 71.7143% packet loss, time 221330ms
rtt min/avg/max/mdev = 0.348/2.136/18.258/1.757 ms, pipe 30- Lines 1–2: The cut: link A is detached in the middle, so both routers keep carrier on their interfaces.
- Line 4: Ten pings a second from h1 to h2, started 5 seconds earlier.
- Line 7: 1,506 of 2,100 pings lost: about 159 seconds. The errors are R1's host unreachable replies once it gave up resolving R2 on link A.
vyos@R1:~$ show bgp neighbors 10.0.12.2 | match "Last reset"
Last reset 00:07:41, Notification sent (Hold Timer Expired)- Line 2: The hold timer expired: three minutes after the last keepalive.
set protocols bgp neighbor 10.0.12.2 bfd profile 'FAST'
set protocols bgp neighbor 10.0.12.6 bfd profile 'FAST'frr version 10.2.1_git
frr defaults traditional
hostname R2
no ipv6 forwarding
service integrated-vtysh-config
!
interface eth0
description link A to R1
ip address 10.0.12.2/30
exit
!
interface eth1
description link B to R1 (backup)
ip address 10.0.12.6/30
exit
!
interface eth2
description LAN2
ip address 198.51.100.129/25
exit
!
interface lo
ip address 192.0.2.2/32
exit
!
router bgp 64502
bgp router-id 192.0.2.2
no bgp ebgp-requires-policy
neighbor 10.0.12.1 remote-as 64501
neighbor 10.0.12.1 description R1 over link A
neighbor 10.0.12.1 bfd
neighbor 10.0.12.1 bfd profile FAST
neighbor 10.0.12.5 remote-as 64501
neighbor 10.0.12.5 description R1 over link B
neighbor 10.0.12.5 bfd
neighbor 10.0.12.5 bfd profile FAST
!
address-family ipv4 unicast
network 192.0.2.2/32
network 198.51.100.128/25
neighbor 10.0.12.1 weight 100
maximum-paths 1
exit-address-family
exit
!
bfd
profile FAST
exit
!
profile MULTIHOP
transmit-interval 1000
receive-interval 1000
exit
!
peer 192.0.2.1 multihop local-address 192.0.2.2
profile MULTIHOP
exit
!
exit
!- Lines 26–36: Two eBGP sessions, each with BFD and the FAST profile.
- Lines 38–43: The LAN and loopback, link A preferred, one path.
- Lines 46–58: Both profiles, and the multihop peer between the loopbacks.
vyos@R1:~$ show bgp neighbors 10.0.12.2 | match "BFD:|Detect|Status:"
BFD: Type: single hop
Detect Multiplier: 3, Min Rx interval: 300, Min Tx interval: 300
Status: Up, Last update: 0:00:00:12- Lines 2–4: Single-hop BFD, 300 ms × 3, up.
root@r1-container:~# date +%T; ip link set eth0 nomaster # cut link A in the middle; carrier stays up
08:56:27
root@h1:~# ping -i 0.1 -c 200 -q 198.51.100.130 # started 5 s before the cut
PING 198.51.100.130 (198.51.100.130) 56(84) bytes of data.
--- 198.51.100.130 ping statistics ---
200 packets transmitted, 190 received, 5% packet loss, time 20980ms
rtt min/avg/max/mdev = 0.379/1.586/7.926/0.974 ms- Lines 1–2: The cut: link A is detached in the middle, so both routers keep carrier on their interfaces.
- Line 4: Ten pings a second from h1 to h2, started 5 seconds earlier.
- Line 7: 10 pings lost: about a second.
vyos@R1:~$ show bgp neighbors 10.0.12.2 | match "Last reset"
Last reset 00:00:18, BFD down initiated (n/a)- Line 2: BFD told BGP the path was dead.
Check your understanding
Why are BGP's default timers so much slower than OSPF's?
- BGP sessions often cross networks and carry huge tables; flapping a session is expensive, so its defaults favour stability.
- BGP can't send keepalives more often than once a minute.
- BGP runs over UDP.
- Because BGP routes are always backed up by OSPF.