Skip to content

Commit

Permalink
Kernel <-> KernelAdapter
Browse files Browse the repository at this point in the history
  • Loading branch information
hack3ric committed Nov 14, 2024
1 parent d847fd7 commit 0f39394
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 15 deletions.
6 changes: 3 additions & 3 deletions src/bgp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod nlri;
pub mod route;

use crate::args::RunArgs;
use crate::kernel::{self, Kernel};
use crate::kernel::{self, KernelAdapter};
use crate::net::{Afi, IpPrefixError, IpPrefixErrorKind};
use either::Either;
use flow::FlowError;
Expand Down Expand Up @@ -62,9 +62,9 @@ pub struct Session<S: AsyncRead + AsyncWrite + Unpin> {
impl<S: AsyncRead + AsyncWrite + Unpin> Session<S> {
pub async fn new(c: RunArgs) -> Result<Self> {
let kernel = if c.dry_run {
Kernel::Noop
KernelAdapter::Noop
} else {
Kernel::linux(c.kernel.clone()).await?
KernelAdapter::linux(c.kernel.clone()).await?
};
Ok(Self { config: c, state: Active, routes: Routes::new(kernel) })
}
Expand Down
4 changes: 2 additions & 2 deletions src/bgp/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ use strum::{EnumDiscriminants, FromRepr};
pub struct Routes {
unicast: BTreeMap<IpPrefix, (NextHop, MaybeRc<RouteInfo<'static>>)>,
flow: BTreeMap<Flowspec, (KernelHandle, MaybeRc<RouteInfo<'static>>)>,
kernel: Kernel,
kernel: KernelAdapter,
}

impl Routes {
pub fn new(kernel: Kernel) -> Self {
pub fn new(kernel: KernelAdapter) -> Self {
Self { unicast: BTreeMap::new(), flow: BTreeMap::new(), kernel }
}

Expand Down
4 changes: 2 additions & 2 deletions src/kernel/linux/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod nft;

use super::rtnl::{RtNetlink, RtNetlinkArgs};
use super::{KernelAdapter, Result};
use super::{Kernel, Result};
use crate::bgp::flow::Flowspec;
use crate::bgp::route::RouteInfo;
use clap::Args;
Expand Down Expand Up @@ -35,7 +35,7 @@ impl Linux {
}
}

impl KernelAdapter for Linux {
impl Kernel for Linux {
type Handle = u64;

async fn apply(&mut self, spec: &Flowspec, info: &RouteInfo<'_>) -> Result<Self::Handle> {
Expand Down
26 changes: 19 additions & 7 deletions src/kernel/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Bridges flowspecs to OS kernel.
//!
//! Currently only Linux is supported, which uses nftables. Future support may
//! include *BSD using `pf` as backend.
//! Currently only Linux is supported. Future support may include *BSD using
//! `pf` as backend.

#[cfg(target_os = "linux")]
mod linux;
Expand All @@ -19,30 +19,42 @@ use std::future::Future;
use strum::Display;
use thiserror::Error;

pub trait KernelAdapter {
/// Interface between BGP flowspec and the OS.
pub trait Kernel {
/// Type representing a flowspec's counterpart in kernel.
type Handle;

/// Apply a flowspec to kernel.
fn apply(&mut self, spec: &Flowspec, info: &RouteInfo<'_>) -> impl Future<Output = Result<Self::Handle>>;

/// Remove a flowspec from kernel using previously returned handle.
fn remove(&mut self, handle: Self::Handle) -> impl Future<Output = Result<()>>;

/// Process notifications from kernel, timers, etc.
fn process(&mut self) -> impl Future<Output = Result<()>> {
pending()
}
}

/// Adapter of different `Kernel` implementations.
#[derive(Debug, Serialize, Deserialize)]
pub enum Kernel {
pub enum KernelAdapter {
/// Do nothing.
Noop,

/// Linux implementation, using nftables and rtnetlink.
#[cfg(target_os = "linux")]
Linux(Linux),
}

impl Kernel {
impl KernelAdapter {
#[cfg(target_os = "linux")]
pub async fn linux(args: KernelArgs) -> Result<Self> {
Ok(Self::Linux(Linux::new(args).await?))
}
}

impl KernelAdapter for Kernel {
impl Kernel for KernelAdapter {
type Handle = KernelHandle;

async fn apply(&mut self, spec: &Flowspec, info: &RouteInfo<'_>) -> Result<Self::Handle> {
Expand Down Expand Up @@ -75,7 +87,7 @@ pub enum KernelHandle {

#[cfg(target_os = "linux")]
#[strum(to_string = "{0}")]
Linux(<Linux as KernelAdapter>::Handle),
Linux(<Linux as Kernel>::Handle),
}

#[derive(Debug, Error)]
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/rtnl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ impl RtNetlink {
.filter(|(_, v)| v.iter().all(|p| !p.overlaps(prefix)))
.next()
{
// there's a table whose content doesn't overlap with our prefix, we reuse it
prefixes.insert(prefix);
*table_id
} else {
Expand All @@ -84,7 +85,6 @@ impl RtNetlink {
.priority(self.args.rt_rule_priority)
.execute()
.await?;
self.handle.rule().get(rtnetlink::IpVersion::V4);
table_id
};

Expand Down

0 comments on commit 0f39394

Please sign in to comment.