Skip to content

feat(fib): per-class maximum_paths_ebgp / maximum_paths_ibgp (ADR-0066)#263

Merged
lance0 merged 2 commits into
mainfrom
feat/ecmp-per-class-maxpaths
May 25, 2026
Merged

feat(fib): per-class maximum_paths_ebgp / maximum_paths_ibgp (ADR-0066)#263
lance0 merged 2 commits into
mainfrom
feat/ecmp-per-class-maxpaths

Conversation

@lance0
Copy link
Copy Markdown
Owner

@lance0 lance0 commented May 25, 2026

ECMP follow-up 2/4 — per-class maximum_paths_ebgp / maximum_paths_ibgp (ADR-0066)

Adds per-table per-class ECMP caps, FRR's maximum-paths / maximum-paths ibgp:
eBGP and iBGP equal-cost groups can carry different install widths.

Semantics (coexist, non-breaking)

  • A per-class value overrides the table's overall maximum_paths for that class.
  • An unset class falls back to maximum_paths, then 1 — so existing configs are byte-for-byte unchanged.
  • The equal-cost group is homogeneous, so the best route's class (Route::is_ebgp) selects the cap.

Change

  • [[fib_tables]].maximum_paths_ebgp / maximum_paths_ibgp config + validation (same >= 1 / <= 256 guardrail, refactored into one helper).
  • Per-class re-cap moves into the per-candidate projection loop (src/fib.rs, per_class_max_paths).
  • max_install_paths widens the RIB gather to max(maximum_paths, maximum_paths_ebgp, maximum_paths_ibgp) across tables, so projection can reach any per-class width.

Tests

  • maximum_paths_ebgp_caps_ebgp_group, maximum_paths_ibgp_caps_ibgp_group, per_class_overrides_with_maximum_paths_fallback (projection).
  • fib_tables_per_class_maximum_paths_round_trip + per-class cases in fib_tables_reject_invalid_guardrails (0 / over-cap).

No new interop: per-class only changes which cap applies, not the kernel
RTA_MULTIPATH install path itself (covered by M50). Docs: CONFIGURATION.md
(also backfills the previously-missing maximum_paths row), COMPARISON.md
footnote, CHANGELOG.md.

Next: Link Bandwidth ext-community parse (PR3), then weighted/unequal-cost multipath (PR4, + ADR).

Add per-table `[[fib_tables]].maximum_paths_ebgp` and `maximum_paths_ibgp`
(FRR's `maximum-paths` / `maximum-paths ibgp`): cap eBGP and iBGP equal-cost
groups independently.

They coexist with the overall `maximum_paths` — a per-class value overrides it
for that class, and an unset class falls back to `maximum_paths` then `1`, so
existing configs are byte-for-byte unchanged. The equal-cost group is
homogeneous, so the best route's class (`Route::is_ebgp`) selects the cap; the
re-cap moves into the per-candidate projection loop (`src/fib.rs`), and
`max_install_paths` widens the RIB gather to the max of all three caps so
projection can reach any per-class width. Validation applies the same `>= 1` /
`<= 256` guardrail to all three (refactored into one helper).

No new interop: per-class only changes which cap applies, not the kernel
RTA_MULTIPATH install path (covered by M50). Tests: projection per-class cap +
fallback (eBGP/iBGP), config round-trip, validation rejects 0 / over-cap for the
new fields. Docs: CONFIGURATION (also backfills the missing maximum_paths row),
COMPARISON footnote, CHANGELOG.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds per-class ECMP width caps to FIB table configuration so eBGP and iBGP equal-cost groups can be installed with different maximum path counts, while preserving existing behavior when unset.

Changes:

  • Introduces [[fib_tables]].maximum_paths_ebgp and maximum_paths_ibgp with shared validation guardrails (>= 1, <= 256).
  • Applies per-class capping during FIB projection and widens RIB candidate gathering to the maximum of overall/per-class caps.
  • Adds/updates unit tests and updates configuration/docs/changelog to describe the new knobs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/fib.rs Adds per-class max-path selection during projection and projection tests.
src/fib_runtime.rs Widens RIB gather width to cover overall and per-class caps.
src/config/validation.rs Refactors ECMP cap validation into a shared helper and validates new fields.
src/config/tests.rs Adds parsing/guardrail tests for the new per-class fields.
src/config/schema.rs Extends FibTableConfig schema with new per-class ECMP cap fields and docs.
docs/CONFIGURATION.md Documents maximum_paths plus new per-class ECMP cap fields.
docs/COMPARISON.md Updates multipath feature comparison text to reflect per-class caps availability.
CHANGELOG.md Adds changelog entry describing per-class ECMP caps and semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/fib.rs Outdated
Comment on lines 338 to 355
/// Project configured FIB tables and Loc-RIB install candidates using the
/// current RIB peer-group map for table allow-list checks.
#[must_use]
/// Per-class ECMP width: the eBGP/iBGP override if set, else the table's overall
/// `maximum_paths`, else 1 (today's single-next-hop behavior). The equal-cost
/// group is homogeneous, so the best route's class selects the cap.
fn per_class_max_paths(table: &FibTableConfig, is_ebgp: bool) -> usize {
if is_ebgp {
table.maximum_paths_ebgp.or(table.maximum_paths)
} else {
table.maximum_paths_ibgp.or(table.maximum_paths)
}
.unwrap_or(1)
.max(1) as usize
}

pub(crate) fn project_fib_intent_with_peer_groups(
tables: &[FibTableConfig],
@lance0 lance0 requested a deployment to kernel-dataplane-auto May 25, 2026 00:10 — with GitHub Actions Queued
@lance0 lance0 requested a deployment to kernel-dataplane-auto May 25, 2026 00:10 — with GitHub Actions Queued
The per_class_max_paths helper was inserted between the doc comment /
#[must_use] and project_fib_intent_with_peer_groups, so the projection
function lost its documentation and must-use lint while the helper was
mis-documented as doing projection. Move the helper above the doc block
so each attribute lands on its intended function.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

@lance0 lance0 merged commit 8d71179 into main May 25, 2026
25 checks passed
@lance0 lance0 deleted the feat/ecmp-per-class-maxpaths branch May 25, 2026 00:39
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.

2 participants