How to Filter BGP and EVPN Routes in Proxmox VE 9.2

Updated on Oct 10, 2026
Kimberly N
21 MINS READ
Table of Contents
Proxmox BGP EVPN configuration

Proxmox VE 9.2 added route maps and prefix lists to the SDN stack. Before this, if you wanted to filter BGP or EVPN routes, you had to edit frr.conf.local manually. Now you can create these filters in the web UI, and Proxmox writes the FRR config for you on every node.

What You Will Build

In this guide, you will learn to build a three-node EVPN network, connect it to an upstream router with BGP, and then use prefix lists and route maps to control which routes come in and go out.

Item Value
Nodes pve1, pve2, pve3
Node IPs (underlay) 192.168.50.11, 192.168.50.12, 192.168.50.13
Upstream router 192.168.50.1, ASN 65001
Cluster ASN 65000
Exit nodes pve1 (primary), pve2
EVPN controller evpnctl
EVPN zone evpnz1 (VRF VXLAN ID 4000, MTU 1450)
VNet web Tag 11000, subnet 172.16.10.0/24, gateway 172.16.10.1
VNet db Tag 11001, subnet 172.16.20.0/24, gateway 172.16.20.1
VNet lab Tag 11002, subnet 172.16.30.0/24, gateway 172.16.30.1

The goals of the filters are simple:

  • The upstream router can send us only the default route (0.0.0.0/0).
  • We send the upstream router only the web and db subnets. The lab subnet stays private.
  • Remote EVPN peers cannot announce the lab prefix to us.

The IP ranges and names here are examples. Replace them with your own values.

Requirements and Planning

Check these items before you start your Proxmox BGP EVPN configuration with route maps:

  • Three Proxmox VE 9.2 nodes in one cluster.
  • A private or routed network between the nodes with working IP connectivity.
  • Root SSH access to all nodes.
  • A router that can run BGP. A Linux box with FRR works well.
  • Open ports: TCP 179 (BGP) and UDP 4789 (VXLAN) between the nodes, plus TCP 179 to the upstream router.

Remember to use private ASNs only. The private ranges are 64512 to 65534 and 4200000000 to 4294967294. A public ASN can break real routing by mistake.

Check the Proxmox VE version

Before you build the EVPN fabric, make sure every node runs Proxmox VE 9.2. Route maps and prefix lists do not exist in older versions, so the menus will be missing in the UI. Run this on every node:

Bash
pveversion

You should see pve-manager/9.2.x. If not, update your server:

Bash
apt updateapt full-upgrade -y

You must reboot the server if a new kernel was installed.

Check the cluster

EVPN settings are stored in the shared SDN config, so all three nodes must be in one healthy cluster. If a node is out of sync or the cluster has no quorum, the SDN changes will not apply to every node. Run this check first to confirm all nodes are online:

Bash
pvecm status

Look for Quorate: Yes and three nodes. If you have no cluster yet, create it on pve1 and join the others:

Bash
# on pve1pvecm create evpncl # on pve2 and pve3pvecm add 192.168.50.11

Step 1: Prepare the Nodes

In this step, you get all three nodes ready for EVPN. You will install FRR, check the network file, set the right MTU, and open the ports that BGP and VXLAN need. Do every part on each node, so the fabric starts clean.

Install and enable FRR

FRR (FRRouting) is the routing software that runs BGP and EVPN on each Proxmox node. Proxmox SDN writes the FRR config for you, but FRR must be installed and running first. Install it on all three nodes with the commands below:

Bash
apt updateapt install frr frr-pythontools -ysystemctl enable --now frr.servicesystemctl status frr.service --no-pager

Check the SDN include line

SDN writes its network files to /etc/network/interfaces.d/. This line must be at the end of /etc/network/interfaces:

Bash
grep -n 'source /etc/network/interfaces.d' /etc/network/interfaces

If it prints nothing, make a backup and add it:

Bash
cp /etc/network/interfaces /etc/network/interfaces.bakecho 'source /etc/network/interfaces.d/*' >> /etc/network/interfaces

On a fresh Proxmox VE install, this line is already there.

Set the underlay MTU

VXLAN adds 50 bytes to every packet. So the MTU inside the overlay must be 50 bytes smaller than the MTU on the underlay. With a normal 1500 MTU on the underlay, the zone MTU is 1450. Open the network file:

Bash
nano /etc/network/interfaces

Make sure the bridge that carries the node IP has the MTU set. This example is for pve1. Change the address and the port name (eno1) to match your node:

Bash
auto vmbr0iface vmbr0 inet static    address 192.168.50.11/24    gateway 192.168.50.1    bridge-ports eno1    bridge-stp off    bridge-fd 0    mtu 1500

Apply the change and check it with the commands below:

Bash
ifreload -aip link show vmbr0 | grep mtu

Note: Be careful when you change network files over SSH. A wrong line can lock you out. If your provider allows jumbo frames (for example, MTU 9000), you can set mtu 9000 here and use 8950 in the zone later.

Open the firewall ports

If you use the Proxmox firewall, edit the cluster rules file. Because /etc/pve is shared, the rules reach all nodes:

Bash
nano /etc/pve/firewall/cluster.fw

Add these lines under the [RULES] section. Create the section if it does not exist:

Bash
[RULES]IN ACCEPT -source 192.168.50.0/24 -p tcp -dport 179 -log nolog # BGPIN ACCEPT -source 192.168.50.0/24 -p udp -dport 4789 -log nolog # VXLAN

If you turn on the firewall for the first time, keep SSH (port 22) and the web UI (port 8006) open, so you do not lock yourself out.

Step 2: Build the Base EVPN Fabric

First, you must build EVPN without filters. Then, you must add the filters later. This order makes problems easy to find in your Proxmox BGP EVPN configuration with route maps.

Create the EVPN controller

In the web UI, go to Datacenter > SDN > Options > Controllers > Add > EVPN, and fill in:

Field Value
ID evpnctl
ASN # 65000
Peers 192.168.50.11,192.168.50.12,192.168.50.13

The peer list must include every node, including the local one. Peers can also be external nodes or route reflectors.

If you prefer a CLI option, you can use the command below instead:

Bash
pvesh create /cluster/sdn/controllers \  --controller evpnctl --type evpn \  --asn 65000 \  --peers 192.168.50.11,192.168.50.12,192.168.50.13

Create the EVPN zone

From the web UI, go to Datacenter > SDN > Zones > Add > EVPN, and fill in:

Field Value
ID evpnz1
Controller evpnctl
VRF VXLAN ID 4000
Nodes pve1, pve2, pve3
Exit Nodes pve1, pve2
Primary Exit Node pve1
MTU 1450
Advertise Subnets Enabled

The VRF VXLAN ID must be different from the VXLAN IDs (tags) of the VNets. Exit nodes are the gateways to the real network, and they announce a default route inside EVPN. The primary exit node forces all outside traffic through pve1. This is needed when your upstream router does not support ECMP, or when you use SNAT. Advertise Subnets helps when a VM is silent, because it announces the full subnet.

If you prefer a CLI option, you can use the command below instead:

Bash
pvesh create /cluster/sdn/zones \  --zone evpnz1 --type evpn \  --controller evpnctl \  --vrf-vxlan 4000 \  --nodes pve1,pve2,pve3 \  --exitnodes pve1,pve2 \  --exitnodes-primary pve1 \  --advertise-subnets 1 \  --mtu 1450

Create the VNets and subnets

At this point, go to Datacenter > SDN > VNets > Create. VNet IDs can have up to 8 characters:

VNet Zone Tag Subnet Gateway
web evpnz1 11000 172.16.10.0/24 172.16.10.1
db evpnz1 11001 172.16.20.0/24 172.16.20.1
lab evpnz1 11002 172.16.30.0/24 172.16.30.1

After you create a VNet, select it and add the subnet in the Subnets panel. In an EVPN zone, the gateway is deployed on the VNet on every node, so VMs can use it as an anycast gateway.

If you prefer a CLI option, you can use the command below instead:

Bash
for v in "web 11000 172.16.10.0/24 172.16.10.1" \         "db 11001 172.16.20.0/24 172.16.20.1" \         "lab 11002 172.16.30.0/24 172.16.30.1"; do  set -- $v  pvesh create /cluster/sdn/vnets --vnet "$1" --zone evpnz1 --tag "$2"  pvesh create /cluster/sdn/vnets/"$1"/subnets \    --subnet "$3" --type subnet --gateway "$4"done

Apply the changes and Check the base fabric

SDN changes stay pending until you apply them. In the UI, go to Datacenter > SDN and click Apply. Or use the CLI:

Bash
pvesh set /cluster/sdn

To check the base fabric, run these on each node:

Bash
vtysh -c "show bgp l2vpn evpn summary"ip -br link show webip -d link show vxlan_webip -br link show type vrf

You should see two established neighbors in the EVPN summary, a web bridge, a vxlan_web device with MTU 1450, and a VRF named vrf_evpnz1.

You can also see the generated files with the following commands:

Bash
ls /etc/pve/sdncat /etc/pve/sdn/controllers.cfgcat /etc/pve/sdn/zones.cfg

Test with two guests

Create two VMs or containers. Put one on pve2 and one on pve3. Set their network bridge to web. Inside each guest, set a static IP and the right MTU. On Debian, edit /etc/network/interfaces in the guest:

Bash
auto eth0iface eth0 inet static    address 172.16.10.11/24    gateway 172.16.10.1    mtu 1450

Use 172.16.10.12/24 for the second guest. Restart the network, then test:

Bash
ping -c 3 172.16.10.1ping -c 3 172.16.10.12ping -M do -s 1422 -c 3 172.16.10.12

The last ping sends the biggest packet that fits: 1422 bytes of data plus 28 bytes of headers equals 1450. If it works, the overlay MTU is correct.

Step 3: Create the Prefix Lists

This is the main part of the Proxmox BGP EVPN configuration with route maps setup. You must create the prefix lists. Go to Datacenter > SDN > Prefix Lists > Add. Create three lists. 

The names only_default, only_default_v6, and loopbacks_ips are reserved. Proxmox creates them itself, so do not use them.

List 1: default-only

This first prefix list matches only the default route (0.0.0.0/0). We will use it later to accept nothing else from the upstream router. Create it with the values below:

Seq Action Prefix ge le
10 permit 0.0.0.0/0 empty empty

With no ge or le, this matches exactly 0.0.0.0/0. It does not match other routes.

List 2: tenant-nets

This second prefix list matches the web and db subnets. We will use it to control which networks we send to the upstream router. Leave the lab subnet out of this list:

Seq Action Prefix ge le
10 permit 172.16.10.0/24 empty empty
20 permit 172.16.20.0/24 empty empty

List 3: lab-net

This third prefix list matches the lab subnet and every smaller route inside it, such as host routes. We will use it later to block the lab network from remote EVPN peers. Create it with the values below:

Seq Action Prefix ge le
10 permit 172.16.30.0/24 24 32

Here ge 24 and le 32 match the /24 itself and also smaller routes inside it, such as /32 host routes. Proxmox checks that ge is not bigger than le, and that neither is smaller than the prefix length.

Leave gaps in the sequence numbers (10, 20, 30). This leaves room to add lines later.

Step 4: Create the Route Maps

Route maps use the prefix lists to decide what to do with each route. Go to Datacenter > SDN > Route Maps > Add. Each entry has an Order (0 to 65535), an Action, and optional Match and Set values. You must create these entries.

Route map: from-upstream

This map controls what we accept from the upstream router. Create it with the values below:

Order Action Match Set
10 permit ip-address-prefix-list = default-only local-preference = 200

Only the default route passes. Every other route is dropped automatically. The route also gets a higher local preference.

Route map: to-upstream

This map controls what we announce to the upstream router. Create it with the values below:

Order Action Match Set
10 permit ip-address-prefix-list = tenant-nets metric = 100

Only 172.16.10.0/24 and 172.16.20.0/24 can leave. The lab subnet is dropped automatically, so it stays private.

Route map: evpn-in

This map controls what we accept from other EVPN peers. Create it with the values below:

Order Action Match Set
10 deny route-type = prefix and ip-address-prefix-list = lab-net none
20 permit none (matches all) none

An entry applies only when all of its match rules are true. Entry 10 drops only prefix routes (EVPN type-5) that match the lab network. Entry 20 lets all other routes pass. Without entry 20, every other EVPN route would be dropped, and the fabric would break.

This map blocks the lab prefix route from remote peers. VM-level routes (type-2) are not touched, so VMs in lab can still talk to each other.

Step 5: Peer with the Upstream Router

Exit nodes talk to the upstream router with BGP. This part of the Proxmox BGP EVPN configuration with route maps guide adds that link. You must create one BGP controller per exit node.

Create the BGP controllers

Go to Datacenter > SDN > Options > Controllers > Add > BGP and fill in:

Field bgp-pve1 bgp-pve2
Node pve1 pve2
ASN # 65000 65000
Peer 192.168.50.1 192.168.50.1
EBGP Enabled Enabled
Route Map In from-upstream from-upstream
Route Map Out to-upstream to-upstream

The ASN here is the local ASN of the node. EBGP is on because the upstream router has a different ASN (65001). The peer is directly connected, so you do not need ebgp-multihop.

If you prefer the CLI option, you can use the command below:

Bash
for n in pve1 pve2; do  pvesh create /cluster/sdn/controllers \    --controller bgp-$n --type bgp --node $n \    --asn 65000 --peers 192.168.50.1 --ebgp 1 \    --route-map-in from-upstream --route-map-out to-upstreamdone

Fix the EVPN controller

When a BGP controller exists, and the EVPN controller is in auto mode, the EVPN peers reuse the BGP session type. That makes the node-to-node sessions eBGP, and they will fail because all nodes use the same ASN. To avoid this, you must set the type manually.

Open Datacenter > SDN > Options > Controllers, edit evpnctl, and set:

Field Value
BGP Mode internal
Route Map In evpn-in

The nodes now use iBGP between each other (same ASN 65000) and eBGP to the upstream router.

Apply the changes and Configure the upstream router

To apply the changes, go to Datacenter > SDN and click Apply. Or, run the command below:

Bash
pvesh set /cluster/sdn

To configure the upstream router, you can use a Linux router with FRR. Install it and turn on the BGP daemon:

Bash
apt updateapt install frr -ysed -i 's/^bgpd=no/bgpd=yes/' /etc/frr/daemonssystemctl restart frr

Then, open the FRR shell and add the config:

Bash
vtysh
Bash
configure terminalrouter bgp 65001 bgp router-id 192.168.50.1 no bgp ebgp-requires-policy neighbor 192.168.50.11 remote-as 65000 neighbor 192.168.50.12 remote-as 65000 address-family ipv4 unicast  neighbor 192.168.50.11 default-originate  neighbor 192.168.50.12 default-originate exit-address-familyexitendwrite memory

The default-originate lines send a default route to both exit nodes. The line no bgp ebgp-requires-policy is for the lab only. Newer FRR blocks eBGP routes if no route map is set on the session. In production, use route maps on the router too.

Step 6: Apply Proxmox BGP EVPN Configuration

Proxmox now has the full filter set. This is what each node does after you apply. The EVPN controller keeps its own built-in MAP_VTEP_IN and MAP_VTEP_OUT maps and calls your map from them.

On exit nodes, Proxmox also keeps a built-in rule that denies default routes inside EVPN. This stops traffic loops between exit nodes, and your map does not remove it.

Use the commands below to look at what Proxmox stored:

Bash
pvesh get /cluster/sdn/prefix-listspvesh get /cluster/sdn/route-mapsls /etc/pve/sdn

You should see the files prefix-lists.cfg and route-maps.cfg in that folder. Do not edit them manually. Use the UI or the API.

Now you must look at what FRR got. Run this on pve1:

Bash
vtysh -c "show running-config" | grep -E -A3 'prefix-list|route-map'
Bash
Example Output:  ip prefix-list default-only seq 10 permit 0.0.0.0/0ip prefix-list tenant-nets seq 10 permit 172.16.10.0/24ip prefix-list tenant-nets seq 20 permit 172.16.20.0/24ip prefix-list lab-net seq 10 permit 172.16.30.0/24 ge 24 le 32route-map from-upstream permit 10 match ip address prefix-list default-only set local-preference 200route-map to-upstream permit 10 match ip address prefix-list tenant-nets set metric 100

If the lines are missing, you forgot to click Apply, or the map is not attached to a controller.

Step 7: Verify the Result

Now you must check that everything works as planned. In this step, you should look at the BGP sessions, the routes you accept and announce, and the EVPN routes. Also, you should confirm that your route maps are being used.

Check the BGP sessions

First, make sure the BGP sessions are up. If a session is down, no routes can move, and the route maps have nothing to filter. Run these commands on each node:

Bash
vtysh -c "show bgp summary"vtysh -c "show bgp l2vpn evpn summary"

On the exit nodes, the neighbor 192.168.50.1 must be in the Established state, and it must show 1 prefix received. The two EVPN peers must be established too.

Check what we accept

Next, check which routes the exit nodes accept from the upstream router. The from-upstream route map should let only the default route through. Run these commands on pve1 and pve2:

Bash
vtysh -c "show bgp ipv4 unicast neighbors 192.168.50.1 received-routes"vtysh -c "show bgp ipv4 unicast"

The first command shows routes before the incoming map. The second shows routes after it. Only 0.0.0.0/0 should be in the second list, with local preference 200.

Check what we announce

Now check which routes the exit nodes send to the upstream router. The to-upstream route map should allow only the web and db subnets. Run this command on pve1 and pve2:

Bash
vtysh -c "show bgp ipv4 unicast neighbors 192.168.50.1 advertised-routes"

You should see 172.16.10.0/24 and 172.16.20.0/24 with metric 100. You must not see 172.16.30.0/24. On the upstream router, check the same:

Bash
vtysh -c "show bgp ipv4 unicast"

Check the EVPN routes and the VRF

At this point, you must look at the EVPN side. These commands show the routes shared between nodes, the routes inside the VRF, and the VNIs that are active. Run them on each node and compare the output:

Bash
vtysh -c "show bgp l2vpn evpn route type prefix"vtysh -c "show bgp l2vpn evpn route type macip"vtysh -c "show ip route vrf vrf_evpnz1"vtysh -c "show evpn vni"

Check that the maps are used

Finally, you must confirm that FRR is really using your prefix lists and route maps. Each route map shows a counter that goes up every time it is used. Run these commands on each node:

Bash
vtysh -c "show ip prefix-list"vtysh -c "show route-map from-upstream"vtysh -c "show route-map to-upstream"vtysh -c "show route-map evpn-in"

The route map output has an Invoked counter. If a map is never invoked, it is not attached to the session.

Test from a guest

From a guest in web, check outside access and that the lab subnet is not visible upstream:

Bash
ping -c 3 172.16.20.12ping -c 3 192.168.50.1

Outside traffic needs the upstream router to know the way back to 172.16.10.0/24. If it does not, enable SNAT on the subnet, or add routes on the router.

Change a rule and re-check

When you change a map, you must apply the SDN, and then ask FRR to resend routes without resetting the session:

Bash
vtysh -c "clear bgp ipv4 unicast 192.168.50.1 soft in"vtysh -c "clear bgp ipv4 unicast 192.168.50.1 soft out"

Running EVPN Over a WireGuard Tunnel

This guide builds one site on a private routed network. If your nodes are in different data centers and you need an encrypted link, you must build the tunnel first. You can check our guide on how to build a multi-site Proxmox SDN with a WireGuard fabric. In that setup, the tunnel is the underlay.

If you want to run this EVPN design over that tunnel, you must follow these rules:

  • Use the WireGuard addresses as the EVPN controller peers.
  • Use the tunnel MTU rule from that guide: 1370 in the zone and in the guests.
  • Use different IP ranges for the tenant networks. Do not reuse the ranges of the tunnel.
  • Do not open UDP 4789 on public interfaces. Allow it only on the tunnel interface.

How to Fix Common BGP EVPN Issues

Even with a good setup, things can go wrong. In this section, you can find the most common problems, such as missing routes, wrong ASNs, MTU issues, and one-way traffic. Each problem comes with simple checks and fixes.

Missing routes

Most Proxmox BGP EVPN configuration issues come from the session or the map. Start with the session, then the map.

Bash
vtysh -c "show bgp summary"vtysh -c "show bgp l2vpn evpn summary"vtysh -c "show route-map"vtysh -c "show ip prefix-list"

Common causes and fixes include:

  • You did not click Apply. Check with pvesh get /cluster/sdn/route-maps and vtysh -c "show running-config".
  • The implicit deny drops the route. Add a final permit entry if you want everything else to pass.
  • The prefix does not match. A line without ge or le matches one exact network. A /24 route does not match a /16 entry unless you set le 24 or ge 24.
  • The sequence is wrong. The first match wins, so a deny with a low number can hide a later permit.
  • The default route is missing inside EVPN. On exit nodes, Proxmox's built-in rule drops default routes from other EVPN peers on purpose. The default route comes from the exit nodes themselves.
  • The session shows (Policy) in show bgp summary. FRR blocks eBGP routes when no route map is set. Attach a map to the session.
  • The route was filtered in the past, and you changed the map. Run clear bgp ... soft in.

Wrong ASNs

When a BGP session will not come up, the state and the last error usually tell you why. Run these commands to see both:

Bash
vtysh -c "show bgp summary"vtysh -c "show bgp neighbors 192.168.50.1" | grep -E 'remote AS|BGP state|Last reset'journalctl -u frr -n 50 --no-pager

Common causes and fixes include:

  • The state is Idle or Active. The peer is not reachable; the firewall blocks TCP 179, or the ASN does not match.
  • The log says Bad Peer AS. The remote ASN on one side is wrong. Check the neighbor ... remote-as line on the router.
  • All EVPN controllers on one node must use the same ASN.
  • If a node has two iBGP sessions with different ASNs, Proxmox rejects the config. One FRR instance has only one local ASN.
  • The EVPN peers are eBGP when they should be iBGP. Set BGP Mode to internal on the EVPN controller.
  • You used a public ASN. Use private ASNs only.

MTU issues

Use this section to check for MTU problems when ping works but SSH, HTTPS, or file transfers hang. Test the network between the nodes, then test from inside a guest.

Bash
ping -M do -s 1472 -c 3 192.168.50.12ping -M do -s 1422 -c 3 172.16.10.12

Common causes and fixes include:

  • The zone MTU is bigger than the underlay MTU minus 50.
  • The guest MTU is still 1500. Set it to the zone MTU in the guest network file.
  • A switch or the provider network has a smaller MTU than you think.
  • The MTU on the node bridge went back to default after a reload. Check ip link show vmbr0.

Asymmetric reachability

Use this section when traffic works in one direction, but replies do not return. Check the routes on both sides, then review the route maps, exit nodes, and firewall rules.

Bash
vtysh -c "show bgp l2vpn evpn route type macip"vtysh -c "show bgp l2vpn evpn route type prefix"vtysh -c "show ip route vrf vrf_evpnz1"vtysh -c "show evpn mac vni 11000"

Run these on both nodes and compare. Common causes and fixes include:

  • A route map filters routes on one node only. Check the maps on both sides with show route-map.
  • You have two exit nodes, but the upstream router sends replies to the other one. Use a primary exit node, or make sure the upstream router uses ECMP.
  • The upstream router has no route back to the tenant subnet. Check show bgp ipv4 unicast on it. Fix the to-upstream map, enable SNAT, or add a static route.
  • A silent VM is not seen by the network. Turn on Advertise Subnets in the zone.
  • A floating IP moves between VMs. Turn on Disable ARP ND Suppression in the zone.
  • You want to reach a guest from an exit node itself. By default, exit nodes only forward. Turn on Exit Nodes Local Routing.
  • A firewall sees only one direction of a flow and drops it. Check firewall rules on both nodes.

Conclusion

At this point, you have a Proxmox VE 9.2 EVPN fabric with BGP peers, VNets, and route filters. Prefix lists select the networks, and route maps control which routes you accept and announce. Before using the setup in production, check the BGP sessions, routes, MTU, and traffic in both directions.

Plan your ASNs, MTU, and exit nodes, then test each route map before going live. For this setup, you can use dedicated hosting for virtual networks.

Proxmox VE 9.2 can create route maps and prefix lists in the SDN. You can attach them to BGP and EVPN controllers.

In the web UI, under Datacenter > SDN > Prefix Lists and Datacenter > SDN > Route Maps.

In the shared folder /etc/pve/sdn/, in prefix-lists.cfg and route-maps.cfg.

No. A simple full mesh of nodes needs only an EVPN controller. Add a BGP controller when you peer with an outside router or use a different ASN per node.