Proxmox · Networking

Proxmox VE Software-Defined Networking (SDN): EVPN and VXLAN Architecture Guide

A definitive, battle-tested engineering guide to Software-Defined Networking (SDN) with BGP EVPN and VXLAN zones in Proxmox VE. Learn how to eliminate VLAN trunking sprawl, build wire-speed distributed Anycast Gateways, master the 50-byte MTU trap, and cleanly isolate multi-tenant enterprise labs across cluster nodes.

By K Shankar R Karanth Homelab Proxmox Concept Guide Tested on: Proxmox VE 8.2 / 8.3, FRRouting 8.5+, Linux Kernel 6.8, Debian 12 (Bookworm)
Quick idea: Proxmox VE Software-Defined Networking (SDN) with BGP EVPN and VXLAN replaces fragile 802.1Q VLAN trunking and multicast flooding with a resilient, BGP-driven control plane. By combining VXLAN encapsulation over UDP port 4789 with FRRouting (FRR) exchanging Type-2 MAC/IP and Type-5 subnet routes, you unlock wire-speed Layer 2 network extensions and distributed Anycast default gateways across all cluster nodes without hair-pinning traffic through an external firewall.
VXLAN (Data Plane)

Encapsulates Layer 2 Ethernet frames inside standard UDP datagrams (port 4789), stretching broadcast domains over any routable Layer 3 physical underlay.

BGP EVPN (Control Plane)

Replaces data-plane flood-and-learn broadcasting with MP-BGP routing advertisements via FRRouting (FRR), synchronising MAC/IP bindings in milliseconds.

Anycast Gateway

Replicates identical default gateway IP and MAC addresses across every hypervisor node, routing inter-VNet traffic locally with zero gateway bottlenecks.

The Multi-Node Lab Bottleneck: Why Traditional 802.1Q VLANs Break Down

If you have ever built an enterprise homelab or multi-node virtualization cluster, you know the exact moment traditional networking begins to fight back. You start innocently enough: three Proxmox VE nodes, a managed gigabit or 10G switch, and a handful of 802.1Q VLAN tags carved out for management, storage, DMZ, and Active Directory lab domains. It feels clean, organised, and professional.

Then reality arrives. You want to spin up a simulated corporate acquisition with overlapping subnets. You want to test Kubernetes clusters with dynamic CNI overlays. You want to spin up an isolated malware analysis sandbox, a staging Active Directory forest, and a dedicated penetration testing target range. Suddenly, every single architectural change requires touching the configuration of your physical core switch, updating trunk ports across every hypervisor NIC, and praying that a Spanning Tree Protocol (STP) recalculation does not black-hole your storage network for 30 seconds while your family wonders why the streaming video froze.

Traditional 802.1Q VLAN trunking suffers from three fundamental architectural ceilings in modern virtualized data centres:

  1. The 4,094 VLAN Limit: The 12-bit VLAN identifier in standard Ethernet frames caps you at 4,094 distinct tags. In multi-tenant environments or complex multi-tier testing labs, that ceiling disappears shockingly fast.
  2. Physical Configuration Sprawl: Every time you provision a new isolated network, that VLAN tag must be explicitly plumbed, trunked, and allowed across every intermediate physical switch, patch panel, and hypervisor bonding interface. Configuration drift becomes an inevitability.
  3. The “Hair-Pinning” Gateway Bottleneck: In a traditional VLAN architecture, inter-VLAN routing is centralised. If a web server VM on Node 1 needs to talk to a database server VM sitting on the exact same physical host in a different VLAN, that packet must leave the hypervisor, traverse the physical switch, hit a physical router or a virtualized firewall appliance (such as pfSense or OPNsense), get routed, and traverse the exact same physical link back into the host. This “router-on-a-stick” hairpin topology consumes physical link bandwidth and adds unnecessary latency.

Think of traditional VLANs like running dedicated physical copper intercom wires between every single office in a sprawling corporate campus. If Department A moves to the fourth floor, an electrician must physically climb into the ceiling, pull new cables, and patch them into the wall board.

Software-Defined Networking with VXLAN and EVPN is like modern packet-switched VoIP: your data is tucked inside standard, sealed postal delivery envelopes (UDP packets) and delivered over whatever existing roads (your standard physical IP network) already exist. The underlying physical switches never know or care what is inside the envelope; they simply forward UDP traffic at wire speed. Meanwhile, BGP EVPN acts as the automated global corporate directory, instantly informing every hypervisor host which node currently hosts which virtual machine and MAC address.

What Is Proxmox VE SDN? Core Architecture & Zone Types

Starting with Proxmox VE 8.1 and mature in Proxmox VE 8.2 and 8.3, Software-Defined Networking (SDN) is installed by default and fully integrated into the Proxmox Web GUI and cluster configuration engine. Orchestrated by the libpve-network-perl core package, SDN abstracts physical networking into declarative cluster-wide virtual objects managed centrally under Datacenter → SDN.

Whenever you make a networking change in Proxmox SDN, the cluster writes the declarative configuration to cluster-shared files in /etc/pve/sdn/. When you click Apply, Proxmox dynamically compiles and reloads native Linux networking constructs (Linux bridges, VXLAN tunnel interfaces, VRFs, and routing tables) across all cluster nodes using ifupdown2 and FRRouting (FRR).

To master Proxmox SDN, you must understand its hierarchy of four core primitives:

  • Controllers: The control plane software or protocol engine (such as BGP or ISIS) that coordinates routing information and MAC address tables across nodes.
  • Zones: A logical network boundary that defines the encapsulation technology, MTU, routing domain (VRF), and transport rules for virtual networks.
  • VNets (Virtual Networks): The virtual Layer 2 broadcast domains created inside a zone. In the Proxmox GUI, each VNet appears as a standard Linux bridge (e.g. vnet-app) that you attach to virtual machine and container network interfaces.
  • Subnets: The Layer 3 IP prefix assigned to a VNet, defining the IP address range, default gateway, SNAT rules, and DHCP/IPAM allocations.

Proxmox VE provides several zone plugins to match different infrastructure topologies:

Zone Type Encapsulation Control Plane Best Use Case
Simple None (Local Bridge) None Isolated single-node host-only networks with optional SNAT for outbound internet access.
VLAN 802.1Q Tagging Physical Switch Trunk Traditional environments where physical switches already manage 802.1Q tags and routing.
QinQ Stacked 802.1ad VLANs Physical Switch Trunk Service provider or nested multi-tenant topologies requiring dual VLAN tag encapsulation.
VXLAN UDP 4789 Encapsulation Multicast or Unicast Mesh Small clusters needing Layer 2 extension across nodes without 802.1Q VLAN trunking.
EVPN VXLAN + VRF (L3VNI) MP-BGP via FRRouting (FRR) Enterprise-grade multi-node fabrics, distributed Anycast Gateways, and high-density lab isolation.

Plain VXLAN vs. BGP EVPN: Why Control Planes Matter

At first glance, many engineers ask: “Proxmox already has a plain VXLAN zone plugin. Why should I introduce BGP and FRRouting with an EVPN zone?”

The answer lies in how a network learns where MAC addresses live. VXLAN is purely a data-plane encapsulation format. It defines how to wrap an Ethernet frame inside a UDP packet, but it does not specify how Node 1 discovers that VM-B (MAC: 52:54:00:12:34:56) is currently running on Node 3.

In a plain VXLAN zone, Proxmox must rely on traditional Ethernet “flood-and-learn” mechanics:

  • Multicast Underlay: Nodes join an IP multicast group (e.g. 239.0.0.1). When a VM broadcasts an ARP request, Node 1 sends the encapsulated packet to the multicast group. Every node in the cluster receives and processes it. However, enterprise switches often drop multicast by default, IGMP snooping requires dedicated queriers, and running multicast over routed underlays is notoriously brittle.
  • Head-End Replication (HER / Unicast Mesh): If multicast is disabled, Node 1 must duplicate every broadcast, unknown unicast, and multicast (BUM) packet and send a unicast UDP copy to every single peer node in the cluster. With 3 nodes, this is manageable; with 8 or 16 nodes, BUM flooding saturates physical switch uplinks and CPU cycles.

Ethernet Virtual Private Network (EVPN) solves this by pairing VXLAN with Multiprotocol BGP (MP-BGP) per RFC 7432 and RFC 8365. Instead of flooding broadcast packets across the network to discover endpoints, hypervisors communicate through a BGP control plane running locally in the FRRouting (FRR) daemon.

When a virtual machine boots or connects to a VNet on Node 1, the Linux kernel detects its MAC and IP address. FRR immediately packages this binding into an MP-BGP update and transmits it over TCP port 179 to all peer nodes. Within milliseconds, every hypervisor in the cluster knows the exact VTEP (Virtual Tunnel Endpoint) IP address needed to reach that VM.

The EVPN Superpower: ARP Suppression In an EVPN zone, when a VM broadcasts an ARP request looking for another host, the local hypervisor intercepts the ARP packet. Because FRR already distributed the IP-to-MAC mapping via BGP Type-2 routes, the hypervisor answers the ARP request locally on behalf of the target! Zero broadcast packets hit the physical network.

The Three Core EVPN Route Types in Proxmox

Under the hood, FRRouting distributes three critical EVPN Network Layer Reachability Information (NLRI) route types across your Proxmox cluster:

  1. Type-2 (MAC/IP Advertisement Route): Advertises a specific guest MAC address and optional IP address along with its associated VXLAN Network Identifier (VNI). This enables direct unicast forwarding and hypervisor-level ARP suppression.
  2. Type-3 (Inclusive Multicast Ethernet Tag / IMET Route): Sets up automatic point-to-point unicast tunnel meshes for handling legitimate broadcast traffic without requiring physical switch multicast configurations.
  3. Type-5 (IP Prefix Route): Advertises an entire subnet prefix (e.g. 10.100.10.0/24) bound to a Layer 3 VRF (Virtual Routing and Forwarding) instance. This enables inter-VNet routing and external network route leaking.
Feature Traditional 802.1Q VLAN Plain VXLAN (No Controller) Proxmox BGP EVPN
Network Scale 4,094 VLANs max 16.7 Million VNIs (24-bit) 16.7 Million VNIs (24-bit)
Underlay Prerequisite VLAN-trunked L2 switches L3 IP network with Multicast/HER Standard routed L3 IP network (Unicast only)
Control Plane None (Data-plane learning) None (Flood-and-learn) MP-BGP via FRRouting (FRR)
BUM Traffic Handling Physical broadcast flooding Multicast or Head-End Replication Type-3 routes with Local ARP Suppression
Inter-Subnet Routing External Router (Hairpin) External Router VM (Hairpin) Distributed Anycast Gateway (Kernel wire-speed)
VM Live Migration Requires common L2 trunk Requires common L2 underlay Instant BGP Type-2 update with sequence bump

Architecture & Packet Encapsulation Flow

To debug Software-Defined Networking with confidence, you must be able to visualize the packet as it travels from a virtual machine’s virtual network interface card (vNIC) across the physical wire and into a destination VM.

The Anatomy of a VXLAN Packet

When a virtual machine sends an Ethernet frame into an EVPN VNet bridge, the hypervisor kernel wraps the entire original frame in a new set of outer network headers before transmitting it across the physical network:

+-----------------------------------------------------------------------------------------+
|                               Outer Physical Headers (50 Bytes)                         |
+-----------------------------+-----------------------------+-----------------------------+
| Outer Ethernet Header (14B) |   Outer IPv4 Header (20B)   |   Outer UDP Header (8B)     |
| Src MAC: PVE Node NIC       | Src IP: Node 1 VTEP IP      | Src Port: Dynamic Hash      |
| Dst MAC: Next-Hop Switch    | Dst IP: Node 2 VTEP IP      | Dst Port: 4789 (VXLAN)      |
+-----------------------------+-----------------------------+-----------------------------+
|                               VXLAN Header (8 Bytes)                                    |
+-----------------------------------------------------------------------------------------+
| Flags: 8 bits (I=1 valid)   | Reserved: 24 bits           | VNI: 24 bits (e.g. 10010)   |
+-----------------------------------------------------------------------------------------+
|                             Inner Tenant Payload (Original Frame)                       |
+-----------------------------------------------------------------------------------------+
| Inner Ethernet Header (14B) | Inner IP Header (20B)       | TCP/UDP & Tenant Data       |
| Src MAC: VM-A (App Server)  | Src IP: 10.100.10.15        | Payload Data                |
| Dst MAC: VM-B (Database)    | Dst IP: 10.100.10.25        |                             |
+-----------------------------------------------------------------------------------------+

Notice the outer UDP source port: the Linux kernel computes a hash of the inner payload’s Layer 3/4 headers and uses it as the outer UDP source port. This ensures that physical switches running Equal-Cost Multi-Path (ECMP) load-balancing will spread VXLAN tunnels evenly across bonded NICs and physical uplinks without inspecting the encapsulated tenant traffic.

Enterprise 3-Node Cluster Architecture Diagram

The diagram below illustrates a production-grade 3-node Proxmox VE cluster connected via a standard routed physical underlay, running an EVPN zone with distributed Anycast Gateways:

+-----------------------------------------------------------------------------------------+
|                                    PROXMOX VE CLUSTER                                   |
|                                                                                         |
|  +---------------------------+  +---------------------------+  +---------------------+  |
|  |       pve-01 (Node 1)     |  |       pve-02 (Node 2)     |  |   pve-03 (Node 3)   |  |
|  |  Physical IP: 192.168.10.1|  |  Physical IP: 192.168.10.2|  |  IP: 192.168.10.3   |  |
|  |  VTEP IP:     192.168.10.1|  |  VTEP IP:     192.168.10.2|  |  VTEP: 192.168.10.3 |  |
|  +-------------+-------------+  +-------------+-------------+  +----------+----------+  |
|                |                              |                           |             |
|                |  BGP EVPN Peering (TCP 179)  |                           |             |
|                |<============================>|                           |             |
|                |<========================================================>|             |
|                |              |<=========================================>|             |
|                |                              |                           |             |
|  +-------------v-------------+  +-------------v-------------+  +----------v----------+  |
|  |   VRF: vrf-enterprise     |  |   VRF: vrf-enterprise     |  | VRF: vrf-enterprise |  |
|  |   Anycast MAC:            |  |   Anycast MAC:            |  | Anycast MAC:        |  |
|  |   aa:bb:cc:dd:ee:ff       |  |   aa:bb:cc:dd:ee:ff       |  | aa:bb:cc:dd:ee:ff   |  |
|  +-------------+-------------+  +-------------+-------------+  +----------+----------+  |
|                |                              |                           |             |
|    +-----------+-----------+      +-----------+-----------+               |             |
|    |                       |      |                       |               |             |
| +--v--------+       +------v---+  +--v--------+       +------v---+     +------v---+         |
| | vnet-app  |       | vnet-db  |  | vnet-app  |       | vnet-db  |     | vnet-app |         |
| | VNI:10010 |       | VNI:10020|  | VNI:10010 |       | VNI:10020|     | VNI:10010|         |
| | Gw: .10.1 |       | Gw: .20.1|  | Gw: .10.1 |       | Gw: .20.1|     | Gw: .10.1|         |
| +-----+-----+       +-----+----+  +-----+-----+       +-----+----+     +-----+----+         |
|       |                   |             |                   |                |          |
|    +--v---+            +--v---+      +--v---+            +--v---+         +--v---+      |
|    | VM-A |            | VM-C |      | VM-B |            | VM-D |         | VM-E |      |
|    | Web1 |            | DB1  |      | Web2 |            | DB2  |         | Web3 |      |
|    +------+            +------+      +------+            +------+         +------+      |
|                                                                                         |
+-----------------------------------------------------------------------------------------+
                                             |
                     Physical Underlay Network (192.168.10.0/24)
                     MTU 9000 (Jumbo Frames) / UDP 4789 Enabled
                                             |
                                  +----------v----------+
                                  | Physical Core / ToR |
                                  |    Switch Fabric    |
                                  +---------------------+

The Distributed Anycast Gateway: Zero Hairpinning

In a standard network, every subnet has a single default gateway IP bound to a specific router interface (e.g. 10.100.10.1 on pfSense interface vlan10). If a host sends a packet to an outside subnet, it addresses the packet to the router’s physical MAC address.

In a Proxmox EVPN zone with Anycast Gateway enabled, the exact same default gateway IP address and Anycast MAC address exist simultaneously on every single hypervisor node in the cluster.

When VM-A (10.100.10.15) on Node 1 sends a query to VM-C (10.100.20.25) in the database subnet:

  1. VM-A issues an ARP query for its default gateway (10.100.10.1).
  2. The local Linux bridge on Node 1 intercepts the ARP and answers immediately with the shared Anycast MAC (e.g. aa:bb:cc:dd:ee:ff).
  3. VM-A sends the IP packet to the Anycast MAC. Node 1’s local kernel Layer 3 VRF receives the packet, performs a route lookup inside vrf-enterprise, routes the packet directly into the 10.100.20.0/24 subnet, encapsulates it in VXLAN (VNI 10020), and transmits it directly to Node 2.
  4. The packet enters Node 2, decapsulates, and is delivered to VM-C.

Inter-VNet routing happens entirely in hypervisor memory and kernel space at full line rate. No central router is involved, no firewall links are saturated, and inter-subnet latency drops from milliseconds to microseconds.

The Golden Rule: MTU Sizing and the 50-Byte Trap

There is a rite of passage every infrastructure engineer undergoes when deploying VXLAN for the first time: you set up the overlay, boot two Linux VMs on different nodes, and run ping 10.100.10.20. The ping replies instantly with sub-millisecond response times. You celebrate, open an SSH session to the remote VM, run ls -la /etc, and the terminal completely freezes.

You try curl https://example.com; it connects, exchanges TLS client hellos, and stalls dead. You can ping, but real traffic dies.

Welcome to the 50-Byte MTU Trap.

Standard Ethernet has a Maximum Transmission Unit (MTU) of 1,500 bytes. When a guest VM sends a full-size 1,500-byte TCP packet with the DF (Don’t Fragment) bit set, the hypervisor encapsulates it with outer Ethernet, IPv4, UDP, and VXLAN headers, creating a 1,550-byte physical frame:

Layer Header Component Size in Bytes
Outer L2 Outer Ethernet MAC Header (without 802.1Q tag) 14 bytes
Outer L3 Outer IPv4 Transport Header 20 bytes
Outer L4 Outer UDP Header (Destination Port 4789) 8 bytes
Overlay L4 VXLAN Shim Header (VNI and Flags) 8 bytes
Total VXLAN Encapsulation Overhead 50 bytes

If your physical switch or NIC is set to standard MTU 1,500, the physical switch encounters a 1,550-byte frame. Because the frame exceeds the physical MTU and the outer packet cannot be fragmented, the switch drops the packet silently. Short packets (like 64-byte ICMP pings or TCP SYN handshakes) slip through easily; full-sized TCP data payloads hit a brick wall. Path MTU Discovery (PMTUD) often fails because intermediate switches do not return ICMP “Fragmentation Needed” datagrams to the inner VM.

The Two MTU Design Strategies

Strategy A: 1450 Overlay

Underlay MTU: 1500 | Zone MTU: 1450
Used when physical switches cannot support jumbo frames. All guest VMs and DHCP servers must be explicitly configured for MTU 1450.

Strategy B: Jumbo Underlay

Underlay MTU: 9000 | Zone MTU: 1500
The gold standard. Physical NICs and switches run MTU 9000 (or 1550+). Tenant VMs run standard MTU 1500 with zero guest customization.

The Golden Rule

Underlay MTU ≥ Overlay MTU + 50
Never violate this inequality. If underlay is 1500, zone MTU must be 1450. If zone is 1500, underlay must be at least 1550.

Whenever possible in an enterprise homelab or production cluster, choose Strategy B. Set your physical NICs, Linux bonds, and switch trunk ports to MTU 9,000 (or at least 1,550 or 1,600). Set your Proxmox SDN Zone MTU to 1500. That way, any template, ISO, or guest OS you deploy operates with standard 1,500 MTU without touching guest network settings.

Required Ports, Protocols & Firewall Rules

Software-Defined Networking depends on both data plane encapsulation and control plane routing protocols. If you use Proxmox VE’s built-in datacenter firewall (pve-firewall), or if your nodes traverse an upstream managed firewall, you must ensure the following traffic matrix is explicitly permitted between all hypervisor cluster nodes:

Port / Protocol Protocol Direction Source Destination Architectural Purpose
4789/UDP UDP Inbound / Outbound PVE Cluster Nodes (VTEPs) PVE Cluster Nodes (VTEPs) VXLAN Data Plane: Encapsulated tenant Layer 2 frames (IANA assigned standard port).
179/TCP TCP Inbound / Outbound PVE Cluster Nodes PVE Cluster Nodes / Route Reflectors BGP EVPN Control Plane: FRRouting peering for Type-2 MAC/IP and Type-5 subnet distribution.
5404, 5405/UDP UDP Inbound / Outbound PVE Cluster Nodes PVE Cluster Nodes Corosync Cluster Quorum: Cluster state heartbeat and pmxcfs configuration replication.
8006/TCP TCP Inbound / Outbound Admin Workstations / Nodes PVE Cluster Nodes Proxmox Web GUI & REST API: Cluster management and SDN configuration staging.
22/TCP TCP Inbound / Outbound Admin Workstations / Nodes PVE Cluster Nodes SSH Maintenance & Tunneling: Cluster synchronisation, remote debugging, and console access.
60000–60050/TCP TCP Inbound / Outbound PVE Cluster Nodes PVE Cluster Nodes QEMU Live Migration: Memory state transfer during live VM workload migration between hosts.
3784/UDP UDP Inbound / Outbound PVE Cluster Nodes PVE Cluster Nodes BFD (Bidirectional Forwarding Detection): Optional sub-second BGP link failure detection.
Firewall rule note: If you enable the Proxmox Datacenter Firewall, create a cluster-wide Security Group called secgroup-sdn-underlay permitting incoming UDP 4789 and TCP 179 from your management/cluster IP subnet (e.g. 192.168.10.0/24). Apply this security group to the host firewall of every cluster node.

Step-by-Step Implementation: Building an EVPN Fabric

Let us walk through configuring a production-grade EVPN-VXLAN fabric across three Proxmox nodes (pve-01: 192.168.10.1, pve-02: 192.168.10.2, pve-03: 192.168.10.3). We will create two isolated workload tiers:

  • App Tier VNet (vnet-app): VNI 10010, Subnet 10.100.10.0/24, Anycast Gateway 10.100.10.1.
  • DB Tier VNet (vnet-db): VNI 10020, Subnet 10.100.20.0/24, Anycast Gateway 10.100.20.1.

Step 1: Install FRRouting Packages

While Proxmox VE 8.x includes the base SDN framework, BGP EVPN requires FRRouting (FRR) and its Python orchestration plugins. Run the following on all cluster nodes via SSH:

# Update repository indices and install FRRouting SDN packages
apt-get update
apt-get install -y frr frr-pythontools libpve-network-perl

# Ensure the FRR daemon is enabled and running at boot
systemctl enable --now frr

Step 2: Prepare Physical Interfaces with Jumbo MTU

On each node, configure the underlying physical network interface or Linux bridge with an MTU of 9,000 (or at least 1,550). Edit /etc/network/interfaces:

# /etc/network/interfaces (Example on pve-01)
auto lo
iface lo inet loopback

# Physical 10G NIC configured for Jumbo Frames
auto eno1
iface eno1 inet manual
	mtu 9000

# Standard management bridge for host access and VXLAN underlay transport
auto vmbr0
iface vmbr0 inet static
	address 192.168.10.1/24
	gateway 192.168.10.254
	bridge-ports eno1
	bridge-stp off
	bridge-fd 0
	mtu 9000
Production note: Apply network changes with ifreload -a. Verify that your physical switch ports supporting vmbr0/eno1 are also explicitly configured for MTU 9000 or 9216.

Step 3: Define the BGP EVPN Controller

The controller instructs FRR how to peer with cluster nodes. In a 3-node cluster, a full iBGP mesh (where all nodes peer with one another) is simple and resilient. We will use private Autonomous System Number (ASN) 65000.

In the Proxmox Web GUI, navigate to Datacenter → SDN → Controllers → Add → BGP:

  • ID: bgp-cluster
  • Node: (Leave blank for global, or configure per-node if individual router IDs are desired)
  • ASN: 65000
  • Peers: 192.168.10.1,192.168.10.2,192.168.10.3
  • eBGP: Disabled (unchecked, since all nodes share ASN 65000)

This compiles into /etc/pve/sdn/controllers.cfg:

# /etc/pve/sdn/controllers.cfg
bgp: bgp-cluster
	asn 65000
	peers 192.168.10.1,192.168.10.2,192.168.10.3

Step 4: Create the EVPN Zone with Anycast Gateway

Navigate to Datacenter → SDN → Zones → Add → EVPN:

  • ID: evpn-zone
  • Controller: bgp-cluster
  • VRF VXLAN ID (L3VNI): 10000 (Dedicated VXLAN ID used exclusively for routing between subnets)
  • Exit Nodes: pve-01,pve-02 (Nodes that have physical outbound internet access)
  • Exit Nodes Local Routing: Enabled (checked)
  • Advertise Subnets: Enabled (checked, distributes Type-5 prefix routes)
  • MTU: 1500 (Because our underlay is MTU 9000)
  • MAC: aa:bb:cc:dd:ee:ff (Shared Anycast MAC address for all default gateways)

This compiles into /etc/pve/sdn/zones.cfg:

# /etc/pve/sdn/zones.cfg
evpn: evpn-zone
	controller bgp-cluster
	vrf-vxlan 10000
	advertise-subnets 1
	exitnodes pve-01,pve-02
	exitnodes-local-routing 1
	ipam pve
	mac aa:bb:cc:dd:ee:ff
	mtu 1500

Step 5: Provision VNets and Subnets

Now we carve out our tenant networks inside the EVPN zone. Navigate to Datacenter → SDN → VNets → Add:

  1. Create VNet vnet-app:
    • Name: vnet-app
    • Zone: evpn-zone
    • Tag (VNI): 10010
  2. Select vnet-app, click Subnets → Add:
    • Subnet: 10.100.10.0/24
    • Gateway: 10.100.10.1
    • SNAT: Enabled (if VMs require outbound internet via exit nodes)
  3. Create VNet vnet-db:
    • Name: vnet-db
    • Zone: evpn-zone
    • Tag (VNI): 10020
  4. Select vnet-db, click Subnets → Add:
    • Subnet: 10.100.20.0/24
    • Gateway: 10.100.20.1
    • SNAT: Disabled (keeps database tier completely private)

These definitions populate /etc/pve/sdn/vnets.cfg and /etc/pve/sdn/subnets.cfg:

# /etc/pve/sdn/vnets.cfg
vnet: vnet-app
	zone evpn-zone
	tag 10010

vnet: vnet-db
	zone evpn-zone
	tag 10020

# /etc/pve/sdn/subnets.cfg
subnet: evpn-zone-10.100.10.0-24
	vnet vnet-app
	gateway 10.100.10.1
	snat 1

subnet: evpn-zone-10.100.20.0-24
	vnet vnet-db
	gateway 10.100.20.1

Step 6: Apply the Configuration Cluster-Wide

In the Proxmox Web GUI, go to Datacenter → SDN and click the blue Apply button. Alternatively, execute from the terminal on any node:

# Trigger cluster-wide SDN compilation and reload
pvesdn reload

Proxmox automatically regenerates /etc/network/interfaces.d/sdn, creates the Linux VRF vrf-evpn-zone, binds the VXLAN tunnel interfaces, and updates the FRRouting configuration in /etc/frr/frr.conf.

Connecting External Networks: Exit Nodes & pfSense Integration

An isolated overlay network is great for lab testing, but your VMs almost always need to reach the outside world: to install Debian packages, query external DNS servers, or allow you to access web services from your home workstation.

In Proxmox EVPN, external connectivity is handled by Exit Nodes using one of two patterns:

Pattern 1: Exit Nodes with Source NAT (SNAT)

When you enable SNAT on a subnet (as we did for 10.100.10.0/24 above) and specify exitnodes pve-01,pve-02 in the EVPN zone, Proxmox configures the designated exit nodes to masquerade outbound packets.

When VM-A (10.100.10.15) sends traffic to an internet IP address (e.g. 1.1.1.1):

  1. Node 1 routes the packet inside vrf-evpn-zone toward the primary exit node (pve-01) using the L3VNI (10000).
  2. Node 1 decapsulates the packet and passes it to the host’s physical default gateway (vmbr0), replacing the source IP 10.100.10.15 with the node’s physical IP (192.168.10.1) via iptables MASQUERADE.
  3. Inbound reply packets are demultiplexed by conntrack and sent back into the EVPN overlay to VM-A.

Pattern 2: Upstream BGP Peering to pfSense / OPNsense

In advanced enterprise labs, you may prefer true end-to-end routing without NAT. You can configure your upstream firewall (such as pfSense or OPNsense running the FRR package) to act as an external BGP peer to your Proxmox EVPN controller.

By establishing an eBGP session between pfSense (ASN 64512) and Proxmox (ASN 65000), Proxmox advertises its Type-5 subnet prefixes directly to pfSense. Your entire home network can then route directly into 10.100.10.0/24 without port forwarding or double NAT!

Operational Scripts & Inspection Commands

Use the comprehensive command reference below to inspect EVPN control plane state, verify VXLAN tunnel health, inspect BGP routing tables, and validate end-to-end MTU performance:

# ----------------------------------------------------------------------
# 1. SDN SERVICE & COMPILATION VERIFICATION
# ----------------------------------------------------------------------

# Inspect SDN zone status across cluster
pvesdn status

# Trigger local SDN reload and interface compilation
pvesdn reload

# Inspect dynamically generated SDN network interface definitions
cat /etc/network/interfaces.d/sdn

# Check FRRouting systemd daemon status
systemctl status frr

# Review recent FRR daemon logs for syntax or peering errors
journalctl -u frr -n 50 --no-pager


# ----------------------------------------------------------------------
# 2. FRROUTING (vtysh) CONTROL PLANE INSPECTION
# ----------------------------------------------------------------------

# Check BGP summary and peer session states (State must be Established)
vtysh -c 'show bgp summary'

# Inspect BGP L2VPN EVPN peering status and prefix exchange counts
vtysh -c 'show bgp l2vpn evpn summary'

# List all learned EVPN route advertisements (Type-2, Type-3, Type-5)
vtysh -c 'show bgp l2vpn evpn route'

# Inspect detailed VNI status, local VTEP IP, and Anycast MAC bindings
vtysh -c 'show evpn vni detail'

# View the EVPN MAC address table learned across all hypervisor nodes
vtysh -c 'show evpn mac vni all'

# View the EVPN neighbor ARP/IP table learned from hypervisor snooping
vtysh -c 'show evpn next-hops'

# Inspect the VRF routing table for inter-VNet routing
vtysh -c 'show ip route vrf vrf-evpn-zone'


# ----------------------------------------------------------------------
# 3. LINUX KERNEL DATA PLANE INSPECTION
# ----------------------------------------------------------------------

# List all kernel VXLAN network devices and their bound UDP ports
ip -d link show type vxlan

# Display all VRF (Virtual Routing and Forwarding) master devices
ip link show type vrf

# View the Layer 2 Forwarding Database (FDB) on the App VNet bridge
# Look for 'dst <remote_vtep_ip>' entries showing remote VM MAC locations
bridge fdb show dev vnet-app

# Inspect kernel IP route entries inside the EVPN VRF
ip route show vrf vrf-evpn-zone

# Verify that the Anycast Gateway IP and MAC are bound to the VNet bridge
ip addr show dev vnet-app


# ----------------------------------------------------------------------
# 4. PATH MTU & NETWORK CONNECTIVITY VALIDATION
# ----------------------------------------------------------------------

# Test physical underlay jumbo frame reachability with DF bit set
# 8972 bytes payload + 28 bytes IP/ICMP headers = 9000 bytes MTU
ping -M do -s 8972 -c 4 192.168.10.2

# Test overlay tenant MTU reachability from inside a guest VM
# 1472 bytes payload + 28 bytes headers = 1500 bytes standard MTU
ping -M do -s 1472 -c 4 10.100.10.25

# Trace UDP 4789 VXLAN encapsulation live on the physical interface
tcpdump -nn -i eno1 'udp port 4789' -c 10

# Trace BGP TCP 179 control plane keepalive traffic
tcpdump -nn -i vmbr0 'tcp port 179' -c 10
Healthy output verification: When you run vtysh -c 'show bgp l2vpn evpn summary', check the Up/Down and State/PfxRcd columns for each peer IP. If the state displays an integer (e.g. 4 or 6) rather than a word like Active or Connect, the BGP session is healthy and actively exchanging EVPN routes.

BGP EVPN Verification Cheat Sheet

When diagnosing EVPN control plane health in FRRouting via vtysh, use the status indicators below to evaluate BGP neighbor states and EVPN route advertisements:

Status / Symbol Technical Meaning Health Evaluation
State: Established TCP 3-way handshake complete; BGP OPEN and KEEPALIVE messages exchanged successfully. Healthy (Optimal state)
State: Active BGP daemon is actively attempting to establish a TCP connection with the peer but getting no reply or connection refused. Problem: Firewall dropping TCP 179, incorrect peer IP, or remote FRR stopped.
State: Connect BGP daemon is waiting for the TCP 3-way handshake to complete. Problem: Routing issue or network latency between hypervisors.
State: Idle BGP process is reset, waiting for start timer or administrative enabling. Investigate: Peer administratively shutdown or local interface down.
Route: [2]:[0]:... Type-2 Route: Advertises a tenant MAC and IP address associated with a VNI. Normal: Indicates active virtual machine or container endpoint.
Route: [3]:[0]:... Type-3 Route: Inclusive Multicast Ethernet Tag (IMET) advertising VTEP reachability for BUM traffic. Normal: Established automatically for every node participating in the VNI.
Route: [5]:[0]:... Type-5 Route: IP Prefix route advertising an entire subnet bound to a Layer 3 VRF. Normal: Enables inter-VNet routing and external route propagation.

Troubleshooting Playbook: Real Scars & Production Fixes

Even with careful planning, software-defined networking introduces failure modes that do not exist in standard bridged setups. Below is a diagnostic matrix compiled from real enterprise and homelab deployments:

Symptom Likely Root Cause Diagnostic & Resolution
BGP peers stuck in Active or Connect state TCP port 179 blocked by firewall, wrong peer IP in controllers.cfg, or FRR daemon not running on remote node. Check firewall with iptables -L -n -v | grep 179. Verify remote FRR with systemctl status frr. Test raw TCP connectivity with nc -zv 192.168.10.2 179.
Ping works between VMs, but SSH hangs on ls and HTTPS stalls The 50-Byte MTU Trap: Physical underlay MTU is 1500, causing 1550-byte encapsulated packets to be dropped by physical switches. Either increase physical switch and NIC MTU to 9000 (Strategy B), or reduce the EVPN zone MTU to 1450 in zones.cfg and reload SDN with pvesdn reload.
Inter-VNet routing fails between subnets (VM in App tier cannot reach DB tier) Missing or mismatched VRF-VXLAN ID (L3VNI), or advertise-subnets not enabled in zones.cfg. Confirm both subnets belong to the same EVPN zone. Verify vrf-vxlan 10000 is defined in /etc/pve/sdn/zones.cfg and check VRF routes with vtysh -c 'show ip route vrf vrf-evpn-zone'.
pvesdn reload throws syntax error or FRR fails to start Missing frr-pythontools package, corrupt controllers.cfg, or overlapping ASN configurations. Run apt-get install -y frr-pythontools. Test FRR syntax directly with vtysh -c 'show running-config' and check journalctl -u frr -e.
VM live migration succeeds, but VM loses network for 30–60 seconds Target node failed to send BGP Type-2 update with incremented MAC mobility sequence number, or ARP cache on peers is stale. Verify FRR version is ≥ 8.5. Inspect learned MACs on target host with vtysh -c 'show evpn mac vni 10010'. Ensure Anycast MAC is identical across all nodes.
VMs have no internet access through Exit Nodes Exit nodes missing snat 1 in subnets.cfg, physical IP forwarding disabled, or upstream router lacks static route. Verify net.ipv4.ip_forward = 1 in /etc/sysctl.conf on exit nodes. Confirm iptables MASQUERADE rule exists with iptables -t nat -L -n -v.
Duplicate IP or gateway flapping warnings in dmesg Different Anycast MAC configured on different nodes, or Anycast MAC left blank and auto-generated per-node. Explicitly set a static mac aa:bb:cc:dd:ee:ff in /etc/pve/sdn/zones.cfg so all hypervisors share the exact same gateway MAC address.
Production note: Never mix eBGP (different ASNs per node) and iBGP (same ASN across nodes) inside the same local Proxmox SDN controller unless you are peering with external Top-of-Rack data centre spine switches. In a standard cluster, stick to a single private ASN (such as 65000) for pure simplicity.

Final Thoughts

Software-Defined Networking transforms Proxmox VE from a capable hypervisor cluster into a true private cloud fabric. By shifting your network control plane from rigid physical switch trunks into BGP EVPN, you decouple your virtual workloads from physical cabling and VLAN limitations.

You gain the freedom to spin up complex multi-tier topologies, duplicate lab environments, and deploy ephemeral Kubernetes or Active Directory testing ranges in seconds—all while enjoying the wire-speed performance of distributed Anycast Gateways and the resilience of a self-healing BGP mesh.

Once you configure your underlay physical switches for Jumbo Frames and let FRRouting handle the heavy lifting, you will wonder how you ever tolerated managing 802.1Q switch trunks by hand.

Key takeaway: Treat your physical network as an unopinionated transport road (the underlay) and let BGP EVPN and VXLAN handle all segmentation, routing, and workload mobility (the overlay). Always obey the golden rule: Underlay MTU ≥ Overlay MTU + 50.
Next in this series

Next, we can explore advanced multi-site lab routing: peering your Proxmox EVPN fabric over pfSense Site-to-Site WireGuard tunnels, or combining SDN with Proxmox High Availability for automated zero-downtime workload recovery.


Discover more from Karanth.ovh

Subscribe to get the latest posts sent to your email.