diff --git a/src/commons/api/roas.rs b/src/commons/api/roas.rs index 63f78b46..5fb9f8e5 100644 --- a/src/commons/api/roas.rs +++ b/src/commons/api/roas.rs @@ -160,6 +160,18 @@ impl RoaDefinition { } } + pub fn nr_of_allowed_prefixes(&self) -> u128 { + let pfx_len = self.prefix.addr_len(); + let max_len = self.effective_max_length(); + + // 10.0.0.0/8-8 -> 1 2^1 - 1 ... 2 ^ (max - len + 1) -1 + // 10.0.0.0/8-9 -> 1 + 2 = 3 2^2 - 1 + // 10.0.0.0/8-10 -> 1 + 2 + 4 = 7 2^3 - 1 + // 10.0.0.0/8-11 -> 1 + 2 + 4 + 8 = 15 2^4 - 1 + + (1u128 << (max_len - pfx_len + 1)) - 1 + } + pub fn max_length_valid(&self) -> bool { if let Some(max_length) = self.max_length { match self.prefix { @@ -182,13 +194,6 @@ impl RoaDefinition { pub fn overlaps(&self, other: &RoaDefinition) -> bool { self.prefix.matching_or_less_specific(&other.prefix) || other.prefix.matching_or_less_specific(&self.prefix) } - - /// Returns all prefixes covered by the max length of this definition. - /// Note that if the effective max length equals the prefix length, this - /// means that the single prefix in this definition is returned. - pub fn to_specific_prefixes(&self) -> Vec { - self.prefix.to_specific_prefixes(self.effective_max_length()) - } } impl FromStr for RoaDefinition { @@ -432,31 +437,6 @@ impl TypedPrefix { && self.prefix().min().le(&other.prefix().min()) && self.prefix().max().ge(&other.prefix().max()) } - - pub fn to_specific_prefixes(&self, len: u8) -> Vec { - let mut res = vec![]; - - let nr_specifics = 1 << (len - self.addr_len()); - - // note that the lower 12 bytes are disregarded for IPv4 - // by our implementation, so the increment here is the - // same for both address families. - let increment: u128 = 1 << (128 - len); - - for i in 0..nr_specifics { - let base = self.addr().to_bits() + i * increment; - let pfx = Prefix::new(base, len); - - let pfx = match self { - TypedPrefix::V4(_) => TypedPrefix::V4(Ipv4Prefix(pfx)), - TypedPrefix::V6(_) => TypedPrefix::V6(Ipv6Prefix(pfx)), - }; - - res.push(pfx); - } - - res - } } impl FromStr for TypedPrefix { @@ -704,7 +684,6 @@ mod tests { use super::*; use crate::test::definition; - use crate::test::typed_prefix; #[test] fn parse_delta() { @@ -830,18 +809,16 @@ mod tests { } #[test] - fn split_definition_to_specifics() { - fn check(def: &str, pfxs: &[&str]) { + fn roa_nr_allowed_pfx() { + fn check(def: &str, expected: u128) { let def = definition(def); - let expected: Vec = pfxs.iter().map(|s| typed_prefix(s)).collect(); - let seen = def.to_specific_prefixes(); - assert_eq!(seen, expected); + let calculated = def.nr_of_allowed_prefixes(); + assert_eq!(calculated, expected); } - check("10.0.0.0/16-16 => 64496", &["10.0.0.0/16"]); - check("10.0.0.0/15-16 => 64496", &["10.0.0.0/16", "10.1.0.0/16"]); - - check("2001:db8::/32-32 => 64496", &["2001:db8::/32"]); - check("2001:db8::/32-33 => 64496", &["2001:db8::/33", "2001:db8:8000::/33"]); + check("10.0.0.0/15-15 => 64496", 1); + check("10.0.0.0/15-16 => 64496", 3); + check("10.0.0.0/15-17 => 64496", 7); + check("10.0.0.0/15-18 => 64496", 15); } } diff --git a/src/commons/bgp/analyser.rs b/src/commons/bgp/analyser.rs index ad843061..3e6826be 100644 --- a/src/commons/bgp/analyser.rs +++ b/src/commons/bgp/analyser.rs @@ -1,6 +1,4 @@ -use std::collections::HashSet; use std::env; -use std::iter::FromIterator; use tokio::sync::RwLock; @@ -8,7 +6,7 @@ use chrono::Duration; use rpki::x509::Time; -use crate::commons::api::{AsNumber, ResourceSet, RoaDefinition, TypedPrefix}; +use crate::commons::api::{AsNumber, ResourceSet, RoaDefinition}; use crate::commons::bgp::{ make_roa_tree, make_validated_announcement_tree, Announcement, AnnouncementValidity, Announcements, BgpAnalysisEntry, BgpAnalysisReport, BgpAnalysisState, BgpAnalysisSuggestion, IpRange, RisDumpError, RisDumpLoader, @@ -137,21 +135,7 @@ impl BgpAnalyser { .map(|va| va.announcement()) .collect(); - let authorizes_excess: Vec = { - let mut unannounced_specifics: HashSet = - HashSet::from_iter(roa.to_specific_prefixes().into_iter()); - - for authorized_pfx in authorizes.iter().map(|a| a.prefix()) { - if authorized_pfx.addr_len() == roa.effective_max_length() { - unannounced_specifics.remove(authorized_pfx); - } - } - - unannounced_specifics - .into_iter() - .map(|tp| Announcement::new(roa.asn(), tp)) - .collect() - }; + let authorizes_excess: bool = { (authorizes.len() as u128) < roa.nr_of_allowed_prefixes() }; let disallows: Vec = covered .iter() @@ -165,13 +149,8 @@ impl BgpAnalyser { if authorizes.is_empty() && disallows.is_empty() { entries.push(BgpAnalysisEntry::roa_unseen(roa)) - } else if !authorizes_excess.is_empty() { - entries.push(BgpAnalysisEntry::roa_too_permissive( - roa, - authorizes, - disallows, - authorizes_excess, - )) + } else if authorizes_excess { + entries.push(BgpAnalysisEntry::roa_too_permissive(roa, authorizes, disallows)) } else { entries.push(BgpAnalysisEntry::roa_seen(roa, authorizes, disallows)) } diff --git a/src/commons/bgp/report.rs b/src/commons/bgp/report.rs index 2dc3643e..0009f530 100644 --- a/src/commons/bgp/report.rs +++ b/src/commons/bgp/report.rs @@ -375,12 +375,6 @@ impl fmt::Display for BgpAnalysisReport { writeln!(f, "\t\t{}", ann)?; } - writeln!(f)?; - writeln!(f, "\t\tAuthorizes additional *invisible* announcements:")?; - for ann in roa.authorizes_excess.iter() { - writeln!(f, "\t\t{}", ann)?; - } - if !roa.disallows.is_empty() { writeln!(f)?; writeln!(f, "\t\tDisallows:")?; @@ -512,8 +506,6 @@ pub struct BgpAnalysisEntry { #[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")] authorizes: Vec, #[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")] - authorizes_excess: Vec, - #[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")] disallows: Vec, } @@ -568,7 +560,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes, - authorizes_excess: vec![], disallows, } } @@ -582,7 +573,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes: vec![], - authorizes_excess: vec![], disallows, } } @@ -596,7 +586,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by, authorizes: vec![], - authorizes_excess: vec![], disallows: vec![], } } @@ -605,11 +594,9 @@ impl BgpAnalysisEntry { definition: RoaDefinition, mut authorizes: Vec, mut disallows: Vec, - mut authorizes_excess: Vec, ) -> Self { authorizes.sort(); disallows.sort(); - authorizes_excess.sort(); BgpAnalysisEntry { definition, state: BgpAnalysisState::RoaTooPermissive, @@ -617,7 +604,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes, - authorizes_excess, disallows, } } @@ -630,7 +616,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes: vec![], - authorizes_excess: vec![], disallows: vec![], } } @@ -643,7 +628,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes: vec![], - authorizes_excess: vec![], disallows: vec![], } } @@ -656,7 +640,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes: vec![], - authorizes_excess: vec![], disallows: vec![], } } @@ -686,7 +669,6 @@ impl BgpAnalysisEntry { disallowed_by, made_redundant_by: vec![], authorizes: vec![], - authorizes_excess: vec![], disallows: vec![], } } @@ -699,7 +681,6 @@ impl BgpAnalysisEntry { disallowed_by: vec![], made_redundant_by: vec![], authorizes: vec![], - authorizes_excess: vec![], disallows: vec![], } } diff --git a/test-resources/bgp/expected_full_report.json b/test-resources/bgp/expected_full_report.json index 085b5f81..f0328787 100644 --- a/test-resources/bgp/expected_full_report.json +++ b/test-resources/bgp/expected_full_report.json @@ -35,12 +35,6 @@ "prefix": "10.0.2.0/23" } ], - "authorizes_excess": [ - { - "asn": 64496, - "prefix": "10.0.0.0/23" - } - ], "disallows": [ { "asn": 64497, diff --git a/test-resources/bgp/expected_full_report.txt b/test-resources/bgp/expected_full_report.txt index b58b0e2f..39dfc0be 100644 --- a/test-resources/bgp/expected_full_report.txt +++ b/test-resources/bgp/expected_full_report.txt @@ -13,9 +13,6 @@ Authorizations which may be too permissive: 10.0.0.0/22 => 64496 10.0.2.0/23 => 64496 - Authorizes additional *invisible* announcements: - 10.0.0.0/23 => 64496 - Disallows: 10.0.0.0/22 => 64497 10.0.0.0/24 => 64496