PIVOT AI LAB
PROJECT PIVOT AI INFRASTRUCTURE ARTICLE 02
FIELD NOTES / VIRTUAL FABRIC / ARTICLE 02

Building an AI Fabric with SONiC, BGP, and EVPN

A tested two-spine, three-leaf Clos: routed Linux workloads, EVPN/VXLAN, packet captures, and measured failover.

September 2026 evidenceSONiC • eBGP • ECMP • EVPN / VXLANEditorial preview / no publication
2 × 3Spines × leaves in virtual Clos
2 pathseBGP ECMP next hops
6 / 6Overlay directions passing
1.896 sMeasured example failover recovery

The first working version of a fabric tells me whether I can configure its protocols. The first failure test tells me whether I understand how those protocols affect the traffic running through it.

For Project Pivot I built a five-switch Clos topology in Containerlab using virtual SONiC. Two spines provide the transit paths; three leaves connect Linux endpoints. The routed underlay uses eBGP, ECMP, and BFD. On top of that I added a deliberately small EVPN/VXLAN domain with three more endpoints. Each stage had to pass its own validation before I moved on.

The design builds on work I have done with larger production VXLAN/EVPN deployments, but the purpose here was different. I wanted a reproducible environment where I could shut down an active path, impair forwarding without taking the interface down, inspect the route changes, and compare those changes with what a workload reported.

Logical Containerlab SONiC Clos with routed compute endpoints and separate EVPN overlay endpoints
Figure 01. The actual logical topology: two SONiC virtual spines, three SONiC virtual leaves, routed gpu1–gpu3 Linux endpoints, and overlay1–overlay3 Linux endpoints. The gpu names are workload labels, not physical accelerators.

01 / A deliberately small, testable Clos

The topology has spine1 and spine2 connected to leaf1, leaf2, and leaf3. Every leaf has a routed link to each spine. Spines are transit devices; the leaves are the network edge for the test endpoints. The routed workloads attach on Ethernet8: gpu1 at 10.10.1.1/31, gpu2 at 10.10.2.1/31, and gpu3 at 10.10.3.1/31.

These names could easily be mistaken for actual GPU systems, so the distinction is worth making: they are Linux containers generating ordinary IP traffic. There were no NVIDIA accelerators on this SONiC fabric, and the results do not represent NCCL or GPU-to-GPU transfers.

A production AI backend may use a pure Layer-3 design without an EVPN Layer-2 overlay. I retained both models in this lab because they test different mechanisms. Routed endpoint prefixes establish the underlay and ECMP behaviors. The overlay exercises distributed MAC learning, VTEP reachability, VXLAN encapsulation, and fault isolation.

02 / Start with underlay reachability and ECMP

Each leaf forms eBGP adjacencies toward the two spines. The fabric advertises loopback and workload reachability across the routed underlay, allowing remote leaves to find the endpoints without extending an access VLAN through the network.

On leaf1, the remote prefix 10.10.2.0/31 appeared through two equal-cost next hops: 10.0.0.0 on Ethernet0 toward spine1 and 10.0.0.2 on Ethernet4 toward spine2. That routing-table evidence established eligible paths. It did not prove that one individual flow would be sprayed evenly over both links.

Underlay two-way ECMP next-hop selection and per-flow behavior
Figure 02. Two installed next hops for a remote /31 do not imply per-packet load balancing. Individual flows are hashed to eligible paths; distinct flows can select different spines.

I tested that distinction by observing actual workload paths. Traffic from gpu1 to gpu2 selected spine2; traffic from gpu1 to gpu3 selected spine1. During simultaneous iperf3 workloads, the interface-counter deltas on both leaf1 uplinks confirmed forwarding activity on both paths.

BFD was integrated so a forwarding-path failure could be detected faster than waiting for the ordinary BGP hold timer. That still left several steps between a BFD state change and a resumed application stream: neighbor or path withdrawal, forwarding-table update, ECMP reselection, and transport recovery.

This separation would become visible in the failure measurements.

03 / Add EVPN without confusing it with the underlay

Next I activated the L2VPN EVPN address family across the fabric and added one overlay endpoint to each leaf on Ethernet12. VLAN 100 was mapped to VNI 10100. The overlay hosts used 192.168.100.11/24, .12/24, and .13/24; each had a deterministic MAC beginning with 02:00:00:00:01.

The leaves served as VTEPs with loopback addresses 10.255.0.11, .12, and .13. The spines propagated EVPN routes between leaves but did not terminate VXLAN. In this lab the spines participated in the EVPN control plane; they were not acting as the iBGP route reflectors I had used in a different enterprise design.

The jobs are separate:

EVPN VTEP and Type-2 and Type-3 control plane alongside VXLAN forwarding
Figure 03. Type-3 IMET identifies VTEPs participating in VNI 10100; Type-2 identifies endpoint MAC locations. VXLAN carries frames between the participating leaf VTEPs over the routed IP fabric.

The first routes I checked were Type-3 Inclusive Multicast Ethernet Tag (IMET) advertisements. Each leaf discovered the other two VTEPs for VNI 10100, allowing head-end replication for broadcast, unknown-unicast, and multicast traffic. Type-3 establishes VNI membership; it does not tell me which host MAC resides behind which leaf.

Once the access ports were operational and endpoint traffic started, the leaves advertised Type-2 MAC/IP routes. Leaf1 learned its local overlay1 MAC on Ethernet12 and the two remote MACs through Vxlan0-100, toward 10.255.0.12 and 10.255.0.13. That was the next evidence layer: EVPN had distributed real host-location information rather than merely forming BGP sessions.

04 / Prove encapsulation on the wire, not only in BGP

With BGP and FDB state looking right, I captured overlay traffic. For a packet from overlay1 to overlay2, the evidence showed this outer header:

Field Observed value
Outer source VTEP 10.255.0.11
Outer destination VTEP 10.255.0.12
UDP destination 4789
VXLAN VNI 10100
Inner source → destination 192.168.100.11 → 192.168.100.12
VXLAN outer and inner packet header with exact lab values
Figure 04. Annotated reconstruction of the documented tcpdump observation. This is a diagram based on the recorded fields, not an invented terminal screenshot or a substitute for the archived pcap evidence.

The request and response used different spine paths in one observation. That is legitimate ECMP behavior: the overlay requires reachability between VTEPs, not symmetric physical forwarding through the same spine.

All six directed tests between overlay1, overlay2, and overlay3 passed. At this point I had three independently useful observations: EVPN routes, the forwarding database, and traffic carried in the expected VXLAN encapsulation. An established EVPN adjacency on its own would not have established those outcomes.

05 / Shut down the actual path carrying the workload

A redundant fabric is easier to draw than to validate. For Day 5 I used a test harness that identified the currently selected spine, took down the corresponding leaf uplink, and kept ICMP and TCP traffic running. The harness preserved traceroute, BFD state, next-hop state, packet-loss observations, TCP throughput, restoration, and post-test validation.

For gpu1 → gpu2, the active route used spine2. I disabled leaf1 Ethernet4, forcing the alternate route through spine1. The measurement recorded 1.896 seconds of recovery, a 2.079-second successful-reply gap, nine consecutive lost pings, and two TCP zero-throughput intervals. The existing TCP connection survived the test.

For gpu1 → gpu3, the active route used spine1. I disabled leaf1 Ethernet0, shifting traffic to spine2. Recovery measured 2.056 seconds, with a 2.070-second successful-reply gap, nine lost pings, and two zero-throughput intervals. The TCP session again survived.

Two measured application-level failovers with traffic moved between spines
Figure 05. Measured Day 5 recovery and reply-gap intervals. These are application-level observations from two test cases, not BFD detection-time measurements or a production convergence service-level objective.

The exact seconds matter less than the explanation. BFD detection is not application recovery. A timer setting can be fast while the end-to-end service still experiences an interruption. The test also verified that after restoration BFD returned up, both ECMP paths became available again, and fabric and workload validation passed.

06 / Failure testing must include the overlay

With basic routed failover proven, I extended fault injection to the overlay: a hard link failure, a silent forwarding impairment, and a VTEP-isolation scenario. I checked BFD and BGP state alongside VTEP routes, EVPN advertisements, FDB entries, and endpoint validation before and after the tests.

The Day 7 repository includes the test-overlay-failures.sh harness and timestamped baseline, incident, and final-state files. Those records are more useful than a success banner alone, because they preserve what changed and what returned to normal. The Day 8 follow-up went deeper into traffic and interface counters, including a 500 Mbit/s UDP workload during a silent-forwarding-path experiment.

Layered incident investigation from BFD to endpoint recovery
Figure 06. Evidence ladder used in the lab: protocol, forwarding, encapsulation, and workload each answer a different question. Later observability work added time-correlated exporter and dashboard signals.

A deliberate silent impairment is especially valuable because the interface can remain administratively and operationally up. An operator who checks only show interfaces status can miss the condition entirely. BFD, route withdrawal, and the behavior of a continuously running workload provide a stronger view.

I treat the scripted results as bounded lab evidence. Virtual SONiC does not reproduce production ASIC buffering, hardware PFC, ECN marking, physical RoCE congestion behavior, or real GPU collectives. Those require different equipment and measurement methods.

07 / Rebuildability is part of operational readiness

The fabric was not left as a collection of manually configured running containers. After Day 6, I destroyed the Containerlab topology and rebuilt it using the source-controlled configuration and bootstrap process. The recreated fabric passed all three independent validators:

FABRIC VALIDATION:   PASS
WORKLOAD VALIDATION: PASS
OVERLAY VALIDATION:  PASS

The repository captured the relevant operational scripts, including bootstrap-fabric.sh, validate-fabric.sh, validate-workload.sh, validate-overlay.sh, test-failover.sh, and the later overlay-failure harness. The test automation was developed with AI assistance, then run, diagnosed, and validated against observable network behavior; it should not be mistaken for hand-authored Python coding experience.

For an SRE-oriented portfolio, that repeatability is as important as a polished topology diagram. It allows a future experiment to start from a known baseline and gives another engineer a reasonable path to verify the results.

08 / What I would carry into a production design

This project made several habits concrete. Before trusting an overlay, I verify VTEP reachability. Before trusting EVPN, I look for the correct route types and FDB entries. Before trusting redundant paths, I identify the path used by a real flow and intentionally remove it. Before declaring recovery, I measure the application and check that full redundancy has returned.

I would also apply more explicit production controls than a small isolated lab requires: BGP neighbor authentication where supported and operationally appropriate, management-plane isolation, prefix and route-policy filtering, change-reviewed configuration, restricted telemetry access, and rollback plans. If an EVPN overlay is needed at all, its VLAN/VNI and tenant boundaries need an explicit security model. A GPU backend network does not automatically need Layer 2 extension merely because VXLAN is familiar.

The major lesson from this build is operational, not cosmetic: the fabric is testable because routing state, overlay state, packet behavior, and workload behavior were all measured independently. That is the foundation I want before introducing the harder congestion and RDMA questions that come next.

Evidence trail

The underlying experiment records are maintained in the Project Pivot Git repository on fabric-lab-1 under fabric/sonic-clos/:

The diagrams are explanatory reconstructions. They are not direct screenshots, raw packet captures, or proof of physical ASIC behavior.

Protocol and platform references