Skip to content

bgp: add EVPN control plane (RFC 7432, route types 2/3/5) - #136

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

bgp: add EVPN control plane (RFC 7432, route types 2/3/5)#136
gusbourg wants to merge 23 commits into
holo-routing:masterfrom
gusbourg:bgp-evpn-pr

Conversation

@gusbourg

@gusbourg gusbourg commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Adds the BGP L2VPN EVPN control plane (RFC 7432):

  • L2VPN-EVPN AFI/SAFI.
  • Route types 2 (MAC/IP Advertisement), 3 (Inclusive Multicast Ethernet Tag), 5 (IP Prefix).
  • RT-based import.
  • Packet round-trip test + an evpn conformance topology.

Control plane only — VXLAN/bridge dataplane (VTEP) wiring is out of scope here. Multihoming (types 1/4, MAC mobility, DF election) is a planned follow-up.

Stacked on #135 (L3VPN + VRF foundation) — those commits drop out of this diff once #135 merges.

🤖 Generated with Claude Code

gusbourg and others added 22 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