Skip to content

Commit

Permalink
Introduce OwnedPathAttributes (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
DRiKE authored Oct 9, 2024
1 parent e5fccaf commit 1d1fbdb
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
12 changes: 6 additions & 6 deletions src/bgp/message/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ pub struct OpenMessage<Octets> {
/// ## Convenience methods
///
/// * [`my_asn()`][`OpenMessage::my_asn`]: returns the 32bit ASN if present,
/// otherwise falls back to the conventional 16bit ASN (though represented as
/// the 32bit [`inetnum::asn::Asn`][`Asn`]);
/// otherwise falls back to the conventional 16bit ASN (though represented
/// as the 32bit [`inetnum::asn::Asn`][`Asn`]);
/// * [`multiprotocol_ids()`][`OpenMessage::multiprotocol_ids`]: returns an
/// iterator over all the AFI/SAFI combinations listed as Capability in the
/// Optional Parameters. If this yields an empty iterator, one can assume the
/// default (IPv4/Unicast) can be used, but it is up to the user to handle as
/// such.
/// iterator over all the AFI/SAFI combinations listed as Capability in the
/// Optional Parameters. If this yields an empty iterator, one can assume
/// the default (IPv4/Unicast) can be used, but it is up to the user to
/// handle as such.
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
Expand Down
16 changes: 8 additions & 8 deletions src/bgp/message/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ impl<Octs: Octets> AsRef<[u8]> for UpdateMessage<Octs> {
/// To accommodate for these hassles, the following methods are provided:
///
/// * [`nlris()`][`UpdateMessage::nlris`] and
/// [`withdrawals()`][`UpdateMessage::withdrawals`],
/// providing iterators over announced and withdrawn prefixes ;
/// [`withdrawals()`][`UpdateMessage::withdrawals`],
/// providing iterators over announced and withdrawn prefixes ;
/// * [`next_hop()`][`UpdateMessage::next_hop`], returning the [`NextHop`] ;
/// * [`all_communities()`][`UpdateMessage::all_communities`], returning an
/// optional `Vec` containing all conventional, Extended and Large
/// Communities, wrapped in the [`Community`] enum.
/// optional `Vec` containing all conventional, Extended and Large
/// Communities, wrapped in the [`Community`] enum.
///
/// For the mandatory path attributes, we have:
///
Expand Down Expand Up @@ -1154,12 +1154,12 @@ impl Default for PduParseInfo {
/// and non AddPath enabled withdrawals, this struct holds booleans for all
/// three sections where AddPath PathIds might or might not occur:
///
/// * the conventional IPv4 Unicast sections in the PDU, which are either
/// both AddPath enabled or not, and,
/// * the conventional IPv4 Unicast sections in the PDU, which are either
/// both AddPath enabled or not, and,
///
/// * the MP_REACH and MP_UNREACH path attributes, which might carry NLRI for
/// different address families and (thus) might differ in being AddPath
/// enabled or not.
/// different address families and (thus) might differ in being AddPath
/// enabled or not.
#[derive(Copy, Clone, Default, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
Expand Down
59 changes: 59 additions & 0 deletions src/bgp/path_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,65 @@ pub trait AttributeHeader {
}


//------------ OwnedPathAttributes -------------------------------------------


#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct OwnedPathAttributes {
ppi: PduParseInfo,
raw: Vec<u8>
}

impl OwnedPathAttributes {
pub fn new(ppi: PduParseInfo, raw: Vec<u8>) -> Self {
Self { ppi, raw }
}

pub fn iter(&self) -> PathAttributes<Vec<u8>> {
let parser = Parser::from_ref(&self.raw);
PathAttributes::new(parser, self.ppi)
}

pub fn pdu_parse_info(&self) -> PduParseInfo {
self.ppi
}

pub fn into_vec(self) -> Vec<u8> {
self.raw
}

pub fn get<A: FromAttribute>(&self) -> Option<A> {
if let Some(attr_type) = A::attribute_type() {
self.iter().get(attr_type)
.and_then(|a| a.to_owned().ok())
.and_then(|a| A::from_attribute(a))
} else {
None
}
}
}

impl<'a, O> From<PathAttributes<'a, O>> for OwnedPathAttributes
where
O: AsRef<[u8]>
{
fn from(value: PathAttributes<'a, O>) -> Self {
OwnedPathAttributes {
ppi: value.pdu_parse_info,
raw: value.parser.as_slice().to_owned()
}
}
}

impl From<(PduParseInfo, Vec<u8>)> for OwnedPathAttributes {
fn from(value: (PduParseInfo, Vec<u8>)) -> Self {
Self::new(value.0, value.1)
}
}



//------------ PathAttributesBuilder -----------------------------------------

pub type AttributesMap = BTreeMap<u8, PathAttribute>;
Expand Down
2 changes: 1 addition & 1 deletion src/bgp/path_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::{
/// Comparing two `OrdRoute`s, wrapping two routes with different sets of path
/// attributes, might still yield 'equal'. Instead, consider comparing on the
/// `PaMap` and/or `Tiebreakerinfo` directly (or [`fn inner`]).
#[derive(Copy, Clone, Debug, Hash)]
#[derive(Copy, Clone, Debug)]
pub struct OrdRoute<'a, OS> {
pa_map: &'a PaMap,
tiebreakers: TiebreakerInfo,
Expand Down

0 comments on commit 1d1fbdb

Please sign in to comment.