« All posts

bfdd vs XDP-based BFD Fast Path Under CPU Stress: 44 vs 0 Flaps

Under CPU stress, FRR's bfdd flapped 44 times in 120 seconds while an XDP-based BFD fast path stayed at zero flaps, matching line-card-level reliability.

An engineer benchmarked how BFD, the failure detector underlying BGP/OSPF, behaves under CPU load, since software BFD is known to false-flap and is the reason operators run conservative timers instead of aggressive ones. FRR's bfdd flapped 44 times in 120 seconds under timer/hrtimer stress, even though p99 latency stayed at a healthy 10.2ms — the maximum TX gap spiked to 970ms, a starvation pattern invisible to percentile-based monitoring. A minimal busy-loop userspace daemon survived the identical stress with zero flaps, pointing to bfdd's event-loop design rather than userspace itself as the culprit. Winning the scheduling priority war with SCHED_FIFO (chrt -f 90 plus core pinning) eliminated flaps but isn't realistic on a box actually forwarding traffic, and SO_TXTIME with the etf qdisc improved jitter without fixing liveness, while also dropping untimestamped packets like ARP.

An XDP-based fast path achieved zero flaps at normal process priority with a 12.5ms max gap. Because bpf_timer can't originate packets, the design rewrites incoming BFD frames in place and bounces them back via XDP_TX, letting the TX clock ride the peer's clock rather than the Linux scheduler's. Dead-peer detection runs via a 5ms bpf_timer sweep over the session map, while the RFC 5880 finite-state machine stays in userspace, keeping interoperability with stock FRR intact. A five-minute full-matrix soak test produced just one flap in eleven minutes, caused by a single softirq-delayed echo during an hrtimer storm that self-recovered in 3.8ms.

The results suggest commodity NICs running XDP can approximate hardware line-card BFD offload behavior in plain Linux. Testing was limited to a single IPv4 session without authentication in a VM testbed with one async-clocked peer; bare-metal validation is still pending. The next step is integrating this into FRR's distributed-BFD dataplane socket (bfddp) so it can plug in without patching bfdd itself.