public inbox for pve-devel@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: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-22 13:51 [pve-devel] [PATCH network 0/6] add EVPN " 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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal