Enabling BMP in Bird 2.17.5

'Claude, fix my prod pipeline. No mistakes.'


Let's get into it. I wanted to add BMP to my fleet of Debian-based routing nodes so I could send the BMP data to Akvorado, my existing netflow/sflow collector. I created the following file in my repository:

### bmp.conf.j2
protocol bmp {
    station address ip {% if bmp_station_address %}{{ bmp_station_address }}{% endif %} port {% if bmp_station_port %}{{ bmp_station_port }}{% endif %};
    monitoring rib in pre_policy yes;
    monitoring rib in post_policy yes;
}

If you don't speak native Jinja (like me), this might look like a mess of variables - because it is. Below is what Bird's example looks like, sourced from bird v2.17.5's BMP documentation. Non-Jinja speakers can enjoy plain, human-readable configuration:

protocol bmp {
    # The monitoring station to connect to
    station address ip 198.51.100.10 port 1790;

    # Monitor received routes (in import table)
    monitoring rib in pre_policy;

    # Monitor accepted routes (passed import filters)
    monitoring rib in post_policy;

    # Allow only 64M of pending data
    tx buffer limit 64;
}

For reference, my Jinja template renders out into the following:

protocol bmp {
    station address ip fe80::0123:4567:8900 port 10179; ## real ip hidden
    monitoring rib in pre_policy yes;
    monitoring rib in post_policy yes;
} 

and in case you're wondering 'does removing the yes make any difference'?

root@onca-pl-rt02:/etc/bird# cat bmp.conf 
protocol bmp {
    station address ip fe80::0123:4567:8900 port 10179;
    monitoring rib in pre_policy;
    monitoring rib in post_policy;
}
root@onca-pl-rt02:/etc/bird# birdc conf
BIRD 2.17.5 ready.
Reading configuration from /etc/bird/bird.conf
/etc/bird/bmp.conf:1:10 syntax error, unexpected CF_SYM_UNDEFINED

it does not. Onto the fix! It turns out the fix was already implemented in 3.x, but the fix was never backported to the 2.x code (at least not as of the time of writing, 2026-08-18). BMP support was added briefly, removed, and was never re-added. This change is byte-for-byte the same as the fix implemented in 3.x.

on line 322 of configure.ac

# this line should be on line 322
all_protocols="$proto_bfd babel bgp mrt ospf perf pipe radv rip rpki static"

# change it to this (add bmp right  V--- THERE)
all_protocols="$proto_bfd babel bgp bmp mrt ospf perf pipe radv rip rpki static"

Now, once I had two of my European [read: nonessential] routers running this newly patched version of bird, it was time to make sure that bmp1 was up and running... well, something like that, anyways. birdc show protocols all bmp1 showed it was still in an unconnected/waiting state. I checked Akvorado and I didn't see any BGP attributes in the flows, so I thought about the end-to-end chain and my security posture, which pointed me at one place: my local site firewall (doing its job1). One quick policy change to permit tcp/10179 inbound to fe80::0123:4567:8900 and BMP data started flowing immediately.

root@miit-pl-rt01:/etc/bird# birdc show protocols all bmp1
BIRD 2.17.5 ready.
Name       Proto      Table      State  Since         Info
bmp1       BMP        ---        up     2026-08-18 20:44:05  Established
  Station address:    fe80::0123:4567:8900
  Station port:       10179
  Pending TX:               0  B (limit 1024.0 MB)
  Session TX:              36  B
  Total TX:                36  B

After a bit of role mangling to ensure that this wouldn't immediately brick my entire fleet (only the two eurorouters temporarily), I slowly deployed this to production, router by router, just to be safe.

a screenshot of a Zabbix widget titled 'backbone icmp' showing several drops within the last ~6 hours where each router was briefly inaccessible during a package install/reconfigure

Current Status

Bird v2.17.5-bmp1 is installed, pinned, and operating across my entire fleet. BMP is also operational:

[onca-pl-rt02] bmp1       BMP        ---        up     2026-08-18 22:23:56  Established
[abva-pl-rt02] bmp1       BMP        ---        up     2026-08-18 21:22:57  Established
[kcmo-pl-rt01] bmp1       BMP        ---        up     2026-08-18 21:35:53  Established
[fmca-pl-rt02] bmp1       BMP        ---        up     2026-08-18 21:51:13  Established
[amnl-pl-rt01] bmp1       BMP        ---        up     2026-08-18 21:23:12  Established
[miit-pl-rt01] bmp1       BMP        ---        up     2026-08-18 20:44:05  Established

If/when this patch is backported to bird2, I will happily remove my workaround for this issue. I am hoping bird3 is tested as stable and I can simply move to a more modern codebase - maybe that will be the next test for miit-pl-rt01 - but that will be another day. It's bedtime for me. Thanks for following along =)


  1. I manage firewalls professionally for $dayjob. I hear quite often 'it's a firewall problem'. Sometimes, sure, a L7 NGFW is prone to all sorts of changes and tweaks at the behest of The Vendor; but usually the firewall is successfully accomplishing its intended purpose: dropping unpermitted traffic. If you did not request your traffic to be permitted, that is not my problem =)

3