Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3daa433
test(dataplane): expose static-lock model-checker failures
daniel-noland Aug 23, 2026
a7d32f6
fix(dpdk): keep the ACL registry lock process-global
daniel-noland Aug 23, 2026
19e298f
docs(concurrency): remove unsafe static-lock guidance
daniel-noland Aug 23, 2026
493d253
feat(routing): provide per-worker test readers
daniel-noland Aug 23, 2026
0baf269
refactor(dataplane): separate shared and worker test state
daniel-noland Aug 23, 2026
ce768bd
test(dataplane): model-check shared masquerade allocation
daniel-noland Aug 23, 2026
86af364
fix(flow-filter): keep ACL table names process-unique
daniel-noland Aug 23, 2026
e3470d7
test(dataplane): vary multi-worker configurations
daniel-noland Aug 23, 2026
239dcec
feat(tracectl): retain trace evidence until a test fails
daniel-noland Aug 23, 2026
80e7921
test(dataplane): split a flow across two workers
daniel-noland Aug 23, 2026
5fb03ec
fix(nat): release flow guards before ICMP handling
daniel-noland Aug 23, 2026
8ed0eaf
test(dataplane): republish routes during forwarding
daniel-noland Aug 23, 2026
7af8268
test(dataplane): update live next hops during forwarding
daniel-noland Aug 23, 2026
a34ad1a
test(dataplane): apply overlays while traffic is running
daniel-noland Aug 23, 2026
9745313
test(config): report operation-algebra coverage gaps
daniel-noland Aug 23, 2026
3c7eb4a
test(dataplane): preserve traffic outside a config change
daniel-noland Aug 23, 2026
86665e7
test(dataplane): publish both configuration generations
daniel-noland Aug 23, 2026
f865cfe
fix(nix): reject sanitizer ABI mismatches
daniel-noland Aug 23, 2026
8439ff2
test(dataplane): sustain traffic through configuration apply
daniel-noland Aug 23, 2026
21f4c18
test(dataplane): isolate masquerade swap tuple reuse
daniel-noland Aug 23, 2026
24be0c0
fix(dataplane): use modeled barriers in concurrency tests
daniel-noland Aug 28, 2026
f8d0153
test(config): classify no_multipath in the coverage census
daniel-noland Sep 15, 2026
316227c
test(flow-filter): scope imports to the std backend
daniel-noland Sep 15, 2026
4995d14
docs(dpdk): complete the OnceLock initialization rationale
daniel-noland Sep 15, 2026
dd325cf
fix(just): reject sanitizer runs without a sysroot stamp
daniel-noland Sep 15, 2026
0bda173
fix(concurrency): handle flow races during configuration updates
daniel-noland Sep 21, 2026
1dd8b60
fix(nat): reject port-forwarding reverse-flow collisions
daniel-noland Sep 21, 2026
70b62e5
fix(flow-entry): reserve flow counts before publishing entries
daniel-noland Sep 21, 2026
73fd447
test(dataplane): separate generation opening from masquerade
daniel-noland Sep 21, 2026
0e58738
chore(dataplane): forward the routing shuttle feature explicitly
daniel-noland Sep 21, 2026
92d960a
test(concurrency): initialize process-global counters directly
daniel-noland Sep 21, 2026
4b117c6
test(nat): skip the remaining full-flow fuzz probe under Miri
daniel-noland Sep 21, 2026
2e10b74
docs: clarify concurrency comments and diagnostics
daniel-noland Sep 21, 2026
e64c6ef
fix(nat): publish flow pairs atomically
daniel-noland Sep 22, 2026
41001ed
test(nat): record that a forward key does not determine its reverse key
daniel-noland Sep 22, 2026
d860143
test(just): give every recipe a Bolero budget
daniel-noland Sep 22, 2026
8e7937a
fix(hardware): bind unclaimed NICs to vfio-pci
daniel-noland Aug 23, 2026
da5b06e
test(dataplane): build replies from delivered addresses
daniel-noland Aug 24, 2026
4a225c0
fix(nat): retry burst flow lookup with the original key
daniel-noland Aug 24, 2026
eba0317
feat(config): generate static NAT exposes
daniel-noland Aug 24, 2026
6f33990
test(dataplane): use endpoint-owned addresses for inbound traffic
daniel-noland Aug 24, 2026
a8125c4
feat(config): generate port-forwarding exposes
daniel-noland Aug 24, 2026
73ce524
feat(config): generate peering ACLs
daniel-noland Aug 24, 2026
66acf7e
test(config): measure ACL schema coverage
daniel-noland Aug 24, 2026
af9aa3b
feat(config): generate stateful peering ACLs
daniel-noland Aug 24, 2026
d0bb2d7
feat(config): generate overlapping ACL rules
daniel-noland Aug 24, 2026
17fc999
feat(config): vary gateway groups, ACL logging, and timeouts
daniel-noland Aug 24, 2026
fad2823
feat(config): narrow ACL rules by protocol, port, and destination
daniel-noland Aug 24, 2026
92aac9b
feat(config): vary port-forwarding protocols
daniel-noland Aug 24, 2026
435c5a9
feat(config): generate address exclusions
daniel-noland Aug 24, 2026
42ee175
feat(config): generate default-route exposes
daniel-noland Aug 24, 2026
3565355
test(dataplane): reject traffic to excluded addresses
daniel-noland Aug 24, 2026
3c698b3
fix(config): make PermitByProtocol's exception narrow to the prefix i…
daniel-noland Sep 15, 2026
b5bf3e6
test(dataplane): use the shared fleet accessor in race regressions
daniel-noland Sep 21, 2026
5034c7d
test(config): draw enough configurations to reach a one-rule ACL
daniel-noland Sep 22, 2026
9389b93
test(config): stand the algebra coverage guards down on a small sample
daniel-noland Sep 22, 2026
3aea35d
test(config): stand the other four algebra coverage guards down too
daniel-noland Sep 22, 2026
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
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ CARGO_LLVM_COV_BUILD_DIR = { value = "target/llvm-cov/target", relative = true,

[build]
# Register `emulated` and `instrumented` so cfg sites do not trip unexpected_cfgs natively.
rustflags = ["--cfg=tokio_unstable", "--check-cfg=cfg(emulated)", "--check-cfg=cfg(instrumented)"]
rustflags = ["--cfg=tokio_unstable", "--check-cfg=cfg(emulated)", "--check-cfg=cfg(instrumented)", "--check-cfg=cfg(sanitized)"]

[target.wasm32-wasip1]
# Trailing `--` separates wasmtime's CLI from the module + module args
Expand Down
8 changes: 8 additions & 0 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ test-group = 'vm'
[test-groups]
vm = { max-threads = 1 }

# Find hung tests by stopping each test after 10 seconds and the run after five minutes. These
# limits can also stop valid, slow tests. Rerun reported tests with a normal profile.
[profile.scratch]
slow-timeout = { period = "10s", terminate-after = 1 }
global-timeout = "300s"
fail-fast = false
final-status-level = "all"

[profile.miri]
slow-timeout = { period = "500s" }

Expand Down
21 changes: 11 additions & 10 deletions Cargo.lock

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

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,9 @@ k8s-openapi = { version = "0.28.0", default-features = false, features = [] }
kanal = { version = "0.1.1", default-features = false, features = [] }
kube = { version = "4.2.0", default-features = false, features = [] }
kube-core = { version = "4.2.0", default-features = false, features = [] }
#left-right = { version = "0.11.7", default-features = false, features = [] }
left-right = { git = "https://github.com/githedgehog/left-right.git", branch = "fredi/fix-writehandle-drop", default-features = false, features = [] }
# The hh/shuttle fork makes WriteHandle::wait yield to Shuttle. Without it, the writer's
# sched_yield loop blocks the scheduler thread, preventing the reader from releasing its epoch.
left-right = { git = "https://github.com/githedgehog/left-right.git", branch = "hh/shuttle", default-features = false, features = [] }
libc = { version = "0.2.189", default-features = false, features = [] }
linkme = { version = "0.3.37", default-features = false, features = [] }
log = { version = "0.4.34", default-features = false, features = [] } # TODO: try to remove this
Expand Down
18 changes: 10 additions & 8 deletions acl-filter/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use acl::dpdk::lookup::DpdkAclLookup;
use acl::dpdk::rule::{AclFieldChunks, RuleSpec};
#[cfg(test)]
use acl::reference::table::{RefRule, ReferenceTable};
use concurrency::sync::LazyLock;
use concurrency::sync::atomic::{AtomicU64, Ordering};
use config::ConfigError;
use config::external::overlay::ValidatedOverlay;
use config::external::overlay::acl::{AclAction, AclProtoMatch, AclScope, ValidatedAclRule};
Expand Down Expand Up @@ -404,16 +402,20 @@ impl<K: MatchKey, A> fmt::Debug for AnyTable<K, A> {
}
}

// Lazily initialized so this compiles under the loom backend, whose AtomicU64::new is not const
// (each instance registers with the loom executor). The atomic itself is still the backend atomic,
// so fetch_add() stays instrumented; only construction is deferred. On every other backend LazyLock
// is a thin wrapper over an otherwise-const atomic.
static TABLE_SEQ: LazyLock<AtomicU64> = LazyLock::new(|| AtomicU64::new(0));
// DPDK's ACL registry survives model-checker executions. Its name counter must also persist to
// avoid reusing a live context's name.
use concurrency::process_global::atomic::{AtomicU64, Ordering};

static TABLE_SEQ: AtomicU64 = AtomicU64::new(0);

fn next_in_sequence() -> u64 {
TABLE_SEQ.fetch_add(1, Ordering::Relaxed)
}

/// A process-unique rte_acl context name. rte_acl rejects duplicate names, and a hot-swap briefly
/// keeps the old and new contexts alive at once, so the name must be unique across the process.
fn table_name(base: &str) -> String {
format!("acl_{base}_{}", TABLE_SEQ.fetch_add(1, Ordering::Relaxed))
format!("acl_{base}_{}", next_in_sequence())
}

/// Build one table for the selected backend from rules in precedence (insertion) order.
Expand Down
2 changes: 1 addition & 1 deletion acl-filter/src/nf_fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn filter(built: &crate::fuzz_gen::BuiltOverlay) -> AclFilter {
fn judged(drawn: usize) -> bool {
/// Sixteen cases' worth: far under any real run, far over a single replay.
const ENOUGH_PROBES: usize = PROBES * 16;
!cfg!(instrumented) && !cfg!(emulated) && drawn >= ENOUGH_PROBES
!cfg!(instrumented) && !cfg!(emulated) && !cfg!(sanitized) && drawn >= ENOUGH_PROBES
}

#[derive(Default)]
Expand Down
2 changes: 1 addition & 1 deletion acl-filter/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ mod end_to_end {
// Port forwarding
let mut portfw_writer = PortFwTableWriter::new();
portfw_writer
.update_from_vpc_table(overlay.vpc_table())
.update_from_vpc_table(overlay.vpc_table(), &flow_table, 1)
.unwrap();
pipeline = pipeline.add_stage(PortForwarder::new(
"port-forwarder",
Expand Down
6 changes: 2 additions & 4 deletions acl/benches/table_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
mod bench {
use std::hint::black_box;

use concurrency::sync::LazyLock;
use concurrency::sync::atomic::{AtomicU32, Ordering};
use concurrency::process_global::atomic::{AtomicU32, Ordering};
use core::net::{Ipv4Addr, Ipv6Addr};
use core::num::NonZero;

Expand Down Expand Up @@ -54,8 +53,7 @@ mod bench {
const RULE_COUNTS: [usize; 15] = [
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
];
// Lazily initialized so this compiles under the loom backend, whose AtomicU32::new is not const
static SEQ: LazyLock<AtomicU32> = LazyLock::new(|| AtomicU32::new(0));
static SEQ: AtomicU32 = AtomicU32::new(0);

fn unique_name(prefix: &str) -> String {
format!("{prefix}_{}", SEQ.fetch_add(1, Ordering::Relaxed))
Expand Down
12 changes: 4 additions & 8 deletions acl/src/dpdk/dyn_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,9 @@ mod failing_repros {
offset,
}
}
use concurrency::sync::LazyLock;
use concurrency::sync::atomic::{AtomicU32, Ordering};
use concurrency::process_global::atomic::{AtomicU32, Ordering};

// Lazily initialized so this compiles under the loom backend, whose AtomicU32::new is not const
static SEQ: LazyLock<AtomicU32> = LazyLock::new(|| AtomicU32::new(0));
static SEQ: AtomicU32 = AtomicU32::new(0);
fn uname(p: &str) -> String {
format!("{p}_{}", SEQ.fetch_add(1, Ordering::Relaxed))
}
Expand Down Expand Up @@ -507,11 +505,9 @@ mod tests {

dpdk_table_alias!(type FiveTupleTable<A> = FiveTuple);

use concurrency::sync::LazyLock;
use concurrency::sync::atomic::{AtomicU32, Ordering};
use concurrency::process_global::atomic::{AtomicU32, Ordering};

// Lazily initialized so this compiles under the loom backend, whose AtomicU32::new is not const
static CTX_SEQ: LazyLock<AtomicU32> = LazyLock::new(|| AtomicU32::new(0));
static CTX_SEQ: AtomicU32 = AtomicU32::new(0);
fn unique_name(prefix: &str) -> String {
format!("{prefix}_{}", CTX_SEQ.fetch_add(1, Ordering::Relaxed))
}
Expand Down
13 changes: 5 additions & 8 deletions acl/tests/property_dyn_shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
#![cfg(feature = "dpdk")]
#![allow(clippy::expect_used, clippy::unwrap_used)]

use concurrency::sync::LazyLock;
use concurrency::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use concurrency::process_global::atomic::{AtomicU32, AtomicU64, Ordering};
use core::num::NonZero;

use bolero::TypeGenerator;
Expand Down Expand Up @@ -148,8 +147,7 @@ impl ValueGenerator for ShapeMisses {
}
}

// Lazily initialized so this compiles under the loom backend, whose AtomicU32::new is not const
static CTX_SEQ: LazyLock<AtomicU32> = LazyLock::new(|| AtomicU32::new(0));
static CTX_SEQ: AtomicU32 = AtomicU32::new(0);

fn unique_name(prefix: &str) -> String {
format!("{prefix}_{}", CTX_SEQ.fetch_add(1, Ordering::Relaxed))
Expand Down Expand Up @@ -210,10 +208,9 @@ where
#[test]
#[dpdk::with_eal]
fn dyn_dpdk_and_reference_agree_on_random_shapes() {
// Lazily initialized so this compiles under the loom backend, whose AtomicU64::new is not const
static ASSERTED_HITS: LazyLock<AtomicU64> = LazyLock::new(|| AtomicU64::new(0));
static ASSERTED_MISSES: LazyLock<AtomicU64> = LazyLock::new(|| AtomicU64::new(0));
static SHAPES_RUN: LazyLock<AtomicU64> = LazyLock::new(|| AtomicU64::new(0));
static ASSERTED_HITS: AtomicU64 = AtomicU64::new(0);
static ASSERTED_MISSES: AtomicU64 = AtomicU64::new(0);
static SHAPES_RUN: AtomicU64 = AtomicU64::new(0);

bolero::check!()
.with_type::<(RawShape, Box<[u8]>, Box<[u8]>)>()
Expand Down
6 changes: 2 additions & 4 deletions acl/tests/property_predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
#![cfg(feature = "dpdk")]
#![allow(clippy::expect_used, clippy::unwrap_used)]

use concurrency::sync::LazyLock;
use concurrency::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use concurrency::process_global::atomic::{AtomicU32, AtomicU64, Ordering};
use core::net::{Ipv4Addr, Ipv6Addr};
use core::num::NonZero;
use core::ops::Bound;
Expand Down Expand Up @@ -180,8 +179,7 @@ enum Verdict {
Drop,
}

// Lazily initialized so this compiles under the loom backend, whose AtomicU32::new is not const
static CTX_SEQ: LazyLock<AtomicU32> = LazyLock::new(|| AtomicU32::new(0));
static CTX_SEQ: AtomicU32 = AtomicU32::new(0);

fn unique_name(prefix: &str) -> String {
format!("{prefix}_{}", CTX_SEQ.fetch_add(1, Ordering::Relaxed))
Expand Down
7 changes: 0 additions & 7 deletions concurrency/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@
//! schedule that `parking_lot` permits. Tests that hinge on that
//! interleaving need `RwLock<T>` with explicit `read()` then
//! `write()`, or a richer state machine in the facade.
//! * **`static FOO: Mutex<T> = Mutex::new(...)` does not compile
//! under loom.** `loom::sync::Mutex::new` is plain `fn`, not
//! `const fn`, so a static initialiser fails to typecheck. Use
//! `OnceLock` for the static (the facade re-exports
//! `std::sync::OnceLock` under all backends) or move the
//! construction into a runtime initialiser gated by
//! `#[concurrency_mode(std)]`.
//! * **`OnceLock` under loom/shuttle** is the real `std::sync::OnceLock`,
//! not a model-aware shim. Loom and shuttle do not see the
//! atomics inside `OnceLock::get_or_init`, so tests whose
Expand Down
4 changes: 2 additions & 2 deletions config/src/external/overlay/acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,8 @@ impl ValidatedAclRule {

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Acl {
default: AclAction,
rules: Vec<AclRule>,
pub(crate) default: AclAction,
pub(crate) rules: Vec<AclRule>,
}

impl Acl {
Expand Down
Loading
Loading