Skip to content

feat(flowspec): support guarded manual destination CIDRs - #324

Merged
lance0 merged 17 commits into
mainfrom
feature/flowspec-destination-cidrs
Oct 24, 2026
Merged

lance0 merged 17 commits into
mainfrom
feature/flowspec-destination-cidrs

Conversation

@lance0

@lance0 lance0 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Allow aligned, wholly owned destination CIDRs in manual FlowSpec creation, such as UDP/443 across 203.0.112.0/22, as one discard or police rule. IPv4 /32 and IPv6 /128 remain defaults; operators opt in through existing prefix-length bounds.

  • Refuse host bits, partial/conflicting ownership and every safelist overlap. Preserve complete matches, TTLs, quotas, dry-run and immutable withdrawal intent.
  • Recheck repair safety and withdraw owned subnet rules when a host inside them becomes safelisted. Inventory publication serializes with lifecycle mutations.
  • Show full rule/lifetime previews and exact-target reports without implying host aggregation. Document retained intent and downgrade preparation.

Exact head 5fffa9c passes all 18 fresh hosted checks, including backend/PostgreSQL, frontend, Rust 1.89, security, interop and both images. Released GoBGP 4.10.0/rustbgpd 0.79.0 fixtures qualify API-to-CIDR announce/read, restart repair, withdrawal and TTL expiry. Independent source reviews found no remaining issues; affected links and patch hygiene pass. Native full-gate limitations are recorded; no completed native gate is claimed.

Speaker read-back does not qualify router forwarding/filtering. This PR targets #322 and contains only the CIDR feature. Merge order: #323 → #327 → #322 → #324 → #325 → #326. Use merge commits; after the predecessor lands, retarget the next PR to main before merging.

Closes #320.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The broader routing scope needs human sign-off after the incomplete full gate and released-speaker CIDR lifecycle validation finish successfully.

No open issues 🎉

What changed in this PR

Adds guarded manual destination CIDRs to FlowSpec, addressing #320 while preserving host-only defaults for automatic mitigation and RTBH.

Changes:

  • Adds aligned subnet admission with whole-prefix ownership, safelist overlap checks, and lifecycle-safe repair and withdrawal.
  • Adds complete rule previews, CIDR-aware navigation, and exact-target incident reports without host aggregation.
  • Adds backend, frontend, and speaker lifecycle coverage, plus configuration and downgrade guidance.
File Description
tests/​integration.rs Tests CIDR admission, identity, ownership, and reload serialization.
tests/​integration_rustbgpd.rs Adds rustbgpd CIDR restart and withdrawal fixture.
tests/​integration_postgres.rs Checks PostgreSQL/mock safelist overlap parity.
tests/​integration_gobgp.rs Adds GoBGP CIDR restart and withdrawal fixture.
tests/​integration_destination_reports.rs Tests exact-target CIDR reports without host aggregation.
tests/​common/​speaker_contract.rs Adds subnet rules to shared speaker contracts.
tests/​common/​destination_lifecycle.rs Adds shared API-to-speaker CIDR lifecycle checks.
src/​state.rs Serializes inventory publication with lifecycle operations.
src/​scheduler/​reconcile.rs Rechecks subnet safety and withdraws unsafe saved rules.
src/​guardrails/​mod.rs Updates invalid-destination test expectations.
src/​domain/​mod.rs Exports destination parsing support.
src/​domain/​flowspec.rs Permits aligned destination networks in match validation.
src/​domain/​destination.rs Parses destinations and rejects host bits.
src/​domain/​blackhole.rs Generalizes safelist withdrawal logging and metrics.
src/​db/​traits.rs Defines safelist checks as prefix overlap checks.
src/​db/​repository.rs Uses PostgreSQL symmetric network overlap.
src/​db/​mock.rs Mirrors prefix overlap behavior in the mock repository.
src/​config/​inventory.rs Resolves unambiguous whole-prefix customer ownership.
src/​api/​handlers/​safelist.rs Withdraws overlapping non-host FlowSpec rules.
src/​api/​handlers/​observations.rs Generates exact-target reports with match and expiry details.
src/​api/​handlers.rs Adds guarded manual CIDR admission and target normalization.
README.md Clarifies host-only defaults and subnet opt-in.
frontend/​lib/​destination.ts Adds destination parsing and CIDR-aware links.
frontend/​lib/​api.ts Documents destination CIDRs in the request type.
frontend/​components/​dashboard/​mitigations-content-live.tsx Routes CIDR target links to mitigation details.
frontend/​components/​dashboard/​flowspec-rule-dialog.tsx Adds CIDR validation and match/action/lifetime preview.
frontend/​app/​(dashboard)/​mitigations/​[id]/​page.tsx Preserves CIDR context and sanitizes report filenames.
frontend/​__tests__/​destination.test.ts Tests destination parsing and target navigation.
frontend/​__tests__/​amplification-surfaces.test.tsx Tests CIDR forms, previews, links, and reports.
FEATURES.md Describes guarded subnet support and safelist protection.
docs/​reference/​configuration.md Explains prefix bounds and retained-intent behavior.
docs/​reference/​api.md Documents CIDR admission, identity, filtering, and reports.
docs/​how-to/​upgrading.md Adds CIDR withdrawal and downgrade procedures.
docs/​cookbook/​manual-mitigation.md Adds a subnet mitigation recipe.
docs/​adr/​README.md Updates the destination-prefix decision index.
docs/​adr/​031-source-prefix-matches.md Aligns source-match guidance with guarded destinations.
docs/​adr/​028-amplification-matches.md Extends amplification guidance to manual CIDRs.
docs/​adr/​004-destination-prefix-32-only.md Defines guarded manual subnet admission and lifecycle policy.
CHANGELOG.md Records manual CIDR support and related safeguards.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Broader routing scope needs human sign-off after the incomplete full gate and released-speaker CIDR lifecycle qualification finish.

No open issues 🎉

Review effort: Balanced

@lance0
lance0 force-pushed the feature/flowspec-destination-cidrs branch from b2fd374 to 5fffa9c Compare October 24, 2026 03:22
@lance0
lance0 changed the base branch from fix/ctutils-constant-time to docs/scrubber-diversion-contract October 24, 2026 03:22
@lance0
lance0 marked this pull request as ready for review October 24, 2026 04:11
@lance0
lance0 changed the base branch from docs/scrubber-diversion-contract to main October 24, 2026 14:50
Inventory load and reload now reject unparseable customer prefixes and
asset IPs. Whole-prefix lookup reports an invalid inventory as an error
instead of a lost owner, and repair keeps the rule with a repair error.
Previously one typo for an unrelated customer withdrew every live
destination CIDR at the POP.

Remove the uncalled covered_blackholes helper.
Tell operators to confirm destination minimum lengths are 32 and 128
before upgrading if they do not want CIDRs, since lower values had no
effect before. Document inventory validation, RFC 8955 precedence
between CIDR and host rules, and that diversion stays host-only.
…ination-cidrs

# Conflicts:
#	docs/project/scrubber-diversion-contract.md
@lance0
lance0 merged commit 382a646 into main Oct 24, 2026
16 checks passed
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.

Flowspec DstPrefix > /32

2 participants