Skip to content
Open
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
3 changes: 3 additions & 0 deletions bfd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name = "bfd"
version = "0.1.0"
edition = "2024"

[features]
test-support = []

[dependencies]
anyhow.workspace = true
mg-common.workspace = true
Expand Down
5 changes: 5 additions & 0 deletions bfd/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ impl Daemon {
Self::with_dispatcher(Dispatcher::new(), log)
}

#[cfg(feature = "test-support")]
pub fn new_for_test(log: Logger) -> Self {
Self::with_dispatcher(Dispatcher::new_for_test(), log)
}

// Non-public method to allow construction with a custom dispatcher.
//
// This is used by tests when they want to use a `Dispatcher` with a custom
Expand Down
20 changes: 20 additions & 0 deletions bfd/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ impl Dispatcher {
Self::with_backend(Arc::new(TokioUdpBinder))
}

#[cfg(feature = "test-support")]
pub(crate) fn new_for_test() -> Self {
Self::with_backend(Arc::new(NoopListenerBackend))
}

fn with_backend(backend: Arc<dyn ListenerBackend>) -> Self {
Self {
peer_to_listen_addr: HashMap::default(),
Expand Down Expand Up @@ -276,6 +281,21 @@ trait ListenerBackend: Send + Sync + 'static {
) -> Result<JoinHandle<()>, AddPeerError>;
}

#[cfg(feature = "test-support")]
struct NoopListenerBackend;

#[cfg(feature = "test-support")]
impl ListenerBackend for NoopListenerBackend {
fn spawn(
&self,
_listen_addr: SocketAddr,
_sessions: SharedSessions,
_log: Logger,
) -> Result<JoinHandle<()>, AddPeerError> {
Ok(tokio::spawn(std::future::pending()))
}
}

/// Production [`ListenerBackend`]: binds a real UDP socket and spawns a
/// [`ListenerTask`] to read from it.
struct TokioUdpBinder;
Expand Down
4 changes: 3 additions & 1 deletion mg-api-types/versions/src/bfd_nonzero_detect_mult/bfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use serde::{Deserialize, Serialize};
use std::net::IpAddr;
use std::num::NonZeroU8;

#[derive(Debug, Copy, Clone, Deserialize, Serialize, JsonSchema)]
#[derive(
Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema,
)]
pub struct BfdPeerConfig {
/// Address of the peer to add.
pub peer: IpAddr,
Expand Down
8 changes: 6 additions & 2 deletions mg-api-types/versions/src/initial/bfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::net::IpAddr;

#[derive(Debug, Copy, Clone, Deserialize, Serialize, JsonSchema)]
#[derive(
Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema,
)]
pub struct BfdPeerConfig {
/// Address of the peer to add.
pub peer: IpAddr,
Expand All @@ -21,7 +23,9 @@ pub struct BfdPeerConfig {
pub mode: SessionMode,
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]
#[derive(
Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema,
)]
pub enum SessionMode {
SingleHop,
MultiHop,
Expand Down
1 change: 1 addition & 0 deletions mgd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ socket2.workspace = true
[dev-dependencies]
tempfile = "3"
proptest.workspace = true
bfd = { workspace = true, features = ["test-support"] }

[features]
default = ["mg-lower"]
Expand Down
11 changes: 8 additions & 3 deletions mgd/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,26 @@ impl MgAdminApi for MgAdminApiImpl {
async fn get_bfd_peers(
ctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Vec<BfdPeerInfo>>, HttpError> {
bfd_admin::get_bfd_peers(ctx).await
ctx.context().bfd.get_peers().map(HttpResponseOk)
}

async fn add_bfd_peer(
ctx: RequestContext<Self::Context>,
request: TypedBody<BfdPeerConfig>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
bfd_admin::add_bfd_peer(ctx, request).await
let ctx = ctx.context();
ctx.bfd.add_new_peer(ctx.db.clone(), request.into_inner())?;
Ok(HttpResponseUpdatedNoContent())
}

async fn remove_bfd_peer(
ctx: RequestContext<Self::Context>,
params: Path<DeleteBfdPeerPathParams>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
bfd_admin::remove_bfd_peer(ctx, params).await
let ctx = ctx.context();
let peer = params.into_inner().addr;
ctx.bfd.remove_peer(ctx.db.clone(), peer).await?;
Ok(HttpResponseUpdatedNoContent())
}

async fn read_routers(
Expand Down
Loading