Skip to content
Thomas Mangin edited this page Aug 16, 2026 · 6 revisions

Pre-Alpha. This page describes behavior that may change.

Ze implements RFC 7854 BMP in both directions: as a receiver (accepting feeds from routers) and as a sender (streaming state to collectors). Adj-RIB-Out support per RFC 8671 is included.

Configuration

Receiver

The receiver listens for TCP connections from BMP-enabled routers:

environment {
    bmp {
        enabled true;
        server default {
            ip 0.0.0.0;
            port 11019;
        }
        max-sessions 100;
    }
}
Field Default Description
enabled false Enable BMP receiver.
server - Named listener endpoints (same pattern as SSH/web).
port 11019 Listen TCP port (IANA assigned for BMP).
max-sessions 100 Maximum concurrent BMP sessions (1-1000).

Multiple listeners are supported. Port conflicts with other ze listeners are detected at config commit time.

Sender

The sender connects to external BMP collectors:

bgp {
    bmp {
        sender {
            collector monitoring-station {
                address 10.0.0.100;
                port 11019;
            }
            route-monitoring-policy pre-policy;
            loc-rib true;
            statistics-timeout 0;
        }
    }
}
Field Default Description
collector - Named collector endpoints.
route-monitoring-policy all pre-policy (Adj-RIB-In), post-policy (Adj-RIB-Out, RFC 8671), or all.
loc-rib false Stream local RIB best-path changes as Loc-RIB Route Monitoring (RFC 9069, Peer Type 3).
statistics-timeout 0 Seconds between statistics reports (0 = disabled).

The sender reconnects automatically with exponential backoff (30s to 720s).

CLI commands

Command Description
ze show bmp sessions Active BMP receiver sessions (router address, sysName, uptime).
ze show bmp peers Monitored BGP peers (AS, BGP ID, up/down status).
ze show bmp collectors Sender collector connection status.
ze show bmp rib Show all BMP-monitored routes.

Protocol details

Ze handles all 7 BMP message types:

Type Receiver Sender
Initiation Parses sysName/sysDescr Sends ze identity on connect
Termination Closes session cleanly Sends before disconnect
Peer Up Tracks monitored peer Sends on BGP Established
Peer Down Marks peer down Sends on BGP session close
Route Monitoring Decodes inner BGP UPDATE Wraps received/sent UPDATEs
Statistics Report Stores per-peer counters Periodic (if configured)
Route Mirroring Logs raw BGP PDUs Not implemented (follow-up)

Adj-RIB-Out (RFC 8671)

The sender wraps sent BGP UPDATEs as Route Monitoring with O+L flags (post-policy). The route-monitoring-policy controls which direction(s) are streamed.

Loc-RIB monitoring (RFC 9069)

Setting loc-rib true on the sender streams the router's own best paths (post best-path selection) to collectors, in addition to the Adj-RIB-In/Adj-RIB-Out feeds. Ze subscribes to the RIB's best-change events and reconstructs a Route Monitoring UPDATE for each change, carrying a Loc-RIB per-peer header (Peer Type 3):

  • The Peer Address and Peer AS are 0 (not applicable to a Loc-RIB), and the Peer BGP ID is the local router-id.
  • Exactly one Loc-RIB Peer Up is sent per RIB instance, before the first Route Monitoring, with zero-length sent/received OPENs.
  • Enabling monitoring triggers a full-table replay, so a collector that connects later still receives the current Loc-RIB, not just changes from that point on.
  • A Loc-RIB Peer Down is sent on shutdown to signal the end of monitoring.

Every connection is a fresh session, and the dump always closes

A BMP session carries no state across TCP connections, so a collector that connects, or reconnects after a drop, is told everything again: Initiation, a Peer Up for every established BGP peer, then (with loc-rib true) the Loc-RIB Peer Up, a full fresh table dump, and an End-of-RIB marker for every family the dump owes. The families are IPv4 unicast and IPv6 unicast.

A family the dump carried no route for still gets its marker, so a table with IPv6 populated and IPv4 empty closes both, and a wholly empty Loc-RIB closes both as well. RFC 4724 section 4 requires the marker "including the case when there is no update to send" for an address family, and RFC 7854 section 5 imports that definition for the BMP dump. Without it a collector cannot tell an empty table from a dump still in flight.

Each dump carries a correlation token that the RIB echoes back on every batch it produces, and dumps are serialized, so two collectors that reconnect together each get a complete dump of their own. Ze closes a family only for a batch whose token matches. A replay another subsystem asks for still fans out to every collector as Route Monitoring, because those routes are real, but it closes no family.

Reconnection is not immediate: after a connection ends Ze waits out its reconnect interval before redialing, so a flapping collector cannot drive a dump loop.

A slow collector cannot stall BGP

Nothing that produces a BMP message writes to the collector socket. Each message is copied into that collector's transmit queue, and the session's own goroutine drains it, so an unresponsive collector costs the BGP RIB a memory copy rather than a blocking write.

The queue is bounded in bytes, 256 MiB per collector, sized to absorb a full Loc-RIB dump. The bound is not what catches a collector that stops reading outright: the drain's per-write deadline catches that one in seconds, long before 256 MiB accumulates. The bound bites for the other shape, a collector that keeps reading but steadily slower than Ze produces, where every write succeeds and it is the backlog that grows. In either case Ze logs bmp: collector connection stalled, resetting session and resets the session with a plain TCP close, with no Termination message, because the session is abandoned rather than shut down. The collector's next connection gets a complete fresh session. A message is never silently dropped: either it is delivered, or the session that owed it is reset.

Stopping a collector session is different. It sends a Termination message (RFC 7854 section 4.5) and then closes the TCP connection. When a socket write is already in flight to a collector that is not reading, Ze gives it one second and closes anyway rather than delaying the shutdown of the other collectors.

Loc-RIB Route Monitoring carries ORIGIN, AS_PATH, and NEXT_HOP with the NLRI. The best-change feed does not carry communities or LOCAL_PREF, so those attributes are absent from the Loc-RIB stream (a documented fidelity limit: RFC 9069 forbids a RIB back-door for the full attribute set).

Looking glass integration

When the BMP receiver is enabled, monitored routes are stored in the RIB under a separate "bmp" protocol namespace. These routes are visible through dedicated looking glass endpoints and CLI commands but never enter best-path selection or the FIB.

API endpoints

Endpoint Description
GET /api/looking-glass/protocols/bmp List BMP-monitored peers.
GET /api/looking-glass/routes/bmp/{name} Routes from a specific BMP peer.

The {name} parameter is the composite peer key in <router>:<peer-address> format (e.g., 10.0.0.1:12345:192.168.1.1). Responses follow the birdwatcher format for compatibility with Alice-LG.

Route lifecycle

  • Injection: Route Monitoring messages inject BGP UPDATE routes under a BMP-specific ProtocolID with composite keys <router>:<peer-address>.
  • Peer Down: All routes for the monitored peer are withdrawn.
  • Session disconnect: All routes for all peers of that router are withdrawn.
  • Best-path isolation: BMP routes are stored under a separate ProtocolID. The best-path algorithm only iterates BGP peers, so BMP routes are automatically excluded with zero filter code.

BMP routes are separate from BGP routes: ze bgp rib show excludes BMP-monitored routes, and ze show bmp rib excludes real BGP routes.

Limitations

  • Peer Up messages contain minimal synthetic OPENs built from AS metadata. Capabilities are not reflected.
  • Per-NLRI ribout dedup is not yet implemented; all UPDATEs are forwarded as-is.
  • Loc-RIB Route Monitoring (RFC 9069) omits communities and LOCAL_PREF, which the best-change feed does not carry.
  • Route Mirroring encoding on the sender side is not implemented.

See also

Adapted from main/docs/guide/bmp.md.

Home

About

First Steps

Configuration

Operation

Interfaces

Plugins

Plugin Development

Chaos Testing

Blueprints

Development

Reference

Clone this wiki locally