Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0396adb
feat(utils): add crate left-right-tlcache
Fredi-raspall Oct 10, 2025
5739902
feat(left-right-tlcache): use ahash for local map
Fredi-raspall Oct 10, 2025
67083a8
feat(left-right-tlcache): use thiserror
Fredi-raspall Oct 13, 2025
0e1543f
feat(left-right-tlcache): cache entry invalidation
Fredi-raspall Oct 13, 2025
24ef747
feat(left-right-tlcache): reduce provider queries
Fredi-raspall Oct 14, 2025
58ef94b
feat(left-right-tlcache): avoid potential race
Fredi-raspall Oct 14, 2025
4905cc1
feat(left-right-tlcache): avoid duplicate rhandles
Fredi-raspall Oct 14, 2025
936b9ea
feat(left-right-tlcache): filter bad rhandles
Fredi-raspall Oct 14, 2025
ab1aa69
feat(left-right-tlcache): bad handle removal
Fredi-raspall Oct 14, 2025
882d0e5
feat(left-right-tlcache): add cache purge method
Fredi-raspall Oct 14, 2025
88b21ec
feat(left-right-tlcache): add simple tests
Fredi-raspall Oct 14, 2025
5eb0fe2
feat(routing): add FibReaderFactory type
Fredi-raspall Oct 12, 2025
1039017
feat(routing): refactor FibTable & rename FibId
Fredi-raspall Oct 12, 2025
7949efb
feat(routing): impl Hash for Fib
Fredi-raspall Oct 12, 2025
6b5c07b
feat(routing): impl AsRef<FibReader> for ReadHandle
Fredi-raspall Oct 13, 2025
a10c391
feat(routing): impl Identity for Fib
Fredi-raspall Oct 13, 2025
aaa6137
feat(routing): add version to FibTable
Fredi-raspall Oct 15, 2025
46251e6
feat(routing): AsRef for FibReaderFactory
Fredi-raspall Oct 15, 2025
3edf9f8
feat(routing): implement fibtable cache
Fredi-raspall Oct 15, 2025
0142fae
feat(routing): method to get Rc<FibReader>
Fredi-raspall Oct 15, 2025
48c8fb3
feat(routing): method to get FibReaders from cache
Fredi-raspall Oct 15, 2025
b8144fa
feat(dataplane): lookup fibreader from cache
Fredi-raspall Oct 15, 2025
70b7598
feat(routing): enforce fibtable cache usage
Fredi-raspall Oct 15, 2025
7231d8f
feat(left-right-tlcache): Add refresh and iterator
Fredi-raspall Oct 15, 2025
7b24fd0
feat(routing): add provider method for fibtable
Fredi-raspall Oct 16, 2025
5065d66
feat(left-right-tlcache): optimization for iter
Fredi-raspall Oct 16, 2025
6897da7
feat(left-right-tlcache): minimize num of rhandles
Fredi-raspall Oct 17, 2025
7f32131
feat(routing): removed unused code
Fredi-raspall Oct 17, 2025
90499f7
feat(routing): cleanup, improve logs & tests
Fredi-raspall Oct 17, 2025
1323381
feat(routing): misc cleanups
Fredi-raspall Oct 3, 2025
56abb27
feat(routing): revert to UnsafeCell in fibgroups
Fredi-raspall Oct 17, 2025
d4034c8
feat(routing): misc fixes in Fib
Fredi-raspall Oct 8, 2025
912c759
feat(routing): add fib concurrency tests
Fredi-raspall Oct 8, 2025
f3b56b0
feat(routing): speculative fix for fib deletion
Fredi-raspall Oct 19, 2025
48d3ad6
feat(routing): add fibtable concurrency test
Fredi-raspall Oct 18, 2025
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
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"id",
"init",
"interface-manager",
"left-right-tlcache",
"mgmt",
"nat",
"net",
Expand Down Expand Up @@ -51,6 +52,7 @@ hardware = { path = "./hardware", package = "dataplane-hardware" }
id = { path = "./id", package = "dataplane-id" }
init = { path = "./init", package = "dataplane-init" }
interface-manager = { path = "./interface-manager", package = "dataplane-interface-manager" }
left-right-tlcache = { path = "./left-right-tlcache", package = "dataplane-left-right-tlcache" }
lpm = { path = "./lpm", package = "dataplane-lpm" }
mgmt = { path = "./mgmt", package = "dataplane-mgmt" }
nat = { path = "./nat", package = "dataplane-nat" }
Expand Down
81 changes: 32 additions & 49 deletions dataplane/src/packet_processor/ipforward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ use std::net::IpAddr;
use tracing::{debug, error, trace, warn};

use routing::fib::fibobjects::{EgressObject, FibEntry, PktInstruction};
use routing::fib::fibtable::FibTable;
use routing::fib::fibtable::FibTableReader;
use routing::fib::fibtype::FibId;
use routing::fib::fibtype::FibKey;

use routing::evpn::Vtep;
use routing::rib::encapsulation::{Encapsulation, VxlanEncapsulation};
Expand Down Expand Up @@ -56,11 +55,11 @@ impl IpForwarder {
/// Forward a [`Packet`]
fn forward_packet<Buf: PacketBufferMut>(&self, packet: &mut Packet<Buf>, vrfid: VrfId) {
let nfi = &self.name;
let fibid = if let Some(dst_vpcd) = packet.get_meta().dst_vpcd {
let fibkey = if let Some(dst_vpcd) = packet.get_meta().dst_vpcd {
let VpcDiscriminant::VNI(dst_vni) = dst_vpcd;
FibId::from_vni(dst_vni)
FibKey::from_vni(dst_vni)
} else {
FibId::from_vrfid(vrfid)
FibKey::from_vrfid(vrfid)
};

/* get destination ip address */
Expand All @@ -71,57 +70,39 @@ impl IpForwarder {
};
debug!("{nfi}: processing packet to {dst} with vrf {vrfid}");

/* Get the fib to use: this lookup could be avoided since
we know the interface the packet came from and it has to be
attached to a certain fib if the vrf metadata value was set.
This extra lookup is a side effect of splitting into stages.
*/

/* Read-only access to the fib table */
let Some(fibtr) = self.fibtr.enter() else {
error!("{nfi}: Unable to lookup fib for vrf {vrfid}");
packet.done(DoneReason::InternalFailure);
return;
};
/* Lookup the fib which needs to be consulted */
let Some(fibr) = fibtr.get_fib(&fibid) else {
warn!("{nfi}: Unable to find fib with id {fibid} for vrf {vrfid}");
/* access fib, by fetching FibReader from cache */
let Ok(fibr) = &self.fibtr.get_fib_reader(fibkey) else {
warn!("{nfi}: Unable to read fib. Key={fibkey}");
packet.done(DoneReason::InternalFailure);
return;
};
/* Read-only access to fib */
let Some(fib) = fibr.enter() else {
warn!("{nfi}: Unable to read from fib {fibid}");
warn!("{nfi}: Unable to read from fib. Key={fibkey}");
packet.done(DoneReason::InternalFailure);
return;
};
/* Perform lookup in the fib */

/* Perform lookup in the fib. This always returns a FibEntry */
let (prefix, fibentry) = fib.lpm_entry_prefix(packet);
if let Some(fibentry) = &fibentry {
debug!("{nfi}: Packet hits prefix {prefix} in fib {fibid}");
debug!("{nfi}: Entry is:\n{fibentry}");

/* decrement packet TTL, unless the packet is for us */
if !fibentry.is_iplocal() {
Self::decrement_ttl(packet, dst);
if packet.is_done() {
debug!("TTL/Hop-count limit exceeded!");
return;
}
debug!("{nfi}: Packet hits prefix {prefix} in fib {fibkey}");
debug!("{nfi}: Entry is:\n{fibentry}");

/* decrement packet TTL, unless the packet is for us */
if !fibentry.is_iplocal() {
Self::decrement_ttl(packet, dst);
if packet.is_done() {
debug!("TTL/Hop-count limit exceeded!");
return;
}
/* execute instructions according to FIB */
self.packet_exec_instructions(&fibtr, packet, fibentry, fib.get_vtep());
} else {
debug!("Could not get fib group for {prefix}. Will drop packet...");
packet.done(DoneReason::InternalFailure);
}
/* execute instructions according to FIB */
self.packet_exec_instructions(packet, fibentry, fib.get_vtep());
}

/// Execute a local packet instruction
fn packet_exec_instruction_local<Buf: PacketBufferMut>(
&self,
packet: &mut Packet<Buf>,
fibtable: &FibTable,
_ifindex: InterfaceIndex, /* we get it from metadata */
) {
let nfi = &self.name;
Expand All @@ -134,14 +115,18 @@ impl IpForwarder {
let vni = vxlan.vni();
debug!("{nfi}: DECAPSULATED vxlan packet:\n {packet}");
debug!("{nfi}: Packet comes with vni {vni}");
let fibid = FibId::from_vni(vni);
let Some(fib) = fibtable.get_fib(&fibid) else {
error!("{nfi}: Failed to find fib {fibid} associated to vni {vni}");

// access fib for Vni vni
let fibkey = FibKey::from_vni(vni);
let Ok(fibr) = self.fibtr.get_fib_reader(fibkey) else {
error!("{nfi}: Failed to find fib associated to vni {vni}. Fib key = {fibkey}");
packet.done(DoneReason::Unroutable);
return;
};
let Some(next_vrf) = fib.get_id().map(|id| id.as_u32()) else {
debug!("{nfi}: Failed to access fib {fibid} to determine vrf");
let Some(next_vrf) = fibr.get_id().map(|id| id.as_u32()) else {
debug!(
"{nfi}: Failed to access fib {fibkey} to determine vrf. Fib Key={fibkey}"
);
packet.done(DoneReason::InternalFailure);
return;
};
Expand Down Expand Up @@ -331,15 +316,14 @@ impl IpForwarder {
/// Execute a [`PktInstruction`] on the packet
fn packet_exec_instruction<Buf: PacketBufferMut>(
&self,
fibtable: &FibTable,
vtep: &Vtep,
packet: &mut Packet<Buf>,
instruction: &PktInstruction,
) {
match instruction {
PktInstruction::Drop => self.packet_exec_instruction_drop(packet),
PktInstruction::Local(ifindex) => {
self.packet_exec_instruction_local(packet, fibtable, *ifindex);
self.packet_exec_instruction_local(packet, *ifindex);
}
PktInstruction::Encap(encap) => self.packet_exec_instruction_encap(packet, encap, vtep),
PktInstruction::Egress(egress) => self.packet_exec_instruction_egress(packet, egress),
Expand All @@ -349,13 +333,12 @@ impl IpForwarder {
/// Execute all of the [`PktInstruction`]s indicated by the given [`FibEntry`] on the packet
fn packet_exec_instructions<Buf: PacketBufferMut>(
&self,
fibtable: &FibTable,
packet: &mut Packet<Buf>,
fibentry: &FibEntry,
vtep: &Vtep,
) {
for inst in fibentry.iter() {
self.packet_exec_instruction(fibtable, vtep, packet, inst);
self.packet_exec_instruction(vtep, packet, inst);
if packet.is_done() {
return;
}
Expand Down
14 changes: 14 additions & 0 deletions left-right-tlcache/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "dataplane-left-right-tlcache"
version = "0.1.0"
edition = "2024"
publish = false
license = "Apache-2.0"

[dependencies]
left-right = { workspace = true }
ahash = { workspace = true }
thiserror = { workspace = true }

[dev-dependencies]
serial_test = { workspace = true }
Loading
Loading