diff --git a/src/bgp/communities.rs b/src/bgp/communities.rs index 5a071d75..d198e934 100644 --- a/src/bgp/communities.rs +++ b/src/bgp/communities.rs @@ -534,7 +534,7 @@ impl ExtendedCommunity { Self(raw) } - pub fn raw(self) -> [u8; 8] { + pub fn to_raw(self) -> [u8; 8] { self.0 } @@ -767,6 +767,11 @@ impl From<[u8; 8]> for Community { Community::Extended(ExtendedCommunity(raw)) } } +impl From<[u8; 8]> for ExtendedCommunity { + fn from(raw: [u8; 8]) -> ExtendedCommunity { + ExtendedCommunity(raw) + } +} impl FromStr for ExtendedCommunity { @@ -896,7 +901,7 @@ impl Display for ExtendedCommunity { (_,_) => { write!(f, "0x")?; - for b in &self.raw() { + for b in &self.to_raw() { write!(f, "{:02X}", b)?; } Ok(()) diff --git a/src/bgp/message/update_builder.rs b/src/bgp/message/update_builder.rs index 04e79774..62ec4395 100644 --- a/src/bgp/message/update_builder.rs +++ b/src/bgp/message/update_builder.rs @@ -225,7 +225,7 @@ pub mod new_pas { 10 => ClusterList(ClusterIds), Flags::OPT_NON_TRANS, 14 => MpReachNlri(MpReachNlriBuilder), Flags::OPT_NON_TRANS, 15 => MpUnreachNlri(MpUnreachNlriBuilder), Flags::OPT_NON_TRANS, - //16=> ExtendedCommunities TODO + 16 => ExtendedCommunities(ExtendedCommunitiesList), Flags::OPT_TRANS, //17=> As4Path TODO //18=> As4Aggregator TODO 20 => Connector(Ipv4Addr), Flags::OPT_TRANS, @@ -750,6 +750,54 @@ pub mod new_pas { } } + //--- ExtendedCommunities + + use crate::bgp::communities::ExtendedCommunity; + #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + pub struct ExtendedCommunitiesList { + communities: Vec + } + + impl ExtendedCommunitiesList { + fn new(communities: Vec) + -> ExtendedCommunitiesList + { + ExtendedCommunitiesList {communities } + } + + pub fn communities(&self) -> &Vec { + &self.communities + } + } + + + impl Attribute for ExtendedCommunities { + fn value_len(&self) -> usize { + self.0.communities.len() * 8 + } + + fn compose_value(&self, target: &mut Target) + -> Result<(), Target::AppendError> + { + for c in &self.0.communities { + target.append_slice(&c.to_raw())?; + } + Ok(()) + } + + fn parse(parser: &mut Parser, _sc: SessionConfig) + -> Result + { + let mut communities = Vec::with_capacity(parser.remaining() / 8); + let mut buf = [0u8; 8]; + while parser.remaining() > 0 { + parser.parse_buf(&mut buf)?; + communities.push(buf.into()); + } + Ok(ExtendedCommunities(ExtendedCommunitiesList::new(communities))) + } + } + //--- Connector (deprecated) impl Attribute for Connector { @@ -1018,7 +1066,16 @@ pub mod new_pas { } ); - //TODO 16 ExtendedCommunities + check( + vec![ + 0xc0, 0x10, 0x08, 0x00, 0x02, 0xfc, 0x85, 0x00, + 0x00, 0xcf, 0x08 + ], + ExtendedCommunities(ExtendedCommunitiesList::new(vec![ + "rt:64645:53000".parse().unwrap() + ])).into() + ); + //TODO 17 As4Path //TODO 18 As4Aggregator