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
next prev parent 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