From 174822cbcddc13a5e27119af5605835ee68e938b Mon Sep 17 00:00:00 2001 From: Jasper den Hertog Date: Tue, 26 Mar 2024 13:59:14 +0100 Subject: [PATCH 1/3] enable AfiSafiType optionally coming from a field on a NLRI struct, not the type --- src/bgp/message/update.rs | 6 ++-- src/bgp/message/update_builder.rs | 29 +++++++++---------- src/bgp/nlri/afisafi.rs | 46 ++++++++++++++++++++++++++++++- src/bgp/workshop/route.rs | 5 ++-- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/bgp/message/update.rs b/src/bgp/message/update.rs index 228d947e..bc352e9a 100644 --- a/src/bgp/message/update.rs +++ b/src/bgp/message/update.rs @@ -25,7 +25,7 @@ use crate::bgp::types::{ }; use crate::bgp::nlri::afisafi::{ - AfiSafiNlri, AfiSafiParse, NlriIter, NlriEnumIter, Nlri, NlriType + AfiSafi as Saif_al_Afi, AfiSafiNlri, AfiSafiParse, Nlri, NlriEnumIter, NlriIter, NlriType }; use crate::util::parser::ParseError; @@ -291,7 +291,7 @@ impl UpdateMessage { where O: Octets, Octs: Octets = O>, - ASP: AfiSafiNlri + AfiSafiParse<'a, O, Octs> + ASP: AfiSafiNlri + Saif_al_Afi + AfiSafiParse<'a, O, Octs> { if ASP::afi_safi() == AfiSafi::Ipv4Unicast && !self.withdrawals.is_empty() { return Ok(Some(NlriIter::<_, _, ASP>::new( @@ -442,7 +442,7 @@ impl UpdateMessage { where O: Octets, Octs: Octets = O>, - ASP: AfiSafiNlri + AfiSafiParse<'a, O, Octs> + ASP: AfiSafiNlri + Saif_al_Afi + AfiSafiParse<'a, O, Octs> { // If the requested announcements are of type Ipv4Unicast, and the // conventional announcements range is non-zero, return that. diff --git a/src/bgp/message/update_builder.rs b/src/bgp/message/update_builder.rs index 5a5345ee..31d0e143 100644 --- a/src/bgp/message/update_builder.rs +++ b/src/bgp/message/update_builder.rs @@ -8,9 +8,10 @@ use log::warn; use crate::bgp::aspath::HopPath; use crate::bgp::communities::StandardCommunity; use crate::bgp::message::{Header, MsgType, UpdateMessage, SessionConfig}; -use crate::bgp::nlri::afisafi::{AfiSafiNlri, AfiSafiParse, NlriCompose}; +use crate::bgp::nlri::afisafi::{AfiSafi, AfiSafiNlri, AfiSafiParse, NlriCompose}; use crate::bgp::path_attributes::{Attribute, PaMap, PathAttributeType}; -use crate::bgp::types::{AfiSafi, NextHop}; +use crate::bgp::types::{AfiSafi as AfiSafiTrait, NextHop}; +use crate::bgp::nlri::afisafi::IsNlri; use crate::util::parser::ParseError; //------------ UpdateBuilder ------------------------------------------------- @@ -30,7 +31,7 @@ impl UpdateBuilder { impl UpdateBuilder where - A: AfiSafiNlri + NlriCompose, + A: AfiSafiNlri + AfiSafi + NlriCompose, Target: OctetsBuilder + octseq::Truncate, { @@ -59,7 +60,7 @@ where pub fn from_workshop( ws: crate::bgp::workshop::route::RouteWorkshop - ) -> UpdateBuilder, A> { + ) -> UpdateBuilder, A> where A: AfiSafi + IsNlri { let mut res = Self::from_attributes_builder(ws.attributes().clone()); let nlri = ws.nlri(); @@ -270,7 +271,7 @@ where impl UpdateBuilder where - A: Clone + AfiSafiNlri + NlriCompose + A: Clone + AfiSafiNlri + AfiSafi + NlriCompose { pub fn into_message(self, session_config: &SessionConfig) -> Result::Octets>, ComposeError> @@ -679,7 +680,7 @@ pub struct PduIterator<'a, Target, A> { impl<'a, Target, A> Iterator for PduIterator<'a, Target, A> where - A: AfiSafiNlri + NlriCompose, + A: AfiSafiNlri + AfiSafi + NlriCompose, Target: Clone + OctetsBuilder + FreezeBuilder + AsMut<[u8]> + octseq::Truncate, ::Octets: Octets { @@ -722,13 +723,13 @@ impl IntoIterator for UpdateBuilder UpdateBuilder, A> { +impl UpdateBuilder, A> { pub fn new_vec() -> Self { UpdateBuilder::from_target(Vec::with_capacity(23)).unwrap() } } -impl UpdateBuilder { +impl UpdateBuilder { pub fn new_bytes() -> Self { Self::from_target(BytesMut::new()).unwrap() } @@ -764,7 +765,7 @@ impl MpReachNlriBuilder { _session_config: &SessionConfig ) where - A: AfiSafiNlri + NlriCompose + AfiSafiParse<'a, O, Octs, Output = A>, + A: AfiSafiNlri + AfiSafi + NlriCompose + AfiSafiParse<'a, O, Octs, Output = A>, Octs: Octets = O>, O: Octets, { @@ -776,7 +777,7 @@ impl MpReachNlriBuilder { } } -impl MpReachNlriBuilder { +impl MpReachNlriBuilder { pub fn new() -> Self { Self { announcements: Vec::new(), @@ -810,7 +811,7 @@ impl MpReachNlriBuilder { } - pub fn afi_safi(&self) -> AfiSafi { + pub fn afi_safi(&self) -> AfiSafiTrait { A::afi_safi() } @@ -883,7 +884,7 @@ impl MpReachNlriBuilder { } } -impl Default for MpReachNlriBuilder { +impl Default for MpReachNlriBuilder { fn default() -> Self { Self::new() } @@ -1130,7 +1131,7 @@ where _session_config: &SessionConfig ) where - A: AfiSafiNlri + NlriCompose + AfiSafiParse<'a, O, Octs, Output = A>, + A: AfiSafiNlri + AfiSafi + NlriCompose + AfiSafiParse<'a, O, Octs, Output = A>, Octs: Octets = O>, O: Octets, { @@ -1142,7 +1143,7 @@ where } } -impl MpUnreachNlriBuilder { +impl MpUnreachNlriBuilder { pub fn new() -> Self { Self { withdrawals: Vec::new(), diff --git a/src/bgp/nlri/afisafi.rs b/src/bgp/nlri/afisafi.rs index 64851933..68b88a6d 100644 --- a/src/bgp/nlri/afisafi.rs +++ b/src/bgp/nlri/afisafi.rs @@ -44,6 +44,10 @@ paste! { fn nlri(&self) -> Self::Nlri { self.1.nlri() } + + fn afi_safi_type(&self) -> AfiSafiType { + <[<$nlri Nlri>]$(<$gen>)? as AfiSafi>::afi_safi() + } } impl$(<$gen>)? AfiSafi for [<$nlri AddpathNlri>]$(<$gen>)? { @@ -475,9 +479,10 @@ pub trait IsNlri { } /// A type representing an NLRI for a certain AFI+SAFI. -pub trait AfiSafiNlri: AfiSafi + IsNlri + Clone + Hash + Debug { +pub trait AfiSafiNlri: Clone + Hash + Debug { type Nlri; fn nlri(&self) -> Self::Nlri; + fn afi_safi_type(&self) -> AfiSafiType; // TODO //fn nexthop_compatible(&self, nh: &super::nexthop::NextHop) -> bool; @@ -590,6 +595,9 @@ impl AfiSafiNlri for Ipv4UnicastNlri { fn nlri(&self) -> Self::Nlri { self.0 } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl FromStr for Ipv4UnicastNlri { @@ -682,6 +690,9 @@ impl AfiSafiNlri for Ipv4MulticastNlri { fn nlri(&self) -> Self::Nlri { self.0 } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl FromStr for Ipv4MulticastNlri { @@ -760,6 +771,9 @@ impl AfiSafiNlri for Ipv4MplsUnicastNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv4MplsUnicastNlri @@ -815,6 +829,9 @@ impl AfiSafiNlri for Ipv4MplsVpnUnicastNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv4MplsVpnUnicastNlri @@ -870,6 +887,9 @@ impl AfiSafiNlri for Ipv4RouteTargetNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv4RouteTargetNlri @@ -922,6 +942,9 @@ impl AfiSafiNlri for Ipv4FlowSpecNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv4FlowSpecNlri @@ -1008,6 +1031,9 @@ impl AfiSafiNlri for Ipv6UnicastNlri { fn nlri(&self) -> Self::Nlri { self.0 } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl FromStr for Ipv6UnicastNlri { type Err = &'static str; @@ -1086,6 +1112,9 @@ impl AfiSafiNlri for Ipv6MulticastNlri { fn nlri(&self) -> Self::Nlri { self.0 } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv6MulticastNlri @@ -1125,6 +1154,9 @@ impl AfiSafiNlri for Ipv6MplsUnicastNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv6MplsUnicastNlri @@ -1180,6 +1212,9 @@ impl AfiSafiNlri for Ipv6MplsVpnUnicastNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv6MplsVpnUnicastNlri @@ -1235,6 +1270,9 @@ impl AfiSafiNlri for Ipv6FlowSpecNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for Ipv6FlowSpecNlri @@ -1318,6 +1356,9 @@ impl AfiSafiNlri for L2VpnVplsNlri { fn nlri(&self) -> Self::Nlri { self.0 } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for L2VpnVplsNlri @@ -1358,6 +1399,9 @@ impl AfiSafiNlri for L2VpnEvpnNlri { fn nlri(&self) -> Self::Nlri { self.0.clone() } + fn afi_safi_type(&self) -> AfiSafiType { + ::afi_safi() + } } impl<'a, O, P> AfiSafiParse<'a, O, P> for L2VpnEvpnNlri diff --git a/src/bgp/workshop/route.rs b/src/bgp/workshop/route.rs index d60b89e6..d8e76e22 100644 --- a/src/bgp/workshop/route.rs +++ b/src/bgp/workshop/route.rs @@ -19,7 +19,7 @@ use crate::bgp::{ }, }; -use crate::bgp::nlri::afisafi::{AfiSafiNlri, AfiSafiType, Nlri}; +use crate::bgp::nlri::afisafi::{AfiSafi, AfiSafiNlri, AfiSafiType, Nlri}; use crate::bgp::nlri::nexthop::NextHop; use crate::bgp::types::ConventionalNextHop; @@ -126,9 +126,10 @@ impl RouteWorkshop { where for<'a> Vec: OctetsFrom>, { + let afi_safi_type = nlri.afi_safi_type(); let mut res = Self::new(nlri); - if N::afi_safi() == AfiSafiType::Ipv4Unicast && + if afi_safi_type == AfiSafiType::Ipv4Unicast && pdu.has_conventional_nlri() { if let Ok(Some(nh)) = pdu.conventional_next_hop() { From e0bd6b47cfca1d9457d0a9999096adcf70fc9702 Mon Sep 17 00:00:00 2001 From: Jasper den Hertog Date: Tue, 26 Mar 2024 14:06:41 +0100 Subject: [PATCH 2/3] clippy --- src/bgp/workshop/route.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bgp/workshop/route.rs b/src/bgp/workshop/route.rs index d8e76e22..a4aa28aa 100644 --- a/src/bgp/workshop/route.rs +++ b/src/bgp/workshop/route.rs @@ -19,7 +19,7 @@ use crate::bgp::{ }, }; -use crate::bgp::nlri::afisafi::{AfiSafi, AfiSafiNlri, AfiSafiType, Nlri}; +use crate::bgp::nlri::afisafi::{AfiSafiNlri, AfiSafiType, Nlri}; use crate::bgp::nlri::nexthop::NextHop; use crate::bgp::types::ConventionalNextHop; From 68aa4d0669140bd38ff180b8a3af9ca9163a75ac Mon Sep 17 00:00:00 2001 From: Jasper den Hertog Date: Tue, 26 Mar 2024 16:01:30 +0100 Subject: [PATCH 3/3] missing trait bounds --- src/bgp/nlri/afisafi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bgp/nlri/afisafi.rs b/src/bgp/nlri/afisafi.rs index 68b88a6d..d91a5e63 100644 --- a/src/bgp/nlri/afisafi.rs +++ b/src/bgp/nlri/afisafi.rs @@ -495,7 +495,7 @@ pub trait AfiSafiParse<'a, O, P>: Sized + IsNlri fn parse(parser: &mut Parser<'a, P>) -> Result; } -pub trait NlriCompose: AfiSafiNlri { +pub trait NlriCompose: AfiSafiNlri + AfiSafi + IsNlri { fn compose(&self, target: &mut Target) -> Result<(), Target::AppendError>;