[pve-devel] [PATCH pve-network 1/6] sdn: evpn: prepare IPv6 underlay support
Hannes Laimer
h.laimer at proxmox.com
Thu Jan 22 14:51:46 CET 2026
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 at 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
More information about the pve-devel
mailing list