Skip to content

Commit

Permalink
BFD support (#4852)
Browse files Browse the repository at this point in the history
  • Loading branch information
rcgoodfellow authored Jan 31, 2024
1 parent 98180bf commit 749d23e
Show file tree
Hide file tree
Showing 34 changed files with 1,108 additions and 16 deletions.
17 changes: 16 additions & 1 deletion common/src/nexus_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ pub struct BackgroundTaskConfig {
pub phantom_disks: PhantomDiskConfig,
/// configuration for service zone nat sync task
pub sync_service_zone_nat: SyncServiceZoneNatConfig,
/// configuration for the bfd manager task
pub bfd_manager: BfdManagerConfig,
}

#[serde_as]
Expand Down Expand Up @@ -378,6 +380,14 @@ pub struct NatCleanupConfig {
pub period_secs: Duration,
}

#[serde_as]
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct BfdManagerConfig {
/// period (in seconds) for periodic activations of this background task
#[serde_as(as = "DurationSeconds<u64>")]
pub period_secs: Duration,
}

#[serde_as]
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct SyncServiceZoneNatConfig {
Expand Down Expand Up @@ -527,7 +537,7 @@ mod test {
};
use crate::address::{Ipv6Subnet, RACK_PREFIX};
use crate::api::internal::shared::SwitchLocation;
use crate::nexus_config::SyncServiceZoneNatConfig;
use crate::nexus_config::{BfdManagerConfig, SyncServiceZoneNatConfig};
use camino::{Utf8Path, Utf8PathBuf};
use dropshot::ConfigDropshot;
use dropshot::ConfigLogging;
Expand Down Expand Up @@ -672,6 +682,7 @@ mod test {
dns_external.max_concurrent_server_updates = 8
external_endpoints.period_secs = 9
nat_cleanup.period_secs = 30
bfd_manager.period_secs = 30
inventory.period_secs = 10
inventory.nkeep = 11
inventory.disable = false
Expand Down Expand Up @@ -773,6 +784,9 @@ mod test {
nat_cleanup: NatCleanupConfig {
period_secs: Duration::from_secs(30),
},
bfd_manager: BfdManagerConfig {
period_secs: Duration::from_secs(30),
},
inventory: InventoryConfig {
period_secs: Duration::from_secs(10),
nkeep: 11,
Expand Down Expand Up @@ -838,6 +852,7 @@ mod test {
dns_external.max_concurrent_server_updates = 8
external_endpoints.period_secs = 9
nat_cleanup.period_secs = 30
bfd_manager.period_secs = 30
inventory.period_secs = 10
inventory.nkeep = 3
inventory.disable = false
Expand Down
15 changes: 15 additions & 0 deletions dev-tools/omdb/tests/env.out
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ EXECUTING COMMAND: omdb ["nexus", "--nexus-internal-url", "http://127.0.0.1:REDA
termination: Exited(0)
---------------------------------------------
stdout:
task: "bfd_manager"
Manages bidirectional fowarding detection (BFD) configuration on rack
switches


task: "dns_config_external"
watches external DNS data stored in CockroachDB

Expand Down Expand Up @@ -96,6 +101,11 @@ EXECUTING COMMAND: omdb ["nexus", "background-tasks", "doc"]
termination: Exited(0)
---------------------------------------------
stdout:
task: "bfd_manager"
Manages bidirectional fowarding detection (BFD) configuration on rack
switches


task: "dns_config_external"
watches external DNS data stored in CockroachDB

Expand Down Expand Up @@ -156,6 +166,11 @@ EXECUTING COMMAND: omdb ["--dns-server", "[::1]:REDACTED_PORT", "nexus", "backgr
termination: Exited(0)
---------------------------------------------
stdout:
task: "bfd_manager"
Manages bidirectional fowarding detection (BFD) configuration on rack
switches


task: "dns_config_external"
watches external DNS data stored in CockroachDB

Expand Down
12 changes: 12 additions & 0 deletions dev-tools/omdb/tests/successes.out
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ EXECUTING COMMAND: omdb ["nexus", "background-tasks", "doc"]
termination: Exited(0)
---------------------------------------------
stdout:
task: "bfd_manager"
Manages bidirectional fowarding detection (BFD) configuration on rack
switches


task: "dns_config_external"
watches external DNS data stored in CockroachDB

Expand Down Expand Up @@ -339,6 +344,13 @@ task: "nat_v4_garbage_collector"
started at <REDACTED TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
warning: unknown background task: "nat_v4_garbage_collector" (don't know how to interpret details: Null)

task: "bfd_manager"
configured period: every 30s
currently executing: no
last completed activation: iter 2, triggered by an explicit signal
started at <REDACTED TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
warning: unknown background task: "bfd_manager" (don't know how to interpret details: Object {})

task: "external_endpoints"
configured period: every 1m
currently executing: no
Expand Down
59 changes: 59 additions & 0 deletions nexus/db-model/src/bfd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::schema::bfd_session;
use crate::{impl_enum_type, SqlU32};
use chrono::DateTime;
use chrono::Utc;
use ipnetwork::IpNetwork;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

impl_enum_type!(
#[derive(SqlType, Debug, Clone, Copy)]
#[diesel(postgres_type(name = "bfd_mode", schema = "public"))]
pub struct BfdModeEnum;

#[derive(
Clone,
Copy,
Debug,
AsExpression,
FromSqlRow,
PartialEq,
Serialize,
Deserialize
)]
#[diesel(sql_type = BfdModeEnum)]
pub enum BfdMode;

SingleHop => b"single_hop"
MultiHop => b"multi_hop"
);

#[derive(
Queryable, Insertable, Selectable, Clone, Debug, Serialize, Deserialize,
)]
#[diesel(table_name = bfd_session)]
pub struct BfdSession {
pub id: Uuid,
pub local: Option<IpNetwork>,
pub remote: IpNetwork,
pub detection_threshold: SqlU32,
pub required_rx: SqlU32,
pub switch: String,
pub mode: BfdMode,
pub time_created: DateTime<Utc>,
pub time_modified: DateTime<Utc>,
pub time_deleted: Option<DateTime<Utc>>,
}

impl From<nexus_types::external_api::params::BfdMode> for BfdMode {
fn from(value: nexus_types::external_api::params::BfdMode) -> Self {
match value {
nexus_types::external_api::params::BfdMode::SingleHop => {
BfdMode::SingleHop
}
nexus_types::external_api::params::BfdMode::MultiHop => {
BfdMode::MultiHop
}
}
}
}
2 changes: 2 additions & 0 deletions nexus/db-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern crate diesel;
extern crate newtype_derive;

mod address_lot;
mod bfd;
mod bgp;
mod block_size;
mod bootstore;
Expand Down Expand Up @@ -106,6 +107,7 @@ mod db {
pub use self::macaddr::*;
pub use self::unsigned::*;
pub use address_lot::*;
pub use bfd::*;
pub use bgp::*;
pub use block_size::*;
pub use bootstore::*;
Expand Down
17 changes: 16 additions & 1 deletion nexus/db-model/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use omicron_common::api::external::SemverVersion;
///
/// This should be updated whenever the schema is changed. For more details,
/// refer to: schema/crdb/README.adoc
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(30, 0, 0);
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(31, 0, 0);

table! {
disk (id) {
Expand Down Expand Up @@ -1485,6 +1485,21 @@ table! {
}
}

table! {
bfd_session (remote, switch) {
id -> Uuid,
local -> Nullable<Inet>,
remote -> Inet,
detection_threshold -> Int8,
required_rx -> Int8,
switch -> Text,
mode -> crate::BfdModeEnum,
time_created -> Timestamptz,
time_modified -> Timestamptz,
time_deleted -> Nullable<Timestamptz>,
}
}

table! {
db_metadata (singleton) {
singleton -> Bool,
Expand Down
88 changes: 88 additions & 0 deletions nexus/db-queries/src/db/datastore/bfd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::DataStore;
use crate::context::OpContext;
use crate::db;
use crate::db::error::public_error_from_diesel;
use crate::db::error::ErrorHandler;
use crate::db::pagination::paginated;
use async_bb8_diesel::AsyncRunQueryDsl;
use diesel::{ExpressionMethods, QueryDsl, SelectableHelper};
use ipnetwork::IpNetwork;
use nexus_db_model::BfdSession;
use nexus_db_model::SqlU32;
use nexus_types::external_api::params;
use omicron_common::api::external::DataPageParams;
use omicron_common::api::external::{
CreateResult, DeleteResult, ListResultVec,
};
use uuid::Uuid;

impl DataStore {
pub async fn bfd_session_list(
&self,
opctx: &OpContext,
pagparams: &DataPageParams<'_, Uuid>,
) -> ListResultVec<BfdSession> {
use db::schema::bfd_session::dsl;
let conn = self.pool_connection_authorized(opctx).await?;
paginated(dsl::bfd_session, dsl::id, pagparams)
.select(BfdSession::as_select())
.filter(dsl::time_deleted.is_null())
.load_async(&*conn)
.await
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))
}

pub async fn bfd_session_create(
&self,
opctx: &OpContext,
config: &params::BfdSessionEnable,
) -> CreateResult<BfdSession> {
use db::schema::bfd_session::dsl;
let conn = self.pool_connection_authorized(opctx).await?;

let session = BfdSession {
id: Uuid::new_v4(),
local: config.local.map(Into::into),
remote: config.remote.into(),
detection_threshold: SqlU32::new(config.detection_threshold.into()),
required_rx: SqlU32::new(
config.required_rx.try_into().unwrap_or(u32::MAX),
),
switch: config.switch.to_string(),
mode: config.mode.into(),
time_created: chrono::Utc::now(),
time_modified: chrono::Utc::now(),
time_deleted: None,
};

diesel::insert_into(dsl::bfd_session)
.values(session)
.returning(BfdSession::as_returning())
.get_result_async(&*conn)
.await
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))
}

pub async fn bfd_session_delete(
&self,
opctx: &OpContext,
config: &params::BfdSessionDisable,
) -> DeleteResult {
use db::schema::bfd_session::dsl;
let conn = self.pool_connection_authorized(opctx).await?;

diesel::update(dsl::bfd_session)
.filter(dsl::remote.eq(IpNetwork::from(config.remote)))
.filter(dsl::switch.eq(config.switch.to_string()))
.filter(dsl::time_deleted.is_null())
.set(dsl::time_deleted.eq(chrono::Utc::now()))
.execute_async(&*conn)
.await
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))
.map(|_| ())
}
}
4 changes: 4 additions & 0 deletions nexus/db-queries/src/db/datastore/bgp.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::DataStore;
use crate::context::OpContext;
use crate::db;
Expand Down
1 change: 1 addition & 0 deletions nexus/db-queries/src/db/datastore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use std::sync::Arc;
use uuid::Uuid;

mod address_lot;
mod bfd;
mod bgp;
mod bootstore;
mod certificate;
Expand Down
1 change: 1 addition & 0 deletions nexus/db-queries/src/db/pool_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub type DbConnection = DTraceConnection<PgConnection>;
static CUSTOM_TYPE_KEYS: &'static [&'static str] = &[
"address_lot_kind",
"authentication_mode",
"bfd_mode",
"block_size",
"caboose_which",
"dataset_kind",
Expand Down
1 change: 1 addition & 0 deletions nexus/examples/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ dns_external.max_concurrent_server_updates = 5
# them (on a sunny day).
external_endpoints.period_secs = 60
nat_cleanup.period_secs = 30
bfd_manager.period_secs = 30
# How frequently to collect hardware/software inventory from the whole system
# (even if we don't have reason to believe anything has changed).
inventory.period_secs = 600
Expand Down
Loading

0 comments on commit 749d23e

Please sign in to comment.