Skip to content

Commit

Permalink
bgp, routing: convert RIB to use prefix-trie
Browse files Browse the repository at this point in the history
For storing routing tables, we need a data structure where we can
do longest-prefix matches, a requirement for things like BGP nexthop
resolution, policy application, among others.

For that, we'll be using the prefix-trie crate, which has excellent
performance numbers, an ergonomic API similar to std::collections,
and no additional dependencies.

The transition to prefix-trie is straightforward due to its API's
similarity to BTreeMap.

Signed-off-by: Renato Westphal <[email protected]>
  • Loading branch information
rwestphal committed Mar 11, 2024
1 parent dfb0aae commit e9413e5
Show file tree
Hide file tree
Showing 8 changed files with 14 additions and 9 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ netlink-sys = "0.8"
num-derive = "0.3"
num-traits = "0.2"
pickledb = "0.5"
prefix-trie = { version = "0.3", features = ["ipnetwork"] }
prost = "0.12"
rand = "0.8.5"
rtnetlink = "0.13"
Expand Down
1 change: 1 addition & 0 deletions holo-bgp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ itertools.workspace = true
libc.workspace = true
num-derive.workspace = true
num-traits.workspace = true
prefix-trie.workspace = true
rand.workspace = true
serde.workspace = true
serde_json.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion holo-bgp/src/af.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub trait AddressFamily: Sized {
// The type of IP address used by this address family.
type IpAddr: IpAddrKind;
// The type of IP network used by this address family.
type IpNetwork: IpNetworkKind<Self::IpAddr>;
type IpNetwork: IpNetworkKind<Self::IpAddr> + prefix_trie::Prefix;

// Get the routing table for this address family from the provided
// `RoutingTables`.
Expand Down
2 changes: 1 addition & 1 deletion holo-bgp/src/neighbor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ impl Neighbor {
A: AddressFamily,
{
let table = A::table(&mut rib.tables);
for (prefix, dest) in &mut table.prefixes {
for (prefix, dest) in table.prefixes.iter_mut() {
dest.adj_rib.remove(&self.remote_addr);
table.queued_prefixes.insert(*prefix);
}
Expand Down
8 changes: 4 additions & 4 deletions holo-bgp/src/northbound/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ fn load_callbacks() -> Callbacks<Instance> {
let afi_safi = args.list_entry.as_global_afi_safi().unwrap();
let state = instance.state.as_ref().unwrap();
let total = match afi_safi {
AfiSafi::Ipv4Unicast => state.rib.tables.ipv4_unicast.prefixes.len(),
AfiSafi::Ipv6Unicast => state.rib.tables.ipv6_unicast.prefixes.len(),
AfiSafi::Ipv4Unicast => state.rib.tables.ipv4_unicast.prefixes.iter().count(),
AfiSafi::Ipv6Unicast => state.rib.tables.ipv6_unicast.prefixes.iter().count(),
};
Some(total as u32)
})
Expand Down Expand Up @@ -134,8 +134,8 @@ fn load_callbacks() -> Callbacks<Instance> {
.path(bgp::global::statistics::total_prefixes::PATH)
.get_element_u32(|instance, _args| {
if let Some(state) = &instance.state {
let total = state.rib.tables.ipv4_unicast.prefixes.len()
+ state.rib.tables.ipv6_unicast.prefixes.len();
let total = state.rib.tables.ipv4_unicast.prefixes.iter().count()
+ state.rib.tables.ipv6_unicast.prefixes.iter().count();
Some(total as u32)
} else {
None
Expand Down
3 changes: 2 additions & 1 deletion holo-bgp/src/rib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::time::Instant;
use holo_utils::bgp::RouteType;
use holo_utils::ibus::IbusSender;
use holo_utils::protocol::Protocol;
use prefix_trie::map::PrefixMap;
use serde::{Deserialize, Serialize};

use crate::af::{AddressFamily, Ipv4Unicast, Ipv6Unicast};
Expand Down Expand Up @@ -46,7 +47,7 @@ pub struct RoutingTables {

#[derive(Debug)]
pub struct RoutingTable<A: AddressFamily> {
pub prefixes: BTreeMap<A::IpNetwork, Destination>,
pub prefixes: PrefixMap<A::IpNetwork, Destination>,
pub queued_prefixes: BTreeSet<A::IpNetwork>,
}

Expand Down
1 change: 1 addition & 0 deletions holo-routing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ derive-new.workspace = true
enum-as-inner.workspace = true
futures.workspace = true
ipnetwork.workspace = true
prefix-trie.workspace = true
rtnetlink.workspace = true
tokio.workspace = true
tracing.workspace = true
Expand Down
5 changes: 3 additions & 2 deletions holo-routing/src/rib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ use holo_utils::southbound::{
};
use holo_utils::{UnboundedReceiver, UnboundedSender};
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
use prefix_trie::map::PrefixMap;
use tokio::sync::mpsc;

use crate::{ibus, netlink};

#[derive(Debug)]
pub struct Rib {
pub ipv4: BTreeMap<Ipv4Network, BTreeMap<u32, Route>>,
pub ipv6: BTreeMap<Ipv6Network, BTreeMap<u32, Route>>,
pub ipv4: PrefixMap<Ipv4Network, BTreeMap<u32, Route>>,
pub ipv6: PrefixMap<Ipv6Network, BTreeMap<u32, Route>>,
pub mpls: BTreeMap<Label, Route>,
pub ip_update_queue: BTreeSet<IpNetwork>,
pub mpls_update_queue: BTreeSet<Label>,
Expand Down

0 comments on commit e9413e5

Please sign in to comment.