[pve-devel] [PATCH proxmox-perl-rs 4/7] perl-rs: sdn: implement OSPF interface file configuration generation

Gabriel Goller g.goller at proxmox.com
Fri Mar 28 18:13:11 CET 2025


Add function to generate /etc/network/interfaces configuration for OpenFabric nodes:
- Auto-create dummy interfaces with proper router-id
- Configure interface addresses and IP forwarding
- Support for both IPv4 and IPv6 addressing on both dummy and other
  interfaces

Signed-off-by: Gabriel Goller <g.goller at proxmox.com>
---
 pve-rs/src/sdn/openfabric.rs | 72 ++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/pve-rs/src/sdn/openfabric.rs b/pve-rs/src/sdn/openfabric.rs
index 680b3d081e47..2d21e6dae5e1 100644
--- a/pve-rs/src/sdn/openfabric.rs
+++ b/pve-rs/src/sdn/openfabric.rs
@@ -353,6 +353,78 @@ mod export {
             .ok_or(anyhow::anyhow!("node not found"))
     }
 
+    #[export]
+    fn get_interfaces_etc_network_config(
+        #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>,
+        node: Hostname,
+    ) -> Result<String, Error> {
+        let guard = this.section_config.lock().unwrap();
+        let mut interfaces = String::new();
+
+        guard.iter().try_for_each(|section| {
+            if let OpenFabricSectionConfig::Node(node_section) = section.1 {
+                if node_section.node_id.node == node {
+                    // create dummy interface for this fabric
+                    writeln!(interfaces)?;
+                    writeln!(interfaces, "auto dummy_{}", node_section.node_id.fabric_id)?;
+                    match node_section.router_id {
+                        IpAddr::V4(_) => writeln!(
+                            interfaces,
+                            "iface dummy_{} inet static",
+                            node_section.node_id.fabric_id
+                        )?,
+                        IpAddr::V6(_) => writeln!(
+                            interfaces,
+                            "iface dummy_{} inet6 static",
+                            node_section.node_id.fabric_id
+                        )?,
+                    }
+                    writeln!(interfaces, "\tlink-type dummy")?;
+                    writeln!(interfaces, "\tip-forward 1")?;
+                    // add dummy interface address as /32
+                    match node_section.router_id {
+                        IpAddr::V4(ipv4_addr) => {
+                            writeln!(interfaces, "\taddress {}/32", ipv4_addr)?
+                        }
+                        IpAddr::V6(ipv6_addr) => {
+                            writeln!(interfaces, "\taddress {}/128", ipv6_addr)?
+                        }
+                    }
+
+                    // add ip-addrs to all other interfaces and ensure they exist
+                    // also enable ip-forwarding on all interfaces as this is needed for unnumbered
+                    // peering
+                    node_section
+                        .clone()
+                        .interface
+                        .into_iter()
+                        .try_for_each(|i| {
+                            let interface_name = i.name.clone();
+                            writeln!(interfaces)?;
+                            writeln!(interfaces, "auto {interface_name}")?;
+                            if let Some(ip) = i.ip.map(|i| i.to_string()) {
+                                writeln!(interfaces, "iface {interface_name} inet static")?;
+                                writeln!(interfaces, "\taddress {}", ip)?;
+                                writeln!(interfaces, "\tip-forward 1")?;
+                            }
+                            if let Some(ipv6) = i.ipv6.map(|i| i.to_string()) {
+                                writeln!(interfaces, "iface {interface_name} inet6 static")?;
+                                writeln!(interfaces, "\taddress {ipv6}")?;
+                                writeln!(interfaces, "\tip6-forward 1")?;
+                            }
+                            if i.ip.is_none() && i.ipv6.is_none() {
+                                writeln!(interfaces, "iface {interface_name} inet manual")?;
+                                writeln!(interfaces, "\tip-forward 1")?;
+                            }
+                            Ok::<(), std::fmt::Error>(())
+                        })?;
+                }
+            }
+            Ok::<(), std::fmt::Error>(())
+        })?;
+        Ok(interfaces)
+    }
+
     #[export]
     pub fn enabled_daemons(
         #[try_from_ref] this: &PerlSectionConfig<OpenFabricSectionConfig>,
-- 
2.39.5





More information about the pve-devel mailing list