From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id F1B6F1FF141 for ; Fri, 16 Jan 2026 12:09:16 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B50AA16DD4; Fri, 16 Jan 2026 12:09:19 +0100 (CET) From: Hannes Laimer To: pve-devel@lists.proxmox.com Date: Fri, 16 Jan 2026 12:08:41 +0100 Message-ID: <20260116110843.89615-2-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260116110843.89615-1-h.laimer@proxmox.com> References: <20260116110843.89615-1-h.laimer@proxmox.com> MIME-Version: 1.0 X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1768561677665 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.057 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH pve-network 1/2] sdn: vxlan: make local underlay selection work for IPv6 peers X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" 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 --- 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