Hello,
I would like to extend BMP in BIRD 3 and I am writing before starting the work, following the "upfront consultation" advice in CONTRIBUTING.md and Maria's reply to Matthieu Gouel in January [1].
Why: today I monitor my routers by polling "show protocols all" over the control socket every 60 seconds. Every poll costs the daemon CPU, and what I get is a snapshot: a session that flaps between two polls, or a route that changes and changes back, is invisible, and anything I do see is up to a minute late. For route-level questions (what is actually in the table, what was dropped by RPKI or other filters, when did it change) I would need "show route" dumps, which do not scale. BMP already pushes Peer Up/Down and Adj-RIB-In pre/post-policy to my own collector; what I miss is:
- Loc-RIB monitoring (RFC 9069): the selected routes of the BIRD tables I choose to monitor, including non-BGP ones, as a stream instead of table dumps.
- Statistics Reports (RFC 7854 4.8, RFC 8671): periodic reports of the route counters BIRD already keeps, where they map to defined stat types, so most of my CLI polling can stop.
- Adj-RIB-Out (RFC 8671): what we announce to each peer, to verify export policy (RPKI invalids, leaks) from the collector. This is the one I need least; it is on the list because others asked for it here [3] and I would rather align with your TX plans than leave it out.
To avoid confusion: the current "post-policy" monitoring is Adj-RIB-In after import filters (L flag). Loc-RIB (peer type 3) and Adj-RIB-Out (O flag) do not exist in BIRD today.
How I would do it in thread-next, please correct me where I am wrong:
1. Loc-RIB. BIRD has no BGP Loc-RIB as such: a table is shared by all protocols and its best route is chosen by preference, not only by the BGP decision process. I would map one configured BIRD table to one Loc-RIB instance peer: channels on protocol bmp, one rt_export_subscribe of best routes per table through the existing bmp_add_table path, the table name in the VRF/Table Name TLV, the F flag when the channel has an export filter, and the local AS and BGP ID of the per-peer header taken from the bmp protocol configuration and the router id. Mandatory BGP attributes synthesized for non-BGP routes, which RFC 9069 explicitly allows in a Loc-RIB. Does this mapping match how you would present BIRD tables as Loc-RIBs?
2. Peer state. Whatever BMP needs beyond the current ea_bgp_* attributes (counters for statistics, VRF/RD for the RD Instance peer type and distinguisher, FSM event code for Peer Down) published by BGP in proto_state and read by BMP. I would like to agree on the attribute set before coding.
3. Statistics. A timer in BMP. The counters live in the BGP channel import and export stats on BGP's side, and they must not turn into a journal item per route update. Either BGP publishes a snapshot into proto_state on its own timer while some BMP instance wants statistics, or the counters become atomics that BMP's timer reads. I lean to the first; which fits your locking rules better?
4. Adj-RIB-Out, post-policy only; pre-policy Adj-RIB-Out is out of scope. bgp_ptx already exposes a struct rt_exporter as c->c.out_table with feed_net implemented, but there is no live journal push yet ("TODO: actually implement exports" in bgp_free_pending_tx). I would push on prefix add/withdraw in the ptx path, only when the exporter has subscribers, and let BMP subscribe out_table the same way it subscribes import tables today. Is this the merging of the BMP TX with the BGP TX data structures you mentioned in [1], and is anyone already working on it? This is the only hot-path change; the push sits behind a "has subscribers" check, documentation will say it needs export table and what it costs, and I will measure and post numbers. Its initial dump is one table per peer, so it depends on item 6.
5. Tests. I could not find BMP cases in bird-tools netlab master. I would write them (BIRD to collector: Peer Up, route monitoring pre/post/out, End-of-RIB after the initial dump, Loc-RIB, statistics). David mentioned a BMP lab test case in April [2]; if that exists somewhere I would rather build on it.
6. Initial dump pacing. bmp_check_routes walks the whole feed in one event run and nothing is written to the socket until it returns, so the entire Adj-RIB-In dump (one message per route, roughly 130 bytes each, times pre/post) sits in TX buffers before the first byte goes out. Above "tx buffer limit" the session is declared stalled and reconnected, which starts the same dump again; with a table larger than the limit this loops forever, logging "Connection stalled" each time. I would break out of the walk after N routes or when the TX backlog passes a high-water mark derived from the limit, reschedule the event and let the socket drain in between. The stall at the hard limit stays for a collector that really does not read. Two questions: do you prefer this local to BMP, or implemented generically as rt_export_retry_later (which is declared but not defined)? And a paused reader keeps journal items of the table alive; is there a bound you want on that lag? This one is independent of the rest and I can send it first as a standalone patch.
Questions:
- Is this direction acceptable for thread-next? What would you do differently?
- Patch order I have in mind: dump pacing (6), BGP state attributes, Loc-RIB, statistics, per-peer header, Adj-RIB-Out, docs, tests. Adj-RIB-Out can also be a separate round later if you prefer.
- Does any of this collide with your unpublished plans for BGP TX or BMP?
Thanks,
Taichi Aoki