Skip to content

Commit

Permalink
Introduce a per-ingress-id prefix overview in Rib HTTP endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
DRiKE committed Oct 31, 2024
1 parent a2be831 commit 1a41399
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
24 changes: 12 additions & 12 deletions src/units/bmp_tcp_in/http/router_info/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl RouterInfoApi {
<th>Timestamp</th>
<th>IP Address</th>
<th>ASN</th>
<th># Prefixes</th>
<th>Prefixes</th>
<th>Flags</th>
</tr>
"#
Expand All @@ -179,17 +179,17 @@ impl RouterInfoApi {

for pph in peer_states.get_peers() {
let peer_key = format!("{}", pph);
let num_prefixes = peer_states
.get_announced_prefixes(pph)
.map_or(0, |iter| iter.count());
let prefixes_link = if num_prefixes > 0 {
format!(
"<a href=\"{}/prefixes/{}\">{}</a>",
&base_http_path, pph, num_prefixes
)
} else {
"0".to_string()
};
let prefixes_link = peer_states.get_peer_ingress_id(pph)
.map(|ingress_id|
format!(
"<a href=\"/prefixes/{}\">prefixes</a>",
ingress_id
)
).unwrap_or("".to_string());

// As soon as the per-mui iterators in the store work, remove
// this line and actually show the hyperlinks.
let prefixes_link = "".to_string();
writeln!(peer_report, "<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{:08b} [<a href=\"{}/flags/{}\">more</a>]</td></tr>",
pph.timestamp(),
pph.address(),
Expand Down
45 changes: 44 additions & 1 deletion src/units/rib_unit/http/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ impl ProcessRequest for PrefixesApi {
if request.method() == Method::GET
&& req_path.starts_with(self.http_api_path.deref())
{
match self.handle_prefix_query(req_path, request).await {
let res = match request.uri().path().split("/").count() {
3 => self.handle_ingress_id_query(req_path, request).await,
_ => self.handle_prefix_query(req_path, request).await,
};
match res {
Ok(res) => Some(res),
Err(err) => Some(
Response::builder()
Expand Down Expand Up @@ -283,6 +287,45 @@ impl PrefixesApi {
Ok(res)
}

async fn handle_ingress_id_query(
&self,
req_path: &str,
_request: &Request<Body>,
) -> Result<Response<Body>, String> {
debug!("in handle_ingress_id_query");

let ingress_id = req_path
.strip_prefix(self.http_api_path.as_str()).unwrap()
.parse::<ingress::IngressId>()
.map_err(|e| e.to_string())?;

if self.rib_type != RibType::Physical {
return Err("unsupported on virtual rib".to_string());
}

let store = self.rib.load();
let mut res = String::new();
let records = store.match_ingress_id(ingress_id).map_err(|e| e.to_string())?;

for pubrec in records {
res += &pubrec.prefix.to_string();
res.push('\n');
for m in pubrec.meta {
res.push('\t');
res += &serde_json::to_string(&m.meta).unwrap();
res.push('\n');
}
}

Ok(
Response::builder()
.header("Content-Type", "text/plain")
.body(res.into())
.unwrap()
)

}

fn parse_include_param(
params: &QueryParams,
query_limits: Arc<ArcSwap<QueryLimits>>,
Expand Down
30 changes: 28 additions & 2 deletions src/units/rib_unit/rib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use log::{debug, error};
// typevalue::TypeValue,
//}, vm::FieldIndex};
use rotonda_store::{
custom_alloc::UpsertReport, prelude::multi::{PrefixStoreError, RouteStatus}, MatchOptions, MultiThreadedStore, QueryResult,
epoch
custom_alloc::UpsertReport, epoch, prelude::{multi::{PrefixStoreError, RouteStatus}, PrefixRecord}, MatchOptions, MultiThreadedStore, QueryResult
};
use inetnum::{addr::Prefix, asn::Asn};
use routecore::bgp::{nlri::afisafi::{IsPrefix, Nlri}, path_attributes::PaMap, path_selection::{OrdRoute, Rfc4271, TiebreakerInfo}, types::AfiSafiType};
Expand Down Expand Up @@ -298,6 +297,33 @@ impl Rib {
}
Ok(unicast_res)
}

pub fn match_ingress_id(
&self,
ingress_id: IngressId,
//match_options: &MatchOptions,
) -> Result<Vec<PrefixRecord<RotondaPaMap>>, String> {
let guard = &epoch::pin();
let store = (*self.unicast).as_ref()
.ok_or(PrefixStoreError::StoreNotReadyError.to_string())?;
let include_withdrawals = false;
let mut res = store
.iter_records_for_mui_v4(ingress_id, include_withdrawals, guard)
.collect::<Vec<_>>();
res.append(&mut store
.iter_records_for_mui_v6(ingress_id, include_withdrawals, guard)
.collect::<Vec<_>>()
);

//tmp: while the per mui methods do not work yet, we can use
//.prefixes_iter() to test the output.
//let res = store.prefixes_iter().collect::<Vec<_>>();
debug!(
"rib::match_ingress_id for {ingress_id}: {} results",
res.len()
);
Ok(res)
}
}

impl Default for Rib {
Expand Down

0 comments on commit 1a41399

Please sign in to comment.