The proxmox-frr FrrConfig structs changed a bit so that we can serialize them nicely using templates -- this means we also need to change the FrrConfig generation code a bit.
Due to the decision that every protocol corresponds to a single template file (with a few exceptions, e.g. common interface options etc.) we also have per-protocol structs that contain all the structs needed for that fabric to work. So we no longer have: config/ ├─ interfaces/ │ ├─ openfabric │ ├─ ospf ├─ routers/ │ ├─ openfabric │ ├─ ospf but: config/ ├─ openfabric/ │ ├─ interfaces │ ├─ routers ├─ ospf/ │ ├─ interfaces │ ├─ routers Thought honestly I don't think this change is so impacting -- except a few enums that we can remove. Signed-off-by: Gabriel Goller <[email protected]> --- proxmox-ve-config/src/sdn/fabric/frr.rs | 145 +++++++++++++----------- proxmox-ve-config/src/sdn/frr.rs | 11 +- 2 files changed, 81 insertions(+), 75 deletions(-) diff --git a/proxmox-ve-config/src/sdn/fabric/frr.rs b/proxmox-ve-config/src/sdn/fabric/frr.rs index 486f7dc51dcb..86c77b8b4c57 100644 --- a/proxmox-ve-config/src/sdn/fabric/frr.rs +++ b/proxmox-ve-config/src/sdn/fabric/frr.rs @@ -1,17 +1,20 @@ use std::net::{IpAddr, Ipv4Addr}; + use tracing; -use proxmox_frr::ospf::{self, NetworkType}; +use proxmox_frr::openfabric::{OpenfabricInterface, OpenfabricRouter, OpenfabricRouterName}; +use proxmox_frr::ospf::{self, NetworkType, OspfInterface, OspfRouter, OspfRouterName}; use proxmox_frr::route_map::{ - AccessAction, AccessList, AccessListName, AccessListRule, ProtocolRouteMap, ProtocolType, - RouteMap, RouteMapMatch, RouteMapMatchInner, RouteMapName, RouteMapSet, + AccessAction, AccessList, AccessListName, AccessListRule, ProtocolRouteMap, RouteMap, + RouteMapMatch, RouteMapMatchInner, RouteMapName, RouteMapSet, +}; +use proxmox_frr::{ + FrrConfig, FrrWord, Interface, InterfaceName, OpenfabricFrrConfig, OspfFrrConfig, }; -use proxmox_frr::{FrrConfig, FrrWord, Interface, InterfaceName, Router, RouterName}; use proxmox_network_types::ip_address::Cidr; use proxmox_sdn_types::net::Net; use crate::common::valid::Valid; - use crate::sdn::fabric::section_config::protocol::{ openfabric::{OpenfabricInterfaceProperties, OpenfabricProperties}, ospf::OspfInterfaceProperties, @@ -31,6 +34,8 @@ pub fn build_fabric( let mut routemap_seq = 100; let mut current_router_id: Option<Ipv4Addr> = None; let mut current_net: Option<Net> = None; + let mut new_openfabric_config = OpenfabricFrrConfig::default(); + let mut new_ospf_config = OspfFrrConfig::default(); for (fabric_id, entry) in config.into_inner().iter() { match entry { @@ -53,7 +58,9 @@ pub fn build_fabric( .as_ref() .ok_or_else(|| anyhow::anyhow!("no IPv4 or IPv6 set for node"))?; let (router_name, router_item) = build_openfabric_router(fabric_id, net.clone())?; - frr_config.router.insert(router_name, router_item); + new_openfabric_config + .router + .insert(router_name, router_item); // Create dummy interface for fabric let (interface, interface_name) = build_openfabric_dummy_interface( @@ -62,7 +69,7 @@ pub fn build_fabric( node.ip6().is_some(), )?; - if frr_config + if new_openfabric_config .interfaces .insert(interface_name, interface) .is_some() @@ -83,7 +90,7 @@ pub fn build_fabric( node.ip6().is_some(), )?; - if frr_config + if new_openfabric_config .interfaces .insert(interface_name, interface) .is_some() @@ -96,11 +103,12 @@ pub fn build_fabric( let rule = AccessListRule { action: AccessAction::Permit, network: Cidr::from(ipv4cidr), + is_ipv6: false, seq: None, }; let access_list_name = AccessListName::new(format!("pve_openfabric_{}_ips", fabric_id)); - frr_config.access_lists.push(AccessList { + new_openfabric_config.access_lists.push(AccessList { name: access_list_name, rules: vec![rule], }); @@ -109,11 +117,12 @@ pub fn build_fabric( let rule = AccessListRule { action: AccessAction::Permit, network: Cidr::from(ipv6cidr), + is_ipv6: true, seq: None, }; let access_list_name = AccessListName::new(format!("pve_openfabric_{}_ip6s", fabric_id)); - frr_config.access_lists.push(AccessList { + new_openfabric_config.access_lists.push(AccessList { name: access_list_name, rules: vec![rule], }); @@ -121,37 +130,43 @@ pub fn build_fabric( if let Some(ipv4) = node.ip() { // create route-map - frr_config.routemaps.push(build_openfabric_routemap( - fabric_id, - IpAddr::V4(ipv4), - routemap_seq, - )); + new_openfabric_config + .routemaps + .push(build_openfabric_routemap( + fabric_id, + IpAddr::V4(ipv4), + routemap_seq, + )); routemap_seq += 10; let protocol_routemap = ProtocolRouteMap { is_ipv6: false, - protocol: ProtocolType::Openfabric, routemap_name: RouteMapName::new("pve_openfabric".to_owned()), }; - frr_config.protocol_routemaps.insert(protocol_routemap); + new_openfabric_config + .protocol_routemaps + .insert(protocol_routemap); } if let Some(ipv6) = node.ip6() { // create route-map - frr_config.routemaps.push(build_openfabric_routemap( - fabric_id, - IpAddr::V6(ipv6), - routemap_seq, - )); + new_openfabric_config + .routemaps + .push(build_openfabric_routemap( + fabric_id, + IpAddr::V6(ipv6), + routemap_seq, + )); routemap_seq += 10; let protocol_routemap = ProtocolRouteMap { is_ipv6: true, - protocol: ProtocolType::Openfabric, routemap_name: RouteMapName::new("pve_openfabric6".to_owned()), }; - frr_config.protocol_routemaps.insert(protocol_routemap); + new_openfabric_config + .protocol_routemaps + .insert(protocol_routemap); } } FabricEntry::Ospf(ospf_entry) => { @@ -167,13 +182,13 @@ pub fn build_fabric( let frr_word_area = FrrWord::new(fabric.properties().area.to_string())?; let frr_area = ospf::Area::new(frr_word_area)?; let (router_name, router_item) = build_ospf_router(*router_id)?; - frr_config.router.insert(router_name, router_item); + new_ospf_config.router.insert(router_name, router_item); // Add dummy interface let (interface, interface_name) = build_ospf_dummy_interface(fabric_id, frr_area.clone())?; - if frr_config + if new_ospf_config .interfaces .insert(interface_name, interface) .is_some() @@ -187,7 +202,7 @@ pub fn build_fabric( let (interface, interface_name) = build_ospf_interface(frr_area.clone(), interface)?; - if frr_config + if new_ospf_config .interfaces .insert(interface_name, interface) .is_some() @@ -203,10 +218,11 @@ pub fn build_fabric( network: Cidr::from( fabric.ip_prefix().expect("fabric must have a ipv4 prefix"), ), + is_ipv6: false, seq: None, }; - frr_config.access_lists.push(AccessList { + new_ospf_config.access_lists.push(AccessList { name: access_list_name, rules: vec![rule], }); @@ -218,26 +234,26 @@ pub fn build_fabric( )?; routemap_seq += 10; - frr_config.routemaps.push(routemap); + new_ospf_config.routemaps.push(routemap); let protocol_routemap = ProtocolRouteMap { is_ipv6: false, - protocol: ProtocolType::Ospf, routemap_name: RouteMapName::new("pve_ospf".to_owned()), }; - frr_config.protocol_routemaps.insert(protocol_routemap); + new_ospf_config.protocol_routemaps.insert(protocol_routemap); } } } + frr_config.ospf = new_ospf_config; + frr_config.openfabric = new_openfabric_config; Ok(()) } /// Helper that builds a OSPF router with a the router_id. -fn build_ospf_router(router_id: Ipv4Addr) -> Result<(RouterName, Router), anyhow::Error> { - let ospf_router = proxmox_frr::ospf::OspfRouter { router_id }; - let router_item = Router::Ospf(ospf_router); - let router_name = RouterName::Ospf(proxmox_frr::ospf::OspfRouterName); +fn build_ospf_router(router_id: Ipv4Addr) -> Result<(OspfRouterName, OspfRouter), anyhow::Error> { + let router_item = proxmox_frr::ospf::OspfRouter { router_id }; + let router_name = proxmox_frr::ospf::OspfRouterName; Ok((router_name, router_item)) } @@ -245,11 +261,10 @@ fn build_ospf_router(router_id: Ipv4Addr) -> Result<(RouterName, Router), anyhow fn build_openfabric_router( fabric_id: &FabricId, net: Net, -) -> Result<(RouterName, Router), anyhow::Error> { - let ofr = proxmox_frr::openfabric::OpenfabricRouter { net }; - let router_item = Router::Openfabric(ofr); +) -> Result<(OpenfabricRouterName, OpenfabricRouter), anyhow::Error> { + let router_item = proxmox_frr::openfabric::OpenfabricRouter { net }; let frr_word_id = FrrWord::new(fabric_id.to_string())?; - let router_name = RouterName::Openfabric(frr_word_id.into()); + let router_name = frr_word_id.into(); Ok((router_name, router_item)) } @@ -257,10 +272,10 @@ fn build_openfabric_router( fn build_ospf_interface( area: ospf::Area, interface: &OspfInterfaceProperties, -) -> Result<(Interface, InterfaceName), anyhow::Error> { +) -> Result<(Interface<OspfInterface>, InterfaceName), anyhow::Error> { let frr_interface = proxmox_frr::ospf::OspfInterface { area, - // Interfaces are always none-passive + // Interfaces are always non-passive passive: None, network_type: if interface.ip.is_some() { None @@ -269,7 +284,7 @@ fn build_ospf_interface( }, }; - let interface_name = InterfaceName::Ospf(interface.name.as_str().try_into()?); + let interface_name = interface.name.as_str().try_into()?; Ok((frr_interface.into(), interface_name)) } @@ -277,13 +292,12 @@ fn build_ospf_interface( fn build_ospf_dummy_interface( fabric_id: &FabricId, area: ospf::Area, -) -> Result<(Interface, InterfaceName), anyhow::Error> { - let frr_interface = proxmox_frr::ospf::OspfInterface { - area, - passive: Some(true), - network_type: None, - }; - let interface_name = InterfaceName::Openfabric(format!("dummy_{}", fabric_id).try_into()?); +) -> Result<(Interface<OspfInterface>, InterfaceName), anyhow::Error> { + let frr_interface = proxmox_frr::ospf::OspfInterface::builder() + .area(area) + .passive(true) + .build(); + let interface_name = format!("dummy_{}", fabric_id).try_into()?; Ok((frr_interface.into(), interface_name)) } @@ -297,7 +311,7 @@ fn build_openfabric_interface( fabric_config: &OpenfabricProperties, is_ipv4: bool, is_ipv6: bool, -) -> Result<(Interface, InterfaceName), anyhow::Error> { +) -> Result<(Interface<OpenfabricInterface>, InterfaceName), anyhow::Error> { let frr_word = FrrWord::new(fabric_id.to_string())?; let mut frr_interface = proxmox_frr::openfabric::OpenfabricInterface { fabric_id: frr_word.into(), @@ -315,7 +329,7 @@ fn build_openfabric_interface( if frr_interface.hello_interval.is_none() { frr_interface.hello_interval = fabric_config.hello_interval; } - let interface_name = InterfaceName::Openfabric(interface.name.as_str().try_into()?); + let interface_name = interface.name.as_str().try_into()?; Ok((frr_interface.into(), interface_name)) } @@ -324,18 +338,15 @@ fn build_openfabric_dummy_interface( fabric_id: &FabricId, is_ipv4: bool, is_ipv6: bool, -) -> Result<(Interface, InterfaceName), anyhow::Error> { +) -> Result<(Interface<OpenfabricInterface>, InterfaceName), anyhow::Error> { let frr_word = FrrWord::new(fabric_id.to_string())?; - let frr_interface = proxmox_frr::openfabric::OpenfabricInterface { - fabric_id: frr_word.into(), - hello_interval: None, - passive: Some(true), - csnp_interval: None, - hello_multiplier: None, - is_ipv4, - is_ipv6, - }; - let interface_name = InterfaceName::Openfabric(format!("dummy_{}", fabric_id).try_into()?); + let frr_interface = proxmox_frr::openfabric::OpenfabricInterface::builder() + .fabric_id(frr_word.into()) + .passive(true) + .is_ipv4(is_ipv4) + .is_ipv6(is_ipv6) + .build(); + let interface_name = format!("dummy_{}", fabric_id).try_into()?; Ok((frr_interface.into(), interface_name)) } @@ -350,14 +361,14 @@ fn build_openfabric_routemap(fabric_id: &FabricId, router_ip: IpAddr, seq: u32) seq, action: AccessAction::Permit, matches: vec![match router_ip { - IpAddr::V4(_) => RouteMapMatch::V4(RouteMapMatchInner::IpAddress(AccessListName::new( + IpAddr::V4(_) => RouteMapMatch::V4(RouteMapMatchInner::Address(AccessListName::new( format!("pve_openfabric_{fabric_id}_ips"), ))), - IpAddr::V6(_) => RouteMapMatch::V6(RouteMapMatchInner::IpAddress(AccessListName::new( + IpAddr::V6(_) => RouteMapMatch::V6(RouteMapMatchInner::Address(AccessListName::new( format!("pve_openfabric_{fabric_id}_ip6s"), ))), }], - sets: vec![RouteMapSet::IpSrc(router_ip)], + sets: vec![RouteMapSet::Src(router_ip)], } } @@ -373,10 +384,10 @@ fn build_ospf_dummy_routemap( name: routemap_name.clone(), seq, action: AccessAction::Permit, - matches: vec![RouteMapMatch::V4(RouteMapMatchInner::IpAddress( + matches: vec![RouteMapMatch::V4(RouteMapMatchInner::Address( AccessListName::new(format!("pve_ospf_{fabric_id}_ips")), ))], - sets: vec![RouteMapSet::IpSrc(IpAddr::from(router_ip))], + sets: vec![RouteMapSet::Src(IpAddr::from(router_ip))], }; Ok(routemap) diff --git a/proxmox-ve-config/src/sdn/frr.rs b/proxmox-ve-config/src/sdn/frr.rs index f7929c1f6c16..bc98440b9912 100644 --- a/proxmox-ve-config/src/sdn/frr.rs +++ b/proxmox-ve-config/src/sdn/frr.rs @@ -1,6 +1,4 @@ -use std::collections::{BTreeMap, BTreeSet}; - -use proxmox_frr::FrrConfig; +use proxmox_frr::{FrrConfig, OpenfabricFrrConfig, OspfFrrConfig}; use crate::common::valid::Valid; use crate::sdn::fabric::{section_config::node::NodeId, FabricConfig}; @@ -28,11 +26,8 @@ impl FrrConfigBuilder { /// interface if there isn't a more specific one.) pub fn build(self, current_node: NodeId) -> Result<FrrConfig, anyhow::Error> { let mut frr_config = FrrConfig { - router: BTreeMap::new(), - interfaces: BTreeMap::new(), - access_lists: Vec::new(), - routemaps: Vec::new(), - protocol_routemaps: BTreeSet::new(), + openfabric: OpenfabricFrrConfig::default(), + ospf: OspfFrrConfig::default(), }; crate::sdn::fabric::frr::build_fabric(current_node, self.fabrics, &mut frr_config)?; -- 2.47.3 _______________________________________________ pve-devel mailing list [email protected] https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
