diff --git a/Cargo.lock b/Cargo.lock index b38cda6a452..95c5e8e9e8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4441,6 +4441,7 @@ dependencies = [ "serde_with", "sled-agent-client", "slog", + "static_assertions", "steno", "strum", "subprocess", diff --git a/nexus/db-model/src/vpc.rs b/nexus/db-model/src/vpc.rs index 5f2f82119e6..f8dc68c5192 100644 --- a/nexus/db-model/src/vpc.rs +++ b/nexus/db-model/src/vpc.rs @@ -115,7 +115,7 @@ impl IncompleteVpc { /// /// This is used to retry insertion of a VPC in the case where we can't find /// an available VNI. - pub fn with_new_vni(self) -> Self { + pub fn with_random_vni(self) -> Self { Self { vni: Vni(external::Vni::random()), ..self } } } diff --git a/nexus/db-queries/Cargo.toml b/nexus/db-queries/Cargo.toml index eaf3dc12959..c16c0f5319e 100644 --- a/nexus/db-queries/Cargo.toml +++ b/nexus/db-queries/Cargo.toml @@ -47,6 +47,7 @@ serde_urlencoded.workspace = true serde_with.workspace = true sled-agent-client.workspace = true slog.workspace = true +static_assertions.workspace = true steno.workspace = true thiserror.workspace = true tokio = { workspace = true, features = [ "full" ] } diff --git a/nexus/db-queries/src/db/datastore/vpc.rs b/nexus/db-queries/src/db/datastore/vpc.rs index 3652ccc87ab..f376eaa9c13 100644 --- a/nexus/db-queries/src/db/datastore/vpc.rs +++ b/nexus/db-queries/src/db/datastore/vpc.rs @@ -313,7 +313,7 @@ impl DataStore { Ok(Some(vpcs)) => return Ok(vpcs), Err(e) => return Err(e), Ok(None) => { - vpc = vpc.with_new_vni(); + vpc = vpc.with_random_vni(); debug!( opctx.log, "VNI exhaustion detected while inserting VPC, retrying"; diff --git a/nexus/db-queries/src/db/queries/vpc.rs b/nexus/db-queries/src/db/queries/vpc.rs index b94f92233a7..4b36aabff99 100644 --- a/nexus/db-queries/src/db/queries/vpc.rs +++ b/nexus/db-queries/src/db/queries/vpc.rs @@ -294,6 +294,13 @@ pub const MAX_VNI_SEARCH_RANGE_SIZE: u32 = 2048; #[cfg(test)] pub const MAX_VNI_SEARCH_RANGE_SIZE: u32 = 10; +// Ensure that we cannot search a range that extends beyond the valid guest VNI +// range. +static_assertions::const_assert!( + MAX_VNI_SEARCH_RANGE_SIZE + <= (external::Vni::MAX_VNI - external::Vni::MIN_GUEST_VNI) +); + impl VniShifts { fn new(vni: Vni) -> Self { let base_u32 = u32::from(vni.0);