The server now keeps what it learns in table::RibTable. The Adj-RIB-In actor is gone, and with it the queue every UPDATE from every session went through. - A session takes a number in the table when it is established and writes its UPDATEs into the table itself. Its routes are removed when it ends, on a blocking thread since that looks at every prefix; a session torn down without cleaning up still has them removed. - For every prefix the best route is chosen (RFC 4271 §9.1.2.2) as routes come and go. Nothing acts on the choice yet beyond showing it. - The UPDATE decoder hands over the bytes of the attributes it kept, so the table finds the attribute set from them without writing the attributes out again. On a session with two-octet AS numbers the bytes are not in the table's form, and the parsed attributes are used. - /api/routes/received marks the best route of each prefix and returns at most `limit` routes (default 1000): the table can hold hundreds of millions. /api/status has the totals, and the status page says how many it is showing. The time a route was received is no longer kept or shown. - The event stream reports changes of best route (best_changed, best_withdrawn) in place of every route received. Each client follows the table's journal with a reader of its own, from the moment it connects: table::RibTable::reader_from_now. - Metrics: bgp_rib_routes, bgp_rib_prefixes, bgp_rib_attribute_sets and bgp_rib_journal_entries replace bgp_adj_rib_in_routes. - A line is no longer logged at INFO for every UPDATE sent or received; a full table is a million of them. They are at DEBUG. - A table with no room for another peer ends the session with Cease / Out of Resources. Four peers sending a synthetic full table each over TCP, 4.9 million routes: 0.80 s, against 4.76 s before. One peer: 0.45 s against 0.69 s. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
BGP
This crate provides the bgp binary, which runs the Border Gateway Protocol
daemon together with its read-only HTTP status interface.
cargo run -- path/to/config.textpb
The configuration format is defined in crates/server/proto/config.proto;
testdata/server.textpb is a worked example. The daemon is configured
entirely through that file: peers, and the routes it originates
(originate { prefix: ... }). There is no way to change either at runtime.
When http_endpoint is set the binary also serves:
| Path | Purpose |
|---|---|
GET /statusz |
Status page: configuration, peers and session state, originated and received routes, live event log |
GET /api/status |
Router ID, ASN, uptime and table sizes |
GET /api/config |
The configuration file as read at startup |
GET /api/peers |
Configured peers and established sessions |
GET /api/routes/local |
Originated routes |
GET /api/routes/received |
Adj-RIB-In contents |
GET /api/events |
Server-sent events for session and route changes |
GET /metricz |
Prometheus metrics |
Everything under it is read-only and unauthenticated. Bind it to loopback or put it behind a reverse proxy.
What it does today
It establishes sessions (both dialling configured peers and accepting connections, with RFC 4271 collision detection), announces its originated routes to every peer with itself as next hop, and records what peers send in an Adj-RIB-In. It does not select best paths, re-advertise received routes or program a forwarding table, and it has no import or export policy.
Trying it without a router
fake_peer is a minimal BGP speaker that connects to the daemon, announces a
prefix, prints every UPDATE it receives and, with --echo, re-announces each
received prefix back with its own ASN prepended (dropping NO_EXPORT routes).
That makes originated prefixes show up in the received table as if they had
travelled through a neighbouring AS:
cargo run -- testdata/server.textpb
cargo run -p bgp-integration-tests --example fake_peer -- \
--server 127.0.0.1:179 --asn 65001 --announce 203.0.113.0/24 --echo
Please refer to the other implementation crates in this repository where most of the actual implementation lives.
Warning: This is still very much a work in progress and is not yet ready for production use.