diff --git a/holo-routing/src/lib.rs b/holo-routing/src/lib.rs index 53e1c483..ae3fc75c 100644 --- a/holo-routing/src/lib.rs +++ b/holo-routing/src/lib.rs @@ -105,7 +105,7 @@ impl Master { } Some(_) = self.birt.update_queue_rx.recv() => { self.birt - .process_birt_update_queue().await; + .process_birt_update_queue(&self.interfaces).await; } } } diff --git a/holo-routing/src/rib.rs b/holo-routing/src/rib.rs index 2a605148..9f9795b9 100644 --- a/holo-routing/src/rib.rs +++ b/holo-routing/src/rib.rs @@ -77,7 +77,7 @@ impl Birt { let bfr_id = msg.bier_info.bfr_id; msg.bier_info.bfr_bss.iter().for_each(|bsl| { if let Some(nexthop) = msg.nexthops.first() - && let Nexthop::Address { addr, .. } = nexthop + && let Nexthop::Address { addr, ifindex, .. } = nexthop { // Insert or update the entry in the BIRT self.entries @@ -86,6 +86,7 @@ impl Birt { .or_insert(BirtEntry { bfr_prefix: msg.prefix.ip(), bfr_nbr: (*addr), + ifindex: *ifindex, }); // Add BIER route to the update queue @@ -98,26 +99,47 @@ impl Birt { let _ = self.entries.remove(&(msg.sd_id, msg.bfr_id, msg.bsl)); } - pub(crate) async fn process_birt_update_queue(&mut self) { + pub(crate) async fn process_birt_update_queue( + &mut self, + ifaces: &BTreeMap, + ) { let mut bift = Bift::new(); // Compute Forwarding BitMasks (F-BMs) for ((sd_id, bfr_id, bsl), nbr) in &self.entries { match Bitstring::from(*bfr_id, *bsl) { Ok(bfr_bs) => { + let ifname = ifaces + .iter() + .filter_map(|(_, iface)| { + if iface.ifindex == nbr.ifindex { + Some(iface.ifname.clone()) + } else { + None + } + }) + .collect::>(); // Pattern matching is mandatory as Bitstring does not implement Copy, hence cannot use Entry interface let key = (*sd_id, nbr.bfr_nbr, bfr_bs.si); match bift.get_mut(&key) { - Some((e, v)) => match e.mut_or(bfr_bs) { + Some((e, v, _, _)) => match e.mut_or(bfr_bs) { Ok(()) => { - v.push(*bfr_id); + v.push((*bfr_id, nbr.bfr_prefix)); } Err(e) => { e.log(); } }, None => { - let _ = bift.insert(key, (bfr_bs, vec![*bfr_id])); + let _ = bift.insert( + key, + ( + bfr_bs, + vec![(*bfr_id, nbr.bfr_prefix)], + nbr.ifindex, + ifname.first().unwrap().to_owned(), + ), + ); } } } diff --git a/holo-utils/src/bier.rs b/holo-utils/src/bier.rs index b96c60bf..631c1860 100644 --- a/holo-utils/src/bier.rs +++ b/holo-utils/src/bier.rs @@ -20,11 +20,13 @@ use crate::ip::AddressFamily; pub type SubDomainId = u8; pub type BfrId = u16; pub type SetIdentifier = u8; -pub type Bift = - HashMap<(SubDomainId, IpAddr, SetIdentifier), (Bitstring, Vec)>; +pub type Bift = HashMap< + (SubDomainId, IpAddr, SetIdentifier), + (Bitstring, Vec<(BfrId, IpAddr)>, u32, String), +>; pub async fn bift_sync(bift: &Bift) { - for ((_sd_id, nbr, _si), (bs, ids)) in bift.iter() { + for ((_sd_id, nbr, _si), (bs, ids, idx, name)) in bift.iter() { /* List the position of bits that are enabled in the bitstring, this is required by the Bitvectors of Fastclick but this not ideal. FIXME: Find a better way to share a bitstring with Fastclick @@ -48,13 +50,16 @@ pub async fn bift_sync(bift: &Bift) { .join(","); // TODO: Batch route addition when multiple BfrIds have the same F-BM - for id in ids { - let body = format!("{:#?} {} {:#?}", id, bs, nbr); + for (id, prefix) in ids { + let body = format!( + "{:#?} {:#?} {} {:#?} {} {}", + id, prefix, bs, nbr, idx, name + ); // TODO: Use gRPC rather than plain HTTP let client = reqwest::Client::new(); let _res = client // TODO: Make Fastclick BIFT URI configurable through YANG model - .post("http://127.0.0.1/bift/add") + .post("http://127.0.0.1/bift0/add") .body(body.clone()) .send() .await; @@ -106,6 +111,7 @@ pub struct BierInfo { pub struct BirtEntry { pub bfr_prefix: IpAddr, pub bfr_nbr: IpAddr, + pub ifindex: u32, } #[derive(Clone, Debug, Default, Eq, PartialEq)]