From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH pve-network 1/2] sdn: vxlan: make local underlay selection work for IPv6 peers
Date: Fri, 16 Jan 2026 12:08:41 +0100 [thread overview]
Message-ID: <20260116110843.89615-2-h.laimer@proxmox.com> (raw)
In-Reply-To: <20260116110843.89615-1-h.laimer@proxmox.com>
IPv6 peers couldn't be matched to local underlay addresses, so nodes
would not skip their own peer IP. We need this for VXLAN IPv6 support.
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
src/PVE/Network/SDN/Zones/Plugin.pm | 72 +++++++++++++++++--
.../zones/vxlan/ipv6/expected_sdn_interfaces | 15 ++++
src/test/zones/vxlan/ipv6/interfaces | 7 ++
src/test/zones/vxlan/ipv6/sdn_config | 17 +++++
4 files changed, 104 insertions(+), 7 deletions(-)
create mode 100644 src/test/zones/vxlan/ipv6/expected_sdn_interfaces
create mode 100644 src/test/zones/vxlan/ipv6/interfaces
create mode 100644 src/test/zones/vxlan/ipv6/sdn_config
diff --git a/src/PVE/Network/SDN/Zones/Plugin.pm b/src/PVE/Network/SDN/Zones/Plugin.pm
index 826ebdf..bfa96f7 100644
--- a/src/PVE/Network/SDN/Zones/Plugin.pm
+++ b/src/PVE/Network/SDN/Zones/Plugin.pm
@@ -4,6 +4,7 @@ use strict;
use warnings;
use PVE::Tools qw(run_command);
+use Net::IP qw(ip_is_ipv6);
use PVE::IPRoute2;
use PVE::JSONSchema;
use PVE::Cluster;
@@ -278,14 +279,54 @@ sub del_bridge_fdb {
#helper
+sub _normalize_ip {
+ my ($ip) = @_;
+
+ return undef if !defined($ip);
+ $ip =~ s!/.*$!!;
+ return $ip;
+}
+
+sub _get_iface_addresses {
+ my ($iface_cfg) = @_;
+
+ return () if !$iface_cfg;
+
+ my @addrs;
+ for my $key (qw(address address6)) {
+ my $val = $iface_cfg->{$key};
+ next if !defined($val);
+ if (ref($val) eq 'ARRAY') {
+ push @addrs, @$val;
+ } else {
+ push @addrs, $val;
+ }
+ }
+
+ return @addrs;
+}
+
+sub _address_matches_family {
+ my ($address, $family) = @_;
+
+ my $ip = _normalize_ip($address);
+ return 0 if !defined($ip);
+
+ return ip_is_ipv6($ip) ? $family == 6 : $family == 4;
+}
+
sub get_local_route_ip {
my ($targetip) = @_;
my $ip = undef;
my $interface = undef;
+ my @cmd = ('/sbin/ip');
+ push @cmd, '-6' if ip_is_ipv6($targetip);
+ push @cmd, 'route', 'get', $targetip;
+
run_command(
- ['/sbin/ip', 'route', 'get', $targetip],
+ \@cmd,
outfunc => sub {
if ($_[0] =~ m/src ($PVE::Tools::IPRE)/) {
$ip = $1;
@@ -307,16 +348,33 @@ sub find_local_ip_interface_peers {
#if iface is defined, return ip if exist (if not,try to find it on other ifaces)
if ($iface) {
- my $ip = $ifaces->{$iface}->{address};
- return ($ip, $iface) if $ip;
+ my @iface_addrs = _get_iface_addresses($ifaces->{$iface});
+ if (!@{$peers} && @iface_addrs) {
+ my $ip = _normalize_ip($iface_addrs[0]);
+ return ($ip, $iface) if $ip;
+ }
+ foreach my $address (@{$peers}) {
+ my $family = ip_is_ipv6($address) ? 6 : 4;
+ foreach my $iface_addr (@iface_addrs) {
+ next if !_address_matches_family($iface_addr, $family);
+ my $ip = _normalize_ip($iface_addr);
+ return ($ip, $iface) if $ip;
+ }
+ }
}
#is a local ip member of peers list ?
foreach my $address (@{$peers}) {
- while (my $interface = each %$ifaces) {
- my $ip = $ifaces->{$interface}->{address};
- if ($ip && $ip eq $address) {
- return ($ip, $interface);
+ my $family = ip_is_ipv6($address) ? 6 : 4;
+ my $peer_ip = _normalize_ip($address);
+ next if !defined($peer_ip);
+ foreach my $interface (keys %$ifaces) {
+ foreach my $iface_addr (_get_iface_addresses($ifaces->{$interface})) {
+ next if !_address_matches_family($iface_addr, $family);
+ my $ip = _normalize_ip($iface_addr);
+ if ($ip && $ip eq $peer_ip) {
+ return ($ip, $interface);
+ }
}
}
}
diff --git a/src/test/zones/vxlan/ipv6/expected_sdn_interfaces b/src/test/zones/vxlan/ipv6/expected_sdn_interfaces
new file mode 100644
index 0000000..032ab99
--- /dev/null
+++ b/src/test/zones/vxlan/ipv6/expected_sdn_interfaces
@@ -0,0 +1,15 @@
+#version:1
+
+auto myvnet
+iface myvnet
+ bridge_ports vxlan_myvnet
+ bridge_stp off
+ bridge_fd 0
+ mtu 1450
+
+auto vxlan_myvnet
+iface vxlan_myvnet
+ vxlan-id 100
+ vxlan_remoteip 2a08:2200:100:1::11
+ vxlan_remoteip 2a08:2200:100:1::12
+ mtu 1450
diff --git a/src/test/zones/vxlan/ipv6/interfaces b/src/test/zones/vxlan/ipv6/interfaces
new file mode 100644
index 0000000..602179b
--- /dev/null
+++ b/src/test/zones/vxlan/ipv6/interfaces
@@ -0,0 +1,7 @@
+auto vmbr0
+iface vmbr0 inet static
+ address 2a08:2200:100:1::10/64
+ gateway 2a08:2200:100:1::1
+ bridge-ports eth0
+ bridge-stp off
+ bridge-fd 0
diff --git a/src/test/zones/vxlan/ipv6/sdn_config b/src/test/zones/vxlan/ipv6/sdn_config
new file mode 100644
index 0000000..484be23
--- /dev/null
+++ b/src/test/zones/vxlan/ipv6/sdn_config
@@ -0,0 +1,17 @@
+{
+ version => 1,
+ vnets => {
+ ids => {
+ myvnet => { tag => 100, type => "vnet", zone => "myzone" },
+ },
+ },
+ zones => {
+ ids => {
+ myzone => {
+ ipam => "pve",
+ type => "vxlan",
+ peers => "2a08:2200:100:1::10,2a08:2200:100:1::11,2a08:2200:100:1::12",
+ },
+ },
+ },
+}
--
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-16 11:09 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-16 11:08 [pve-devel] [PATCH docs/network 0/3] SDN VXLAN IPv6 underlay support Hannes Laimer
2026-01-16 11:08 ` Hannes Laimer [this message]
2026-01-16 11:08 ` [pve-devel] [PATCH pve-network 2/2] sdn: vxlan: enforce single address family in peers list Hannes Laimer
2026-01-16 11:08 ` [pve-devel] [PATCH pve-docs 1/1] sdn: vxlan: add short section about underlay address family 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=20260116110843.89615-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