From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id B0B061FF185 for ; Mon, 7 Jul 2025 13:24:25 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 012B730838; Mon, 7 Jul 2025 13:25:08 +0200 (CEST) Date: Mon, 7 Jul 2025 13:25:03 +0200 From: Wolfgang Bumiller To: Gabriel Goller Message-ID: References: <20250702145101.894299-1-g.goller@proxmox.com> <20250702145101.894299-13-g.goller@proxmox.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20250702145101.894299-13-g.goller@proxmox.com> X-SPAM-LEVEL: Spam detection results: 0 AWL 0.078 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: Re: [pve-devel] [PATCH proxmox-ve-rs v4 06/22] frr: add openfabric types X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Cc: pve-devel@lists.proxmox.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" On Wed, Jul 02, 2025 at 04:49:57PM +0200, Gabriel Goller wrote: > Implement OpenFabric-specific variants of common enums that > encapsulate protocol properties defined in proxmox-network-types. The > primary addition is OpenFabricInterface, which stores > protocol-specific timing parameters: HelloInterval (neighbor discovery > frequency), CsnpInterval (database synchronization frequency), and > HelloMultiplier (neighbor failure detection). Added `is_ipv6` flag to > support FRR's command prefixing requirements during serialization for > IPv6-specific commands (we need to add a 'ipv6' prefix to some > commands). > > Signed-off-by: Gabriel Goller > --- > proxmox-frr/debian/control | 2 + > proxmox-frr/src/lib.rs | 1 + > proxmox-frr/src/openfabric.rs | 114 ++++++++++++++++++++++++++++++++++ > 3 files changed, 117 insertions(+) > create mode 100644 proxmox-frr/src/openfabric.rs > > diff --git a/proxmox-frr/debian/control b/proxmox-frr/debian/control > index 07b4fbe87629..894bfeac8a65 100644 > --- a/proxmox-frr/debian/control > +++ b/proxmox-frr/debian/control > @@ -9,6 +9,7 @@ Build-Depends-Arch: cargo:native , > librust-anyhow-1+default-dev , > librust-itoa-1+default-dev (>= 1.0.9-~~) , > librust-proxmox-network-types-0.1+default-dev , > + librust-proxmox-sdn-types-0.1+default-dev , > librust-serde-1+default-dev , > librust-serde-1+derive-dev , > librust-serde-with-3+default-dev , > @@ -30,6 +31,7 @@ Depends: > librust-anyhow-1+default-dev, > librust-itoa-1+default-dev (>= 1.0.9-~~), > librust-proxmox-network-types-0.1+default-dev, > + librust-proxmox-sdn-types-0.1+default-dev, > librust-serde-1+default-dev, > librust-serde-1+derive-dev, > librust-serde-with-3+default-dev, > diff --git a/proxmox-frr/src/lib.rs b/proxmox-frr/src/lib.rs > index 5e0b34602cf4..ba9eedfb4549 100644 > --- a/proxmox-frr/src/lib.rs > +++ b/proxmox-frr/src/lib.rs > @@ -1,3 +1,4 @@ > +pub mod openfabric; > use std::{fmt::Display, str::FromStr}; > > use serde::{Deserialize, Serialize}; > diff --git a/proxmox-frr/src/openfabric.rs b/proxmox-frr/src/openfabric.rs > new file mode 100644 > index 000000000000..91c18dc27254 > --- /dev/null > +++ b/proxmox-frr/src/openfabric.rs > @@ -0,0 +1,114 @@ > +use std::fmt::Debug; > +use std::fmt::Display; > + > +use proxmox_sdn_types::net::Net; > +use serde::{Deserialize, Serialize}; > +use serde_with::SerializeDisplay; > + > +use thiserror::Error; > + > +use crate::FrrWord; > +use crate::FrrWordError; > + > +/// The name of a OpenFabric router. Is an FrrWord. > +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, SerializeDisplay, PartialOrd, Ord)] > +pub struct OpenfabricRouterName(FrrWord); > + > +impl From for OpenfabricRouterName { > + fn from(value: FrrWord) -> Self { > + Self(value) > + } > +} > + > +impl OpenfabricRouterName { > + pub fn new(name: FrrWord) -> Self { > + Self(name) > + } > +} > + > +impl Display for OpenfabricRouterName { > + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { > + write!(f, "openfabric {}", self.0) > + } > +} > + > +/// All the properties a OpenFabric router can hold. > +/// > +/// These can serialized with a " " space prefix as they are in the `router openfabric` block. > +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, PartialOrd, Ord)] > +pub struct OpenfabricRouter { > + /// The NET address > + pub net: Net, > +} > + > +impl OpenfabricRouter { > + pub fn new(net: Net) -> Self { > + Self { net } > + } > + > + pub fn net(&self) -> &Net { > + &self.net > + } > +} > + > +/// The OpenFabric properties. > +/// > +/// This struct holds all the OpenFabric interface properties. The most important one here is the > +/// fabric_id, which ties the interface to a fabric. When serialized these properties all get > +/// prefixed with a space (" ") as they are inside the interface block. They serialize roughly to: > +/// > +/// ```text > +/// interface ens20 > +/// ip router openfabric > +/// ipv6 router openfabric > +/// openfabric hello-interval > +/// openfabric hello-multiplier > +/// openfabric csnp-interval > +/// openfabric passive > +/// ``` > +/// > +/// The is_ipv4 and is_ipv6 properties decide if we need to add `ip router openfabric`, `ipv6 > +/// router openfabric`, or both. A interface can only be part of a single fabric. An* > +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, PartialOrd, Ord)] > +pub struct OpenfabricInterface { > + // Note: an interface can only be a part of a single fabric (so no vec needed here) > + pub fabric_id: OpenfabricRouterName, > + pub passive: Option, ^ So in `FrrSerializer` we do all this manually - but for the derived `Serialize` implementation, shouldn't we have a `#[serde(skip_serializing_if = "Option::is_none")` here? (and probably also down below...) > + pub hello_interval: Option, > + pub csnp_interval: Option, > + pub hello_multiplier: Option, > + pub is_ipv4: bool, > + pub is_ipv6: bool, > +} > + > +impl OpenfabricInterface { If the struct and its fields are all `pub` - why do we need/want getters? > + pub fn fabric_id(&self) -> &OpenfabricRouterName { > + &self.fabric_id > + } > + pub fn passive(&self) -> Option { > + self.passive > + } > + pub fn hello_interval(&self) -> Option { > + self.hello_interval > + } > + pub fn csnp_interval(&self) -> Option { > + self.csnp_interval > + } > + pub fn hello_multiplier(&self) -> Option { > + self.hello_multiplier > + } > + pub fn set_hello_interval( > + &mut self, > + interval: impl Into>, > + ) { > + self.hello_interval = interval.into(); > + } > +} > + > +#[derive(Error, Debug)] > +pub enum OpenfabricInterfaceError { > + #[error("Unknown error converting to OpenFabricInterface")] > + UnknownError, > + #[error("Error parsing frr word")] > + FrrWordParse(#[from] FrrWordError), > +} > -- > 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel