Skip to content

C2b-2: FlowSpec auto-mitigation wiring (persistence + config + CLI + daemon)#91

Merged
vxfemboy merged 5 commits into
mainfrom
sp-c-m2b2-flowspec-wiring
Jul 3, 2026
Merged

C2b-2: FlowSpec auto-mitigation wiring (persistence + config + CLI + daemon)#91
vxfemboy merged 5 commits into
mainfrom
sp-c-m2b2-flowspec-wiring

Conversation

@vxfemboy

@vxfemboy vxfemboy commented Jul 3, 2026

Copy link
Copy Markdown
Member

Closes #90. Completes sub-project C2b — makes the C2b-1 FlowSpec auto-mitigation core (#87) durable, configurable, and operable, mirroring the C1c RTBH control plane almost exactly.

What

  • Persistence (blackwall-state): 0005_flowspec migration — flowspec_rules active mirror (partial-unique on (dst,proto,dst_port) WHERE withdrawn_at IS NULL, no-downgrade manualauto upsert) + flowspec_requests intent log. Eight Store methods + impl blackwall_rtbh::FlowSpecJournal for Store. Active rules re-announce on daemon restart. f32 rate round-trips via rate::real (no as-casts).
  • Config (blackwall-core + blackwall-config): FlowSpecPolicy + a flowspec concentration=… max-flows=… rate=… max-rules=… hold-down=… ttl=… directive. Reuses the rtbh block's BGP peer + Policy.prefixes; rejected at parse time if no rtbh block is present, and rejects out-of-range selection tunables.
  • CLI (blackwalld): flowspec add/remove/list mirroring rtbh (eligibility checked before the DB write).
  • Daemon wiring: blackwalld flow builds a single-owner FlowSpecManager task alongside RtbhManager off the shared BgpHandle, rehydrates from list_active_flowspec, and feeds the collector a FanoutSink([Pg, SelectorSink]) so each detection routes to FlowSpec (concentrated) or RTBH (diffuse).

Verification

  • cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- --deny warnings — clean.
  • cargo test --workspace — 44 suites pass (incl. gated DB tests for the new Store methods + FlowSpecJournal, and config validation tests).
  • scripts/coverage.sh95.02% (≥90%).
  • Adversarial review (opus): every mirrored RTBH invariant verified preserved (no-downgrade upsert, only_auto clear, supersede scoping, shared-session BgpHandle, channel wiring not swapped, rehydrate-before-start, Pg sink retained, eligibility-before-DB). Two Low config-hardening findings fixed in the last commit.

Branch is off main (after #87 + #89 landed). Pure-core/thin-IO preserved: all decisions are in the covered blackwall-state/blackwall-rtbh/blackwall-flow cores; only blackwalld glue is coverage-excluded (proven by the flowspec-auto-bird lab gate from C2b-1).

🤖 Generated with Claude Code

vxfemboy added 5 commits July 3, 2026 10:51
…hods, journal

0005_flowspec migration (flowspec_rules active mirror + flowspec_requests intent
log, partial unique index on (dst,proto,dst_port) WHERE withdrawn_at IS NULL);
FlowSpecRuleRow/FlowSpecRequestRow; eight Store methods mirroring the rtbh_*
methods (no-downgrade upsert, only_auto clear, status-driven drain, supersede);
impl blackwall_rtbh::FlowSpecJournal for Store. f32 rate decoded via rate::real
(no as-casts). DB tests gated on DATABASE_URL.
blackwall-core: FlowSpecPolicy (concentration, max-flows, rate, max-rules,
hold-down, ttl — no BGP peer, reuses the rtbh session + Policy.prefixes) as
Policy.flowspec: Option<_>. Policy drops Eq (f64/f32); PartialEq retained.
blackwall-config: flowspec directive mirroring rtbh (key=value, duplicate-guard,
ttl>=hold-down), plus a cross-check rejecting flowspec without an rtbh block.
Every Policy{..} literal across the workspace gains flowspec: None.
…ollector

blackwalld flowspec add/remove/list mirrors the rtbh CLI (eligibility checked
before the DB write). Command::Flow now, when policy.flowspec is set, builds a
FlowSpecManager off the shared BgpHandle, rehydrates from list_active_flowspec,
runs a single-owner flowspec_manager_task (tick + drain flowspec_requests), and
feeds the collector a FanoutSink([Pg, SelectorSink]) so each detection routes to
FlowSpec (concentrated) or RTBH (diffuse). Both managers share the one iBGP
session.
…w-up)

Guard the flowspec directive against silent-misconfig footguns the C2b-2 review
flagged: concentration must be in 0.0..=1.0 (NaN would make select() never pick
FlowSpec), max-flows >= 1 (0 disables selection), rate >= 0 (negative/NaN is a
nonsensical traffic-rate). Added a test covering all four rejections.
@vxfemboy vxfemboy merged commit 79b2d17 into main Jul 3, 2026
2 checks passed
@vxfemboy vxfemboy deleted the sp-c-m2b2-flowspec-wiring branch July 3, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C2b-2: FlowSpec auto-mitigation wiring (persistence + config + CLI + daemon)

1 participant