Repository navigation
Conversation
…tion ADR 023 supersedes ADR 001: the GoBGP sidecar is replaced by rustbgpd driven over gRPC (InjectionService.AddFlowSpec/DeleteFlowSpec, RibService.ListFlowSpecRoutes, NeighborService.GetNeighborState) behind the unchanged FlowSpecAnnouncer trait. Crate embedding - what ROADMAP planned - is not available: rib/transport/api are publish = false, rustbgpd's own embedding doc says "never publish as a library: transport, api, ...", and the peer/RIB orchestration is daemon-private. Embedding would also drop the fail-open property of ADR 003, which relies on the speaker being a separate process. ADR 024 records the decision to migrate to loco-rs in stages with the MSRV bump accepted: a loco shell hosting the existing axum router first, then data layer, controllers and batteries, with explicit parity decisions (auth, WebSocket, metrics, config hot reload, prefixdctl, scheduler). ROADMAP: the rustbgpd milestone is rewritten for the gRPC shape (additive announcer -> parity/validation -> remove GoBGP), and a loco-rs migration milestone is added. ADR 007's trait sketch is corrected to the shipped signatures (list_active/session_status) and the ADR count references updated.
Two corrections from the rustbgpd-side review of the cited API surface: - Drop the EventService.WatchEvents "benefit": rustbgpd's event history covers unicast only, and prefixd does not consume a pushed stream at all - its reconciliation is the ADR 011 poll-and-converge loop (30s default, reading the FlowSpec view). Recorded explicitly so nobody builds a dependency on events. - Replace it with what the controller contract actually guarantees: AddFlowSpec is an upsert that always succeeds (reconciliation re-announce is safe), while deleting an absent rule returns NOT_FOUND and must be treated as drift.
rustbgpd decided (LAN-1961, option B) to qualify and promote the three controller RPCs into the v1 inventory before v1.0, scoped and staged behind the advertised view (LAN-1962) and the documented add/delete contract (LAN-1963). Record that in ADR 023 so the version pin reads as a transitional measure with a review trigger on every rustbgpd minor, not as a permanent constraint.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Records the two architecture decisions from the 2026-09-28 research sweep. Docs only — no code, no behaviour change.
ADR 023 — Drive rustbgpd over gRPC instead of embedding its crates (supersedes ADR 001)
ROADMAP.mdplanned to embedrustbgpd-rib+rustbgpd-transportin-process. That is not available:crates/rib/Cargo.toml:2andcrates/transport/Cargo.toml:2arepublish = false(likewiseapi,telemetry,policy,evpn,event-history,bmp,mrt,cli,bfd).docs/reference/embedding.md:579: "Never publish as a library: transport, api, evpn, evpn-linux, the daemon binary";:577—ribis "not ready to be a stable external API in alpha";:325-326and:688-689name gRPC ("Shape A") as the recommended production embedding.PeerManager,RibManager::run, listener/config wiring) is daemon-private;src/lib.rsexports nothing outsidebench-internals.The decision: keep the
FlowSpecAnnouncertrait (ADR 007) and swap the GoBGP gRPC client for a rustbgpd one —announce→InjectionService.AddFlowSpec,withdraw→DeleteFlowSpec,list_active→RibService.ListFlowSpecRoutes,session_status→NeighborService.ListNeighbors. rustbgpd shipsexamples/ddos-mitigation/config.tomldescribing exactly this topology and naming prefixd. Caveat recorded: those FlowSpec RPCs areexplicitly_outside_v1(docs/reference/v1-stable-surface.json:180), so the version gets pinned and its changelog tracked.ADR 024 — Migrate to loco-rs in stages (MSRV bump accepted)
Owner decision: loco is the target framework and the MSRV bump is fine. The ADR records the costs accepted (MSRV 1.85 → 1.94, SeaORM 2.0 on sqlx 0.9 alongside the current sqlx 0.8 during the transition, a framework with breaking changes in both 1.1 and 1.2) and the parity decisions that survive migration:
axum-login+tower-sessions(ADR 008) — loco ships JWT/API-key only/openapi.jsonroute (loco-openapistill targetsloco-rs ^0.16)prefixdctlstays a standalone binarytokiointerval task — loco's scheduler shells out per firingPhases: (0) MSRV + pin, (1) loco shell mounting the existing
axum::Routerviaafter_routes— zero behaviour change, full suite green, (2) data layer resource-by-resource behind theRepositoryseam, (3) handlers → controllers, (4) batteries (Postgres job queue for alerting), (5) cleanup. Estimated 100-170 person-days for the orthodox full path, so the sequencing rule is explicit: do not start phases 2-3 while the rustbgpd swap is mid-flight.Also in this PR
Superseded by ADR 023, original text kept as the historical record.list_active/session_status,Result<()>); the plannedRustBgpdAnnounceris named as such rather than as an existing type.ROADMAP.md→ rustbgpd milestone rewritten for the gRPC shape (additive announcer → parity/validation → remove GoBGP), new loco-rs migration milestone, and the dependency-cadence gate no longer names GoBGP exclusively.No CHANGELOG entry on purpose: this is decision documentation, and both open PRs (#148, #149) already touch
[Unreleased]— adding a third writer invites conflicts.Linear: LAN-1945 (swap decision, with LAN-1947/1948 as children) and LAN-1946 (loco decision, with LAN-1960 as the Phase 0+1 step); LAN-1957 re-scoped to the loco job queue.