Skip to content

feat(srv6): RFC 9256 candidate-path selection, dynamic BSID, SID verification, drop-upon-invalid#38

Merged
ryskn merged 1 commit into
dev/srv6egress-v1from
feat/srv6-rfc9256-candidate-path-selection
Jul 6, 2026
Merged

feat(srv6): RFC 9256 candidate-path selection, dynamic BSID, SID verification, drop-upon-invalid#38
ryskn merged 1 commit into
dev/srv6egress-v1from
feat/srv6-rfc9256-candidate-path-selection

Conversation

@ryskn

@ryskn ryskn commented Jul 6, 2026

Copy link
Copy Markdown
Owner

What

Port the RFC 9256/9830 receiver-side features from the safi73-vpp PoC into the agent's SR Policy path (bgp_watcherSRv6Provider).

  • Candidate-path selection (§2.9): getPolicyNode selected by highest Priority — wrong on two axes. Selection belongs to Preference (higher wins, default 100; previously not parsed at all), while Priority orders revalidation with lower value first (§2.12, default 128; previously defaulted to 0 = most urgent). Selection is now preference-based with §2.9 tie-breaks (lower originator carried from the BGP path source, then higher discriminator). Priority now orders the RescanState revalidation sweep (revalidatePolicies).
  • Dynamic BSID (§6.2.1): advertisements without a BSID used to install an unusable all-zero-BSID policy. The provider now binds one from the policy pool via Calico IPAM — handle-scoped per <endpoint, color>, stable across candidate switches, released with the last candidate, and reclaimed across agent restarts (release-before-assign on the same handle). S-Flag (Specified-BSID-only, §6.2.3) rejects instead.
  • SID verification (§5.1): the first SID of every segment list, plus any V-Flag segment, must resolve in the FIB to a non-drop path or the list is invalid (::/0 default-drop counted as unreachable). Lookup failures fail open. Adds vpplink.RouteLookup (LPM) and IsDrop mapping in FromFibPath.
  • Drop-upon-invalid (§8.2, I-Flag): when the policy still has candidates but none is valid, orphaned steerings get a fail-closed drop route (RoutePath{IsDrop}, FibTable preserved so the PodVRF node-IP steering drops in the right table) instead of escaping to routing. Lifted before re-steering on recovery, or when the policy's last candidate is withdrawn (policy gone → fail-open per RFC).
  • Watcher parsing: SRv6 Binding SID sub-TLV (type 20; gobgp hands it over as Unknown, decoded raw and preferred over type 13 per RFC 9830 §2.4.2), S/I flags, V-Flag masks per list, weight-0 rejection (§5.1), first-instance-wins for single-instance sub-TLVs.

Existing behaviors kept: >16-SID and SegmentTypeA rejection, NLRI-key replacement, failover re-steer, deferred BSID cleanup.

Notes

  • Old fixtures with SidList-less cached tunnels were updated (a candidate with zero segment lists is now invalid — such advertisements are already rejected at parse time).
  • Not ported: RFC 9830 §4.2 RT/NO_ADVERTISE usability (different layer here — embedded gobgp), periodic revalidation timer (hooked to RescanState instead).

Test

New: routing/srpolicy_parse_test.go (defaults, S/I flags, type-20 preference, V-mask, weight-0, S-Flag-without-BSID) and 9 provider tests (preference selection + tie-breaks, dynamic BSID alloc/stability/release, S-Flag invalid, unreachable-first-SID / V-Flag / fail-open, drop engage / recovery / policy-gone release, priority-ordered revalidation).

GOOS=linux go build green for the whole module; go test ./calico-vpp-agent/connectivity/ ./calico-vpp-agent/routing/ ./vpplink/types/ ./srv6egress/... green (linux container, golang:1.26).

…fication, drop-upon-invalid

Port the RFC 9256/9830 receiver features from the safi73-vpp PoC into the
agent's SR Policy path (bgp_watcher -> SRv6Provider).

Selection (§2.9): getPolicyNode picked the highest Priority, which is wrong
on two axes -- selection is Preference's job (higher wins, default 100, was
not even parsed), and Priority orders revalidation with LOWER value first
(§2.12, default 128, was defaulting to 0 = most urgent). Selection is now
preference-based with §2.9 tie-breaks (lower originator from the BGP path
source, then higher discriminator); Priority orders the RescanState
revalidation sweep instead.

Dynamic BSID (§6.2.1): advertisements without a BSID used to install an
unusable all-zero-BSID policy. The provider now binds a BSID from the policy
pool via Calico IPAM (handle-scoped per <endpoint, color>, stable across
candidate switches, released with the last candidate, reclaimed across agent
restarts). S-Flag (Specified-BSID-only, §6.2.3) still rejects.

SID verification (§5.1): the first SID of every segment list, plus any
segment with the V-Flag, must resolve in the FIB to a non-drop path or the
list is invalid; lookup failures fail open. Adds vpplink.RouteLookup (LPM)
and IsDrop mapping in FromFibPath.

Drop-upon-invalid (§8.2, I-Flag): when a policy still has candidates but
none is valid, orphaned steerings get a fail-closed drop route (FibTable
preserved) instead of falling back to routing; lifted on recovery or when
the policy's last candidate is withdrawn.

Watcher parsing also gains: SRv6 Binding SID sub-TLV (type 20, arrives from
gobgp as Unknown; preferred over type 13 per RFC 9830 §2.4.2), S/I flags,
V-Flag masks, weight-0 rejection (§5.1), first-instance-wins sub-TLVs.
@ryskn ryskn merged commit 1cd331b into dev/srv6egress-v1 Jul 6, 2026
1 check passed
@ryskn ryskn deleted the feat/srv6-rfc9256-candidate-path-selection branch July 6, 2026 11:11
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.

1 participant