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

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


Add function to generate /etc/network/interfaces configuration for OSPF nodes including:
- Create dummy interfaces for each area with /32 addresses
- Configure IP addresses on physical interfaces
- Enable IP forwarding on all relevant interfaces
- Support both numbered and unnumbered interface configurations

Note that the `ospfd` daemon only supports IPv4 so we only have IPv4
addresses for OSPF. In a follow-up we could also support the `ospf6d`
daemon, which supports IPv6.

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

diff --git a/pve-rs/src/sdn/ospf.rs b/pve-rs/src/sdn/ospf.rs
index 63ce0d53ffb8..9f6a7302e0db 100644
--- a/pve-rs/src/sdn/ospf.rs
+++ b/pve-rs/src/sdn/ospf.rs
@@ -337,6 +337,60 @@ mod export {
             .ok_or(anyhow::anyhow!("node not found"))
     }
 
+    #[export]
+    fn get_interfaces_etc_network_config(
+        #[try_from_ref] this: &PerlSectionConfig<OspfSectionConfig>,
+        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 OspfSectionConfig::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.area)?;
+                    writeln!(
+                        interfaces,
+                        "iface dummy_{} inet static",
+                        node_section.node_id.area
+                    )?;
+                    writeln!(interfaces, "\tlink-type dummy")?;
+                    writeln!(interfaces, "\tip-forward 1")?;
+                    // add dummy interface address as /32
+                    writeln!(interfaces, "\taddress {}/32", node_section.router_id)?;
+
+                    // 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")?;
+                            } else {
+                                // unnumbered interface needs ip addresses configured in ospf
+                                writeln!(interfaces, "iface {interface_name} inet static")?;
+                                writeln!(interfaces, "\taddress {}/32", node_section.router_id)?;
+                                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<OspfSectionConfig>,
-- 
2.39.5





More information about the pve-devel mailing list