Linux FRR runnign BGP with BFD doesn't cooperate with RouterOS (7.18 and 7.20)

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-mode profile on FRR. It sometimes eventually settles, but only after flapping ~7 times over ~35 s. Not acceptable.

  • Enabling RouterOS use-bfd first onto an already-stable BGP, then adding FRR bfd. Reaches Up and looks fine - until the first flap, then it oscillates again. Not robust.

  • Decoupling on the FRR side - a standalone bfd peer with BGP not tied to it (no neighbor 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 lan0
    

    This 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/session shows state-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.

I can reply to myself because its an important finding.

FRR 10.7 resolves the problem.

This was a pretty big deal, because with L3HW Mikrotik CRS series makes a very attractive BGP Top of The Rack 10G line rate router for a homelab, but with most poplular load balancers for k8 preferring FRR than BIRD it was a real pain to have to use BIRD.

But I;ve managed to get it working with FRR 10.7.

Also my description has a mistake. The problem was not caused by oscillation, but the dicrepancy.

Router OS would bring up BGP first and then BFD.

FRR would want to bring up BFD and only if that connected would bring up BGP.

So BFD connecting was a prerequisite for BGP, while RouterOS wanted BGP working first. But as I say. It is corrected in FRR 10.7 on both routerOS 7.18 and 7.20

Hi @Luk5566 ,

can confirm - FRR 10.7.0 resolves this. We run it successfully with BGP+BFD against RoS 7.23.1 and newer.
For our setup FRR is preferred over BIRD because of EVPN support.

Best Regards,
YAN