Skip to content

bgp: EVPN aliasing / backup-path resolver - #151

Open
gusbourg wants to merge 27 commits into
holo-routing:masterfrom
gusbourg:bgp-evpn-aliasing-pr
Open

bgp: EVPN aliasing / backup-path resolver#151
gusbourg wants to merge 27 commits into
holo-routing:masterfrom
gusbourg:bgp-evpn-aliasing-pr

Conversation

@gusbourg

@gusbourg gusbourg commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

EVPN multihoming Slice 4 (stacked on #150): aliasing / backup-path resolver. Completes EVPN multihoming.

  • Aliasing next-hop resolution: a multihomed MAC (Type-2 with non-zero ESI) resolves to the set of PEs advertising an EAD-per-EVI route for its (ESI, EVI)intersected with the PEs advertising an EAD-per-ES route for the ESI, so a PE whose segment is down (mass-withdrawn) is excluded.
  • All-Active → all qualifying PEs are active next-hops (load-balance); Single-Active → a primary next-hop plus a backup.
  • Single-homed (ESI 0), or no qualifying EAD → the Type-2 next-hop, unchanged.

Unit tests: the EAD-per-EVI ∩ EAD-per-ES intersection (All-Active); a peer without an EAD-per-ES is dropped; Single-Active primary/backup separation; single-homed passthrough; wrong-ESI / wrong-tag / malformed EAD ignored; missing-EAD fallback.

Scope: control-plane next-hop-set resolution. Dataplane programming of the multi-PE next-hop set (ECMP to multiple VTEPs) and the northbound ES/EVI config/state binding remain deferred.

Stacked on #150.

🤖 Generated with Claude Code

gusbourg and others added 27 commits July 5, 2026 10:41
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add an AddressFamily::Prefix associated type for NLRI/RIB keys while keeping policy, northbound, and IBus boundaries on normal IP network values. IPv4 and IPv6 unicast use identity conversions, preserving current behavior.

Switch BGP RIB prefix storage from PrefixMap to BTreeMap so future address families are not constrained by prefix_trie's primitive-integer key representation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
First step of VRF support (Option C: IETF-native, no schema-mount). Embeds
ietf-network-instance (+ ietf-yang-schema-mount for the import) and adds:

- a deviation removing the mandatory schema-mount root-type (Holo binds by
  name, it does not mount per-instance schema) and deferring bind-ni-name
  (+ its notification) until interface-side VRF support lands;
- holo-network-instance augmentation: a 'network-instance' leafref on
  control-plane-protocol, binding a protocol instance to a VRF by name;
- the network-instance config registry (name/enabled/description) and the
  per-instance NI binding, stored on Master (consumed by later per-VRF
  routing steps).

Validated: holod boots (northbound callbacks complete), commits/round-trips
network-instances + a bound protocol, and the leafref enforces referential
integrity (binding to an unknown VRF is rejected).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le-ids

Southbound VRF learning: holo-interface parses IFLA_MASTER (enslavement)
and the VRF device's IFLA_INFO_DATA table-id from RTM_NEWLINK, carries both
in InterfaceUpdateMsg. holo-routing records each VRF device's table-id and
resolves a matching network-instance's table-id — both when the device is
learned before the NI is configured (on NI create) and after (on
InterfaceUpd).

Exposed via a holo-network-instance:state/table-id oper-state leaf.

Validated: a network-instance bound to a kernel VRF device resolves its
table-id in both orderings (device-before-config and config-before-device).
This table-id is what per-VRF route installation programs routes into.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Thread an optional kernel table id through route messages, RIB route selection, and netlink route add/delete so routes can be installed outside the main table. Instance identity now carries the configured network-instance and static route state is keyed by instance plus prefix, allowing overlapping static prefixes in different VRFs.

When a VRF table has not been resolved yet, static route installation is deferred with a warning and replayed when the matching VRF device is learned, instead of silently programming the main table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Carry the configured network-instance into protocol tasks so BGP can bind its listener and active connect sockets to the matching Linux VRF device. Route messages from VRF-bound protocol instances now inherit the resolved VRF table in routing when the protocol does not specify a table id itself.

Populate the protocol-name to network-instance mapping during create_prepare so first-transaction child config is relayed to the VRF-qualified protocol instance instead of being dropped as a default-instance change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add tests for both VRF table-id resolution orderings: creating a network-instance after its VRF device is learned, and learning the VRF device after the network-instance exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Guard UPDATE processing after FSM transitions so rejected updates cannot reach import code without a neighbor identifier, and ignore notification timestamps in test state snapshots.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keep the optional route table-id available for VRF route programming while preserving the legacy serialized shape for default-table routes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MPLS (LFIB) routes were always built with RTA_MULTIPATH, which the kernel
does not accept for AF_MPLS single-nexthop routes: they installed with no
nexthop and were flagged dead/linkdown, so holo worked as an SR ingress PE
but not as a transit/egress LSR. Emit the nexthop as top-level Oif + Via +
NewDestination attributes for the single-nexthop case (verified against the
kernel with a standalone repro); the multipath encoding is retained for the
ECMP case, which has a separate kernel-side RTA_MULTIPATH/AF_MPLS issue
(iproute2 exhibits it too) tracked as remaining work.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add L3VPN IPv4/IPv6 AFI-SAFI identities, typed route distinguisher and route-target helpers, and labeled VPN NLRI structures with MP_REACH/MP_UNREACH encode/decode support.

Advertise VPNv4/VPNv6 multiprotocol capabilities when the neighbor AF is configured, while decoded VPN updates remain explicitly ignored until the VPN RIB/import path is added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Send deterministic VPNv4 and VPNv6 labeled NLRIs after VPN AF negotiation so FRR can validate Holo's MP-BGP VPN wire encoding before the Phase C VRF export path exists.

This is temporary Phase-B scaffolding; real VPN routes will come from per-VRF export and label allocation in the L3VPN import/export implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add VPNv4 and VPNv6 address-family table types keyed by route distinguisher plus IP prefix, with routing tables and neighbor update queues for both VPN AFs.

Retain decoded VPN MP_REACH routes in pre-policy Adj-RIB-In and remove them on MP_UNREACH while leaving full import policy, label persistence, and VRF export/import for the next Phase C slice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the Phase-B hardcoded VPNv4 and VPNv6 updates that were sent when a VPN-capable session came up.

Real VPN routes must come from Phase-C VRF export/import and label allocation rather than session initialization.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add optional VPN label metadata to BGP Route and LocalRoute so labeled VPN NLRI can carry its label beyond packet decoding.

Store decoded VPNv4 and VPNv6 labels on pre-policy Adj-RIB-In routes while keeping RTs in the existing extended-community attribute path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Accept decoded VPN NLRI into post-policy Adj-RIB-In until the import policy path can carry RD-qualified keys.

Run VPNv4 and VPNv6 routes through NHT and decision processing while disabling kernel Loc-RIB install and generic dissemination for VPN AFs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a generic BGP event-replay fixture covering VPNv4 and VPNv6 MP-BGP negotiation, labeled VPN NLRI import, RT extended-community retention, and VPN AF prefix installation counters.

Adjust the VRF table-id unit test for the current interface update signature after replaying the L3VPN stack onto the cleaned foundation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add L2VPN EVPN AFI/SAFI support for BGP capabilities, MP_REACH/MP_UNREACH codec handling for route types 2, 3, and 5, and a typed EVPN route key in the generalized BGP RIB. Enable standard l2vpn-evpn config/state while keeping VXLAN/bridge dataplane out of scope for this control-plane slice.

Add packet round-trip coverage for IPv4 and IPv6 EVPN route content plus an upstream-style conformance topology that receives RT2, RT3, and RT5 routes with route-target state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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