* [pve-devel] [PATCH proxmox-ve-rs 1/1] ve-config: fabrics: add helpers for proxmox-network-interface-pinning
2025-07-17 15:28 [pve-devel] [PATCH manager/proxmox{-ve-rs, -perl-rs} 0/6] proxmox-network-interface-pinning fixes Stefan Hanreich
@ 2025-07-17 15:28 ` Stefan Hanreich
2025-07-17 19:27 ` [pve-devel] applied: " Thomas Lamprecht
2025-07-17 15:28 ` [pve-devel] [PATCH proxmox-perl-rs 1/1] pve-rs: fabrics: helper for mapping interface names Stefan Hanreich
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Stefan Hanreich @ 2025-07-17 15:28 UTC (permalink / raw)
To: pve-devel
In order to map interface names via the new
proxmox-network-interface-pinning tool, pve-rs needs mutable access to
the interfaces as well as all fabrics in the configuration. Add
helpers for iterating mutably over all fabrics, as well as all
interfaces.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
proxmox-ve-config/src/sdn/fabric/mod.rs | 5 +++++
.../fabric/section_config/protocol/openfabric.rs | 16 ++++++++++++++--
.../sdn/fabric/section_config/protocol/ospf.rs | 15 ++++++++++++++-
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/proxmox-ve-config/src/sdn/fabric/mod.rs b/proxmox-ve-config/src/sdn/fabric/mod.rs
index cac7490..9ec2f61 100644
--- a/proxmox-ve-config/src/sdn/fabric/mod.rs
+++ b/proxmox-ve-config/src/sdn/fabric/mod.rs
@@ -611,6 +611,11 @@ impl FabricConfig {
.ok_or_else(|| FabricConfigError::FabricDoesNotExist(id.to_string()))
}
+ /// Returns an iterator over mutable references to all [`FabricEntry`] in the config
+ pub fn get_fabrics_mut(&mut self) -> impl Iterator<Item = &mut FabricEntry> {
+ self.fabrics.values_mut()
+ }
+
/// Delete a fabric with the specified fabric_id from the [`FabricConfig`].
pub fn delete_fabric(&mut self, id: &FabricId) -> Result<FabricEntry, FabricConfigError> {
self.fabrics
diff --git a/proxmox-ve-config/src/sdn/fabric/section_config/protocol/openfabric.rs b/proxmox-ve-config/src/sdn/fabric/section_config/protocol/openfabric.rs
index 9a9f862..c68147d 100644
--- a/proxmox-ve-config/src/sdn/fabric/section_config/protocol/openfabric.rs
+++ b/proxmox-ve-config/src/sdn/fabric/section_config/protocol/openfabric.rs
@@ -1,4 +1,4 @@
-use std::ops::Deref;
+use std::ops::{Deref, DerefMut};
use proxmox_network_types::ip_address::{Ipv4Cidr, Ipv6Cidr};
use serde::{Deserialize, Serialize};
@@ -72,12 +72,19 @@ pub struct OpenfabricNodeProperties {
}
impl OpenfabricNodeProperties {
- /// Returns an interator over all the interfaces.
+ /// Returns an iterator over all the interfaces.
pub fn interfaces(&self) -> impl Iterator<Item = &OpenfabricInterfaceProperties> {
self.interfaces
.iter()
.map(|property_string| property_string.deref())
}
+
+ /// Returns an iterator over all the interfaces (mutable).
+ pub fn interfaces_mut(&mut self) -> impl Iterator<Item = &mut OpenfabricInterfaceProperties> {
+ self.interfaces
+ .iter_mut()
+ .map(|property_string| property_string.deref_mut())
+ }
}
impl Validatable for NodeSection<OpenfabricNodeProperties> {
@@ -127,6 +134,11 @@ impl OpenfabricInterfaceProperties {
&self.name
}
+ /// Set the name of the interface.
+ pub fn set_name(&mut self, name: InterfaceName) {
+ self.name = name
+ }
+
/// Get the IPv4 of the interface.
pub fn ip(&self) -> Option<Ipv4Cidr> {
self.ip
diff --git a/proxmox-ve-config/src/sdn/fabric/section_config/protocol/ospf.rs b/proxmox-ve-config/src/sdn/fabric/section_config/protocol/ospf.rs
index 1c8ce1d..df0be95 100644
--- a/proxmox-ve-config/src/sdn/fabric/section_config/protocol/ospf.rs
+++ b/proxmox-ve-config/src/sdn/fabric/section_config/protocol/ospf.rs
@@ -1,4 +1,4 @@
-use std::ops::Deref;
+use std::ops::{Deref, DerefMut};
use proxmox_network_types::ip_address::Ipv4Cidr;
use proxmox_sdn_types::area::Area;
@@ -75,11 +75,19 @@ pub struct OspfNodeProperties {
}
impl OspfNodeProperties {
+ /// Returns an iterator over all the interfaces.
pub fn interfaces(&self) -> impl Iterator<Item = &OspfInterfaceProperties> {
self.interfaces
.iter()
.map(|property_string| property_string.deref())
}
+
+ /// Returns an iterator over all the interfaces (mutable).
+ pub fn interfaces_mut(&mut self) -> impl Iterator<Item = &mut OspfInterfaceProperties> {
+ self.interfaces
+ .iter_mut()
+ .map(|property_string| property_string.deref_mut())
+ }
}
impl Validatable for NodeSection<OspfNodeProperties> {
@@ -124,6 +132,11 @@ impl OspfInterfaceProperties {
&self.name
}
+ /// Set the name of the interface.
+ pub fn set_name(&mut self, name: InterfaceName) {
+ self.name = name
+ }
+
/// Get the ip (IPv4) of the OSPF interface.
pub fn ip(&self) -> Option<Ipv4Cidr> {
self.ip
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH proxmox-perl-rs 1/1] pve-rs: fabrics: helper for mapping interface names
2025-07-17 15:28 [pve-devel] [PATCH manager/proxmox{-ve-rs, -perl-rs} 0/6] proxmox-network-interface-pinning fixes Stefan Hanreich
2025-07-17 15:28 ` [pve-devel] [PATCH proxmox-ve-rs 1/1] ve-config: fabrics: add helpers for proxmox-network-interface-pinning Stefan Hanreich
@ 2025-07-17 15:28 ` Stefan Hanreich
2025-07-17 19:00 ` [pve-devel] applied: " Thomas Lamprecht
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 1/4] pve-sdn-commit: fix reloading logic Stefan Hanreich
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Stefan Hanreich @ 2025-07-17 15:28 UTC (permalink / raw)
To: pve-devel
Add a helper method for proxmox-network-interface-pinning to rename
all interfaces of a node in the fabric config according to the mapping
generated by the pinning tool. This method renames all occurences of
an interface name to the pinned version. The logic has been taken and
reimplemented from the Perl helper itself.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
pve-rs/src/bindings/sdn/fabrics.rs | 64 +++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/pve-rs/src/bindings/sdn/fabrics.rs b/pve-rs/src/bindings/sdn/fabrics.rs
index fd81c77..587b1d6 100644
--- a/pve-rs/src/bindings/sdn/fabrics.rs
+++ b/pve-rs/src/bindings/sdn/fabrics.rs
@@ -5,7 +5,7 @@ pub mod pve_rs_sdn_fabrics {
//! This provides the configuration for the SDN fabrics, as well as helper methods for reading
//! / writing the configuration, as well as for generating ifupdown2 and FRR configuration.
- use std::collections::{BTreeMap, HashSet};
+ use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt::Write;
use std::net::IpAddr;
use std::ops::Deref;
@@ -26,6 +26,7 @@ pub mod pve_rs_sdn_fabrics {
Fabric as ConfigFabric, FabricId,
api::{Fabric, FabricUpdater},
};
+ use proxmox_ve_config::sdn::fabric::section_config::interface::InterfaceName;
use proxmox_ve_config::sdn::fabric::section_config::node::{
Node as ConfigNode, NodeId,
api::{Node, NodeUpdater},
@@ -304,6 +305,67 @@ pub mod pve_rs_sdn_fabrics {
.map_err(anyhow::Error::from)
}
+ fn map_name(
+ mapping: &HashMap<String, String>,
+ name: &str,
+ ) -> Result<Option<InterfaceName>, Error> {
+ match name.split_once('.') {
+ Some((interface_name, vlan_id))
+ if !vlan_id.is_empty() && vlan_id.chars().all(char::is_numeric) =>
+ {
+ mapping
+ .get(interface_name)
+ .map(|mapped_name| {
+ InterfaceName::from_string(format!("{mapped_name}.{vlan_id}"))
+ })
+ .transpose()
+ }
+ _ => mapping
+ .get(name)
+ .cloned()
+ .map(InterfaceName::from_string)
+ .transpose(),
+ }
+ }
+
+ /// Method: Map all interface names of a node to a different one, according to the given
+ /// mapping.
+ ///
+ /// Used by proxmox-network-interface-pinning
+ #[export]
+ pub fn map_interfaces(
+ #[try_from_ref] this: &PerlFabricConfig,
+ node_id: NodeId,
+ mapping: HashMap<String, String>,
+ ) -> Result<(), Error> {
+ let mut config = this.fabric_config.lock().unwrap();
+
+ for entry in config.get_fabrics_mut() {
+ let Ok(node) = entry.get_node_mut(&node_id) else {
+ continue;
+ };
+
+ match node {
+ ConfigNode::Openfabric(node_section) => {
+ for interface in node_section.properties_mut().interfaces_mut() {
+ if let Some(mapped_name) = map_name(&mapping, &interface.name())? {
+ interface.set_name(mapped_name);
+ }
+ }
+ }
+ ConfigNode::Ospf(node_section) => {
+ for interface in node_section.properties_mut().interfaces_mut() {
+ if let Some(mapped_name) = map_name(&mapping, &interface.name())? {
+ interface.set_name(mapped_name);
+ }
+ }
+ }
+ }
+ }
+
+ Ok(())
+ }
+
/// Method: Convert the configuration into the section config sections.
///
/// Used for writing the running configuration.
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH pve-manager 1/4] pve-sdn-commit: fix reloading logic
2025-07-17 15:28 [pve-devel] [PATCH manager/proxmox{-ve-rs, -perl-rs} 0/6] proxmox-network-interface-pinning fixes Stefan Hanreich
2025-07-17 15:28 ` [pve-devel] [PATCH proxmox-ve-rs 1/1] ve-config: fabrics: add helpers for proxmox-network-interface-pinning Stefan Hanreich
2025-07-17 15:28 ` [pve-devel] [PATCH proxmox-perl-rs 1/1] pve-rs: fabrics: helper for mapping interface names Stefan Hanreich
@ 2025-07-17 15:28 ` Stefan Hanreich
2025-07-17 19:27 ` [pve-devel] applied-series: " Thomas Lamprecht
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 2/4] proxmox-network-interface-pinning: add fabrics support Stefan Hanreich
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Stefan Hanreich @ 2025-07-17 15:28 UTC (permalink / raw)
To: pve-devel
The API for generating the SDN configuration has been changed in the
fabrics patch series ('387cc48'). Use the new API to commit the SDN
configuration on boot, since otherwise the one-shot service fails to
apply the SDN configuration on boot.
The service was also missing an ifreload, since the ifupdown2 config
gets regenerated by SDN and needs to be applied before generating the
FRR configuration in order for the FRR config generation to work
properly.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
bin/pve-sdn-commit | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/bin/pve-sdn-commit b/bin/pve-sdn-commit
index 2654e17ed..09e4387c5 100644
--- a/bin/pve-sdn-commit
+++ b/bin/pve-sdn-commit
@@ -4,11 +4,26 @@ use strict;
use warnings;
use PVE::Network::SDN;
+use PVE::Tools;
+my $previous_config_has_frr = PVE::Network::SDN::running_config_has_frr();
PVE::Network::SDN::commit_config();
-PVE::Network::SDN::generate_zone_config();
+my $new_config_has_frr = PVE::Network::SDN::running_config_has_frr();
+my $skip_frr = !($previous_config_has_frr || $new_config_has_frr);
+
+PVE::Network::SDN::generate_etc_network_config();
PVE::Network::SDN::generate_dhcp_config();
-PVE::Network::SDN::generate_controller_config(1);
+
+my $err = sub {
+ my $line = shift;
+ if ($line =~ /(warning|error): (\S+):/) {
+ print "$2 : $line \n";
+ }
+};
+
+PVE::Tools::run_command(['ifreload', '-a'], errfunc => $err);
+
+PVE::Network::SDN::generate_frr_config(1) if !$skip_frr;
exit 0;
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] applied-series: [PATCH pve-manager 1/4] pve-sdn-commit: fix reloading logic
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 1/4] pve-sdn-commit: fix reloading logic Stefan Hanreich
@ 2025-07-17 19:27 ` Thomas Lamprecht
0 siblings, 0 replies; 10+ messages in thread
From: Thomas Lamprecht @ 2025-07-17 19:27 UTC (permalink / raw)
To: pve-devel, Stefan Hanreich
On Thu, 17 Jul 2025 17:28:38 +0200, Stefan Hanreich wrote:
> The API for generating the SDN configuration has been changed in the
> fabrics patch series ('387cc48'). Use the new API to commit the SDN
> configuration on boot, since otherwise the one-shot service fails to
> apply the SDN configuration on boot.
>
> The service was also missing an ifreload, since the ifupdown2 config
> gets regenerated by SDN and needs to be applied before generating the
> FRR configuration in order for the FRR config generation to work
> properly.
>
> [...]
Applied the four manager patches, thanks!
It might be nice to early exit if there is no SDN configured, and maybe some
other simple conditions we could check, as always reloading the interfaces
even if not required seems not really ideal. But this can be followed up on.
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH pve-manager 2/4] proxmox-network-interface-pinning: add fabrics support
2025-07-17 15:28 [pve-devel] [PATCH manager/proxmox{-ve-rs, -perl-rs} 0/6] proxmox-network-interface-pinning fixes Stefan Hanreich
` (2 preceding siblings ...)
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 1/4] pve-sdn-commit: fix reloading logic Stefan Hanreich
@ 2025-07-17 15:28 ` Stefan Hanreich
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 3/4] proxmox-network-interface-pinning: die on failing to write interfaces Stefan Hanreich
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 4/4] proxmox-network-interface-pinning: fix pinning after reboot Stefan Hanreich
5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hanreich @ 2025-07-17 15:28 UTC (permalink / raw)
To: pve-devel
The fabric configuration references interfaces of nodes, which need to
be updated when pinning network interface names as well. Use the new
helper provided by perlmod for that.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
PVE/CLI/proxmox_network_interface_pinning.pm | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/PVE/CLI/proxmox_network_interface_pinning.pm b/PVE/CLI/proxmox_network_interface_pinning.pm
index ea98ccb5e..b4c25154a 100644
--- a/PVE/CLI/proxmox_network_interface_pinning.pm
+++ b/PVE/CLI/proxmox_network_interface_pinning.pm
@@ -11,6 +11,7 @@ use PVE::INotify;
use PVE::Network;
use PVE::Network::SDN;
use PVE::Network::SDN::Controllers;
+use PVE::Network::SDN::Fabrics;
use PVE::RPCEnvironment;
use PVE::SectionConfig;
use PVE::Tools;
@@ -24,6 +25,22 @@ sub setup_environment {
PVE::RPCEnvironment->setup_default_cli_env();
}
+my sub update_sdn_fabrics {
+ my ($mapping) = @_;
+
+ print "Updating /etc/pve/sdn/fabrics.cfg\n";
+
+ my $code = sub {
+ my $local_node = PVE::INotify::nodename();
+
+ my $config = PVE::Network::SDN::Fabrics::config();
+ $config->map_interfaces($local_node, $mapping);
+ PVE::Network::SDN::Fabrics::write_config($config);
+ };
+
+ PVE::Network::SDN::lock_sdn_config($code);
+}
+
my sub update_sdn_controllers {
my ($mapping) = @_;
@@ -390,6 +407,7 @@ __PACKAGE__->register_method({
update_host_fw_config($mapping);
update_etc_network_interfaces($mapping, $existing_pins);
update_sdn_controllers($mapping);
+ update_sdn_fabrics($mapping);
print "Successfully updated Proxmox VE configuration files.\n";
print "\nPlease reboot to apply the changes to your configuration\n\n";
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH pve-manager 3/4] proxmox-network-interface-pinning: die on failing to write interfaces
2025-07-17 15:28 [pve-devel] [PATCH manager/proxmox{-ve-rs, -perl-rs} 0/6] proxmox-network-interface-pinning fixes Stefan Hanreich
` (3 preceding siblings ...)
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 2/4] proxmox-network-interface-pinning: add fabrics support Stefan Hanreich
@ 2025-07-17 15:28 ` Stefan Hanreich
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 4/4] proxmox-network-interface-pinning: fix pinning after reboot Stefan Hanreich
5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hanreich @ 2025-07-17 15:28 UTC (permalink / raw)
To: pve-devel
lock_file sets the error variable in perl, but does not die if it
encounters an error in the callback. All other invocations of
lock_file already die, but it was missing for writing the interfaces
s file, which swallowed errors.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
PVE/CLI/proxmox_network_interface_pinning.pm | 1 +
1 file changed, 1 insertion(+)
diff --git a/PVE/CLI/proxmox_network_interface_pinning.pm b/PVE/CLI/proxmox_network_interface_pinning.pm
index b4c25154a..b57362c7e 100644
--- a/PVE/CLI/proxmox_network_interface_pinning.pm
+++ b/PVE/CLI/proxmox_network_interface_pinning.pm
@@ -112,6 +112,7 @@ my sub update_etc_network_interfaces {
};
PVE::Tools::lock_file("/etc/network/.pve-interfaces.lock", 10, $code);
+ die $@ if $@;
}
my sub update_host_fw_config {
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH pve-manager 4/4] proxmox-network-interface-pinning: fix pinning after reboot
2025-07-17 15:28 [pve-devel] [PATCH manager/proxmox{-ve-rs, -perl-rs} 0/6] proxmox-network-interface-pinning fixes Stefan Hanreich
` (4 preceding siblings ...)
2025-07-17 15:28 ` [pve-devel] [PATCH pve-manager 3/4] proxmox-network-interface-pinning: die on failing to write interfaces Stefan Hanreich
@ 2025-07-17 15:28 ` Stefan Hanreich
5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hanreich @ 2025-07-17 15:28 UTC (permalink / raw)
To: pve-devel
We generate a list of existing pins as a reference throughout the
pinning tool. It works by reading the existing link files and looking
up interfaces with the corresponding MAC address. If pins have already
been applied, this would return a mapping of the pinned name to itself
(nic0 => nic0).
We use this list for filtering what we write to the pending
configuration, in order to avoid re-introducing already pinned names
to the pending configuration. This reflexive entry would cause the
interfaces file generation to filter all pinned network interfaces
after reboot, leading to invalid ifupdown2 configuration files. Fix
this by filtering entries in the existing-pins list who are reflexive.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
PVE/CLI/proxmox_network_interface_pinning.pm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/PVE/CLI/proxmox_network_interface_pinning.pm b/PVE/CLI/proxmox_network_interface_pinning.pm
index b57362c7e..271ec0430 100644
--- a/PVE/CLI/proxmox_network_interface_pinning.pm
+++ b/PVE/CLI/proxmox_network_interface_pinning.pm
@@ -328,7 +328,8 @@ sub resolve_pinned {
next;
}
- $resolved->{ $mac_lookup{$mac} } = $pinned->{$mac};
+ $resolved->{ $mac_lookup{$mac} } = $pinned->{$mac}
+ if $mac_lookup{$mac} ne $pinned->{$mac};
}
return $resolved;
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread