From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 96B711FF138 for ; Wed, 18 Feb 2026 11:24:04 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id BC50B1850C; Wed, 18 Feb 2026 11:24:44 +0100 (CET) From: Hannes Laimer To: pve-devel@lists.proxmox.com Subject: [PATCH pve-docs 2/2] sdn: add exmaple for ipv6 in an evpn zone Date: Wed, 18 Feb 2026 11:23:50 +0100 Message-ID: <20260218102350.211294-7-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260218102350.211294-1-h.laimer@proxmox.com> References: <20260218102350.211294-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1771410240232 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.061 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: AWZN4XCK3QTHV3GZG4KVOMC3L42JSR2R X-Message-ID-Hash: AWZN4XCK3QTHV3GZG4KVOMC3L42JSR2R X-MailFrom: h.laimer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Hannes Laimer --- pvesdn.adoc | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/pvesdn.adoc b/pvesdn.adoc index 267ce97..e68a889 100644 --- a/pvesdn.adoc +++ b/pvesdn.adoc @@ -1424,6 +1424,218 @@ can reply back. If you have configured an external BGP router, the BGP-EVPN routes (10.0.1.0/24 and 10.0.2.0/24 in this example), will be announced dynamically. +[[pvesdn_setup_example_evpn_ipv6]] +EVPN with IPv6 Setup Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The example assumes a cluster with three nodes (node1, node2, node3) with P2P +connections between `node1<->node2` and `node2<->node3`. Additionally we'll +also need an `/48` IPv6 prefix routed to the exit node. + +We will start by creating an OpenFabric which will be the underlay for our EVPN +zone. Then we'll set up a VNet with two subnets, one with SLAAC and a `/96` one +with RA enabled and statically assigned IPs. + +.Prefixes +. to `node2` routed `/48`: `2001:db8:abcd::/48` +. `/64` subnet with SLAAC: `2001:db8:abcd:1::/64` +. `/96` subnet without SLAAC: `2001:db8:abcd:2::/96` + +.IPv6 forwarding +This has to be enabled on all nodes. +---- +sysctl -w net.ipv6.conf.all.forwarding=1 +---- + +NOTE: The underlay will be IPv4 based, the overlay IPv6. + +Setup `OpenFabric` +^^^^^^^^^^^^^^^^^^ + +. Create the fabric with `10.0.0.0/24` as its IPv4 prefix and `underlay` as its + name, we can leave the defaults for the rest +. Add the three nodes to the fabric, +.. `node1` with `10.0.0.1`, select P2P NIC between `node1<->node2` +.. `node2` with `10.0.0.2`, select both P2P NICs between `node1<->node2` and + `node2<->node3` +.. `node3` with `10.0.0.3`, select P2P NIC between `node2<->node3` +. Apply the changes + +The resulting config in `/etc/pve/sdn/fabrics.cfg` should look something like +this: + +---- +openfabric_fabric: underlay + ip_prefix 10.0.0.0/24 + +openfabric_node: underlay_node1 + interfaces name=ens19 + ip 10.0.0.1 + +openfabric_node: underlay_node2 + interfaces name=ens20 + interfaces name=ens19 + ip 10.0.0.2 + +openfabric_node: underlay_node3 + interfaces name=ens19 + ip 10.0.0.3 +---- + +Each node should now also be able to reach all of the others, this can quickly +be checked with a + +---- +ping 10.0.0.X +---- + +With `ip -4 r` you should also be able to see the respective `onlink` routes. + +---- +10.0.0.2 nhid 28 via 10.0.0.2 dev ens19 proto openfabric src 10.0.0.1 metric 20 onlink +10.0.0.3 nhid 28 via 10.0.0.2 dev ens19 proto openfabric src 10.0.0.1 metric 20 onlink +---- + +If this works we can continue. + +Create controller +^^^^^^^^^^^^^^^^^ + +Create an EVPN controller, keep `65000` as `ASN#` and select the `underlay` +fabric we have just created. For this we'll name the controller `v6ctl`. Then +apply the changes. + +The relevant config here is `/etc/pve/sdn/controllers.cfg`, and should look +like this: + +---- +evpn: v6ctl + asn 65000 + fabric underlay +---- + +Setup the zone +^^^^^^^^^^^^^^ + +Create a new EVPN zone, select the `v6ctl` as its controller, set the +`VRF_VXLAN Tag` to `6` and name it `v6zone`. As exit node select the node that +the `/48` prefix is routed to. Then apply the changes. + +The relevant config here is `/etc/pve/sdn/zones.cfg`, and after applying should +look something like this: + +---- +evpn: v6zone + controller v6ctl + vrf-vxlan 6 + exitnodes node2 + ipam pve + mac BC:24:11:F2:72:B8 +---- + + +Create the VNets +^^^^^^^^^^^^^^^^ + +.The bigger `/64` with SLAAC +Create a new VNet, name it `net64`, select `v6zone` as zone and set `64` as tag. + +.The smaller `/96` without SLAAC and static IPs +Create a new VNet, name it `net96`, select `v6zone` as zone and set `96` as tag. + +After applying `/etc/pve/sdn/vnets.cfg` should contain: + +---- +vnet: net64 + zone v6zone + tag 64 + +vnet: net96 + zone v6zone + tag 96 +---- + + +Setup the subnets +^^^^^^^^^^^^^^^^^ + +First we'll configure the `/64` subnet in `net64` with SLAAC: + +. Select the `net64` vnet +. Create subnet with `2001:db8:abcd:1::/64` and `2001:db8:abcd:1::1/64` as + gateway +. Under "IPv6 Options" check both `Enable RA` and `SLAAC (A)` + +Then configure the `/96` subnet in `net96`: + +. Select the `net96` vnet +. Create subnet with `2001:db8:abcd:2::/96` and `2001:db8:abcd:2::1/96` as + gateway +. Under "IPv6 Options" only check `Enable RA` + +NOTE: With RAs enabled a default gateway is advertised so we don't have to +specify a gateway explicitly for guests with a static IP. It'll also allow us to +advertise a DNS server, which can be handy because usually we'd need a whole DHCP +server for that. Whether the advertised DNS is used is somewhat client +dependent, as sometimes this option is ignored. + +The relevant config for these is `/etc/pve/sdn/subnets.cfg`, and after applying +these changes should contain + +---- +subnet: v6zone-2001:db8:abcd:1::-64 + vnet net64 + gateway 2001:db8:abcd:1::1 + nd-ra-enable 1 + nd-ra-flag-auto 1 + +subnet: v6zone-2001:db8:abcd:2::-96 + vnet net96 + gateway 2001:db8:abcd:2::1 + nd-ra-enable 1 +---- + +Result +^^^^^^ + +Now we can create two guests to test this, we'll use Debian CTs here, but any +guest will do. + +. configure first guest +.. Select `net64` as bridge during +.. leave the IPv4 section `static` and the IP field empty +.. for IPv6 select `SLAAC` +. configure second guest +.. select `net96` as bridge during +.. leave the IPv4 section `static` and the IP field empty +.. for IPv6 select `static` and set `2001:db8:abcd:2::200/96` as `IPv6` + +NOTE: We can leave `gateway` empty because we have RAs enabled on `net96`, +setting it is also not a problem, just not needed. + +Both guests should have a default route via the gateway's link-local address, +`ip -6 r` + +---- +default via fe80::be24:11ff:fef2:72b8 dev eth0 proto ra metric 1024 expires 1799sec hoplimit 64 pref medium +---- + +This address will match the link-local address on the host's `net64` (or `net96`) interfaces, `ip a show net64`. + +---- +7: net64: mtu 1450 qdisc noqueue master vrf_v6zone state UP group default qlen 1000 + link/ether bc:24:11:f2:72:b8 brd ff:ff:ff:ff:ff:ff + inet6 2001:db8:abcd:1::1/64 scope global + valid_lft forever preferred_lft forever + inet6 fe80::be24:11ff:fef2:72b8/64 scope link proto kernel_ll + valid_lft forever preferred_lft forever +---- + +Before the guests first traffic, `ip -6 neigh show vrf vrf_v6zone` will only +contain an entry for the guests link-local address. After the first `ping +2a00:1450:4001:818::2003`, also the guests GUA should have an entry. + + [[pvesdn_notes]] Notes -- 2.47.3