From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 795061FF0E0 for ; Thu, 09 Jul 2026 15:29:24 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id DFDBA21524; Thu, 09 Jul 2026 15:29:11 +0200 (CEST) From: Stefan Hanreich To: pve-devel@lists.proxmox.com Subject: [PATCH pve-network 3/3] fix #7738: zones: use pre-computed bridge port list Date: Thu, 9 Jul 2026 15:28:55 +0200 Message-ID: <20260709132857.239615-4-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260709132857.239615-1-s.hanreich@proxmox.com> References: <20260709132857.239615-1-s.hanreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1783603737004 X-SPAM-LEVEL: Spam detection results: 0 DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 7SEJF3IOFP5ETDSXA2JCB2JIPCCYN24N X-Message-ID-Hash: 7SEJF3IOFP5ETDSXA2JCB2JIPCCYN24N X-MailFrom: s.hanreich@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The VLAN and QinQ zone utilized ip_link_details to obtain information about the physical ports contained on a bridge. Instead of executing iproute2 and computing the bridge ports for every VNet, precalculate the bridge port list using the new helper in pve-common and then re-use the ouput obtained at the start of the run. Remove the get_bridge_ifaces function, since there are no longer any call sites for this function. Signed-off-by: Stefan Hanreich --- src/PVE/Network/SDN/Zones.pm | 3 +++ src/PVE/Network/SDN/Zones/Plugin.pm | 7 +------ src/PVE/Network/SDN/Zones/QinQPlugin.pm | 5 +++-- src/PVE/Network/SDN/Zones/VlanPlugin.pm | 5 +++-- src/test/run_test_zones.pl | 13 ++++++++++--- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/PVE/Network/SDN/Zones.pm b/src/PVE/Network/SDN/Zones.pm index 4c1468cf..f1fb32d9 100644 --- a/src/PVE/Network/SDN/Zones.pm +++ b/src/PVE/Network/SDN/Zones.pm @@ -7,6 +7,7 @@ use JSON; use PVE::Tools qw(extract_param dir_glob_regex run_command); use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file); +use PVE::IPRoute2; use PVE::Network; use PVE::Network::SDN::Vnets; @@ -117,6 +118,7 @@ sub generate_etc_network_config { return if !$vnet_cfg && !$zone_cfg; my $interfaces_config = PVE::INotify::read_file('interfaces'); + my $bridge_ports = PVE::IPRoute2::get_bridge_port_mapping(); #generate configuration my $config = {}; @@ -157,6 +159,7 @@ sub generate_etc_network_config { $subnet_cfg, $interfaces_config, $config, + $bridge_ports, ); }; if (my $err = $@) { diff --git a/src/PVE/Network/SDN/Zones/Plugin.pm b/src/PVE/Network/SDN/Zones/Plugin.pm index 74a3384c..184fca4e 100644 --- a/src/PVE/Network/SDN/Zones/Plugin.pm +++ b/src/PVE/Network/SDN/Zones/Plugin.pm @@ -5,7 +5,6 @@ use warnings; use PVE::Tools qw(run_command); use Net::IP qw(ip_get_version); -use PVE::IPRoute2; use PVE::JSONSchema; use PVE::Cluster; use PVE::Network; @@ -112,6 +111,7 @@ sub generate_sdn_config { $subnet_cfg, $interfaces_config, $config, + $bridge_ports, ) = @_; die "please implement inside plugin"; @@ -385,11 +385,6 @@ sub is_vlanaware { return PVE::Tools::file_read_firstline("/sys/class/net/$bridge/bridge/vlan_filtering"); } -sub get_bridge_ifaces { - my ($bridge) = @_; - return PVE::IPRoute2::get_physical_bridge_ports($bridge); -} - sub datacenter_config { return PVE::Cluster::cfs_read_file('datacenter.cfg'); } diff --git a/src/PVE/Network/SDN/Zones/QinQPlugin.pm b/src/PVE/Network/SDN/Zones/QinQPlugin.pm index a75940c6..642420e9 100644 --- a/src/PVE/Network/SDN/Zones/QinQPlugin.pm +++ b/src/PVE/Network/SDN/Zones/QinQPlugin.pm @@ -64,6 +64,7 @@ sub generate_sdn_config { $subnet_cfg, $interfaces_config, $config, + $bridge_ports, ) = @_; my ($bridge, $mtu, $stag) = $plugin_config->@{ 'bridge', 'mtu', 'tag' }; @@ -128,9 +129,9 @@ sub generate_sdn_config { } else { # eth--->eth.x(svlan)----->vlanwarebridge-(tag)----->vnet---->vnet - my @bridge_ifaces = PVE::Network::SDN::Zones::Plugin::get_bridge_ifaces($bridge); + my $bridge_ifaces = $bridge_ports->{$bridge}; - for my $bridge_iface (@bridge_ifaces) { + for my $bridge_iface ($bridge_ifaces->@*) { # use named vlan interface to avoid too long names my $svlan_iface = "sv_$zoneid"; diff --git a/src/PVE/Network/SDN/Zones/VlanPlugin.pm b/src/PVE/Network/SDN/Zones/VlanPlugin.pm index 9102b34f..271b3fab 100644 --- a/src/PVE/Network/SDN/Zones/VlanPlugin.pm +++ b/src/PVE/Network/SDN/Zones/VlanPlugin.pm @@ -63,6 +63,7 @@ sub generate_sdn_config { $subnet_cfg, $interfaces_config, $config, + $bridge_ports, ) = @_; my $bridge = $plugin_config->{bridge}; @@ -112,10 +113,10 @@ sub generate_sdn_config { my $bridgevlan = $bridge . "v" . $tag; - my @bridge_ifaces = PVE::Network::SDN::Zones::Plugin::get_bridge_ifaces($bridge); + my $bridge_ifaces = $bridge_ports->{$bridge}; my $bridge_ports = ""; - foreach my $bridge_iface (@bridge_ifaces) { + foreach my $bridge_iface ($bridge_ifaces->@*) { $bridge_ports .= " $bridge_iface.$tag"; } diff --git a/src/test/run_test_zones.pl b/src/test/run_test_zones.pl index dd458b77..f8ef7375 100755 --- a/src/test/run_test_zones.pl +++ b/src/test/run_test_zones.pl @@ -55,6 +55,16 @@ foreach my $test (@tests) { }, ); + my $pve_common_iproute; + $pve_common_iproute = Test::MockModule->new('PVE::IPRoute2'); + $pve_common_iproute->mock( + get_bridge_port_mapping => sub { + return { + vmbr0 => ["eth0"], + },; + }, + ); + my $pve_common_network; $pve_common_network = Test::MockModule->new('PVE::Network'); $pve_common_network->mock( @@ -94,9 +104,6 @@ foreach my $test (@tests) { is_vlanaware => sub { return $interfaces_config->{ifaces}->{vmbr0}->{'bridge_vlan_aware'}; }, - get_bridge_ifaces => sub { - return ('eth0'); - }, find_bridge => sub { return; }, -- 2.47.3