Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bier: BIFT computation and synchronization with Fastclick #32

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions holo-daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,5 @@ rip = ["dep:holo-rip", "holo-routing/rip"]
# Other features
tokio_console = ["dep:console-subscriber"]
io_uring = ["dep:tokio-uring"]

fastclick = ["holo-utils/fastclick"]
42 changes: 23 additions & 19 deletions holo-routing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,29 @@ impl Master {

loop {
tokio::select! {
Some(request) = nb_rx.recv() => {
process_northbound_msg(
self,
&mut resources,
request,
)
.await;
}
Ok(msg) = ibus_rx.recv() => {
ibus::process_msg(self, msg);
}
Some(_) = self.rib.update_queue_rx.recv() => {
self.rib
.process_rib_update_queue(
&self.netlink_handle,
&self.ibus_tx,
)
.await;
}
Some(request) = nb_rx.recv() => {
process_northbound_msg(
self,
&mut resources,
request,
)
.await;
}
Ok(msg) = ibus_rx.recv() => {
ibus::process_msg(self, msg);
}
Some(_) = self.rib.update_queue_rx.recv() => {
self.rib
.process_rib_update_queue(
&self.netlink_handle,
&self.ibus_tx,
)
.await;
}
Some(_) = self.birt.update_queue_rx.recv() => {
self.birt
.process_birt_update_queue(&self.interfaces).await;
}
}
}
}
Expand Down
87 changes: 84 additions & 3 deletions holo-routing/src/rib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use std::net::IpAddr;
use bitflags::bitflags;
use chrono::{DateTime, Utc};
use derive_new::new;
use holo_utils::bier::{BfrId, BirtEntry, Bsl, SubDomainId};
use holo_utils::bier::{
self, BfrId, Bift, BirtEntry, Bitstring, Bsl, SubDomainId,
};
use holo_utils::ibus::IbusSender;
use holo_utils::ip::{AddressFamily, IpNetworkExt, Ipv4AddrExt, Ipv6AddrExt};
use holo_utils::mpls::Label;
Expand Down Expand Up @@ -40,9 +42,12 @@ pub struct Rib {
pub update_queue_rx: UnboundedReceiver<()>,
}

#[derive(Debug, Default)]
#[derive(Debug)]
pub struct Birt {
pub entries: BTreeMap<(SubDomainId, BfrId, Bsl), BirtEntry>,
pub bier_update_queue: BTreeSet<BfrId>,
pub update_queue_tx: UnboundedSender<()>,
pub update_queue_rx: UnboundedReceiver<()>,
}

#[derive(Clone, Debug, new)]
Expand Down Expand Up @@ -72,22 +77,98 @@ 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
.entry((msg.bier_info.sd_id, bfr_id, *bsl))
.and_modify(|be| be.bfr_nbr = *addr)
.or_insert(BirtEntry {
bfr_prefix: msg.prefix.ip(),
bfr_nbr: (*addr),
ifindex: *ifindex,
});

// Add BIER route to the update queue
self.bier_update_queue_add(bfr_id);
}
});
}

pub(crate) fn bier_nbr_del(&mut self, msg: BierNbrUninstallMsg) {
let _ = self.entries.remove(&(msg.sd_id, msg.bfr_id, msg.bsl));
}

pub(crate) async fn process_birt_update_queue(
&mut self,
ifaces: &BTreeMap<String, Interface>,
) {
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::<Vec<String>>();
// 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) {
Ok(()) => {
v.push((*bfr_id, nbr.bfr_prefix));
}
Err(e) => {
e.log();
}
},
None => {
let _ = bift.insert(
key,
(
bfr_bs,
vec![(*bfr_id, nbr.bfr_prefix)],
nbr.ifindex,
ifname.first().unwrap().to_owned(),
),
);
}
}
}
Err(e) => {
e.log();
}
}
}

bier::bift_sync(&bift).await;
}

// Adds BIER route to the update queue.
fn bier_update_queue_add(&mut self, bfr_id: BfrId) {
self.bier_update_queue.insert(bfr_id);
let _ = self.update_queue_tx.send(());
}
}

impl Default for Birt {
fn default() -> Self {
let (update_queue_tx, update_queue_rx) = mpsc::unbounded_channel();
Self {
entries: Default::default(),
bier_update_queue: Default::default(),
update_queue_tx,
update_queue_rx,
}
}
}

// ===== impl Rib =====
Expand Down
2 changes: 2 additions & 0 deletions holo-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tracing.workspace = true
yang3.workspace = true

holo-yang = { path = "../holo-yang" }
reqwest = { version = "0.12.8", optional = true }

[lints.rust]
rust_2018_idioms = "warn"
Expand All @@ -42,3 +43,4 @@ manual_range_contains = "allow"
[features]
default = []
testing = []
fastclick = ["dep:reqwest"]
Loading