An API-first BGP daemon in Rust, built for programmable route-server and control-plane use cases. gRPC is the primary interface for all peer lifecycle, routing, and policy operations. The config file bootstraps initial state; after startup, gRPC owns the truth. No restarts to add peers, change policy, or inject routes.
Status: public alpha. Feature-complete for the initial route-server and control-plane target. Dual-stack BGP/MP-BGP, Add-Path, GR/LLGR, RPKI/RTR, ASPA path verification, FlowSpec, BMP, MRT, and full gRPC/CLI management are implemented. Kernel FIB integration and broader router features remain future work. Validated with 1150+ workspace tests, fuzz targets, and 20 automated interop suites against FRR 10.3.1 and BIRD 2.0.12.
Alpha expectations: The config format and gRPC API are not yet frozen. Breaking changes are possible between minor versions. The daemon runs on Linux (the primary target); other platforms are not tested. See Project Status for details.
- API-first control plane -- full gRPC control surface across 7 services plus a thin CLI (
rustbgpctl) with colored tables, dynamic column alignment, and human-readable uptimes. Dynamic peer management, route injection, policy CRUD, peer groups, streaming events, and daemon control without restarts. - Explicit architecture -- pure FSM with no I/O, single-owner RIB with no locks, bounded channels between tasks. No
Arc<RwLock>on routing state. See ARCHITECTURE.md. - Dual-stack and modern protocol support -- MP-BGP, Add-Path, Extended Next Hop, Extended Messages, GR/LLGR/Notification GR, Route Refresh/Enhanced Route Refresh, FlowSpec, Route Reflector, large and extended communities.
- Operational visibility -- Prometheus metrics, BMP export to collectors, MRT TABLE_DUMP_V2 snapshots, structured JSON logging, per-peer counters.
- Evidence-driven correctness -- fuzz targets on the wire decoder, property tests on the FSM, automated containerlab interop against FRR and BIRD, extensive workspace tests, architecture decision records for every protocol and design choice.
- Reusable wire codec --
rustbgpd-wirehas zero internal dependencies and is independently publishable. Anyone building BGP tooling in Rust can use it without the daemon.
- DDoS mitigation platforms — FlowSpec + RTBH route injection from automation
- Hosting provider prefix management — API-driven customer prefix announcements
- Internet exchange route servers — transparent mode, Add-Path, RPKI, per-member policy
- SDN / network automation controllers — programmable BGP control plane
- Route collectors and looking glasses — structured data via gRPC, MRT, BMP
- Lab and test environments — clean API, structured logs, containerlab interop
See docs/USE_CASES.md for detailed deployment scenarios with architecture diagrams, example configs, and API workflows.
- Full general-purpose router deployments requiring FIB integration
- EVPN / VPN datacenter fabric overlays
- Environments that need the breadth of FRR's multi-decade feature surface
- Operators who want a CLI-first operational model
See docs/COMPARISON.md for a detailed feature comparison with FRR, BIRD, GoBGP, and OpenBGPd.
The fastest way to see rustbgpd in action. Spins up the daemon with an FRR peer that advertises sample IPv4 and IPv6 prefixes — no real routers needed.
cd examples/docker-compose
docker compose up -dOnce both containers are running (a few seconds):
# See the FRR peer come up
docker compose exec rustbgpd rustbgpctl -s http://127.0.0.1:50051 neighbor
# Browse the RIB
docker compose exec rustbgpd rustbgpctl -s http://127.0.0.1:50051 rib
# Live TUI dashboard — sessions, prefix counts, message rates
docker compose exec rustbgpd rustbgpctl -s http://127.0.0.1:50051 topPress q to exit the TUI. When you're done: docker compose down.
# Prerequisites: Rust 1.88+, protobuf-compiler
sudo apt-get install -y protobuf-compiler # Debian/Ubuntu
cargo build --workspace --release
# Binaries are at target/release/rustbgpd and target/release/rustbgpctldocker build -t rustbgpd .For running rustbgpd on a real host with real peers.
# Copy and edit the minimal example
cp examples/minimal/config.toml config.toml
$EDITOR config.toml # set your ASN, router ID, and peer addressThe minimal example sets runtime_state_dir to a user-writable path and
includes prometheus_addr for metrics. For a route-server deployment, start
from examples/route-server/config.toml instead. Full reference:
docs/CONFIGURATION.md.
# Validate config without starting the daemon
./target/release/rustbgpd --check config.toml
# Preview what a config reload (SIGHUP) would change
./target/release/rustbgpd --diff new-config.toml config.toml
# Start the daemon
./target/release/rustbgpd config.toml# The minimal example uses /tmp/rustbgpd as state dir, so point the CLI there:
export RUSTBGPD_ADDR=unix:///tmp/rustbgpd/grpc.sock
rustbgpctl health
rustbgpctl neighbor
rustbgpctl rib
rustbgpctl top # live TUI dashboardIn production with the systemd unit, the default UDS path
(/var/lib/rustbgpd/grpc.sock) matches the CLI default — no env var needed.
# Add a peer at runtime (persisted to config file automatically)
rustbgpctl neighbor 10.0.0.5 add --asn 65005
# Reload config after editing the file
kill -HUP $(pidof rustbgpd)
# Graceful shutdown (writes GR marker, notifies peers)
rustbgpctl shutdown
# Enable shell completions (bash example)
rustbgpctl completions bash > /etc/bash_completion.d/rustbgpctl
# Or use pre-generated: examples/completions/gRPC defaults to a local Unix domain socket. For remote access, prefer an
mTLS proxy — see examples/envoy-mtls/ and
docs/SECURITY.md.
docker run -d --name rustbgpd \
-v $(pwd)/config.toml:/etc/rustbgpd/config.toml:ro \
-v rustbgpd-state:/var/lib/rustbgpd \
-p 179:179 -p 9179:9179 \
rustbgpdOr use systemd with examples/systemd/rustbgpd.service.
Seven services cover the full operational surface:
| Service | RPCs | Purpose |
|---|---|---|
GlobalService |
GetGlobal, SetGlobal |
Daemon identity and configuration |
NeighborService |
AddNeighbor, DeleteNeighbor, ListNeighbors, GetNeighborState, EnableNeighbor, DisableNeighbor, SoftResetIn |
Peer lifecycle + inbound soft reset |
PolicyService |
ListPolicies, GetPolicy, SetPolicy, DeletePolicy, List/Get/Set/DeleteNeighborSet, Get*Chain, Set*Chain, Clear*Chain |
Named policy CRUD, neighbor sets, and global/per-neighbor chain attachment |
PeerGroupService |
ListPeerGroups, GetPeerGroup, SetPeerGroup, DeletePeerGroup, SetNeighborPeerGroup, ClearNeighborPeerGroup |
Peer-group CRUD and neighbor membership assignment |
RibService |
ListReceivedRoutes, ListBestRoutes, ListAdvertisedRoutes, ListFlowSpecRoutes, WatchRoutes |
RIB queries and streaming |
InjectionService |
AddPath, DeletePath, AddFlowSpec, DeleteFlowSpec |
Programmatic route and FlowSpec injection |
ControlService |
GetHealth, GetMetrics, Shutdown, TriggerMrtDump |
Health, metrics, lifecycle, MRT dumps |
# Stream route changes in real time over the default UDS listener
grpcurl -plaintext -unix /var/lib/rustbgpd/grpc.sock \
-import-path . -proto proto/rustbgpd.proto \
rustbgpd.v1.RibService/WatchRoutesFull API reference: docs/API.md
rustbgpd is intentionally built around:
- gRPC-driven control instead of a large interactive CLI surface
- A pure FSM crate with no I/O --
(State, Event) -> (State, Vec<Action>) - Single-owner routing state instead of shared mutable state across tasks
- Bounded channels for all inter-task communication -- backpressure, not locks
- Explicit protocol feature boundaries with ADRs and test-backed development
Designed around an API-first operating model similar to GoBGP, with a smaller and more explicit internal architecture.
| Example | Description |
|---|---|
examples/docker-compose/ |
Quick-start with Docker Compose — rustbgpd + FRR peer with sample routes |
examples/minimal/ |
Smallest working config — single eBGP peer |
examples/route-server/ |
IXP route server with RPKI, Add-Path, policy chains |
examples/ddos-mitigation/ |
FlowSpec + RTBH for automated DDoS mitigation |
examples/hosting-provider/ |
iBGP route injector for customer prefix management |
examples/route-collector/ |
Passive collector with MRT dumps and BMP export |
examples/envoy-mtls/ |
Remote gRPC access via Envoy mTLS proxy |
examples/systemd/ |
systemd unit file with security hardening |
- Default listener: Unix domain socket at
/var/lib/rustbgpd/grpc.sock— local-only, no TCP exposure - Optional read-only listeners: expose monitoring/query RPCs without exposing mutating control RPCs
- Remote access: prefer an mTLS proxy (Envoy example provided) over direct TCP
- Network controls: put gRPC on a management VLAN/interface and firewall it to known hosts
| Evidence | Details |
|---|---|
| Workspace tests | Unit, integration, and property tests (cargo test --workspace) |
| Wire fuzzing | libFuzzer harnesses on message and attribute decoders, CI smoke + nightly extended |
| Interop suites | Automated containerlab tests against FRR 10.3.1 and BIRD 2.0.12 |
| Protocol coverage | RFC 4271 FSM + UPDATE validation, MP-BGP, GR/LLGR, Add-Path, FlowSpec, RPKI, ASPA, Extended Messages, Extended Next Hop, Route Refresh/ERR |
| Architecture decisions | ADRs documenting every protocol and design choice (docs/adr/) |
# Run interop tests
containerlab deploy -t tests/interop/m4-frr.clab.yml
bash tests/interop/scripts/test-m4-frr.shSee docs/INTEROP.md for full procedures and results.
- No kernel FIB integration -- rustbgpd is a control-plane daemon, not a forwarding engine
- No EVPN, VPNv4/v6, or Confederation support
- No native gRPC TLS termination yet (prefer local UDS access or an mTLS proxy)
- No TCP-AO (RFC 5925) -- TCP MD5 and GTSM are supported
- Published bgperf2 benchmarks currently cover 10 peers × 1k prefixes, 2 peers × 10k prefixes, and 2 peers × 100k prefixes; churn and long-duration benchmark automation remain future work (see docs/BENCHMARKS.md)
Alpha — suitable for lab, IX route-server pilots, and programmable control-plane deployments where you are comfortable with an evolving API.
| Dimension | Current state |
|---|---|
| Target use case | IXP route servers, programmable BGP control planes, lab/test environments |
| Maturity | Public alpha (v0.6.x) |
| Supported OS | Linux (primary target). Requires CAP_NET_BIND_SERVICE for port 179. |
| Runtime | Rust 1.88+, single binary, no external dependencies except optional RPKI/BMP/MRT backends |
| Config stability | TOML format may change between minor versions; migrations documented in CHANGELOG |
| API stability | gRPC proto may add fields/RPCs; breaking changes documented in CHANGELOG |
| Not yet supported | Kernel FIB integration, EVPN, VPNv4/v6, Confederation, native gRPC TLS, TCP-AO |
| Tests | 1150+ workspace tests, fuzz targets, 20 automated interop suites (189 assertions) |
| Document | Content |
|---|---|
| docs/USE_CASES.md | Deployment scenarios: DDoS, hosting, IX, SDN, collector |
| ARCHITECTURE.md | Crate graph, runtime model, ownership, data flow |
| docs/DESIGN.md | Tradeoffs, protocol scope, rationale |
| docs/API.md | gRPC API reference with examples for every RPC |
| docs/CONFIGURATION.md | Config reference and examples |
| docs/OPERATIONS.md | Running in production: reload, upgrade, failure modes, debugging |
| docs/SECURITY.md | Security posture, firewall guidance, deployment tiers |
| docs/BENCHMARKS.md | Wire codec and RIB performance numbers, scaling analysis |
| docs/COMPARISON.md | Feature comparison with FRR, BIRD, GoBGP, OpenBGPd |
| docs/INTEROP.md | Interop test coverage and results |
| docs/adr/ | Architecture decision records (50 ADRs) |
| docs/RELEASE_CHECKLIST.md | Pre-release smoke matrix and release steps |
| ROADMAP.md | Remaining gaps and planned work |
| CHANGELOG.md | Release history |
| CONTRIBUTING.md | Development setup, code style, PR process |
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
