There is a 4 year old topic that mentions this here Mikrotik BGP ROS v7.2.3 to Linux FRR BGP Setup not working, no session, no routes but it only mentions a problem no real investigation or how to bypass it.
I wasted an entire day trying to get it working and I had to switch to BIRD (from FRR) in the end (worked on first try). So I'm writing this to warn people that FRR+RouterOS with BFD+BGP is not a good combination.
Here is a detailed description of what I tried and my conclusion. In short: Use BIRD
TL;DR: If you peer a RouterOS switch/router (use-bfd=yes) with a Linux box running FRR, BGP+BFD will come up once and then fall into permanent self-sustaining flapping the moment anything disturbs the session (a reboot, a clear, a link blip). It is not a timer-tuning problem and not the old FRR bug #4133 (that's fixed). It reproduces identically on RouterOS 7.18.2 and 7.20.8 with FRR 10.3. Swapping the Linux daemon to BIRD 2 - changing nothing on the RouterOS side - fixes it completely.
Setup
- Two peers over an L2 segment, eBGP, single-hop BFD (UDP/3784).
- RouterOS: 10.99.0.3, AS 65010
- Linux router: 10.99.0.2, AS 65000
- RouterOS: 7.18.2 (CRS309) and 7.20.8 (CRS317) - both tested, both behave the same.
- Linux: FRR 10.3 vs BIRD 2.17.5 (Debian 13 packages).
- Goal: a few-seconds BGP failover instead of the 30–180 s hold timer.
RouterOS side (identical in every test - only the Linux daemon changes)
/routing/bgp/connection
add name=peer remote.address=10.99.0.2 remote.as=65000 as=65010 \
local.role=ebgp connect=yes listen=no use-bfd=yes
/routing/bfd/configuration
add interfaces=all
Note: RouterOS needs both /routing/bfd/configuration ... interfaces=all and use-bfd=yes on the connection - with only one of them it silently never brings a BFD session up. As a sanity check, RouterOS <-> RouterOS BFD with this exact config is rock-solid (state=up, ~900 ms hold), so the RouterOS side is correct.
What happens with FRR
The obvious config:
router bgp 65000
no bgp ebgp-requires-policy
neighbor 10.99.0.3 remote-as 65010
neighbor 10.99.0.3 bfd
address-family ipv4 unicast
neighbor 10.99.0.3 activate
exit-address-family
This comes up fine on a first, quiet bring-up. But the moment the session is disturbed - the peer reboots, you clear ip bgp, a link flaps - it goes into permanent ~3–5 s oscillation and never recovers on its own. FRR logs, on a loop:
bfd state Up -> Down
%NOTIFICATION: sent to neighbor 10.99.0.3 6/10 (Cease/BFD Down)
... BGP re-establishes in ~2s ...
bfd state Up -> Down
... repeat forever ...
On the RouterOS side, /routing/bfd/session print detail shows state-changes incrementing continuously.
Things I tried that did NOT fix it
-
Relaxing the BFD timers (receive/transmit-interval 1000ms, detect-multiplier 5) and BGP
timers 3 9. No change - fast (300 ms×3) and slow (1 s×5) oscillate the same. It is not a timing problem. -
bfd ... passive-modeprofile on FRR. It sometimes eventually settles, but only after flapping ~7 times over ~35 s. Not acceptable. -
Enabling RouterOS
use-bfdfirst onto an already-stable BGP, then adding FRRbfd. Reaches Up and looks fine - until the first flap, then it oscillates again. Not robust. -
Decoupling on the FRR side - a standalone
bfd peerwith BGP not tied to it (noneighbor bfd):router bgp 65000 neighbor 10.99.0.3 remote-as 65010 bfd peer 10.99.0.3 local-address 10.99.0.2 interface lan0This is steady-state stable, but cold-start/reconnect still races: after a
clear, FRR shows BFD up while RouterOS shows down (discriminator mismatch), and because RouterOS can't decouple its BGP from BFD, it tears its own BGP and churns. Close, but not clean. -
Aligning RouterOS versions (7.18.2 vs 7.20.8). No difference - it's version-independent.
Why it happens (root cause)
It's a circular BGP<->BFD teardown:
- FRR tears BGP the instant BFD goes Up to Down (that's the intended fast-failover behavior).
- RouterOS keeps its BFD session alive only while its BGP session is up (BFD is a child of the BGP connection), and it also drops BGP on BFD-down - and there is no way to decouple them.
So any single disturbance becomes: BGP drops -> RouterOS drops BFD -> FRR sees BFD Up->Down -> FRR tears the just-re-establishing BGP -> RouterOS drops BFD again -> resonance, forever. RouterOS<->RouterOS is fine because both ends are equally "patient" and re-converge together; FRR's fast, asymmetric teardown breaks that symmetry.
(For the record: this is not FRR issue #4133 from 2019 - that one is genuinely fixed in 10.3; the teardown here fires only on a real Up->Down, not on a never-up session. This is a separate, still-present coupling problem.)
The fix: BIRD 2 (nothing changes on the RouterOS side)
Same RouterOS config, same wire, same switches - just replace FRR with BIRD:
router id 10.99.0.2;
protocol device { }
protocol bfd {
interface "*" { interval 1000 ms; multiplier 3; };
}
protocol bgp {
local as 65000;
neighbor 10.99.0.3 as 65010;
passive on; # RouterOS dials (connect=yes listen=no above);
# BIRD listens. Pick ONE dialer or you get the
# classic OpenSent connection-collision flap.
bfd on;
ipv4 { import all; export all; }; # add your own filters/policy
}
Results with BIRD 2.17.5 against both RouterOS 7.18.2 and 7.20.8:
- BGP Established + BFD Up, negotiated Interval 1.0 s / Timeout 5.0 s.
- Survives a full daemon restart cleanly - RouterOS
/routing/bfd/sessionshowsstate-changes=1(came up once and stayed). This is the exact scenario FRR fails. - Failover as expected: kill the router and RouterOS drops the session in ~3 s (multiplier 3 × 1 s) instead of waiting on the BGP hold timer.
BIRD's BGP<->BFD state machine re-converges cleanly with RouterOS where FRR's does not. If you want BFD with RouterOS and a Linux routing daemon, use BIRD.
Tested on RouterOS 7.18.2 (CRS309) + 7.20.8 (CRS317), FRR 10.3, BIRD 2.17.5, single-hop BFD, eBGP.