Skip to content

Commit

Permalink
Merge branch 'main' into compose-messages
Browse files Browse the repository at this point in the history
  • Loading branch information
DRiKE committed Jul 19, 2023
2 parents 4340a47 + 3c55f4e commit 313c798
Show file tree
Hide file tree
Showing 14 changed files with 691 additions and 396 deletions.
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ New
reason about than the wireformat. `HopPath` replaces `AsPathBuilder`.
([#23])

* Added `fn contains` to check whether an `std::net::IpAddr` lies within a
`addr::Prefix`. ([#35])

* Better parsing and creation of BGP NOTIFICATION messages. ([#35])

Bug fixes

Expand All @@ -47,6 +51,7 @@ Other changes
[#22]: https://github.com/NLnetLabs/routecore/pull/22
[#23]: https://github.com/NLnetLabs/routecore/pull/23
[#24]: https://github.com/NLnetLabs/routecore/pull/24
[#35]: https://github.com/NLnetLabs/routecore/pull/35


## 0.2.0
Expand Down
37 changes: 37 additions & 0 deletions src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ impl Prefix {
self.bits.into_int()
== other.bits.into_int() & !(u128::MAX >> self.len())
}

/// Returns `true` if the prefix contains `addr`.
pub fn contains(self, addr: IpAddr) -> bool {
self.min_addr() <= addr && addr <= self.max_addr()
}
}

//--- PartialOrd and Ord
Expand Down Expand Up @@ -1383,4 +1388,36 @@ mod test {
fn clear_host_of_zero_len_prefix() {
assert_eq!(Bits(0), Bits(12345).clear_host(0));
}

#[test]
fn prefix_contains() {
fn test(prefix: &str, addr: &str, expected: bool) {
let p = Prefix::from_str(prefix).unwrap();
let a = IpAddr::from_str(addr).unwrap();
assert_eq!(p.contains(a), expected);
}

for i in [
("10.0.0.0/8", "10.0.0.0", true),
("10.0.0.0/8", "10.1.1.1", true),
("10.0.0.0/8", "10.255.255.255", true),
("10.0.0.0/32", "10.0.0.0", true),
("10.0.0.0/8", "192.168.1.1", false),
("10.0.0.0/8", "2001:0db8::1", false),

("2001:0db8::/32", "2001:0db8::0", true),
("2001:0db8::/32", "2001:0db8::1", true),
("2001:0db8::/32", "10.0.0.1", false),

("::0/120", "0.0.0.10", false),
("0.0.0.0/24", "::1", false),

("0.0.0.1/32", "::1", false),
("0.0.0.1/32", "0.0.0.1", true),
("::1/128", "0.0.0.1", false),
("::1/128", "::1", true),
] {
test(i.0, i.1, i.2);
}
}
}
20 changes: 19 additions & 1 deletion src/bgp/aspath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ pub type OwnedHop = Hop<Vec<u8>>;
///
/// ```Hop(AS10), Hop(AS20), Hop(AS30), Hop(Set(AS40, AS50))```
///
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct HopPath {
/// The hops in this HopPath.
hops: Vec<OwnedHop>,
Expand Down Expand Up @@ -695,6 +696,7 @@ impl<'a, Octs: Octets> Iterator for PathSegments<'a, Octs> {

/// AS_PATH Segment generic over [`Octets`].
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Segment<Octs> {
stype: SegmentType,
four_byte_asns: bool,
Expand Down Expand Up @@ -974,11 +976,27 @@ impl fmt::Display for SegmentType {
/// variant `Segment`, which contain the entire segment and thus (possibly)
/// multiple ASNs.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub enum Hop<Octs> {
Asn(Asn),
Segment(Segment<Octs>),
}

impl<Octs: Octets> Hash for Hop<Octs> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Hop::Asn(asn) => {
state.write_u8(0);
asn.hash(state);
}
Hop::Segment(segment) => {
state.write_u8(1);
segment.hash(state);
}
}
}
}

impl<Octs> Hop<Octs> {
/// Tries to convert the `Hop` into an [`Asn`]. This returns an error if
/// `Hop` is not of the [`Hop::Asn`] variant.
Expand Down
17 changes: 15 additions & 2 deletions src/bgp/communities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ use crate::asn::{Asn, Asn16, ParseAsnError};
//--- Community --------------------------------------------------------------

/// Standard and Extended/Large Communities variants.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd )]
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, )]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub enum Community {
Standard(StandardCommunity),
Extended(ExtendedCommunity),
Expand Down Expand Up @@ -309,7 +310,7 @@ macro_rules! wellknown {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match self {
$($name::$var => write!(f, $pprim),)+
$name::Unrecognized(n) => write!(f, "0x{:08X}", n)
$name::Unrecognized(n) => write!(f, "0xFFFF{:04X}", n)
}
}
}
Expand Down Expand Up @@ -349,6 +350,7 @@ wellknown!(Wellknown,

/// Conventional, RFC1997 4-byte community.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd )]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct StandardCommunity([u8; 4]);

impl StandardCommunity {
Expand Down Expand Up @@ -523,6 +525,7 @@ impl Display for Tag {

/// Extended Community as defined in RFC4360.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd )]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct ExtendedCommunity([u8; 8]);

impl ExtendedCommunity {
Expand Down Expand Up @@ -907,6 +910,7 @@ impl Display for ExtendedCommunity {

/// IPv6 Extended Community as defined in RFC5701.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd )]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Ipv6ExtendedCommunity([u8; 20]);


Expand Down Expand Up @@ -1023,6 +1027,7 @@ impl Display for Ipv6ExtendedCommunity {

/// Large Community as defined in RFC8092.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd )]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct LargeCommunity([u8; 12]);

impl LargeCommunity {
Expand Down Expand Up @@ -1405,4 +1410,12 @@ mod tests {
assert!(<Wellknown as TryFrom<u32>>::try_from(0xffff0001).is_ok());
assert!(<Wellknown as TryFrom<u32>>::try_from(0x0fff0001).is_err());
}

#[test]
fn to_string_and_back() {
let c: Community = [0xFF, 0xFF, 0xFF, 0x05].into();
let s = c.to_string();
let c2 = Community::from_str(&s).unwrap();
assert_eq!(c, c2);
}
}
14 changes: 8 additions & 6 deletions src/bgp/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@ impl<Octs: Octets> Message<Octs> {
typeenum!(
/// BGP Message types.
MsgType, u8,
1 => Open,
2 => Update,
3 => Notification,
4 => Keepalive,
5 => RouteRefresh, // RFC2918
//6 => //Capability, // draft-ietf-idr-dynamic-cap
{
1 => Open,
2 => Update,
3 => Notification,
4 => Keepalive,
5 => RouteRefresh, // RFC2918
//6 => //Capability, // draft-ietf-idr-dynamic-cap
}
);

impl<Octs: Octets> Message<Octs> {
Expand Down
8 changes: 4 additions & 4 deletions src/bgp/message/nlri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ impl NextHop {
(16, AFI::Ipv6, SAFI::Unicast | SAFI::MplsUnicast) =>
//NextHop::Ipv6
parser.advance(16)?,
(32, AFI::Ipv6, SAFI::Unicast) =>
(32, AFI::Ipv6, SAFI::Unicast | SAFI::Multicast) =>
//NextHop::Ipv6LL
parser.advance(16 + 16)?,
(24, AFI::Ipv6, SAFI::MplsVpnUnicast) =>
//NextHop::Ipv6MplsVpnUnicast
parser.advance(8 + 16)?,
(4, AFI::Ipv4, SAFI::Unicast | SAFI::MplsUnicast ) =>
(4, AFI::Ipv4, SAFI::Unicast | SAFI::Multicast | SAFI::MplsUnicast ) =>
//NextHop::Ipv4
parser.advance(4)?,
(12, AFI::Ipv4, SAFI::MplsVpnUnicast) =>
Expand Down Expand Up @@ -63,7 +63,7 @@ impl NextHop {
let res = match (len, afi, safi) {
(16, AFI::Ipv6, SAFI::Unicast | SAFI::MplsUnicast) =>
NextHop::Ipv6(parse_ipv6addr(parser)?),
(32, AFI::Ipv6, SAFI::Unicast) =>
(32, AFI::Ipv6, SAFI::Unicast | SAFI::Multicast) =>
NextHop::Ipv6LL(
parse_ipv6addr(parser)?,
parse_ipv6addr(parser)?
Expand All @@ -73,7 +73,7 @@ impl NextHop {
RouteDistinguisher::parse(parser)?,
parse_ipv6addr(parser)?
),
(4, AFI::Ipv4, SAFI::Unicast | SAFI::MplsUnicast ) =>
(4, AFI::Ipv4, SAFI::Unicast | SAFI::Multicast | SAFI::MplsUnicast ) =>
NextHop::Ipv4(parse_ipv4addr(parser)?),
(12, AFI::Ipv4, SAFI::MplsVpnUnicast) =>
NextHop::Ipv4MplsVpnUnicast(
Expand Down
Loading

0 comments on commit 313c798

Please sign in to comment.