Released yyyy-mm-dd.
-
bmp-tcp-outwire format: the BMP per-peer headerpeer_distinguisherfield (RFC 7854 §4.2) now carries an 8-byte tag derived from the upstream router identity when rotonda is multiplexing multiple upstream BMP sessions into one downstream session. Previously this field was always zero for non-VPN peers, which made the standard(peer_ip, peer_distinguisher, rib_type)peer key collide whenever two upstream routers had a BGP session with the same neighbor. Downstream collectors that rely onpeer_distinguisher == 0for non-VPN peers will see the change; per RFC 7854 the field is opaque to receivers and must not be interpreted, only used as part of the peer key. Real RD/VRF distinguishers from VPN peer types are preserved unchanged.Operators who need the legacy behaviour can set
fan_in_peer_distinguisher = "off"in thebmp-tcp-outunit configuration. The default is"ingress_hash".
-
Added
netom-bmpdump, an offline BMP/BGP/EVPN decoder for PCAP and PCAPNG captures, with TCP reassembly, readable/colorized output, filters, and JSON export. The standalone workspace package is included in the DEB/RPM packages and runtime images. -
netom-cli show ip bgp detail(andshow ipv6 bgp detail) prints every attribute of each path: peer and AS, how it was learned (ingress, BMP, pre/post-policy, ADD-PATH path id), status and RPKI, origin, AS path, next hop including the IPv6 link-local, MED, local preference, atomic aggregate, aggregator, and standard, extended and large communities. An attribute the CLI has no name for is printed raw rather than hidden. It takes a prefix or one route filter (show ip bgp detail source bmp), and also endsshow ip bgp <prefix> detailandshow ip bgp neighbors <ip> routes detail. -
The
show ip bgproute table gains aPeercolumn, so two rows for the same prefix — one route heard from two neighbors, or pre- and post-policy copies from one — can be told apart. -
New
/api/v1/ribs/{ipv4,ipv6}unicast/best-path/{prefix}and.../best-path/{address}endpoints: the RFC 4271 section 9.1 decision process over the routes for one prefix, returning the winner, the ranked alternatives, and the step at which each of them lost, plus the routes that could not compete and why. The address form is a longest-prefix match, answering "which route would forward this". Ordering is routecore'spath_selection;strategy=skipMeddrops the MULTI_EXIT_DISC comparison. Selection runs at query time — the store's own path-selection hook takes one tiebreaker per prefix and so cannot express the per-peer steps d, f and g. Seedocs/best-path-selection.mdanddocs/rib-query-api.md. -
Best path excludes a route whose AS_PATH contains the session's local AS (RFC 4271 section 9.1.2), reported as
asPathLoop. The full path is scanned, so an AS inside an AS_SET or an AS_CONFED segment counts. Skipped for MRT-replayed peers, which record no local ASN. -
Best path implements RFC 5065 section 5.3 for confederations: AS_CONFED segments are excluded from the AS_PATH length, the neighbour AS for the MED comparison is the leftmost AS of the first AS_SEQUENCE past them (or the local AS for a wholly internal path), and a confederation peer counts as internal, so its LOCAL_PREF is weighed. Membership is inferred from the presence of AS_CONFED segments, which RFC 5065 requires to be stripped before a route leaves a confederation.
-
Best path reports equal-cost paths: anything tied with the winner through step e carries
equalCost, andcounts.equalCostsays how many there are. More than one means the winner was picked by a tie-breaker rather than preferred over the rest.netom-climarks those rows with=. -
AS_PATH loop detection reads AS4_PATH as well as AS_PATH (RFC 6793 section 4.2.3). On a session without four-octet ASN support a four-octet local AS appears in AS_PATH only as AS_TRANS, so its loops are visible nowhere else.
-
BGP session ingresses record the peer's BGP Identifier, so best-path step f works for sessions netom terminates itself rather than falling back to a placeholder. Requires the
remote_bgp_idaccessor added to the routecore fork. -
netom-cli:show ip bgp <prefix> bestandshow ip bgp best <address>, rendering the above with the conventional>best marker. -
BGP session ingresses now record the local ASN — from the unit's
my_asnfor sessions netom terminates, and from the Peer Up's sent OPEN for BMP-monitored peers — so a route can be classified as EBGP or IBGP for best-path step d. It also appears aslocal_asnin/api/v1/ingresses. -
netom-cli, a read-only operational CLI speaking router-style commands over the HTTP API:show ip bgp summary,show ip bgp neighbors [<ip>],show ip bgp [<prefix>],show bmp routers,show bmp router <id>,show ingresses,show version,show status,show running-configandshow filters, for IPv4 and IPv6, unicast and FlowSpec. Keywords may be abbreviated to any unambiguous prefix (sh ip b sum);helplists every command, and?lists the keywords that may follow, marking a line that is already runnable with<cr>. Runs one-shot, from repeated-eflags, from piped stdin, or at an interactivenetom>prompt with history and tab-completion.--jsonemits the raw API response, and Cisco-style| include/| exclude/| begin/| countfilters are supported. The endpoint comes from--url,$NETOM_URL, a config file'shttp_listen, orhttp://127.0.0.1:8080, with wildcard listen addresses rewritten to loopback. Seenetom-cli(1). -
New read-only HTTP API endpoints backing the CLI:
/api/v1/status(version, uptime, configured units and targets, RIB sizes, memory),/api/v1/config(the running configuration as TOML, with BGP TCP-MD5 keys and MQTT passwords redacted),/api/v1/filters(Roto script and entrypoints), and/api/v1/bgp/neighbors[/{addr}]. -
Per-peer BGP session status.
/api/v1/bgp/neighborsreports the RFC 4271 FSM state (Idle, Connect, Active, OpenSent, OpenConfirm, Established) forbgp-tcp-inpeers, alongside session uptime, UPDATE and NOTIFICATION counts, prefix counts, and the last error. Configured peers that have never established are now reported too — previously they had no ingress entry and so appeared nowhere. Peers observed through BMP are included in the same response, carrying the monitored router they were seen through. -
Native BGP sessions now record
session_up_timein the ingress register. Besides giving those peers an uptime, this fixes the per-peer header of the Peer Up thatbmp-tcp-outsynthesizes for restreamed native sessions, which previously carried a zero timestamp. -
Active mode for
bgp-tcp-inpeers: setconnect = trueon a peer to have netom initiate the TCP connection instead of only waiting for the peer to connect to the listener, for peers that will not accept us as a passive neighbour. Optionalremote_port(default 179),source_addr, andconnect_retry_secs(default 30) tune the outbound connection;md5_keyworks in this direction too, installed on the socket before connecting. Requires a peer keyed on an exact address; the listener stays active for these peers as well, so whichever side connects first wins. New metrics:bgp_tcp_in_connection_initiated_countandbgp_tcp_in_connect_error_count. Seedocs/bgp-active-mode.md. -
ADD-PATH (RFC 7911) support. Routes from ADD-PATH sessions (BMP-monitored and direct BGP) are no longer dropped: each
(session, path_id)is stored under its own path-child ingress (bgpPathin the/ingressesoutput, withpathIdandparentIngress), so multiple paths for one prefix from one peer coexist in the RIB.bmp-tcp-outrestreams them with full path fidelity — the synthesized Peer Up advertises the ADD-PATH capability for the session's negotiated v4/v6 unicast families and the re-encoded NLRI carry the path id, in the initial dump and live. Path-children disconnect, withdraw, and garbage-collect together with their session. FlowSpec ADD-PATH NLRI are still dropped (counted innetom_unsupported_nlri_dropped_total); MRT ADD-PATH subtypes (RFC 8050) remain unsupported. New metrics:netom_bmp_state_num_addpath_path_children_minted,netom_bmp_state_num_addpath_unknown_path_id_withdrawals, and register-population gauges includingnetom_ingress_register_addpath_path_children.
-
netom-cli show ipv6 bgpshowed-as the next hop of every IPv6 route: the API tags an MP_REACH next hop with its family ({"ipv6Unicast": …},{"ipv6LL": {"global": …, "linkLocal": …}}), which the CLI read as a plain string. It now shows the global address. -
The per-peer prefix count —
State/PfxRcdinnetom-cli show ip bgp summary,prefixesReceivedin the HTTP API, and the Adj-RIB-In gauges (RFC 7854 §4.8 stat types 7 and 9) in synthesized BMP Statistics Reports — counted every accepted NLRI instead of tracking the size of the peer's Adj-RIB-In. BGP's implicit withdraw re-advertises a prefix that is already in the RIB as a plain announcement, with no matching UNREACH to balance it, so the value climbed with churn and never converged: a full-view peer read roughly 3.4M prefixes after six hours on a table of about 1M.The gauge is now maintained by the RIB, which moves it only on a real transition of a
(prefix, peer)into or out of the store. Announcements that replace an existing route are counted asdupPrefixAdvertisements(stat type 1) instead, which was previously always zero — that counter is what makes the churn visible now that it no longer distorts the table size.
Released 2026-03-23.
- The web UI is back, and is completely overhauled.
Released 2026-02-09.
-
Added
filter[peerAddress]to the/ribsHTTP endpoint. -
HTTP API responses now include the
NextHoppart of theMP_REACH_NLRIpath attribute. -
HTTP API supports gzip compressed responses, and streaming/chunking of responses.
We would like to very much thank Rein Fernhout (LevitatingBusinessMan) and Denys Fedoryshchenko for their (ongoing) input and support in various ways.
Released 2025-09-30.
Breaking changes
-
The HTTP machinery has been refactored. The JSON endpoints are under different URLs and also their responses are slightly different from the old version. See the documentation for all the details.
-
Roto has been upgraded to version 0.7 which includes minor but breaking syntax changes. Most notably,
functionis nowfn. More details can be found in the Roto changelog. -
The Roto filters
bgp_in,bmp_inandrib_in_preare now all passed the newIngressInfoobject, containing information about the ingress of the message or route. This can be used to get the peer ASN and address for that specific session, for example. -
In Roto scripts, the
community(u32)function to create a new Community has been removed in favor of the more flexible and more readableCommunity.from(str)which takes either Well-known community names or the canonical form "AS12345:9999". Similarly, aLargeCommunity.from(str)is introduced, which takes the canonical form "AS211321:8888:9999".
New
-
For BMP ingresses, the Peer type, Peer distinguisher, and VRF/Table name are now tracked in the ingress register, and (if set) returned in HTTP API responses. (#128)
-
The new JSON API can filter based on user-defined Roto functions.
-
In Roto scripts, a new
metricsobject is introduced, enabling user-defined counters/gauges for the/metricsPrometheus endpoint. -
The RTR version is now configurable via
initial_versionon the rtr-tcp-in unit, defaulting to version 2. While the RTR protocol describes version negotiation and downgrading should happen automatically, this setting can be used in case of compatibility issues between Rotonda and the cache.
Bug fixes
-
The procedure to find known ingresses (e.g. when a BMP session is re-established) would not take into account the Peer type/distinguisher and VRF/Table name. This could cause mismatches, leading to routes being stored in the wrong spot and/or incorrectly overwriting other routes. Presumably, this only affected monitoring of Loc-RIBs. (#128)
-
The RTR version negotiation now properly responds with a lower version after receiving an Unsupported Version error from the cache.
Known issues
-
The web UI is very minimal in this version.
-
Multiple BMP streams with the same source IP address are currently not properly distinguished, and will show up as one single connected router but with the monitored BGP sessions for both streams.
-
The MRT endpoint is not (yet) available new HTTP API.
-
The built-in metrics on the
/metricsendpoint need work and are not to be trusted blindly at this point. -
Certain error responses from the JSON endpoints are not JSON-formatted yet.
Acknowledgements
We would like to very much thank Hans Kuhn for their (ongoing) input and support in various ways.
Released 2025-06-18.
With this release, Rotonda switches to version 0.6.0 of the roto library.
While many things have improved behind the scenes and under the hood, there are
no breaking or otherwise noticeable changes for Rotonda users.
An overview of the changes in roto 0.6.0 can be found
here.
Released 2025-05-20.
New
- VRP information coming in via RTR updates (both full Cache Resets and Serial responses) now triggers reevaluation of stored prefixes.
- The new
vrp_updatefilter can be used to act upon incoming VRP updates, for example for logging purposes. - The new
rib_in_rov_status_updatefunction can be used to act upon changes with regards to the ROV status of stored routes. - In roto, lists of ASNs and prefixes can be defined in the new
compile_listsfunction. These lists can be used from all other filters to match on, for example for logging and monitoring purposes. - A new
timestamped_printmethod is added on theoutputtype in roto.
Other changes
- The
file-outlogging target now periodically flushes to disk, to prevent information from waiting in the buffer in low traffic scenarios.
Released 2025-04-24.
Breaking changes
- Roto filter names have changed, as dashes are replaced with underscores.
New
- An RTR component is introduced, enabling Rotonda to receive RPKI information from RP software via the RTR protocol.
- Route Origin Validation is available on incoming routes in the 'rib_in_pre'
filter using a new
rpki.check_rov(..)method. The ROV result is included in responses from the RIB's HTTP endpoint.
Bug fixes
- In some cases, log entries would not actually be written to the output file.
- Under certain circumstances existing more specific prefixes, that were not covered by a requested prefix were returned. This is now fixed.
Known issues
- Performing ROV from roto scripts currently only works on incoming routes, using the VRP data that is available at that moment. New VRP data coming in via VRP does not trigger reevaluation of stored routes yet.
Other changes
- Parsing of certain BMP/BGP fields, specifically BGP Capabilities, are more forgiving to prevent reconnection loops.
Released 2025-01-30.
Breaking changes
-
In the embedded
rotothe define and apply blocks are gone. Users can now define variables and functions throughout the script. -
Arguments to filter-maps in
rotohave changed: some of them are now implicit.See the bundled example in
etc/examplesfor more details.
New
- In the
rotolanguage users can now assign variables and functions through the use ofletstatements anywhere in arotoscript. - In
roto, in addition to the breaking changes, there now is support for constants and strings. This enables, amongst other things, customizable logging. Several other helper methods on the various types, including ones to format fields to strings, are introduced. - The new
file-outtarget enables logging to a file in JSON or CSV format. Several helpers to log specific features are available, as well as the aforementioned custom logging via strings. - The
mrt-file-inunit can now be configured to process multiple files in sequence, and is able to process the most common message types seen inupdateMRT files. Furthermore, .bz2 compressed archives can be processed. A new API endpoint enables queueing of files. - Upon re-establishment of a previous BMP session, the previous session information is looked up and re-used. This should reduce memory use, and moreover, prevent confusing results when querying prefixes.
- BMP messages originating from a LocRib are now recognized and stored.
Bug fixes
- Several metric counters were not increased properly.
Known issues
- The "more_specifics" field in a query result may include wrong prefixes.
Other changes
- We no longer build binary packages for Debian 9 "Stretch" and Ubuntu 16.04 LTS "Xenial Xerus".
Acknowledgements
We would like to very much thank the following people for their (ongoing) input and support in various ways: Tobias Fiebig, Ties de Kock, Lisa Bruder, Ralph Koning, Bruno Blanes.
Released 2024-12-06.
Bug Fixes
- A non-monotonic clock measurement caused some threads to panic (under unknown conditions). These measurements now use a monotonic clock, that can not panic.
- The packaged filters.roto.example contained wrongly ordered parameters in its filter definitions, resulting in them not being executed. The orders are fixed and logging is added.
New
- The MRT component can now read gzipped files. Decompression is triggered for files with the '.gz' extension.
Other changes
- A zero-length
sysNamein a BMP InitiationMessage caused all subsequent messages to be marked as hard fails. We now warn on such empty values but proceed as usual, because thesysNameis not crucial to the process in any way.
Released 2024-11-21.
Breaking changes
This release contains mostly refactored components, aiming at better performance and reduced resource requirements.
Most notably, our filter language Roto is now compiled to machine code and
offers user friendly error messages.
Released 2024-01-19
First release