Move all the serialization structs to a new subfolder `ser`. This makes place for the deserialization structs which will land in a new folder `de`. The deserialization structs will be used to parse the output of `vtysh` commands, so that we can show statistics of various sdn objects. Also update all the callsites to use the new subfolder.
Signed-off-by: Gabriel Goller <g.gol...@proxmox.com> --- proxmox-frr/src/lib.rs | 242 +----------------------- proxmox-frr/src/ser/mod.rs | 241 +++++++++++++++++++++++ proxmox-frr/src/{ => ser}/openfabric.rs | 4 +- proxmox-frr/src/{ => ser}/ospf.rs | 2 +- proxmox-frr/src/{ => ser}/route_map.rs | 0 proxmox-frr/src/{ => ser}/serializer.rs | 2 +- proxmox-ve-config/src/sdn/fabric/frr.rs | 170 +++++++++-------- proxmox-ve-config/src/sdn/frr.rs | 2 +- proxmox-ve-config/tests/fabric/main.rs | 2 +- 9 files changed, 340 insertions(+), 325 deletions(-) create mode 100644 proxmox-frr/src/ser/mod.rs rename proxmox-frr/src/{ => ser}/openfabric.rs (97%) rename proxmox-frr/src/{ => ser}/ospf.rs (99%) rename proxmox-frr/src/{ => ser}/route_map.rs (100%) rename proxmox-frr/src/{ => ser}/serializer.rs (99%) diff --git a/proxmox-frr/src/lib.rs b/proxmox-frr/src/lib.rs index 86101182fafd..35b62cb39c91 100644 --- a/proxmox-frr/src/lib.rs +++ b/proxmox-frr/src/lib.rs @@ -1,241 +1 @@ -pub mod openfabric; -pub mod ospf; -pub mod route_map; -pub mod serializer; - -use std::collections::{BTreeMap, BTreeSet}; -use std::fmt::Display; -use std::str::FromStr; - -use crate::route_map::{AccessList, ProtocolRouteMap, RouteMap}; - -use thiserror::Error; - -/// Generic FRR router. -/// -/// This generic FRR router contains all the protocols that we implement. -/// In FRR this is e.g.: -/// ```text -/// router openfabric test -/// !.... -/// ! or -/// router ospf -/// !.... -/// ``` -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum Router { - Openfabric(openfabric::OpenfabricRouter), - Ospf(ospf::OspfRouter), -} - -impl From<openfabric::OpenfabricRouter> for Router { - fn from(value: openfabric::OpenfabricRouter) -> Self { - Router::Openfabric(value) - } -} - -/// Generic FRR routername. -/// -/// The variants represent different protocols. Some have `router <protocol> <name>`, others have -/// `router <protocol> <process-id>`, some only have `router <protocol>`. -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum RouterName { - Openfabric(openfabric::OpenfabricRouterName), - Ospf(ospf::OspfRouterName), -} - -impl From<openfabric::OpenfabricRouterName> for RouterName { - fn from(value: openfabric::OpenfabricRouterName) -> Self { - Self::Openfabric(value) - } -} - -impl Display for RouterName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Openfabric(r) => r.fmt(f), - Self::Ospf(r) => r.fmt(f), - } - } -} - -/// The interface name is the same on ospf and openfabric, but it is an enum so that we can have -/// two different entries in the btreemap. This allows us to have an interface in a ospf and -/// openfabric fabric. -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum InterfaceName { - Openfabric(CommonInterfaceName), - Ospf(CommonInterfaceName), -} - -impl Display for InterfaceName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - InterfaceName::Openfabric(frr_word) => frr_word.fmt(f), - InterfaceName::Ospf(frr_word) => frr_word.fmt(f), - } - } -} - -/// Generic FRR Interface. -/// -/// In FRR config it looks like this: -/// ```text -/// interface <name> -/// ! ... -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum Interface { - Openfabric(openfabric::OpenfabricInterface), - Ospf(ospf::OspfInterface), -} - -impl From<openfabric::OpenfabricInterface> for Interface { - fn from(value: openfabric::OpenfabricInterface) -> Self { - Self::Openfabric(value) - } -} - -impl From<ospf::OspfInterface> for Interface { - fn from(value: ospf::OspfInterface) -> Self { - Self::Ospf(value) - } -} - -#[derive(Error, Debug)] -pub enum FrrWordError { - #[error("word is empty")] - IsEmpty, - #[error("word contains invalid character")] - InvalidCharacter, -} - -/// A simple FRR Word. -/// -/// Every string argument or value in FRR is an FrrWord. FrrWords must only contain ascii -/// characters and must not have a whitespace. -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct FrrWord(String); - -impl FrrWord { - pub fn new<T: AsRef<str> + Into<String>>(name: T) -> Result<Self, FrrWordError> { - if name.as_ref().is_empty() { - return Err(FrrWordError::IsEmpty); - } - - if name - .as_ref() - .as_bytes() - .iter() - .any(|c| !c.is_ascii() || c.is_ascii_whitespace()) - { - eprintln!("invalid char in: \"{}\"", name.as_ref()); - return Err(FrrWordError::InvalidCharacter); - } - - Ok(Self(name.into())) - } -} - -impl FromStr for FrrWord { - type Err = FrrWordError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - Self::new(s) - } -} - -impl Display for FrrWord { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl AsRef<str> for FrrWord { - fn as_ref(&self) -> &str { - &self.0 - } -} - -#[derive(Error, Debug)] -pub enum CommonInterfaceNameError { - #[error("interface name too long")] - TooLong, -} - -/// Name of a interface, which is common between all protocols. -/// -/// FRR itself doesn't enforce any limits, but the kernel does. Linux only allows interface names -/// to be a maximum of 16 bytes. This is enforced by this struct. -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct CommonInterfaceName(String); - -impl TryFrom<&str> for CommonInterfaceName { - type Error = CommonInterfaceNameError; - - fn try_from(value: &str) -> Result<Self, Self::Error> { - Self::new(value) - } -} - -impl TryFrom<String> for CommonInterfaceName { - type Error = CommonInterfaceNameError; - - fn try_from(value: String) -> Result<Self, Self::Error> { - Self::new(value) - } -} - -impl CommonInterfaceName { - pub fn new<T: AsRef<str> + Into<String>>(s: T) -> Result<Self, CommonInterfaceNameError> { - if s.as_ref().len() <= 15 { - Ok(Self(s.into())) - } else { - Err(CommonInterfaceNameError::TooLong) - } - } -} - -impl Display for CommonInterfaceName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -/// Main FRR config. -/// -/// Contains the two main frr building blocks: routers and interfaces. It also holds other -/// top-level FRR options, such as access-lists, router-maps and protocol-routemaps. This struct -/// gets generated using the `FrrConfigBuilder` in `proxmox-ve-config`. -#[derive(Clone, Debug, PartialEq, Eq, Default)] -pub struct FrrConfig { - pub router: BTreeMap<RouterName, Router>, - pub interfaces: BTreeMap<InterfaceName, Interface>, - pub access_lists: Vec<AccessList>, - pub routemaps: Vec<RouteMap>, - pub protocol_routemaps: BTreeSet<ProtocolRouteMap>, -} - -impl FrrConfig { - pub fn new() -> Self { - Self::default() - } - - pub fn router(&self) -> impl Iterator<Item = (&RouterName, &Router)> + '_ { - self.router.iter() - } - - pub fn interfaces(&self) -> impl Iterator<Item = (&InterfaceName, &Interface)> + '_ { - self.interfaces.iter() - } - - pub fn access_lists(&self) -> impl Iterator<Item = &AccessList> + '_ { - self.access_lists.iter() - } - pub fn routemaps(&self) -> impl Iterator<Item = &RouteMap> + '_ { - self.routemaps.iter() - } - - pub fn protocol_routemaps(&self) -> impl Iterator<Item = &ProtocolRouteMap> + '_ { - self.protocol_routemaps.iter() - } -} +pub mod ser; diff --git a/proxmox-frr/src/ser/mod.rs b/proxmox-frr/src/ser/mod.rs new file mode 100644 index 000000000000..a90397b59a9b --- /dev/null +++ b/proxmox-frr/src/ser/mod.rs @@ -0,0 +1,241 @@ +pub mod openfabric; +pub mod ospf; +pub mod route_map; +pub mod serializer; + +use std::collections::{BTreeMap, BTreeSet}; +use std::fmt::Display; +use std::str::FromStr; + +use crate::ser::route_map::{AccessList, ProtocolRouteMap, RouteMap}; + +use thiserror::Error; + +/// Generic FRR router. +/// +/// This generic FRR router contains all the protocols that we implement. +/// In FRR this is e.g.: +/// ```text +/// router openfabric test +/// !.... +/// ! or +/// router ospf +/// !.... +/// ``` +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum Router { + Openfabric(openfabric::OpenfabricRouter), + Ospf(ospf::OspfRouter), +} + +impl From<openfabric::OpenfabricRouter> for Router { + fn from(value: openfabric::OpenfabricRouter) -> Self { + Router::Openfabric(value) + } +} + +/// Generic FRR routername. +/// +/// The variants represent different protocols. Some have `router <protocol> <name>`, others have +/// `router <protocol> <process-id>`, some only have `router <protocol>`. +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum RouterName { + Openfabric(openfabric::OpenfabricRouterName), + Ospf(ospf::OspfRouterName), +} + +impl From<openfabric::OpenfabricRouterName> for RouterName { + fn from(value: openfabric::OpenfabricRouterName) -> Self { + Self::Openfabric(value) + } +} + +impl Display for RouterName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Openfabric(r) => r.fmt(f), + Self::Ospf(r) => r.fmt(f), + } + } +} + +/// The interface name is the same on ospf and openfabric, but it is an enum so that we can have +/// two different entries in the btreemap. This allows us to have an interface in a ospf and +/// openfabric fabric. +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum InterfaceName { + Openfabric(CommonInterfaceName), + Ospf(CommonInterfaceName), +} + +impl Display for InterfaceName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InterfaceName::Openfabric(frr_word) => frr_word.fmt(f), + InterfaceName::Ospf(frr_word) => frr_word.fmt(f), + } + } +} + +/// Generic FRR Interface. +/// +/// In FRR config it looks like this: +/// ```text +/// interface <name> +/// ! ... +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Interface { + Openfabric(openfabric::OpenfabricInterface), + Ospf(ospf::OspfInterface), +} + +impl From<openfabric::OpenfabricInterface> for Interface { + fn from(value: openfabric::OpenfabricInterface) -> Self { + Self::Openfabric(value) + } +} + +impl From<ospf::OspfInterface> for Interface { + fn from(value: ospf::OspfInterface) -> Self { + Self::Ospf(value) + } +} + +#[derive(Error, Debug)] +pub enum FrrWordError { + #[error("word is empty")] + IsEmpty, + #[error("word contains invalid character")] + InvalidCharacter, +} + +/// A simple FRR Word. +/// +/// Every string argument or value in FRR is an FrrWord. FrrWords must only contain ascii +/// characters and must not have a whitespace. +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct FrrWord(String); + +impl FrrWord { + pub fn new<T: AsRef<str> + Into<String>>(name: T) -> Result<Self, FrrWordError> { + if name.as_ref().is_empty() { + return Err(FrrWordError::IsEmpty); + } + + if name + .as_ref() + .as_bytes() + .iter() + .any(|c| !c.is_ascii() || c.is_ascii_whitespace()) + { + eprintln!("invalid char in: \"{}\"", name.as_ref()); + return Err(FrrWordError::InvalidCharacter); + } + + Ok(Self(name.into())) + } +} + +impl FromStr for FrrWord { + type Err = FrrWordError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + Self::new(s) + } +} + +impl Display for FrrWord { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl AsRef<str> for FrrWord { + fn as_ref(&self) -> &str { + &self.0 + } +} + +#[derive(Error, Debug)] +pub enum CommonInterfaceNameError { + #[error("interface name too long")] + TooLong, +} + +/// Name of a interface, which is common between all protocols. +/// +/// FRR itself doesn't enforce any limits, but the kernel does. Linux only allows interface names +/// to be a maximum of 16 bytes. This is enforced by this struct. +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct CommonInterfaceName(String); + +impl TryFrom<&str> for CommonInterfaceName { + type Error = CommonInterfaceNameError; + + fn try_from(value: &str) -> Result<Self, Self::Error> { + Self::new(value) + } +} + +impl TryFrom<String> for CommonInterfaceName { + type Error = CommonInterfaceNameError; + + fn try_from(value: String) -> Result<Self, Self::Error> { + Self::new(value) + } +} + +impl CommonInterfaceName { + pub fn new<T: AsRef<str> + Into<String>>(s: T) -> Result<Self, CommonInterfaceNameError> { + if s.as_ref().len() <= 15 { + Ok(Self(s.into())) + } else { + Err(CommonInterfaceNameError::TooLong) + } + } +} + +impl Display for CommonInterfaceName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +/// Main FRR config. +/// +/// Contains the two main frr building blocks: routers and interfaces. It also holds other +/// top-level FRR options, such as access-lists, router-maps and protocol-routemaps. This struct +/// gets generated using the `FrrConfigBuilder` in `proxmox-ve-config`. +#[derive(Clone, Debug, PartialEq, Eq, Default)] +pub struct FrrConfig { + pub router: BTreeMap<RouterName, Router>, + pub interfaces: BTreeMap<InterfaceName, Interface>, + pub access_lists: Vec<AccessList>, + pub routemaps: Vec<RouteMap>, + pub protocol_routemaps: BTreeSet<ProtocolRouteMap>, +} + +impl FrrConfig { + pub fn new() -> Self { + Self::default() + } + + pub fn router(&self) -> impl Iterator<Item = (&RouterName, &Router)> + '_ { + self.router.iter() + } + + pub fn interfaces(&self) -> impl Iterator<Item = (&InterfaceName, &Interface)> + '_ { + self.interfaces.iter() + } + + pub fn access_lists(&self) -> impl Iterator<Item = &AccessList> + '_ { + self.access_lists.iter() + } + pub fn routemaps(&self) -> impl Iterator<Item = &RouteMap> + '_ { + self.routemaps.iter() + } + + pub fn protocol_routemaps(&self) -> impl Iterator<Item = &ProtocolRouteMap> + '_ { + self.protocol_routemaps.iter() + } +} diff --git a/proxmox-frr/src/openfabric.rs b/proxmox-frr/src/ser/openfabric.rs similarity index 97% rename from proxmox-frr/src/openfabric.rs rename to proxmox-frr/src/ser/openfabric.rs index 6e2a7200ab37..0f0c65062d36 100644 --- a/proxmox-frr/src/openfabric.rs +++ b/proxmox-frr/src/ser/openfabric.rs @@ -5,8 +5,8 @@ use proxmox_sdn_types::net::Net; use thiserror::Error; -use crate::FrrWord; -use crate::FrrWordError; +use crate::ser::FrrWord; +use crate::ser::FrrWordError; /// The name of a OpenFabric router. Is an FrrWord. #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] diff --git a/proxmox-frr/src/ospf.rs b/proxmox-frr/src/ser/ospf.rs similarity index 99% rename from proxmox-frr/src/ospf.rs rename to proxmox-frr/src/ser/ospf.rs index d0e098e099d2..67e39a45b8de 100644 --- a/proxmox-frr/src/ospf.rs +++ b/proxmox-frr/src/ser/ospf.rs @@ -4,7 +4,7 @@ use std::net::Ipv4Addr; use thiserror::Error; -use crate::{FrrWord, FrrWordError}; +use crate::ser::{FrrWord, FrrWordError}; /// The name of the ospf frr router. /// diff --git a/proxmox-frr/src/route_map.rs b/proxmox-frr/src/ser/route_map.rs similarity index 100% rename from proxmox-frr/src/route_map.rs rename to proxmox-frr/src/ser/route_map.rs diff --git a/proxmox-frr/src/serializer.rs b/proxmox-frr/src/ser/serializer.rs similarity index 99% rename from proxmox-frr/src/serializer.rs rename to proxmox-frr/src/ser/serializer.rs index f8a3c7238d94..3a681e2f0d7a 100644 --- a/proxmox-frr/src/serializer.rs +++ b/proxmox-frr/src/ser/serializer.rs @@ -1,6 +1,6 @@ use std::fmt::{self, Write}; -use crate::{ +use crate::ser::{ openfabric::{OpenfabricInterface, OpenfabricRouter}, ospf::{OspfInterface, OspfRouter}, route_map::{AccessList, AccessListName, ProtocolRouteMap, RouteMap}, diff --git a/proxmox-ve-config/src/sdn/fabric/frr.rs b/proxmox-ve-config/src/sdn/fabric/frr.rs index 486f7dc51dcb..10025b3544b9 100644 --- a/proxmox-ve-config/src/sdn/fabric/frr.rs +++ b/proxmox-ve-config/src/sdn/fabric/frr.rs @@ -1,12 +1,7 @@ use std::net::{IpAddr, Ipv4Addr}; use tracing; -use proxmox_frr::ospf::{self, NetworkType}; -use proxmox_frr::route_map::{ - AccessAction, AccessList, AccessListName, AccessListRule, ProtocolRouteMap, ProtocolType, - RouteMap, RouteMapMatch, RouteMapMatchInner, RouteMapName, RouteMapSet, -}; -use proxmox_frr::{FrrConfig, FrrWord, Interface, InterfaceName, Router, RouterName}; +use proxmox_frr::ser::{self}; use proxmox_network_types::ip_address::Cidr; use proxmox_sdn_types::net::Net; @@ -26,7 +21,7 @@ use crate::sdn::fabric::{FabricConfig, FabricEntry}; pub fn build_fabric( current_node: NodeId, config: Valid<FabricConfig>, - frr_config: &mut FrrConfig, + frr_config: &mut ser::FrrConfig, ) -> Result<(), anyhow::Error> { let mut routemap_seq = 100; let mut current_router_id: Option<Ipv4Addr> = None; @@ -93,27 +88,31 @@ pub fn build_fabric( } if let Some(ipv4cidr) = fabric.ip_prefix() { - let rule = AccessListRule { - action: AccessAction::Permit, + let rule = ser::route_map::AccessListRule { + action: ser::route_map::AccessAction::Permit, network: Cidr::from(ipv4cidr), seq: None, }; - let access_list_name = - AccessListName::new(format!("pve_openfabric_{}_ips", fabric_id)); - frr_config.access_lists.push(AccessList { + let access_list_name = ser::route_map::AccessListName::new(format!( + "pve_openfabric_{}_ips", + fabric_id + )); + frr_config.access_lists.push(ser::route_map::AccessList { name: access_list_name, rules: vec![rule], }); } if let Some(ipv6cidr) = fabric.ip6_prefix() { - let rule = AccessListRule { - action: AccessAction::Permit, + let rule = ser::route_map::AccessListRule { + action: ser::route_map::AccessAction::Permit, network: Cidr::from(ipv6cidr), seq: None, }; - let access_list_name = - AccessListName::new(format!("pve_openfabric_{}_ip6s", fabric_id)); - frr_config.access_lists.push(AccessList { + let access_list_name = ser::route_map::AccessListName::new(format!( + "pve_openfabric_{}_ip6s", + fabric_id + )); + frr_config.access_lists.push(ser::route_map::AccessList { name: access_list_name, rules: vec![rule], }); @@ -128,10 +127,12 @@ pub fn build_fabric( )); routemap_seq += 10; - let protocol_routemap = ProtocolRouteMap { + let protocol_routemap = ser::route_map::ProtocolRouteMap { is_ipv6: false, - protocol: ProtocolType::Openfabric, - routemap_name: RouteMapName::new("pve_openfabric".to_owned()), + protocol: ser::route_map::ProtocolType::Openfabric, + routemap_name: ser::route_map::RouteMapName::new( + "pve_openfabric".to_owned(), + ), }; frr_config.protocol_routemaps.insert(protocol_routemap); @@ -145,10 +146,12 @@ pub fn build_fabric( )); routemap_seq += 10; - let protocol_routemap = ProtocolRouteMap { + let protocol_routemap = ser::route_map::ProtocolRouteMap { is_ipv6: true, - protocol: ProtocolType::Openfabric, - routemap_name: RouteMapName::new("pve_openfabric6".to_owned()), + protocol: ser::route_map::ProtocolType::Openfabric, + routemap_name: ser::route_map::RouteMapName::new( + "pve_openfabric6".to_owned(), + ), }; frr_config.protocol_routemaps.insert(protocol_routemap); @@ -164,8 +167,8 @@ pub fn build_fabric( let fabric = ospf_entry.fabric_section(); - let frr_word_area = FrrWord::new(fabric.properties().area.to_string())?; - let frr_area = ospf::Area::new(frr_word_area)?; + let frr_word_area = ser::FrrWord::new(fabric.properties().area.to_string())?; + let frr_area = ser::ospf::Area::new(frr_word_area)?; let (router_name, router_item) = build_ospf_router(*router_id)?; frr_config.router.insert(router_name, router_item); @@ -196,17 +199,18 @@ pub fn build_fabric( } } - let access_list_name = AccessListName::new(format!("pve_ospf_{}_ips", fabric_id)); + let access_list_name = + ser::route_map::AccessListName::new(format!("pve_ospf_{}_ips", fabric_id)); - let rule = AccessListRule { - action: AccessAction::Permit, + let rule = ser::route_map::AccessListRule { + action: ser::route_map::AccessAction::Permit, network: Cidr::from( fabric.ip_prefix().expect("fabric must have a ipv4 prefix"), ), seq: None, }; - frr_config.access_lists.push(AccessList { + frr_config.access_lists.push(ser::route_map::AccessList { name: access_list_name, rules: vec![rule], }); @@ -220,10 +224,10 @@ pub fn build_fabric( routemap_seq += 10; frr_config.routemaps.push(routemap); - let protocol_routemap = ProtocolRouteMap { + let protocol_routemap = ser::route_map::ProtocolRouteMap { is_ipv6: false, - protocol: ProtocolType::Ospf, - routemap_name: RouteMapName::new("pve_ospf".to_owned()), + protocol: ser::route_map::ProtocolType::Ospf, + routemap_name: ser::route_map::RouteMapName::new("pve_ospf".to_owned()), }; frr_config.protocol_routemaps.insert(protocol_routemap); @@ -234,10 +238,10 @@ pub fn build_fabric( } /// 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<(ser::RouterName, ser::Router), anyhow::Error> { + let ospf_router = ser::ospf::OspfRouter { router_id }; + let router_item = ser::Router::Ospf(ospf_router); + let router_name = ser::RouterName::Ospf(ser::ospf::OspfRouterName); Ok((router_name, router_item)) } @@ -245,45 +249,45 @@ 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); - let frr_word_id = FrrWord::new(fabric_id.to_string())?; - let router_name = RouterName::Openfabric(frr_word_id.into()); +) -> Result<(ser::RouterName, ser::Router), anyhow::Error> { + let ofr = ser::openfabric::OpenfabricRouter { net }; + let router_item = ser::Router::Openfabric(ofr); + let frr_word_id = ser::FrrWord::new(fabric_id.to_string())?; + let router_name = ser::RouterName::Openfabric(frr_word_id.into()); Ok((router_name, router_item)) } /// Helper that builds a OSPF interface from an [`ospf::Area`] and the [`OspfInterfaceProperties`]. fn build_ospf_interface( - area: ospf::Area, + area: ser::ospf::Area, interface: &OspfInterfaceProperties, -) -> Result<(Interface, InterfaceName), anyhow::Error> { - let frr_interface = proxmox_frr::ospf::OspfInterface { +) -> Result<(ser::Interface, ser::InterfaceName), anyhow::Error> { + let frr_interface = ser::ospf::OspfInterface { area, // Interfaces are always none-passive passive: None, network_type: if interface.ip.is_some() { None } else { - Some(NetworkType::PointToPoint) + Some(ser::ospf::NetworkType::PointToPoint) }, }; - let interface_name = InterfaceName::Ospf(interface.name.as_str().try_into()?); + let interface_name = ser::InterfaceName::Ospf(interface.name.as_str().try_into()?); Ok((frr_interface.into(), interface_name)) } /// Helper that builds the OSPF dummy interface using the [`FabricId`] and the [`ospf::Area`]. fn build_ospf_dummy_interface( fabric_id: &FabricId, - area: ospf::Area, -) -> Result<(Interface, InterfaceName), anyhow::Error> { - let frr_interface = proxmox_frr::ospf::OspfInterface { + area: ser::ospf::Area, +) -> Result<(ser::Interface, ser::InterfaceName), anyhow::Error> { + let frr_interface = ser::ospf::OspfInterface { area, passive: Some(true), network_type: None, }; - let interface_name = InterfaceName::Openfabric(format!("dummy_{}", fabric_id).try_into()?); + let interface_name = ser::InterfaceName::Openfabric(format!("dummy_{}", fabric_id).try_into()?); Ok((frr_interface.into(), interface_name)) } @@ -297,9 +301,9 @@ fn build_openfabric_interface( fabric_config: &OpenfabricProperties, is_ipv4: bool, is_ipv6: bool, -) -> Result<(Interface, InterfaceName), anyhow::Error> { - let frr_word = FrrWord::new(fabric_id.to_string())?; - let mut frr_interface = proxmox_frr::openfabric::OpenfabricInterface { +) -> Result<(ser::Interface, ser::InterfaceName), anyhow::Error> { + let frr_word = ser::FrrWord::new(fabric_id.to_string())?; + let mut frr_interface = ser::openfabric::OpenfabricInterface { fabric_id: frr_word.into(), // Every interface is not passive by default passive: None, @@ -315,7 +319,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 = ser::InterfaceName::Openfabric(interface.name.as_str().try_into()?); Ok((frr_interface.into(), interface_name)) } @@ -324,9 +328,9 @@ fn build_openfabric_dummy_interface( fabric_id: &FabricId, is_ipv4: bool, is_ipv6: bool, -) -> Result<(Interface, InterfaceName), anyhow::Error> { - let frr_word = FrrWord::new(fabric_id.to_string())?; - let frr_interface = proxmox_frr::openfabric::OpenfabricInterface { +) -> Result<(ser::Interface, ser::InterfaceName), anyhow::Error> { + let frr_word = ser::FrrWord::new(fabric_id.to_string())?; + let frr_interface = ser::openfabric::OpenfabricInterface { fabric_id: frr_word.into(), hello_interval: None, passive: Some(true), @@ -335,29 +339,37 @@ fn build_openfabric_dummy_interface( is_ipv4, is_ipv6, }; - let interface_name = InterfaceName::Openfabric(format!("dummy_{}", fabric_id).try_into()?); + let interface_name = ser::InterfaceName::Openfabric(format!("dummy_{}", fabric_id).try_into()?); Ok((frr_interface.into(), interface_name)) } /// Helper that builds a RouteMap for the OpenFabric protocol. -fn build_openfabric_routemap(fabric_id: &FabricId, router_ip: IpAddr, seq: u32) -> RouteMap { +fn build_openfabric_routemap( + fabric_id: &FabricId, + router_ip: IpAddr, + seq: u32, +) -> ser::route_map::RouteMap { let routemap_name = match router_ip { - IpAddr::V4(_) => RouteMapName::new("pve_openfabric".to_owned()), - IpAddr::V6(_) => RouteMapName::new("pve_openfabric6".to_owned()), + IpAddr::V4(_) => ser::route_map::RouteMapName::new("pve_openfabric".to_owned()), + IpAddr::V6(_) => ser::route_map::RouteMapName::new("pve_openfabric6".to_owned()), }; - RouteMap { + ser::route_map::RouteMap { name: routemap_name.clone(), seq, - action: AccessAction::Permit, + action: ser::route_map::AccessAction::Permit, matches: vec![match router_ip { - IpAddr::V4(_) => RouteMapMatch::V4(RouteMapMatchInner::IpAddress(AccessListName::new( - format!("pve_openfabric_{fabric_id}_ips"), - ))), - IpAddr::V6(_) => RouteMapMatch::V6(RouteMapMatchInner::IpAddress(AccessListName::new( - format!("pve_openfabric_{fabric_id}_ip6s"), - ))), + IpAddr::V4(_) => { + ser::route_map::RouteMapMatch::V4(ser::route_map::RouteMapMatchInner::IpAddress( + ser::route_map::AccessListName::new(format!("pve_openfabric_{fabric_id}_ips")), + )) + } + IpAddr::V6(_) => { + ser::route_map::RouteMapMatch::V6(ser::route_map::RouteMapMatchInner::IpAddress( + ser::route_map::AccessListName::new(format!("pve_openfabric_{fabric_id}_ip6s")), + )) + } }], - sets: vec![RouteMapSet::IpSrc(router_ip)], + sets: vec![ser::route_map::RouteMapSet::IpSrc(router_ip)], } } @@ -366,17 +378,19 @@ fn build_ospf_dummy_routemap( fabric_id: &FabricId, router_ip: Ipv4Addr, seq: u32, -) -> Result<RouteMap, anyhow::Error> { - let routemap_name = RouteMapName::new("pve_ospf".to_owned()); +) -> Result<ser::route_map::RouteMap, anyhow::Error> { + let routemap_name = ser::route_map::RouteMapName::new("pve_ospf".to_owned()); // create route-map - let routemap = RouteMap { + let routemap = ser::route_map::RouteMap { name: routemap_name.clone(), seq, - action: AccessAction::Permit, - matches: vec![RouteMapMatch::V4(RouteMapMatchInner::IpAddress( - AccessListName::new(format!("pve_ospf_{fabric_id}_ips")), - ))], - sets: vec![RouteMapSet::IpSrc(IpAddr::from(router_ip))], + action: ser::route_map::AccessAction::Permit, + matches: vec![ser::route_map::RouteMapMatch::V4( + ser::route_map::RouteMapMatchInner::IpAddress(ser::route_map::AccessListName::new( + format!("pve_ospf_{fabric_id}_ips"), + )), + )], + sets: vec![ser::route_map::RouteMapSet::IpSrc(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..5d4e4b2ebdbd 100644 --- a/proxmox-ve-config/src/sdn/frr.rs +++ b/proxmox-ve-config/src/sdn/frr.rs @@ -1,6 +1,6 @@ use std::collections::{BTreeMap, BTreeSet}; -use proxmox_frr::FrrConfig; +use proxmox_frr::ser::FrrConfig; use crate::common::valid::Valid; use crate::sdn::fabric::{section_config::node::NodeId, FabricConfig}; diff --git a/proxmox-ve-config/tests/fabric/main.rs b/proxmox-ve-config/tests/fabric/main.rs index 47bbbeb77886..09629d406449 100644 --- a/proxmox-ve-config/tests/fabric/main.rs +++ b/proxmox-ve-config/tests/fabric/main.rs @@ -1,5 +1,5 @@ #![cfg(feature = "frr")] -use proxmox_frr::serializer::dump; +use proxmox_frr::ser::serializer::dump; use proxmox_ve_config::sdn::{ fabric::{section_config::node::NodeId, FabricConfig}, frr::FrrConfigBuilder, -- 2.47.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel