feat(bgp): generate the BIRD iBGP config from blackwall's own config #188

Merged
vxfemboy merged 8 commits from sp-bird-gen into main 2026-07-12 03:54:50 +00:00
vxfemboy commented 2026-07-12 00:35:44 +00:00 (Migrated from github.com)

What

Deployment backlog #3 (issue #172, milestone M0): generate the BIRD-side config for the blackwall↔BIRD iBGP session from blackwall's own config, so prefix lists and session params aren't hand-maintained in both blackwall.conf and bird.conf.

Blackwall already runs a native injection-only iBGP speaker that peers with BIRD 2.x; this emits the reciprocal BIRD config as an include file — the operator adds include "blackwall.conf"; to bird.conf. It's orthogonal to the hand-maintained upstream/IX sessions (blackwall injects once, BIRD fans out).

Changes

  • render_bird_ibgp(policy) -> Result<String, BirdGenError> (blackwall-bgp, pure + byte-exact tested): emits OWN_V4/V6 defines + one MP-BGP protocol bgp blackwall session (ipv4/ipv6/flow4/flow6 channels). Unicast import filters use net ~ [prefix+]; flow filters use net.dst ~ [prefix+] (the correct BIRD2 form). MD5 → include "blackwall-secret.conf"; (secret never in the output — the generated include is non-sensitive/GitOps-safe); GTSM → ttl security on;.
  • rtbh local-addr=RtbhPolicy.local_addr (blackwall's BGP source), emitted as BIRD's neighbor AND bound by the speaker as its source — so the two sides match by construction.
  • blackwalld bird-config --config <cfg> prints the include.
  • Real-BIRD2 validation: a bird -p parse-check gate + a netns bird-gen.kdl lab gate that establishes the session and imports both a blackhole and a FlowSpec rule through the generated filters.

Multiple upstreams preserved

This only generates the blackwall↔BIRD glue + OWN defines. BIRD keeps all its hand-maintained upstream/IX sessions; blackwall injects once and BIRD re-advertises to every upstream via the existing per-peer export filters.

Quality

Subagent-driven: 5 tasks each spec+quality reviewed + a final opus whole-branch review (ready to merge). The Task 5 real-BIRD validation earned its keep — it caught two renderer bugs the byte-exact unit tests had codified as correct (a local/neighbor swap and a netnet.dst flow-filter bug that would have silently dropped every FlowSpec rule in production); both fixed and now proven live. clippy --workspace --all-targets --deny warnings clean; fmt clean; coverage 95.38%. No as casts.

## What Deployment backlog **#3** (issue #172, milestone **M0**): generate the BIRD-side config for the blackwall↔BIRD iBGP session from blackwall's own config, so prefix lists and session params aren't hand-maintained in both `blackwall.conf` and `bird.conf`. Blackwall already runs a native injection-only iBGP speaker that peers with BIRD 2.x; this emits the *reciprocal* BIRD config as an `include` file — the operator adds `include "blackwall.conf";` to bird.conf. It's orthogonal to the hand-maintained upstream/IX sessions (blackwall injects once, BIRD fans out). ## Changes - **`render_bird_ibgp(policy) -> Result<String, BirdGenError>`** (`blackwall-bgp`, pure + byte-exact tested): emits `OWN_V4/V6` defines + one MP-BGP `protocol bgp blackwall` session (ipv4/ipv6/flow4/flow6 channels). Unicast import filters use `net ~ [prefix+]`; **flow filters use `net.dst ~ [prefix+]`** (the correct BIRD2 form). MD5 → `include "blackwall-secret.conf";` (**secret never in the output** — the generated include is non-sensitive/GitOps-safe); GTSM → `ttl security on;`. - **`rtbh local-addr=`** → `RtbhPolicy.local_addr` (blackwall's BGP source), emitted as BIRD's `neighbor` AND bound by the speaker as its source — so the two sides match by construction. - **`blackwalld bird-config --config <cfg>`** prints the include. - **Real-BIRD2 validation**: a `bird -p` parse-check gate + a netns `bird-gen.kdl` lab gate that establishes the session and imports **both** a blackhole and a FlowSpec rule through the generated filters. ## Multiple upstreams preserved This only generates the blackwall↔BIRD glue + OWN defines. BIRD keeps all its hand-maintained upstream/IX sessions; blackwall injects once and BIRD re-advertises to every upstream via the existing per-peer export filters. ## Quality Subagent-driven: 5 tasks each spec+quality reviewed + a final opus whole-branch review (**ready to merge**). The Task 5 real-BIRD validation earned its keep — it caught two renderer bugs the byte-exact unit tests had codified as correct (a local/neighbor swap and a `net`→`net.dst` flow-filter bug that would have **silently dropped every FlowSpec rule in production**); both fixed and now proven live. clippy `--workspace --all-targets --deny warnings` clean; fmt clean; coverage 95.38%. No `as` casts.
Sign in to join this conversation.
No description provided.