Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

EVPN L2VNI

This guide stands up the smallest possible EVPN-VXLAN network: two leaf switches that bridge a single L2 segment between two hosts. The result: a host on leaf1 can ARP and ping a host on leaf2 as if they were on the same wire, even though packets between them are encapsulated in VXLAN and forwarded over a routed underlay.

What you'll build

EVPN L2VNI quick start topology

UnderlayOSPFv2 in area 0 over a single /30 link
OverlayiBGP between the two loopbacks with the l2vpn-evpn AFI
L2 serviceVXLAN VNI 10, host-facing ports enslaved to a Linux bridge

The same recipe scales to a leaf-spine fabric — add more leafs, point each new iBGP session at a route reflector, and assign each customer L2 segment its own VNI. Two leafs is the minimum that demonstrates VTEP-to-VTEP MAC distribution; no third device is required.

Prerequisites

  • flockd installed on leaf1 and leaf2. See Installation.
  • Each leaf has at least two interfaces: one toward the other leaf (the transit link) and one toward its locally-attached host.
  • Each host runs a stock Linux that can ping.

This example uses two interfaces per leaf, named with Debian's predictable naming scheme: enp0s3 (transit, toward the other leaf) and enp0s4 (host-facing). Substitute whatever your environment uses.

Step 1 — Underlay IP addressing

Set the loopback IP and transit IP on each leaf.

On leaf1:

# ip addr add 10.0.1.1/32 dev lo
# ip link set lo up
# ip addr add 10.0.0.1/30 dev enp0s3
# ip link set enp0s3 up

On leaf2:

# ip addr add 10.0.2.1/32 dev lo
# ip link set lo up
# ip addr add 10.0.0.2/30 dev enp0s3
# ip link set enp0s3 up

The host-facing port joins the bridge in the next step, so it needs no IP on the leaf side — just bring it up on each leaf:

leaf1# ip link set enp0s4 up
leaf2# ip link set enp0s4 up

Assign IPs to the hosts themselves so they can talk over the L2 segment:

host-a# ip addr add 10.10.10.1/24 dev <port toward leaf1>
host-b# ip addr add 10.10.10.2/24 dev <port toward leaf2>

Step 2 — VXLAN and bridge

flockd does not create VXLAN or bridge interfaces — it learns about them from the kernel and drives BGP-EVPN signalling for them. Create them with ip link.

On leaf1:

# Create the VXLAN tunnel interface for L2VNI 10.
#
#   id 10               L2VNI value
#   local 10.0.1.1      our VTEP source IP (the loopback)
#   dstport 4789        standard VXLAN UDP port
#   nolearning          EVPN drives MAC learning, not the data plane
ip link add vxlan10 type vxlan id 10 local 10.0.1.1 dstport 4789 nolearning

# Create the bridge that joins the VXLAN with the host-facing port.
ip link add br10 type bridge

# Enslave the VXLAN and the host-facing port to the bridge.
# enp0s4 here is the host-facing interface — substitute your own.
ip link set vxlan10 master br10
ip link set enp0s4 master br10

# Bring it all up.
ip link set vxlan10 up
ip link set br10 up

On leaf2:

# Create the VXLAN tunnel interface for L2VNI 10.
#
#   id 10               L2VNI value
#   local 10.0.2.1      our VTEP source IP (the loopback)
#   dstport 4789        standard VXLAN UDP port
#   nolearning          EVPN drives MAC learning, not the data plane
ip link add vxlan10 type vxlan id 10 local 10.0.2.1 dstport 4789 nolearning

# Create the bridge that joins the VXLAN with the host-facing port.
ip link add br10 type bridge

# Enslave the VXLAN and the host-facing port to the bridge.
# enp0s4 here is the host-facing interface — substitute your own.
ip link set vxlan10 master br10
ip link set enp0s4 master br10

# Bring it all up.
ip link set vxlan10 up
ip link set br10 up

Step 3 — flockd configuration

flockd watches /etc/flockd/flockd.json and re-reads it on change, so no daemon restart is needed — saving the file is enough.

/etc/flockd/flockd.json on leaf1:

{
    "ospfv2": {
        "vrfs": {
            "default": {
                "router_id": "10.0.1.1",
                "areas": {
                    "0.0.0.0": {
                        "intfs": {
                            "lo": {},
                            "enp0s3": {
                                "hello_interval": 1,
                                "ospf_intf_type": "point-to-point"
                            }
                        }
                    }
                }
            }
        }
    },
    "bgp": {
        "asn": 65000,
        "id": "10.0.1.1",
        "vrfs": {
            "default": {
                "neighs": {
                    "10.0.2.1 10.0.1.1": {
                        "asn": 65000,
                        "afis": {
                            "l2vpn-evpn": {}
                        }
                    }
                }
            }
        }
    }
}

/etc/flockd/flockd.json on leaf2:

{
    "ospfv2": {
        "vrfs": {
            "default": {
                "router_id": "10.0.2.1",
                "areas": {
                    "0.0.0.0": {
                        "intfs": {
                            "lo": {},
                            "enp0s3": {
                                "hello_interval": 1,
                                "ospf_intf_type": "point-to-point"
                            }
                        }
                    }
                }
            }
        }
    },
    "bgp": {
        "asn": 65000,
        "id": "10.0.2.1",
        "vrfs": {
            "default": {
                "neighs": {
                    "10.0.1.1 10.0.2.1": {
                        "asn": 65000,
                        "afis": {
                            "l2vpn-evpn": {}
                        }
                    }
                }
            }
        }
    }
}

The two configs are deliberately symmetric. Each one:

  • Runs OSPFv2 area 0 on lo (so the loopback is reachable from the peer) and on the transit interface.
  • Peers over iBGP from its loopback to the other leaf's loopback.
  • Enables the l2vpn-evpn AFI on that neighbor — the only address family needed for an L2VNI service. IPv4 underlay reachability is provided by OSPFv2, not by this BGP session.

Step 4 — Verify the control plane

flockc is the local gRPC client. Run the queries below on either leaf; allow ten seconds or so for OSPF and BGP to converge.

Check both protocols are enabled:

flock@leaf1:~$ flockc sys overview
{..."enabled_protocols":["BGPv4","OSPFv2","Static"], ...}

OSPFv2 adjacency on enp0s3 reaches Full:

flock@leaf1:~$ flockc ospfv2 instances
[{"my_router":{"id":"10.0.1.1", ...}, ..., "stats":{...,"neigh_state_count":{...,"full":1}}}]

BGP neighbor reaches established:

flock@leaf1:~$ flockc bgp overview
{"id":"10.0.1.1","asn":65000, ...,"neighbor_summary":{"default":{"count":1,"established":1,"send_converged":1,"recv_converged":1}}}

Local NVE for VNI 10:

flock@leaf1:~$ flockc bgp evpn nve walk
[{"vni":10,"local_vtep_ip":"10.0.1.1","rd":"1:10.0.1.1:2","local_macs":[{"mac":[...],"ip":null,"seq":0}]}]

The single entry shows VNI 10, local VTEP IP 10.0.1.1, and the host's MAC that the bridge has learned.

EVPN RIB:

flock@leaf1:~$ flockc bgp evpn rib walk
[{"prefix":{"rd":"1:10.0.1.1:2","net":{"route":{"Type2MacIp":{...,"mac_addr":[...]}}}}, ...},
 {"prefix":{"rd":"1:10.0.1.1:2","net":{"route":{"Type3Imet":{...,"originating_router_ip":"10.0.1.1"}}}}, ...},
 {"prefix":{"rd":"1:10.0.2.1:2","net":{"route":{"Type2MacIp":{...,"mac_addr":[...]}}}}, ...},
 {"prefix":{"rd":"1:10.0.2.1:2","net":{"route":{"Type3Imet":{...,"originating_router_ip":"10.0.2.1"}}}}, ...}]

Four entries: a Type-3 (Inclusive Multicast Ethernet Tag, IMET) route from each VTEP — the announcement "I'm a VTEP for VNI 10" — and a Type-2 (MAC/IP advertisement) route for each locally-learned host MAC.

Step 5 — Generate traffic

Ping host-b from host-a:

host-a# ping -c 3 10.10.10.2

The first packet may be lost while ARP completes over VXLAN; subsequent packets succeed. This proves the data plane carries L2 traffic between the two hosts over the VXLAN tunnel using the MACs distributed by the EVPN control plane.

Cleanup

To tear down the VXLAN/bridge interfaces on each leaf:

# ip link delete br10
# ip link delete vxlan10

Remove the bgp and ospfv2 blocks from /etc/flockd/flockd.json to stop the protocols.

Where to go next

  • The BGP Component chapter covers the full EVPN configuration surface, including L3VNI for inter-subnet routing, Ethernet Segments for multi-homing, and route targets.
  • For a leaf-spine fabric with a route reflector, replace each leaf's single iBGP neighbor with a peering to the RR and configure route_reflector_client on the RR.