all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH pve-network 1/6] sdn: evpn: prepare IPv6 underlay support
Date: Thu, 22 Jan 2026 14:51:46 +0100	[thread overview]
Message-ID: <20260122135151.292794-2-h.laimer@proxmox.com> (raw)
In-Reply-To: <20260122135151.292794-1-h.laimer@proxmox.com>

Align EVPN's fabric and peer handling with VXLAN. So IPv6-capable
underlays can be selected and IPv6 peers configured.

Like with VXLAN, we don't support a dual-stack underlay, the reasoning
is the same. There is no real value adding that.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
 src/PVE/Network/SDN/Controllers/EvpnPlugin.pm | 70 ++++++++++++++++---
 src/PVE/Network/SDN/Zones/EvpnPlugin.pm       | 28 ++++++--
 2 files changed, 83 insertions(+), 15 deletions(-)

diff --git a/src/PVE/Network/SDN/Controllers/EvpnPlugin.pm b/src/PVE/Network/SDN/Controllers/EvpnPlugin.pm
index e53000a..88bdcb8 100644
--- a/src/PVE/Network/SDN/Controllers/EvpnPlugin.pm
+++ b/src/PVE/Network/SDN/Controllers/EvpnPlugin.pm
@@ -82,22 +82,41 @@ sub generate_frr_config {
             return;
         }
 
-        if (!$current_node->{ip}) {
+        my $all_v6 = 1;
+        my $all_v4 = 1;
+        for my $node (values %$nodes) {
+            $all_v6 = 0 if !$node->{ip6};
+            $all_v4 = 0 if !$node->{ip};
+        }
+
+        my $addr_key;
+        if ($all_v6) {
+            $addr_key = 'ip6';
+        } elsif ($all_v4) {
+            $addr_key = 'ip';
+        } else {
             log_warn(
-                "Node $local_node requires an IP in the fabric $fabric->{id} to configure the EVPN controller"
+                "Fabric $fabric->{id} has no consistent address family for all nodes (need all v6 or all v4)"
+            );
+            return;
+        }
+
+        if (!$current_node->{$addr_key}) {
+            log_warn(
+                "Node $local_node requires a $addr_key address in the fabric $fabric->{id} to configure the EVPN controller"
             );
             return;
         }
 
         for my $node_id (sort keys %$nodes) {
             my $node = $nodes->{$node_id};
-            push @peers, $node->{ip} if $node->{ip};
+            push @peers, $node->{$addr_key} if $node->{$addr_key};
         }
 
         $loopback = "dummy_$fabric->{id}";
 
-        $ifaceip = $current_node->{ip};
-        $routerid = $current_node->{ip};
+        $ifaceip = $current_node->{$addr_key};
+        $routerid = $current_node->{$addr_key};
 
     } elsif ($plugin_config->{'peers'}) {
         @peers = PVE::Tools::split_list($plugin_config->{'peers'});
@@ -216,21 +235,40 @@ sub generate_zone_frr_config {
             return;
         }
 
-        if (!$current_node->{ip}) {
+        my $all_v6 = 1;
+        my $all_v4 = 1;
+        for my $node (values %$nodes) {
+            $all_v6 = 0 if !$node->{ip6};
+            $all_v4 = 0 if !$node->{ip};
+        }
+
+        my $addr_key;
+        if ($all_v6) {
+            $addr_key = 'ip6';
+        } elsif ($all_v4) {
+            $addr_key = 'ip';
+        } else {
+            log_warn(
+                "Fabric $fabric->{id} has no consistent address family for all nodes (need all v6 or all v4)"
+            );
+            return;
+        }
+
+        if (!$current_node->{$addr_key}) {
             log_warn(
-                "Node $local_node requires an IP in the fabric $fabric->{id} to configure the EVPN controller"
+                "Node $local_node requires a $addr_key address in the fabric $fabric->{id} to configure the EVPN controller"
             );
             return;
         }
 
         for my $node (values %$nodes) {
-            push @peers, $node->{ip} if $node->{ip};
+            push @peers, $node->{$addr_key} if $node->{$addr_key};
         }
 
         $loopback = "dummy_$fabric->{id}";
 
-        $ifaceip = $current_node->{ip};
-        $routerid = $current_node->{ip};
+        $ifaceip = $current_node->{$addr_key};
+        $routerid = $current_node->{$addr_key};
 
     } elsif ($controller->{peers}) {
         @peers = PVE::Tools::split_list($controller->{'peers'}) if $controller->{'peers'};
@@ -497,6 +535,18 @@ sub on_update_hook {
         die "must have exactly one of peers / fabric defined"
             if ($controller->{peers} && $controller->{fabric})
             || !($controller->{peers} || $controller->{fabric});
+        if ($controller->{peers}) {
+            my @peers = PVE::Tools::split_list($controller->{peers});
+            my $family;
+
+            foreach my $peer (@peers) {
+                my $peer_family = Net::IP::ip_is_ipv6($peer) ? 6 : 4;
+                if (defined($family) && $family != $peer_family) {
+                    die "peers must contain only IPv4 or only IPv6 addresses\n";
+                }
+                $family = $peer_family;
+            }
+        }
     }
 }
 
diff --git a/src/PVE/Network/SDN/Zones/EvpnPlugin.pm b/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
index 6d89499..227d917 100644
--- a/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
+++ b/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
@@ -176,17 +176,35 @@ sub generate_sdn_config {
         my $current_node = eval { $config->get_node($controller->{fabric}, $local_node) };
         die "could not configure EVPN zone $plugin_config->{id}: $@" if $@;
 
-        die "Node $local_node requires an IP in the fabric $fabric->{id} to configure the EVPN zone"
-            if !$current_node->{ip};
+        my $all_v6 = 1;
+        my $all_v4 = 1;
+        for my $node (values %$nodes) {
+            $all_v6 = 0 if !$node->{ip6};
+            $all_v4 = 0 if !$node->{ip};
+        }
+
+        my $addr_key;
+        if ($all_v6) {
+            $addr_key = 'ip6';
+        } elsif ($all_v4) {
+            $addr_key = 'ip';
+        } else {
+            die
+                "Fabric $fabric->{id} has no consistent address family for all nodes (need all v6 or all v4)";
+        }
+
+        die
+            "Node $local_node requires a $addr_key address in the fabric $fabric->{id} to configure the EVPN zone"
+            if !$current_node->{$addr_key};
 
         for my $node (values %$nodes) {
-            push @peers, $node->{ip} if $node->{ip};
+            push @peers, $node->{$addr_key} if $node->{$addr_key};
         }
 
         $loopback = "dummy_$fabric->{id}";
 
-        $ifaceip = $current_node->{ip};
-        $routerid = $current_node->{ip};
+        $ifaceip = $current_node->{$addr_key};
+        $routerid = $current_node->{$addr_key};
     } else {
         die "neither fabric nor peers configured for EVPN controller $controller->{id}";
     }
-- 
2.47.3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  reply	other threads:[~2026-01-22 13:52 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-22 13:51 [pve-devel] [PATCH network 0/6] add EVPN IPv6 underlay support Hannes Laimer
2026-01-22 13:51 ` Hannes Laimer [this message]
2026-01-22 13:51 ` [pve-devel] [PATCH pve-network 2/6] sdn: controller: fallback to interface mac if no master Hannes Laimer
2026-01-22 13:51 ` [pve-devel] [PATCH pve-network 3/6] sdn: controller: prevent invalid router-id generation from zero mac Hannes Laimer
2026-01-22 13:51 ` [pve-devel] [PATCH pve-network 4/6] sdn: evpn: keep router-id valid on IPv6 underlay Hannes Laimer
2026-01-22 13:51 ` [pve-devel] [PATCH pve-network 5/6] sdn: vxlan: sort peer IPs when generating sdn config Hannes Laimer
2026-01-22 13:51 ` [pve-devel] [PATCH pve-network 6/6] sdn: evpn: add tests covering ipv6 underlays Hannes Laimer
2026-05-15 11:08 ` superseded: [pve-devel] [PATCH network 0/6] add EVPN IPv6 underlay support Hannes Laimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260122135151.292794-2-h.laimer@proxmox.com \
    --to=h.laimer@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal