Build the lab yourself
Three FRR containers (with tcpdump added). The hosts are network namespaces inside each leaf container, plugged into the leaf's bridge with a veth pair, so no Docker network is ever part of a bridge (that combination causes broadcast storms in Docker). Put FRR's daemons file (bgpd=yes) next to these files, then follow the compose file's comments. The root@host1 prompts are ip netns exec host1 … inside leaf1.
# Needs ./daemons (copy /etc/frr/daemons out of the FRR image, set bgpd=yes). Then:
# docker compose up -d --build
# docker compose exec leaf1 vxlan-setup.sh 10.0.0.11 host1 10.100.0.1/24 02:00:00:00:01:01
# docker compose exec leaf2 vxlan-setup.sh 10.0.0.12 host2 10.100.0.2/24 02:00:00:00:02:02
# leaf2.conf is leaf1.conf with "1" -> "2" in the addresses and AS65002.
name: evpn-lab
x-frr: &frr
build:
dockerfile_inline: |
FROM quay.io/frrouting/frr:10.2.1
RUN apk add --no-cache tcpdump
privileged: true
services:
spine:
<<: *frr
volumes: ["./daemons:/etc/frr/daemons:ro", "./spine.conf:/etc/frr/frr.conf"]
networks: { s-l1: { interface_name: eth0 }, s-l2: { interface_name: eth1 } }
leaf1:
<<: *frr
volumes: ["./daemons:/etc/frr/daemons:ro", "./leaf1.conf:/etc/frr/frr.conf", "./vxlan-setup.sh:/usr/local/bin/vxlan-setup.sh:ro"]
networks: { s-l1: { interface_name: eth0 } }
leaf2:
<<: *frr
volumes: ["./daemons:/etc/frr/daemons:ro", "./leaf2.conf:/etc/frr/frr.conf", "./vxlan-setup.sh:/usr/local/bin/vxlan-setup.sh:ro"]
networks: { s-l2: { interface_name: eth0 } }
networks:
s-l1: { enable_ipv4: false, enable_ipv6: true, ipam: { config: [{ subnet: "fd00:80::/64" }] } }
s-l2: { enable_ipv4: false, enable_ipv6: true, ipam: { config: [{ subnet: "fd00:81::/64" }] } }- Lines 1–5: Start, then create the VNI and a host on each leaf.
- Lines 14–17: The spine, linked to both leaves.
- Lines 18–25: The leaves.
frr defaults traditional
hostname leaf2
!
interface eth0
ip address 10.1.2.1/31
!
interface lo
ip address 10.0.0.12/32
!
router bgp 65002
bgp router-id 10.0.0.12
no bgp ebgp-requires-policy
neighbor 10.1.2.0 remote-as 65000
neighbor 10.1.2.0 description spine
!
address-family ipv4 unicast
network 10.0.0.12/32
exit-address-family
!
address-family l2vpn evpn
neighbor 10.1.2.0 activate
advertise-all-vni
exit-address-family
exit
!- Lines 10–11: leaf2: AS65002, loopback 10.0.0.12.
Where next
- BGP on loopbacks vs interface addressesPrerequisite · Intermediate · 45 min
Why BGP sessions between loopbacks survive link failures and use parallel links, and what they need to work: an IGP or static routes, update-source, the eBGP connected check, and BFD. Every failure is reproduced on two real VyOS routers.
- Switching basics: layer 2, VLANs and IP addressingPrerequisite · Beginner · 40 min
How a switch learns MAC addresses and floods broadcasts, how IP subnets and default gateways decide where packets go, how VLANs split a switch into separate networks, and how trunks and a router connect them. Built on a real switch, three PCs and a VyOS router.
- BGP FundamentalsAlso covers BGP · Intermediate · 75 min
How the Border Gateway Protocol glues the internet together: autonomous systems, sessions, path attributes, best-path selection, iBGP scaling and a hands-on eBGP lab with real FRR configuration.
- Debugging BGP: every session state, reproducedAlso covers BGP · Intermediate · 60 min
Break a working BGP lab a dozen ways and learn to read each failure: Idle, Connect, Active and OpenSent, max-prefix, firewalls, wrong AS, TTL, hold timers, missing policy and unreachable next hops, all with real FRR output and packet captures.