diff --git a/Cargo.lock b/Cargo.lock index 196f7b15..2909bec6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,6 +133,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "api_identity" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "omicron-workspace-hack", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "argon2" version = "0.5.3" @@ -141,7 +152,7 @@ checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", - "cpufeatures", + "cpufeatures 0.2.17", "password-hash", ] @@ -187,7 +198,7 @@ dependencies = [ "slog", "slog-async", "slog-term", - "softnpu 0.2.0 (git+https://github.com/oxidecomputer/softnpu?branch=main)", + "softnpu", "strum 0.27.2", "thiserror 1.0.69", "tofino 0.1.0 (git+https://github.com/oxidecomputer/tofino?branch=main)", @@ -257,6 +268,25 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "attest-data" +version = "0.5.0" +source = "git+https://github.com/oxidecomputer/dice-util?rev=1d3084b514389847e8e0f5d966d2be4f18d02d32#1d3084b514389847e8e0f5d966d2be4f18d02d32" +dependencies = [ + "const-oid", + "der", + "getrandom 0.3.4", + "hex", + "hubpack", + "rats-corim", + "salty", + "serde", + "serde_with", + "sha3", + "static_assertions", + "thiserror 2.0.18", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -381,6 +411,16 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "bhyve_api" +version = "0.0.0" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" +dependencies = [ + "bhyve_api_sys 0.0.0 (git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast)", + "libc", + "strum 0.26.3", +] + [[package]] name = "bhyve_api" version = "0.0.0" @@ -394,9 +434,18 @@ dependencies = [ [[package]] name = "bhyve_api" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782#8ccddb47a4c93b7e3480919495dae851afc83782" +dependencies = [ + "bhyve_api_sys 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782)", + "libc", + "strum 0.26.3", +] + +[[package]] +name = "bhyve_api_sys" +version = "0.0.0" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ - "bhyve_api_sys 0.0.0 (git+https://github.com/oxidecomputer/propolis)", "libc", "strum 0.26.3", ] @@ -413,7 +462,7 @@ dependencies = [ [[package]] name = "bhyve_api_sys" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782#8ccddb47a4c93b7e3480919495dae851afc83782" dependencies = [ "libc", "strum 0.26.3", @@ -454,6 +503,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -546,15 +601,44 @@ dependencies = [ "derive_more", "hex", "hkdf", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-workspace-hack", + "rand 0.8.5", + "secrecy", + "serde", + "serde_with", + "sha3", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "slog", + "thiserror 2.0.18", + "tokio", + "uuid", + "vsss-rs", + "zeroize", +] + +[[package]] +name = "bootstore" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "bytes", + "camino", + "chacha20poly1305", + "ciborium", + "derive_more", + "hex", + "hkdf", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "omicron-workspace-hack", "rand 0.8.5", "secrecy", "serde", "serde_with", "sha3", - "sled-hardware-types", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "slog", + "slog-error-chain", "thiserror 2.0.18", "tokio", "uuid", @@ -695,7 +779,18 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", +] + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", ] [[package]] @@ -705,7 +800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", - "chacha20", + "chacha20 0.9.1", "cipher", "poly1305", "zeroize", @@ -849,7 +944,7 @@ dependencies = [ "derive_more", "expectorate", "itertools 0.14.0", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -908,7 +1003,7 @@ source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172 dependencies = [ "chrono", "csv", - "omicron-uuid-kinds", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -1024,6 +1119,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "const_format" version = "0.2.34" @@ -1091,14 +1192,23 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "cpuid_utils" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ - "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis)", + "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast)", "bitflags 2.9.4", - "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis)", + "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast)", "thiserror 1.0.69", ] @@ -1259,7 +1369,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.6.0", + "socket2 0.6.3", "windows-sys 0.59.0", ] @@ -1285,7 +1395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -1336,8 +1446,18 @@ version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -1354,13 +1474,37 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + [[package]] name = "darling_macro" version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core", + "darling_core 0.21.3", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", "quote", "syn 2.0.117", ] @@ -1431,6 +1575,30 @@ dependencies = [ "semver 1.0.27", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "der_derive", + "flagset", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "deranged" version = "0.5.3" @@ -1477,6 +1645,31 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dice-verifier" +version = "0.3.0-pre0" +source = "git+https://github.com/oxidecomputer/dice-util?rev=1d3084b514389847e8e0f5d966d2be4f18d02d32#1d3084b514389847e8e0f5d966d2be4f18d02d32" +dependencies = [ + "async-trait", + "attest-data", + "const-oid", + "ed25519-dalek", + "env_logger", + "hex", + "hubpack", + "log", + "p384", + "rats-corim", + "sha3", + "sled-agent-client", + "sled-agent-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "slog", + "tempfile", + "thiserror 2.0.18", + "tokio", + "x509-cert", +] + [[package]] name = "diff" version = "0.1.13" @@ -1490,6 +1683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -1514,7 +1708,7 @@ dependencies = [ [[package]] name = "dladm" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "libc", "strum 0.26.3", @@ -1523,11 +1717,11 @@ dependencies = [ [[package]] name = "dlpi" version = "0.2.0" -source = "git+https://github.com/oxidecomputer/dlpi-sys?branch=main#555fa6e1315a64f40c72716e4d168697c03795c6" +source = "git+https://github.com/oxidecomputer/dlpi-sys?branch=main#7cce2d3ab9dcac909642e1d1060f27bb2549cfdc" dependencies = [ "libc", "libdlpi-sys 0.1.0 (git+https://github.com/oxidecomputer/dlpi-sys?branch=main)", - "num_enum 0.7.5", + "num_enum 0.7.6", "pretty-hex", "thiserror 2.0.18", "tokio", @@ -1536,11 +1730,11 @@ dependencies = [ [[package]] name = "dlpi" version = "0.2.0" -source = "git+https://github.com/oxidecomputer/dlpi-sys#42b2bfeefdfb8c7b96fc6cfa9ec45ef4554c2714" +source = "git+https://github.com/oxidecomputer/dlpi-sys#7cce2d3ab9dcac909642e1d1060f27bb2549cfdc" dependencies = [ "libc", "libdlpi-sys 0.1.0 (git+https://github.com/oxidecomputer/dlpi-sys)", - "num_enum 0.7.5", + "num_enum 0.7.6", "pretty-hex", "thiserror 2.0.18", ] @@ -1607,7 +1801,7 @@ dependencies = [ "libc", "mockall", "nexus-client", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "openssl", "oxide-tokio-rt", "oximeter", @@ -1719,7 +1913,7 @@ dependencies = [ "aal", "chrono", "common 0.1.0", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "oxnet", "schemars 0.8.22", "serde", @@ -1888,6 +2082,44 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" @@ -1907,7 +2139,10 @@ dependencies = [ "generic-array", "group", "hkdf", + "pem-rfc7468", + "pkcs8", "rand_core 0.6.4", + "sec1", "subtle", "zeroize", ] @@ -1951,6 +2186,25 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "env_filter" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +dependencies = [ + "log", +] + +[[package]] +name = "env_logger" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +dependencies = [ + "env_filter", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1983,7 +2237,7 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "dropshot", - "omicron-uuid-kinds", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -2065,6 +2319,12 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flagset" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" + [[package]] name = "flate2" version = "1.1.2" @@ -2276,7 +2536,7 @@ dependencies = [ "ereport-types", "gateway-messages", "gateway-types", - "omicron-uuid-kinds", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "progenitor 0.10.0", "rand 0.9.2", @@ -2325,7 +2585,7 @@ dependencies = [ "dropshot", "gateway-messages", "hex", - "omicron-uuid-kinds", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -2364,24 +2624,38 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "r-efi 5.3.0", + "wasip2", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasip2", + "wasip3", +] + [[package]] name = "gfss" version = "0.1.0" @@ -2398,6 +2672,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "gfss" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "digest", + "omicron-workspace-hack", + "rand 0.9.2", + "schemars 0.8.22", + "secrecy", + "serde", + "subtle", + "thiserror 2.0.18", + "zeroize", +] + [[package]] name = "git-stub" version = "1.0.0" @@ -3022,6 +3312,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "iddqd" version = "0.3.17" @@ -3085,6 +3381,14 @@ dependencies = [ "bitflags 2.9.4", ] +[[package]] +name = "illumos-sys-hdrs" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" +dependencies = [ + "bitflags 2.9.4", +] + [[package]] name = "illumos-utils" version = "0.1.0" @@ -3107,13 +3411,13 @@ dependencies = [ "itertools 0.14.0", "libc", "macaddr", - "nix", - "omicron-common", - "omicron-uuid-kinds", + "nix 0.30.1", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", - "opte-ioctl", - "oxide-vpc", - "oxlog", + "opte-ioctl 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "oxide-vpc 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "oxlog 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "oxnet", "schemars 0.8.22", "serde", @@ -3131,23 +3435,70 @@ dependencies = [ ] [[package]] -name = "indent_write" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +name = "illumos-utils" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "anyhow", + "async-trait", + "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782)", + "byteorder", + "camino", + "camino-tempfile", + "cfg-if", + "chrono", + "crucible-smf", + "debug-ignore", + "dropshot", + "futures", + "http", + "iddqd", + "ipnetwork", + "itertools 0.14.0", + "libc", + "macaddr", + "nix 0.30.1", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-workspace-hack", + "opte-ioctl 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", + "oxide-vpc 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", + "oxlog 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "oxnet", + "rustix 1.1.2", + "schemars 0.8.22", "serde", -] - -[[package]] + "slog", + "slog-async", + "slog-error-chain", + "slog-term", + "smf 0.2.3", + "thiserror 2.0.18", + "tofino 0.1.0 (git+https://github.com/oxidecomputer/tofino)", + "tokio", + "uuid", + "whoami", + "zone", +] + +[[package]] +name = "indent_write" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] name = "indexmap" version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3179,7 +3530,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4c94e8b5b5e08b71943d585acdb6062daaeb6b19de82ebb377c7c9cbeff44bb" dependencies = [ - "darling", + "darling 0.21.3", "itertools 0.14.0", "proc-macro2", "quote", @@ -3225,8 +3576,8 @@ dependencies = [ "hickory-proto 0.25.2", "hickory-resolver 0.25.2", "internal-dns-types", - "omicron-common", - "omicron-uuid-kinds", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "qorb", "reqwest 0.12.23", @@ -3242,8 +3593,8 @@ dependencies = [ "anyhow", "chrono", "internal-dns-types-versions", - "omicron-common", - "omicron-uuid-kinds", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -3257,7 +3608,7 @@ source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172 dependencies = [ "anyhow", "chrono", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -3409,7 +3760,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] @@ -3429,7 +3780,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -3441,6 +3792,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "kstat-macro" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" +dependencies = [ + "quote", + "syn 2.0.117", +] + [[package]] name = "kstat-rs" version = "0.2.4" @@ -3457,6 +3817,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" version = "0.2.183" @@ -3466,12 +3832,12 @@ checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libdlpi-sys" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/dlpi-sys?branch=main#555fa6e1315a64f40c72716e4d168697c03795c6" +source = "git+https://github.com/oxidecomputer/dlpi-sys?branch=main#7cce2d3ab9dcac909642e1d1060f27bb2549cfdc" [[package]] name = "libdlpi-sys" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/dlpi-sys#42b2bfeefdfb8c7b96fc6cfa9ec45ef4554c2714" +source = "git+https://github.com/oxidecomputer/dlpi-sys#7cce2d3ab9dcac909642e1d1060f27bb2549cfdc" [[package]] name = "libgit2-sys" @@ -3514,23 +3880,23 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libnet" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/netadm-sys?branch=main#24167d269038223b9d5d50c333ecaa34001d8f94" +source = "git+https://github.com/oxidecomputer/netadm-sys?branch=main#e9bf1e519ce304bf9cc6e87b50b9c64a77c8b0c1" dependencies = [ "anyhow", "cfg-if", "colored", "dlpi 0.2.0 (git+https://github.com/oxidecomputer/dlpi-sys)", "libc", - "num_enum 0.7.5", + "num_enum 0.7.6", "nvpair 0.5.0", "nvpair-sys", "oxnet", - "rand 0.9.2", + "rand 0.10.1", "rusty-doors", - "socket2 0.6.0", + "socket2 0.6.3", "thiserror 2.0.18", "tracing", - "winnow 0.7.14", + "winnow 1.0.1", ] [[package]] @@ -3543,13 +3909,13 @@ dependencies = [ "colored", "dlpi 0.2.0 (git+https://github.com/oxidecomputer/dlpi-sys)", "libc", - "num_enum 0.7.5", + "num_enum 0.7.6", "nvpair 0.5.0", "nvpair-sys", "oxnet", "rand 0.9.2", "rusty-doors", - "socket2 0.6.0", + "socket2 0.6.3", "thiserror 2.0.18", "tracing", "winnow 0.7.14", @@ -3781,7 +4147,25 @@ dependencies = [ "chrono", "colored", "progenitor 0.11.1", - "rdb-types", + "rdb-types 0.1.0 (git+https://github.com/oxidecomputer/maghemite?rev=396bb3c570be65f4e8c73ea3243f4af6561a823a)", + "reqwest 0.12.23", + "schemars 0.8.22", + "serde", + "serde_json", + "slog", + "tabwriter", + "uuid", +] + +[[package]] +name = "mg-admin-client" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec#3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" +dependencies = [ + "chrono", + "colored", + "progenitor 0.11.1", + "rdb-types 0.1.0 (git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec)", "reqwest 0.12.23", "schemars 0.8.22", "serde", @@ -3814,13 +4198,13 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.0", ] [[package]] @@ -3954,8 +4338,8 @@ dependencies = [ "futures", "iddqd", "nexus-types", - "omicron-common", - "omicron-uuid-kinds", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "oxnet", "progenitor 0.10.0", @@ -3974,7 +4358,7 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "anyhow", - "api_identity", + "api_identity 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "async-trait", "base64 0.22.1", "chrono", @@ -3993,7 +4377,7 @@ dependencies = [ "http", "humantime", "iddqd", - "illumos-utils", + "illumos-utils 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "indent_write", "internal-dns-types", "ipnet", @@ -4001,9 +4385,9 @@ dependencies = [ "itertools 0.14.0", "newtype-uuid", "newtype_derive", - "omicron-common", - "omicron-passwords", - "omicron-uuid-kinds", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-passwords 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "openssl", "oximeter-db", @@ -4016,9 +4400,9 @@ dependencies = [ "serde", "serde_json", "serde_with", - "sled-agent-types", - "sled-agent-types-versions", - "sled-hardware-types", + "sled-agent-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "sled-agent-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "slog", "slog-error-chain", "steno", @@ -4031,7 +4415,7 @@ dependencies = [ "tokio", "tough", "trust-quorum-protocol", - "trust-quorum-types", + "trust-quorum-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "tufaceous-artifact", "unicode-width 0.1.14", "update-engine", @@ -4052,6 +4436,18 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nix" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -4178,11 +4574,11 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" dependencies = [ - "num_enum_derive 0.7.5", + "num_enum_derive 0.7.6", "rustversion", ] @@ -4200,9 +4596,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4222,7 +4618,7 @@ dependencies = [ [[package]] name = "nvpair" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "libc", "nvpair_sys", @@ -4246,7 +4642,7 @@ source = "git+https://github.com/jmesmon/rust-libzfs?branch=master#ecd5a922247a6 [[package]] name = "nvpair_sys" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "libc", ] @@ -4268,7 +4664,7 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "anyhow", - "api_identity", + "api_identity 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "async-trait", "backoff", "camino", @@ -4282,8 +4678,53 @@ dependencies = [ "ipnetwork", "itertools 0.14.0", "macaddr", - "mg-admin-client", - "omicron-uuid-kinds", + "mg-admin-client 0.1.0 (git+https://github.com/oxidecomputer/maghemite?rev=396bb3c570be65f4e8c73ea3243f4af6561a823a)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-workspace-hack", + "oxnet", + "parse-display", + "progenitor-client 0.10.0", + "protocol", + "rand 0.9.2", + "regress", + "reqwest 0.12.23", + "schemars 0.8.22", + "semver 1.0.27", + "serde", + "serde_human_bytes", + "serde_json", + "serde_with", + "slog", + "slog-error-chain", + "strum 0.27.2", + "thiserror 2.0.18", + "tokio", + "tufaceous-artifact", + "uuid", +] + +[[package]] +name = "omicron-common" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "anyhow", + "api_identity 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "async-trait", + "backoff", + "camino", + "chrono", + "daft", + "dropshot", + "futures", + "hex", + "http", + "iddqd", + "ipnetwork", + "itertools 0.14.0", + "macaddr", + "mg-admin-client 0.1.0 (git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "omicron-workspace-hack", "oxnet", "parse-display", @@ -4322,6 +4763,21 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "omicron-passwords" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "argon2", + "omicron-workspace-hack", + "rand 0.9.2", + "schemars 0.8.22", + "secrecy", + "serde", + "serde_with", + "thiserror 2.0.18", +] + [[package]] name = "omicron-uuid-kinds" version = "0.1.0" @@ -4334,6 +4790,18 @@ dependencies = [ "schemars 0.8.22", ] +[[package]] +name = "omicron-uuid-kinds" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "daft", + "newtype-uuid", + "newtype-uuid-macros", + "paste", + "schemars 0.8.22", +] + [[package]] name = "omicron-workspace-hack" version = "0.1.0" @@ -4456,10 +4924,29 @@ source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f dependencies = [ "bitflags 2.9.4", "dyn-clone", - "illumos-sys-hdrs", + "illumos-sys-hdrs 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "ingot", + "kstat-macro 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "opte-api 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "postcard", + "ref-cast", + "serde", + "tabwriter", + "version_check", + "zerocopy 0.8.27", +] + +[[package]] +name = "opte" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" +dependencies = [ + "bitflags 2.9.4", + "dyn-clone", + "illumos-sys-hdrs 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", "ingot", - "kstat-macro", - "opte-api", + "kstat-macro 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", + "opte-api 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", "postcard", "ref-cast", "serde", @@ -4473,7 +4960,20 @@ name = "opte-api" version = "0.1.0" source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" dependencies = [ - "illumos-sys-hdrs", + "illumos-sys-hdrs 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "ingot", + "ipnetwork", + "postcard", + "serde", + "smoltcp", +] + +[[package]] +name = "opte-api" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" +dependencies = [ + "illumos-sys-hdrs 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", "ingot", "ipnetwork", "postcard", @@ -4488,8 +4988,22 @@ source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f dependencies = [ "libc", "libnet 0.1.0 (git+https://github.com/oxidecomputer/netadm-sys?branch=main)", - "opte", - "oxide-vpc", + "opte 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "oxide-vpc 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "postcard", + "serde", + "thiserror 2.0.18", +] + +[[package]] +name = "opte-ioctl" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" +dependencies = [ + "libc", + "libnet 0.1.0 (git+https://github.com/oxidecomputer/netadm-sys?branch=main)", + "opte 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", + "oxide-vpc 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", "postcard", "serde", "thiserror 2.0.18", @@ -4503,11 +5017,12 @@ checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "oxide-tokio-rt" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84bd87abf37c68d414e4df90a545857542140e07206f75039b8f63b244da87b8" +checksum = "f7d3e6073f692ff812f2d99b61e0ea7f503e54fc9ba44481f619c50a16f0565d" dependencies = [ "anyhow", + "nix 0.31.2", "tokio", "tokio-dtrace", ] @@ -4518,8 +5033,22 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" dependencies = [ "cfg-if", - "illumos-sys-hdrs", - "opte", + "illumos-sys-hdrs 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "opte 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7)", + "serde", + "tabwriter", + "uuid", + "zerocopy 0.8.27", +] + +[[package]] +name = "oxide-vpc" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" +dependencies = [ + "cfg-if", + "illumos-sys-hdrs 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", + "opte 0.1.0 (git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56)", "serde", "tabwriter", "uuid", @@ -4571,7 +5100,7 @@ dependencies = [ "libc", "nom", "num", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "oxide-tokio-rt", "oximeter", @@ -4637,7 +5166,7 @@ dependencies = [ "internal-dns-resolver", "internal-dns-types", "nexus-client", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "oximeter", "schemars 0.8.22", @@ -4692,7 +5221,7 @@ dependencies = [ "chrono", "float-ord", "num", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "oximeter-types-versions", "parse-display", @@ -4710,7 +5239,7 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "chrono", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -4734,6 +5263,23 @@ dependencies = [ "uuid", ] +[[package]] +name = "oxlog" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "anyhow", + "camino", + "chrono", + "clap", + "glob", + "jiff", + "omicron-workspace-hack", + "rayon", + "sigpipe", + "uuid", +] + [[package]] name = "oxnet" version = "0.1.4" @@ -4763,10 +5309,22 @@ dependencies = [ "uuid", ] +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "p4rs" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/p4?branch=main#c13435444832c28e0fb19bc65eaa8b431583a1cf" +source = "git+https://github.com/oxidecomputer/p4?branch=zl%2Fmulticast#0e8a28a2edce0a96dd0ac3a3df95af3d58cee839" dependencies = [ "bitvec", "num", @@ -4777,7 +5335,7 @@ dependencies = [ [[package]] name = "p9ds" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/p9fs#113f170aff6aa1d5add00c19b3a2f3241e16a763" +source = "git+https://github.com/oxidecomputer/p9fs#04fb133ac730f6f69612dcb20d1cb2195e4e89a6" dependencies = [ "ispf", "num_enum 0.5.11", @@ -4905,6 +5463,15 @@ dependencies = [ "serde", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -5029,6 +5596,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -5047,7 +5624,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -5155,6 +5732,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -5421,43 +6007,75 @@ dependencies = [ [[package]] name = "propolis" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "anyhow", "async-trait", - "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis)", + "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast)", + "bit_field", "bitflags 2.9.4", "bitstruct", "byteorder", "cpuid_utils", + "dice-verifier", "dladm", "dlpi 0.2.0 (git+https://github.com/oxidecomputer/dlpi-sys?branch=main)", "erased-serde 0.4.8", "futures", + "iddqd", "ispf", "lazy_static", "libc", "libloading 0.7.4", + "nix 0.31.2", "p9ds", + "paste", "pin-project-lite", - "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis)", + "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast)", "rand 0.9.2", "rfb", "rgb_frame", "serde", "serde_arrays", "serde_json", + "sha2", "slog", - "softnpu 0.2.0 (git+https://github.com/oxidecomputer/softnpu)", + "softnpu", + "static_assertions", "strum 0.26.3", "thiserror 1.0.69", "tokio", - "usdt 0.5.0", + "usdt 0.6.0", "uuid", "viona_api", + "vm-attest", "zerocopy 0.8.27", ] +[[package]] +name = "propolis-client" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782#8ccddb47a4c93b7e3480919495dae851afc83782" +dependencies = [ + "async-trait", + "base64 0.21.7", + "crucible-client-types", + "futures", + "progenitor 0.10.0", + "progenitor-client 0.10.0", + "propolis_api_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782)", + "rand 0.9.2", + "reqwest 0.12.23", + "schemars 0.8.22", + "serde", + "serde_json", + "slog", + "thiserror 1.0.69", + "tokio", + "tokio-tungstenite", + "uuid", +] + [[package]] name = "propolis_api_types" version = "0.0.0" @@ -5471,6 +6089,28 @@ dependencies = [ "uuid", ] +[[package]] +name = "propolis_api_types" +version = "0.0.0" +source = "git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782#8ccddb47a4c93b7e3480919495dae851afc83782" +dependencies = [ + "crucible-client-types", + "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782)", + "schemars 0.8.22", + "serde", + "thiserror 1.0.69", + "uuid", +] + +[[package]] +name = "propolis_types" +version = "0.0.0" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" +dependencies = [ + "schemars 0.8.22", + "serde", +] + [[package]] name = "propolis_types" version = "0.0.0" @@ -5483,7 +6123,7 @@ dependencies = [ [[package]] name = "propolis_types" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782#8ccddb47a4c93b7e3480919495dae851afc83782" dependencies = [ "schemars 0.8.22", "serde", @@ -5544,7 +6184,7 @@ dependencies = [ [[package]] name = "protocol" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/lldp#4c9df170cdfdeead0896e35f20a560f2102ed907" +source = "git+https://github.com/oxidecomputer/lldp#ed02e1a3a96f98107cbbe90f90c7ed1c16edf97d" dependencies = [ "anyhow", "schemars 0.8.22", @@ -5606,7 +6246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "bytes", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand 0.9.2", "ring", @@ -5649,6 +6289,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -5676,6 +6322,17 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20 0.10.0", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -5711,9 +6368,15 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rand_xorshift" version = "0.4.0" @@ -5723,6 +6386,21 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rats-corim" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/rats-corim#f0d5d5168d3d31487a56df32c676b0c6240bcc6b" +dependencies = [ + "ciborium", + "ciborium-io", + "clap", + "hex", + "serde", + "serde_with", + "strum 0.26.3", + "thiserror 2.0.18", +] + [[package]] name = "rayon" version = "1.11.0" @@ -5753,6 +6431,16 @@ dependencies = [ "serde", ] +[[package]] +name = "rdb-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec#3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" +dependencies = [ + "oxnet", + "schemars 0.8.22", + "serde", +] + [[package]] name = "redox_syscall" version = "0.5.17" @@ -5912,7 +6600,7 @@ checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" [[package]] name = "rfb" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "ascii", "bitflags 2.9.4", @@ -5925,10 +6613,20 @@ dependencies = [ "zerocopy 0.8.27", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rgb_frame" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "strum 0.26.3", ] @@ -6111,6 +6809,16 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "salty" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b947325a585e90733e0e9ec097228f40b637cc346f9bd68f84d5c6297d0fcfef" +dependencies = [ + "subtle", + "zeroize", +] + [[package]] name = "same-file" version = "1.0.6" @@ -6234,6 +6942,20 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5145b2263bec888224d054d1c820ceffa7d4a23723a2a822f970fcf1c5b64770" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "secrecy" version = "0.10.3" @@ -6439,9 +7161,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" dependencies = [ "base64 0.22.1", "chrono", @@ -6451,8 +7173,7 @@ dependencies = [ "schemars 0.8.22", "schemars 0.9.0", "schemars 1.2.0", - "serde", - "serde_derive", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -6460,11 +7181,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" dependencies = [ - "darling", + "darling 0.23.0", "proc-macro2", "quote", "syn 2.0.117", @@ -6490,7 +7211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -6501,7 +7222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -6561,6 +7282,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "sigpipe" version = "0.1.3" @@ -6579,40 +7310,99 @@ dependencies = [ "bstr", ] -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "sled-agent-client" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-workspace-hack", + "oxnet", + "progenitor 0.10.0", + "propolis-client", + "regress", + "reqwest 0.12.23", + "schemars 0.8.22", + "serde", + "serde_json", + "sled-agent-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "sled-agent-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "slog", + "trust-quorum-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "uuid", +] + +[[package]] +name = "sled-agent-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" +dependencies = [ + "anyhow", + "async-trait", + "bootstore 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "camino", + "chrono", + "daft", + "iddqd", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-workspace-hack", + "oxnet", + "schemars 0.8.22", + "serde", + "serde_human_bytes", + "serde_json", + "sled-agent-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "slog", + "slog-error-chain", + "strum 0.27.2", + "swrite", + "thiserror 2.0.18", + "toml 0.8.23", + "tufaceous-artifact", + "uuid", +] + [[package]] name = "sled-agent-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" dependencies = [ "anyhow", "async-trait", - "bootstore", + "bootstore 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "camino", "chrono", "daft", "iddqd", - "omicron-common", - "omicron-uuid-kinds", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "omicron-workspace-hack", "oxnet", "schemars 0.8.22", "serde", "serde_human_bytes", "serde_json", - "sled-agent-types-versions", - "sled-hardware-types", + "sled-agent-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "slog", "slog-error-chain", "strum 0.27.2", @@ -6629,30 +7419,64 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "async-trait", - "bootstore", + "bootstore 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "camino", + "chrono", + "daft", + "iddqd", + "illumos-utils 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "indent_write", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-passwords 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-workspace-hack", + "oxnet", + "propolis_api_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=2aa7f9d0ee84a1c45e821d6444b1d2f0e69b743e)", + "schemars 0.8.22", + "serde", + "serde_human_bytes", + "serde_json", + "serde_with", + "sha3", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "slog", + "strum 0.27.2", + "thiserror 2.0.18", + "trust-quorum-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "tufaceous-artifact", + "uuid", +] + +[[package]] +name = "sled-agent-types-versions" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "async-trait", + "bootstore 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "camino", "chrono", "daft", "iddqd", - "illumos-utils", + "illumos-utils 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "indent_write", - "omicron-common", - "omicron-passwords", - "omicron-uuid-kinds", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-passwords 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "omicron-workspace-hack", "oxnet", - "propolis_api_types", + "propolis_api_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=8ccddb47a4c93b7e3480919495dae851afc83782)", "schemars 0.8.22", "serde", "serde_human_bytes", "serde_json", "serde_with", "sha3", - "sled-hardware-types", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "slog", "strum 0.27.2", "thiserror 2.0.18", - "trust-quorum-types-versions", + "trust-quorum-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "tufaceous-artifact", "uuid", ] @@ -6663,8 +7487,23 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "daft", - "illumos-utils", - "omicron-common", + "illumos-utils 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-workspace-hack", + "schemars 0.8.22", + "serde", + "slog", + "thiserror 2.0.18", +] + +[[package]] +name = "sled-hardware-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "daft", + "illumos-utils 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "omicron-workspace-hack", "schemars 0.8.22", "serde", @@ -6848,29 +7687,18 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "softnpu" -version = "0.2.0" -source = "git+https://github.com/oxidecomputer/softnpu?branch=main#7e015d167a914777bc21434d1c61f205f22993b1" -dependencies = [ - "p4rs", - "serde", - "serde_json", - "tokio", + "windows-sys 0.61.0", ] [[package]] name = "softnpu" version = "0.2.0" -source = "git+https://github.com/oxidecomputer/softnpu#7e015d167a914777bc21434d1c61f205f22993b1" +source = "git+https://github.com/oxidecomputer/softnpu?branch=zl%2Fmulticast#284c6830722548714128e63ea04bcca78ee27154" dependencies = [ "p4rs", "serde", @@ -6884,6 +7712,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -7188,7 +8026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix 1.1.2", "windows-sys 0.61.0", @@ -7272,7 +8110,7 @@ dependencies = [ "libc", "libnet 0.1.0 (git+https://github.com/oxidecomputer/netadm-sys)", "lldpd-client", - "omicron-common", + "omicron-common 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "oxide-tokio-rt", "oximeter", "oximeter-instruments", @@ -7286,7 +8124,7 @@ dependencies = [ "signal-hook", "slog", "smf 0.10.0", - "socket2 0.6.0", + "socket2 0.6.3", "thiserror 1.0.69", "tokio", "uuid", @@ -7439,6 +8277,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tls_codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b" +dependencies = [ + "tls_codec_derive", + "zeroize", +] + +[[package]] +name = "tls_codec_derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "tofino" version = "0.1.0" @@ -7452,7 +8311,7 @@ dependencies = [ [[package]] name = "tofino" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tofino#7e56ab6e9a64ebae27cd97cd6e10ebf2cfdc3a33" +source = "git+https://github.com/oxidecomputer/tofino#e25e52991785039e967fd8fe7d86554d976e6d4b" dependencies = [ "anyhow", "cc", @@ -7461,9 +8320,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", @@ -7471,7 +8330,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.0", + "socket2 0.6.3", "tokio-macros", "tracing", "windows-sys 0.61.0", @@ -7490,9 +8349,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -7542,6 +8401,18 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.16" @@ -7853,7 +8724,7 @@ dependencies = [ "clap", "hubpack", "itertools 0.14.0", - "nix", + "nix 0.30.1", "schemars 0.8.22", "serde", "slog", @@ -7898,32 +8769,32 @@ name = "trust-quorum-protocol" version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ - "bootstore", + "bootstore 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "bytes", "camino", "chacha20poly1305", "ciborium", "daft", "derive_more", - "gfss", + "gfss 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "hex", "hkdf", "iddqd", - "omicron-uuid-kinds", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "omicron-workspace-hack", "rand 0.9.2", "secrecy", "serde", "serde_with", "sha3", - "sled-agent-types", - "sled-hardware-types", + "sled-agent-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "slog", "slog-error-chain", "static_assertions", "subtle", "thiserror 2.0.18", - "trust-quorum-types", + "trust-quorum-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "uuid", "zeroize", ] @@ -7934,7 +8805,16 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172a26ea531d1cfc870117a7370418" dependencies = [ "omicron-workspace-hack", - "trust-quorum-types-versions", + "trust-quorum-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", +] + +[[package]] +name = "trust-quorum-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "omicron-workspace-hack", + "trust-quorum-types-versions 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", ] [[package]] @@ -7944,16 +8824,38 @@ source = "git+https://github.com/oxidecomputer/omicron?branch=main#8e30605f52172 dependencies = [ "daft", "derive_more", - "gfss", + "gfss 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "iddqd", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "omicron-workspace-hack", + "rand 0.9.2", + "schemars 0.8.22", + "serde", + "serde_human_bytes", + "serde_with", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", + "slog", + "slog-error-chain", + "thiserror 2.0.18", +] + +[[package]] +name = "trust-quorum-types-versions" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831#becbbb616f5f18b59cc42e511c148734c2ba3831" +dependencies = [ + "daft", + "derive_more", + "gfss 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "iddqd", - "omicron-uuid-kinds", + "omicron-uuid-kinds 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "omicron-workspace-hack", "rand 0.9.2", "schemars 0.8.22", "serde", "serde_human_bytes", "serde_with", - "sled-hardware-types", + "sled-hardware-types 0.1.0 (git+https://github.com/oxidecomputer/omicron?rev=becbbb616f5f18b59cc42e511c148734c2ba3831)", "slog", "slog-error-chain", "thiserror 2.0.18", @@ -7982,6 +8884,25 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror 1.0.69", + "url", + "utf-8", +] + [[package]] name = "typed-path" version = "0.9.3" @@ -8363,6 +9284,12 @@ dependencies = [ "usdt-impl 0.6.0", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -8381,7 +9308,7 @@ version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "serde_core", "wasm-bindgen", @@ -8424,19 +9351,35 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "viona_api" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +source = "git+https://github.com/oxidecomputer/propolis?branch=zl%2Fmulticast#784de5e4b123b48e574bbffc1188c0d5c30b2e62" dependencies = [ "libc", "nvpair 0.0.0", - "viona_api_sys", ] [[package]] -name = "viona_api_sys" -version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis#827e6615bfebfd94d41504dcd1517a0f22e3166a" +name = "vm-attest" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/vm-attest?rev=2cdd17580a4fc6c871d24797016af8dbaac9421d#2cdd17580a4fc6c871d24797016af8dbaac9421d" dependencies = [ + "anyhow", + "attest-data", + "const-oid", + "dice-verifier", + "ed25519-dalek", + "getrandom 0.3.4", + "hex", + "hubpack", "libc", + "log", + "rats-corim", + "serde", + "serde_json", + "serde_with", + "sha2", + "thiserror 2.0.18", + "uuid", + "x509-cert", ] [[package]] @@ -8501,21 +9444,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wasip2", + "wit-bindgen 0.46.0", ] [[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] @@ -8583,6 +9526,28 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] + [[package]] name = "wasm-streams" version = "0.4.2" @@ -8609,6 +9574,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.9.4", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver 1.0.27", +] + [[package]] name = "web-sys" version = "0.3.85" @@ -9029,6 +10006,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -9045,6 +10031,94 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.9.4", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver 1.0.27", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + [[package]] name = "writeable" version = "0.6.1" @@ -9060,6 +10134,18 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid", + "der", + "spki", + "tls_codec", +] + [[package]] name = "xattr" version = "1.6.1" diff --git a/Cargo.toml b/Cargo.toml index efbf670a..310bf380 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,9 +52,9 @@ oximeter = { git = "https://github.com/oxidecomputer/omicron", branch = "main" } oximeter-producer = { git = "https://github.com/oxidecomputer/omicron", branch = "main" } oximeter-instruments = { git = "https://github.com/oxidecomputer/omicron", branch = "main", default-features = false, features = ["kstat"] } oxnet = { version = "0.1.4", default-features = false, features = ["schemars", "serde"] } -propolis = { git = "https://github.com/oxidecomputer/propolis" } +propolis = { git = "https://github.com/oxidecomputer/propolis", branch = "zl/multicast" } smf = { git = "https://github.com/illumos/smf-rs" } -softnpu-lib = { git = "https://github.com/oxidecomputer/softnpu" , package = "softnpu" , branch = "main"} +softnpu-lib = { git = "https://github.com/oxidecomputer/softnpu" , package = "softnpu" , branch = "zl/multicast"} tofino = { git = "https://github.com/oxidecomputer/tofino", branch = "main" } transceiver-controller = { git = "https://github.com/oxidecomputer/transceiver-control", branch = "main" } @@ -82,7 +82,7 @@ libc = "0.2" mockall = "0.13.1" omicron-zone-package = "0.12" openssl = "0.10" -oxide-tokio-rt = "0.1.2" +oxide-tokio-rt = "0.1.4" parking_lot = "0.12" pretty_assertions = "1.4" proc-macro2 = "1.0" @@ -107,7 +107,8 @@ strum = { version = "0.27", features = [ "derive" ] } syn = { version = "2.0", features = ["extra-traits"]} tabwriter = { version = "1", features = ["ansi_formatting"] } thiserror = "1.0" -tokio = "1.37" +# pinned to match omicron main (tokio-rs/tokio#8056) +tokio = "1.52.1" toml = "0.9" usdt = "0.6" uuid = { version = "1.10", features = [ "v4", "serde" ] } @@ -117,3 +118,4 @@ internet-checksum = "0.2" # It's common during development to use a local copy of various complex # dependencies. If you want to use those, uncomment one of these blocks. # + diff --git a/asic/src/softnpu/mcast.rs b/asic/src/softnpu/mcast.rs new file mode 100644 index 00000000..76dd0f78 --- /dev/null +++ b/asic/src/softnpu/mcast.rs @@ -0,0 +1,302 @@ +// 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/ +// +// Copyright 2026 Oxide Computer Company + +//! In-memory multicast group tracking for the [softnpu] backend. +//! +//! Sidecar-lite handles packet replication via port bitmaps in the P4 +//! pipeline, so this module only needs to track group membership for +//! the `AsicMulticastOps` contract. +//! +//! [softnpu]: https://github.com/oxidecomputer/softnpu + +use std::collections::{HashMap, HashSet}; + +use aal::{AsicError, AsicResult}; + +pub struct McGroupData { + groups: HashMap>, +} + +fn no_group(group_id: u16) -> AsicError { + AsicError::InvalidArg(format!("no such multicast group: {group_id}")) +} + +impl McGroupData { + /// Get the list of multicast domains. + pub fn domains(&self) -> Vec { + self.groups.keys().copied().collect() + } + + /// Build a 128-bit port bitmap for a group. Bit N is set if port N + /// is a member. Returns zero for unknown groups. + pub fn port_bitmap(&self, group_id: u16) -> u128 { + match self.groups.get(&group_id) { + Some(ports) => { + let mut bitmap: u128 = 0; + for &port in ports { + bitmap |= 1u128 << port; + } + bitmap + } + None => 0, + } + } + + /// Get the number of ports in a multicast domain. + pub fn domain_port_count(&self, group_id: u16) -> AsicResult { + match self.groups.get(&group_id) { + Some(g) => Ok(g.len()), + None => Err(no_group(group_id)), + } + } + + /// Add a port to a multicast domain. Port must be < 128 to fit + /// in sidecar-lite's 128-bit replication bitmap. + pub fn domain_port_add( + &mut self, + group_id: u16, + port: u16, + _rid: u16, + _level1_excl_id: u16, + ) -> AsicResult<()> { + if port >= 128 { + return Err(AsicError::InvalidArg(format!( + "port {port} exceeds softnpu 128-port bitmap limit" + ))); + } + let group = match self.groups.get_mut(&group_id) { + Some(g) => Ok(g), + None => Err(no_group(group_id)), + }?; + + match group.insert(port) { + true => Ok(()), + false => Err(AsicError::InvalidArg(format!( + "multicast group {group_id} already contains port {port}" + ))), + } + } + + /// Remove a port from a multicast domain. + pub fn domain_port_remove( + &mut self, + group_id: u16, + port: u16, + ) -> AsicResult<()> { + let group = match self.groups.get_mut(&group_id) { + Some(g) => Ok(g), + None => Err(no_group(group_id)), + }?; + + match group.remove(&port) { + true => Ok(()), + false => Err(AsicError::InvalidArg(format!( + "multicast group {group_id} doesn't contain port {port}" + ))), + } + } + + /// Create a multicast domain. + #[allow(clippy::map_entry)] + pub fn domain_create(&mut self, group_id: u16) -> AsicResult<()> { + if self.groups.contains_key(&group_id) { + Err(AsicError::InvalidArg(format!( + "multicast group {group_id} already exists" + ))) + } else { + self.groups.insert(group_id, HashSet::new()); + Ok(()) + } + } + + /// Destroy a multicast domain. + pub fn domain_destroy(&mut self, group_id: u16) -> AsicResult<()> { + match self.groups.remove(&group_id) { + Some(_) => Ok(()), + None => Err(no_group(group_id)), + } + } + + /// Get the total number of multicast domains. + pub fn domains_count(&self) -> usize { + self.groups.len() + } + + /// Validate that the current group count does not exceed the limit. + pub fn set_max_nodes( + &mut self, + max_nodes: u32, + _max_link_aggregated_nodes: u32, + ) -> AsicResult<()> { + let total = self.domains_count(); + if total as u32 > max_nodes { + return Err(AsicError::InvalidArg(format!( + "number of multicast groups {total} exceeds max nodes {max_nodes}" + ))); + } + + Ok(()) + } +} + +pub fn init() -> McGroupData { + McGroupData { groups: HashMap::new() } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn group_lifecycle() { + let mut mc = init(); + + // Create group, add ports. + mc.domain_create(100).unwrap(); + mc.domain_port_add(100, 1, 0, 0).unwrap(); + mc.domain_port_add(100, 5, 0, 0).unwrap(); + + assert_eq!(mc.domain_port_count(100).unwrap(), 2); + assert_eq!(mc.domains_count(), 1); + + // Remove a port. + mc.domain_port_remove(100, 1).unwrap(); + assert_eq!(mc.domain_port_count(100).unwrap(), 1); + + // Destroy group. + mc.domain_destroy(100).unwrap(); + assert_eq!(mc.domains_count(), 0); + } + + #[test] + fn duplicate_group_rejected() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + assert!(mc.domain_create(1).is_err()); + } + + #[test] + fn duplicate_port_rejected() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + mc.domain_port_add(1, 5, 0, 0).unwrap(); + assert!(mc.domain_port_add(1, 5, 0, 0).is_err()); + } + + #[test] + fn remove_nonexistent_port_rejected() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + assert!(mc.domain_port_remove(1, 99).is_err()); + } + + #[test] + fn operations_on_missing_group_rejected() { + let mut mc = init(); + assert!(mc.domain_port_add(42, 1, 0, 0).is_err()); + assert!(mc.domain_port_remove(42, 1).is_err()); + assert!(mc.domain_port_count(42).is_err()); + assert!(mc.domain_destroy(42).is_err()); + } + + #[test] + fn port_bitmap_empty_group() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + assert_eq!(mc.port_bitmap(1), 0); + } + + #[test] + fn port_bitmap_populated() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + mc.domain_port_add(1, 0, 0, 0).unwrap(); + mc.domain_port_add(1, 3, 0, 0).unwrap(); + mc.domain_port_add(1, 7, 0, 0).unwrap(); + + let bm = mc.port_bitmap(1); + assert_eq!(bm & (1 << 0), 1 << 0); + assert_eq!(bm & (1 << 3), 1 << 3); + assert_eq!(bm & (1 << 7), 1 << 7); + assert_eq!(bm & (1 << 1), 0); + } + + #[test] + fn port_bitmap_unknown_group_returns_zero() { + let mc = init(); + assert_eq!(mc.port_bitmap(999), 0); + } + + #[test] + fn port_bitmap_high_port() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + mc.domain_port_add(1, 127, 0, 0).unwrap(); + + let bm = mc.port_bitmap(1); + assert_eq!(bm & (1u128 << 127), 1u128 << 127); + } + + #[test] + fn port_bitmap_ignores_ports_above_127() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + // Port 128 is out of range for a 128-bit bitmap. + assert!(mc.domain_port_add(1, 128, 0, 0).is_err()); + } + + #[test] + fn set_max_nodes_validates() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + mc.domain_create(2).unwrap(); + + assert!(mc.set_max_nodes(1, 0).is_err()); + assert!(mc.set_max_nodes(2, 0).is_ok()); + assert!(mc.set_max_nodes(100, 0).is_ok()); + } + + #[test] + fn domains_returns_created_group_ids() { + let mut mc = init(); + mc.domain_create(10).unwrap(); + mc.domain_create(20).unwrap(); + mc.domain_create(30).unwrap(); + + let mut ids = mc.domains(); + ids.sort(); + assert_eq!(ids, vec![10, 20, 30]); + } + + #[test] + fn port_bitmap_reflects_removal() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + mc.domain_port_add(1, 0, 0, 0).unwrap(); + mc.domain_port_add(1, 3, 0, 0).unwrap(); + + mc.domain_port_remove(1, 0).unwrap(); + + let bm = mc.port_bitmap(1); + assert_eq!(bm & (1 << 0), 0); + assert_eq!(bm & (1 << 3), 1 << 3); + } + + #[test] + fn groups_are_independent() { + let mut mc = init(); + mc.domain_create(1).unwrap(); + mc.domain_create(2).unwrap(); + mc.domain_port_add(1, 5, 0, 0).unwrap(); + mc.domain_port_add(2, 5, 0, 0).unwrap(); + + mc.domain_port_remove(1, 5).unwrap(); + + assert_eq!(mc.domain_port_count(1).unwrap(), 0); + assert_eq!(mc.domain_port_count(2).unwrap(), 1); + assert_eq!(mc.port_bitmap(2) & (1 << 5), 1 << 5); + } +} diff --git a/asic/src/softnpu/mod.rs b/asic/src/softnpu/mod.rs index cfb497ad..ac7172cd 100644 --- a/asic/src/softnpu/mod.rs +++ b/asic/src/softnpu/mod.rs @@ -28,6 +28,8 @@ use common::ports::{ use softnpu_lib::ManagementRequest; +#[cfg(feature = "multicast")] +pub mod mcast; pub mod mgmt; pub mod table; @@ -105,6 +107,9 @@ pub struct Handle { pub mgmt_config: mgmt::ManagementConfig, update_tx: Mutex>>, + + #[cfg(feature = "multicast")] + mc_data: Mutex, } impl Handle { @@ -130,6 +135,8 @@ impl Handle { ports: Mutex::new(HashMap::new()), mgmt_config, update_tx: Mutex::new(None), + #[cfg(feature = "multicast")] + mc_data: Mutex::new(mcast::init()), }) } @@ -148,46 +155,68 @@ impl Handle { #[cfg(feature = "multicast")] impl AsicMulticastOps for Handle { fn mc_domains(&self) -> Vec { - let len = self.ports.lock().unwrap().len() as u16; - (0..len).collect() + let mc_data = self.mc_data.lock().unwrap(); + mc_data.domains() } - fn mc_port_count(&self, _group_id: u16) -> AsicResult { - Ok(self.ports.lock().unwrap().len()) + fn mc_port_count(&self, group_id: u16) -> AsicResult { + let mc_data = self.mc_data.lock().unwrap(); + mc_data.domain_port_count(group_id) } fn mc_port_add( &self, - _group_id: u16, - _port: u16, - _rid: u16, - _level1_excl_id: u16, + group_id: u16, + port: u16, + rid: u16, + level1_excl_id: u16, ) -> AsicResult<()> { - Err(AsicError::OperationUnsupported) + slog::info!( + self.log, + "adding port {port} to multicast group {group_id}" + ); + let mut mc_data = self.mc_data.lock().unwrap(); + mc_data.domain_port_add(group_id, port, rid, level1_excl_id) } - fn mc_port_remove(&self, _group_id: u16, _port: u16) -> AsicResult<()> { - Ok(()) + fn mc_port_remove(&self, group_id: u16, port: u16) -> AsicResult<()> { + slog::info!( + self.log, + "removing port {port} from multicast group {group_id}" + ); + let mut mc_data = self.mc_data.lock().unwrap(); + mc_data.domain_port_remove(group_id, port) } - fn mc_group_create(&self, _group_id: u16) -> AsicResult<()> { - Err(AsicError::OperationUnsupported) + fn mc_group_create(&self, group_id: u16) -> AsicResult<()> { + slog::info!(self.log, "creating multicast group {group_id}"); + let mut mc_data = self.mc_data.lock().unwrap(); + mc_data.domain_create(group_id) } - fn mc_group_destroy(&self, _group_id: u16) -> AsicResult<()> { - Ok(()) + fn mc_group_destroy(&self, group_id: u16) -> AsicResult<()> { + slog::info!(self.log, "destroying multicast group {group_id}"); + let mut mc_data = self.mc_data.lock().unwrap(); + mc_data.domain_destroy(group_id) } fn mc_groups_count(&self) -> AsicResult { - Ok(self.ports.lock().unwrap().len()) + let mc_data = self.mc_data.lock().unwrap(); + Ok(mc_data.domains_count()) } fn mc_set_max_nodes( &self, - _max_nodes: u32, - _max_link_aggregated_nodes: u32, + max_nodes: u32, + max_link_aggregated_nodes: u32, ) -> AsicResult<()> { - Ok(()) + slog::info!( + self.log, + "setting max nodes to {max_nodes}, \ + max link aggregated nodes to {max_link_aggregated_nodes}" + ); + let mut mc_data = self.mc_data.lock().unwrap(); + mc_data.set_max_nodes(max_nodes, max_link_aggregated_nodes) } } diff --git a/asic/src/softnpu/table.rs b/asic/src/softnpu/table.rs index 56d9c1fe..7e045e30 100644 --- a/asic/src/softnpu/table.rs +++ b/asic/src/softnpu/table.rs @@ -4,6 +4,8 @@ // // Copyright 2026 Oxide Computer Company +use std::hash::Hash; + use slog::{error, trace}; use softnpu_lib::{ManagementRequest, TableAdd, TableRemove}; @@ -14,16 +16,41 @@ use aal::{ }; use common::table::TableType; -/// Represents a handle to a SoftNPU ASIC table. The `id` member corresponds to -/// the table path in the P4 program. Well known sidecar-lite.p4 paths follow -/// below. +// Match field names used by the VLAN validity dispatch. +#[cfg(feature = "multicast")] +const VALID_FIELD: &str = "$valid"; +#[cfg(feature = "multicast")] +const VLAN_ID_FIELD: &str = "vlan_id"; + +// Sidecar-lite untagged table names for VLAN dispatch. +#[cfg(feature = "multicast")] +const MCAST_NAT_V4_UNTAGGED: &str = "ingress.nat.nat_v4_mcast_untagged"; +#[cfg(feature = "multicast")] +const MCAST_NAT_V6_UNTAGGED: &str = "ingress.nat.nat_v6_mcast_untagged"; + +/// Represents a handle to a SoftNPU ASIC table. The `type_` member identifies +/// the table and `softnpu_table_name()` maps it to the corresponding +/// sidecar-lite.p4 path. pub struct Table { type_: TableType, implemented: bool, + /// Alternate sidecar-lite table for untagged entries + /// ([`VALID_FIELD`] is false). x4c does not support `$valid` as + /// a table key, so any table that matches on VLAN validity splits + /// into tagged/untagged variants with per-entry dispatch. + /// [`VLAN_ID_FIELD`] is stripped from the keyset for the untagged + /// table. + /// + /// Currently used by multicast NAT (`nat_v4_mcast` / + /// `nat_v4_mcast_untagged`, `nat_v6_mcast` / + /// `nat_v6_mcast_untagged`). + untagged_id: Option<&'static str>, size: usize, } impl Table { + /// Return the sidecar-lite table name for this table, or `None` if the + /// table is not implemented in the softnpu backend. pub fn softnpu_table_name(&self) -> Option<&'static str> { if self.implemented { match self.type_ { @@ -44,6 +71,32 @@ impl Table { TableType::ArpIpv4 => Some("ingress.resolver.resolver_v4"), TableType::NeighborIpv6 => Some("ingress.resolver.resolver_v6"), TableType::PortMacAddress => Some("ingress.mac.mac_rewrite"), + #[cfg(feature = "multicast")] + TableType::McastIpv6 => { + Some("ingress.mcast.mcast_replication_v6") + } + #[cfg(feature = "multicast")] + TableType::McastIpv4SrcFilter => { + Some("ingress.mcast.mcast_source_filter_v4") + } + #[cfg(feature = "multicast")] + TableType::McastIpv6SrcFilter => { + Some("ingress.mcast.mcast_source_filter_v6") + } + #[cfg(feature = "multicast")] + TableType::NatIngressIpv4Mcast => { + Some("ingress.nat.nat_v4_mcast") + } + #[cfg(feature = "multicast")] + TableType::NatIngressIpv6Mcast => { + Some("ingress.nat.nat_v6_mcast") + } + #[cfg(feature = "multicast")] + TableType::McastEgressDecapPorts => { + Some("egress.tbl_decap_ports") + } + #[cfg(feature = "multicast")] + TableType::PortMacAddressMcast => Some("egress.mcast_src_mac"), _ => panic!( "implemented table {} has no softnpu table", self.type_ @@ -53,16 +106,68 @@ impl Table { None } } + + /// Inspect the VLAN `$valid` match field to route entries to the + /// tagged or untagged sidecar-lite table. Returns the primary table + /// name for tables without a VLAN split. + #[cfg(feature = "multicast")] + fn resolve_vlan_table_id( + &self, + fields: &[MatchEntryField], + ) -> Option<&str> { + if let Some(untagged) = self.untagged_id { + let is_untagged = fields.iter().any(|f| { + f.name == VALID_FIELD + && matches!( + &f.value, + MatchEntryValue::Value(ValueTypes::U64(0)) + ) + }); + if is_untagged { + return Some(untagged); + } + } + self.softnpu_table_name() + } + + /// Filter match fields for sidecar-lite serialization. Strips + /// the `$valid` field (consumed by `resolve_vlan_table_id`) and + /// strips `vlan_id` when targeting the untagged table. + #[cfg(feature = "multicast")] + fn filter_vlan_match_fields( + &self, + fields: Vec, + target_table: &str, + ) -> Vec { + if self.untagged_id.is_none() { + return fields; + } + let is_untagged = self.untagged_id == Some(target_table); + fields + .into_iter() + .filter(|f| { + // $valid is consumed by dispatch, not serialized. + if f.name == VALID_FIELD { + return false; + } + // Untagged table has no vlan_id key. + if is_untagged && f.name == VLAN_ID_FIELD { + return false; + } + true + }) + .collect() + } } -// All tables are defined to be 1024 entries deep +// All tables are defined to be 4096 entries deep. const TABLE_SIZE: usize = 4096; impl TableOps for Table { fn new(hdl: &Handle, type_: TableType) -> AsicResult { - // TODO just mapping sidecar.p4 things onto simplified sidecar-lite.p4 - // things to get started. - let implemented = match type_ { + // Mapping sidecar.p4 table types onto simplified sidecar-lite.p4 + // equivalents. + let (implemented, untagged_id) = match type_ { TableType::RouteIdxIpv4 | TableType::RouteFwdIpv4 | TableType::RouteIdxIpv6 @@ -75,14 +180,28 @@ impl TableOps for Table { | TableType::NatIngressIpv4 | TableType::NatIngressIpv6 | TableType::AttachedSubnetIpv4 - | TableType::AttachedSubnetIpv6 => true, + | TableType::AttachedSubnetIpv6 => (true, None), + #[cfg(feature = "multicast")] + TableType::McastIpv6 + | TableType::McastIpv4SrcFilter + | TableType::McastIpv6SrcFilter + | TableType::McastEgressDecapPorts + | TableType::PortMacAddressMcast => (true, None), + #[cfg(feature = "multicast")] + TableType::NatIngressIpv4Mcast => { + (true, Some(MCAST_NAT_V4_UNTAGGED)) + } + #[cfg(feature = "multicast")] + TableType::NatIngressIpv6Mcast => { + (true, Some(MCAST_NAT_V6_UNTAGGED)) + } x => { - error!(hdl.log, "TABLE NOT HANDLED {x}"); - false + error!(hdl.log, "table not handled: {x}"); + (false, None) } }; - Ok(Table { type_, implemented, size: TABLE_SIZE }) + Ok(Table { type_, implemented, untagged_id, size: TABLE_SIZE }) } fn size(&self) -> usize { @@ -90,7 +209,7 @@ impl TableOps for Table { } fn clear(&self, _hdl: &Handle) -> AsicResult<()> { - //TODO implement in softnpu + // TODO: implement in softnpu Ok(()) } @@ -100,19 +219,33 @@ impl TableOps for Table { key: &M, data: &A, ) -> AsicResult<()> { - let Some(table) = self.softnpu_table_name() else { + let Some(default_table) = self.softnpu_table_name() else { return Ok(()); }; let name = self.type_.to_string(); let match_data = key.key_to_ir().unwrap(); let action_data = data.action_to_ir().unwrap(); + // For tables with VLAN dispatch, resolve which sidecar-lite table + // to target and filter out synthetic match fields. + #[cfg(feature = "multicast")] + let (table, fields) = { + let resolved = self + .resolve_vlan_table_id(&match_data.fields) + .unwrap_or(default_table); + let filtered = + self.filter_vlan_match_fields(match_data.fields, resolved); + (resolved.to_string(), filtered) + }; + #[cfg(not(feature = "multicast"))] + let (table, fields) = (default_table.to_string(), match_data.fields); + trace!(hdl.log, "entry_add called"); trace!(hdl.log, "table: {name}"); - trace!(hdl.log, "match_data:\n{:#?}", match_data); + trace!(hdl.log, "match_data (filtered): {fields:#?}"); trace!(hdl.log, "action_data:\n{:#?}", action_data); - let keyset_data = keyset_data(match_data.fields, self.type_); + let keyset_data = keyset_data(fields, self.type_, &table); let (action, parameter_data) = match ( self.type_, @@ -432,99 +565,107 @@ impl TableOps for Table { | (TableType::NatIngressIpv6, "forward_ipv6_to") | (TableType::AttachedSubnetIpv4, "forward_to_v4") | (TableType::AttachedSubnetIpv6, "forward_to_v6") => { - let mut target = Vec::new(); - let mut vni = Vec::new(); - let mut mac = Vec::new(); - for arg in action_data.args { - match arg.name.as_str() { - "target" => { - // "target" is 128 bits - let mut data: Vec = Vec::new(); - match &arg.value { - ValueTypes::U64(_) => { - // Currently the ValueType is always Ptr - error!( - hdl.log, - "expected ValueType::Ptr, \ - received ValueType::U64" - ); - return Ok(()); - } - ValueTypes::Ptr(v) => { - data.extend_from_slice(v.as_slice()); - } - } - let len = data.len(); - let buf = &mut data[len - 16..]; - buf.reverse(); - target.extend_from_slice(buf); - } - "vni" => { - // "vni" is 24 bits - let mut data: Vec = Vec::new(); - match &arg.value { - ValueTypes::U64(v) => { - data.extend_from_slice(&v.to_le_bytes()); - } - ValueTypes::Ptr(_) => { - // Currently the ValueType is always U64 - error!( - hdl.log, - "expected ValueType::U64, \ - received ValueType::Ptr" - ); - return Ok(()); - } - } - vni.extend_from_slice(&data[0..3]); + forward_to_sled_params(hdl, &name, action_data)? + } + #[cfg(feature = "multicast")] + (TableType::NatIngressIpv4Mcast, "mcast_forward_ipv4_to") + | (TableType::NatIngressIpv6Mcast, "mcast_forward_ipv6_to") => { + forward_to_sled_params(hdl, &name, action_data)? + } + // Multicast source filters: no action parameters. + #[cfg(feature = "multicast")] + (TableType::McastIpv4SrcFilter, "allow_source_mcastv4") + | (TableType::McastIpv6SrcFilter, "allow_source_mcastv6") => { + ("allow_source", Vec::new()) + } + // Multicast replication: translate group IDs to port bitmaps. + // + // DPD sends configure_mcastv6 with (mcast_grp_a, mcast_grp_b, + // rid, level1_excl_id, level2_excl_id). Sidecar-lite expects + // set_port_bitmap with (external, underlay, rid). We look up + // the group membership in McGroupData and build the bitmaps. + #[cfg(feature = "multicast")] + (TableType::McastIpv6, "configure_mcastv6") => { + let mut external_grp: u16 = 0; + let mut underlay_grp: u16 = 0; + let mut rid: u16 = 0; + for arg in action_data.args.iter() { + if let ValueTypes::U64(v) = &arg.value { + match arg.name.as_str() { + "mcast_grp_a" => external_grp = *v as u16, + "mcast_grp_b" => underlay_grp = *v as u16, + "rid" => rid = *v as u16, + _ => {} } - "inner_mac" => { - // "mac" is 48 bits - let mut data: Vec = Vec::new(); - match &arg.value { - ValueTypes::U64(v) => { - data.extend_from_slice(&v.to_le_bytes()); - } - ValueTypes::Ptr(_) => { - // Currently the ValueType is always U64 - error!( - hdl.log, - "expected ValueType::U64, \ - received ValueType::Ptr" - ); - return Ok(()); - } - } - mac.extend_from_slice(&data[0..6]) + } + } + + let mc_data = hdl.mc_data.lock().unwrap(); + let external_bitmap = mc_data.port_bitmap(external_grp); + let underlay_bitmap = mc_data.port_bitmap(underlay_grp); + drop(mc_data); + + let mut params = Vec::new(); + params.extend_from_slice(&external_bitmap.to_le_bytes()); + params.extend_from_slice(&underlay_bitmap.to_le_bytes()); + params.extend_from_slice(&rid.to_le_bytes()); + ("set_port_bitmap", params) + } + // Multicast egress decap: pack 8x32-bit bitmap into 128 bits. + // + // DPD sends set_decap_ports with 8x32-bit bitmap fields + // keyed on RID. Sidecar-lite expects a single 128-bit + // bitmap. We pack the low 4 chunks (ports 0-127) into a + // u128 for sidecar-lite's bit<128> decap_bitmap field. + #[cfg(feature = "multicast")] + (TableType::McastEgressDecapPorts, "set_decap_ports") => { + ("set_decap_ports", pack_decap_bitmap(&action_data)) + } + #[cfg(feature = "multicast")] + (TableType::McastEgressDecapPorts, "set_decap_ports_and_vlan") => { + let mut params = pack_decap_bitmap(&action_data); + let mut vlan_id: u16 = 0; + for arg in action_data.args.iter() { + if let ValueTypes::U64(v) = &arg.value + && arg.name.as_str() == "vlan_id" + { + vlan_id = *v as u16; + } + } + params.extend_from_slice(&vlan_id.to_le_bytes()); + ("set_decap_ports_and_vlan", params) + } + // Multicast egress MAC rewrite. + #[cfg(feature = "multicast")] + (TableType::PortMacAddressMcast, "rewrite") => { + let mut params = Vec::new(); + for arg in action_data.args { + match arg.value { + ValueTypes::U64(v) => { + let mac = v.to_le_bytes(); + params.extend_from_slice(&mac[0..6]); } - _ => { - error!(hdl.log, "unknown argument: {}", arg.name); - return Ok(()); + ValueTypes::Ptr(v) => { + params.extend_from_slice(v.as_slice()); } } } - let mut params = Vec::new(); - // arguments currently don't arrive in the correct order, - // so we'll order them manually - params.extend_from_slice(target.as_slice()); - params.extend_from_slice(vni.as_slice()); - params.extend_from_slice(mac.as_slice()); - ("forward_to_sled", params) + ("rewrite_src_mac", params) } (_, x) => { - error!(hdl.log, "ACTION NOT HANDLED {name} {x}"); + error!(hdl.log, "action not handled: {name} {x}"); return Ok(()); } }; let action = action.to_string(); trace!(hdl.log, "sending request to softnpu"); - trace!(hdl.log, "table: {name}"); + trace!(hdl.log, "table: {table}"); trace!(hdl.log, "action: {:#?}", action); trace!(hdl.log, "keyset_data:\n{:#?}", keyset_data); trace!(hdl.log, "parameter_data:\n{:#?}", parameter_data); let msg = ManagementRequest::TableAdd(TableAdd { - table: table.to_string(), + table, action, keyset_data, parameter_data, @@ -535,27 +676,19 @@ impl TableOps for Table { Ok(()) } - fn entry_update( + fn entry_update( &self, hdl: &Handle, key: &M, data: &A, ) -> AsicResult<()> { - let Some(_table) = self.softnpu_table_name() else { - return Ok(()); - }; - let name = self.type_.to_string(); - - let match_data = key.key_to_ir().unwrap(); - let action_data = data.action_to_ir().unwrap(); - - trace!(hdl.log, "entry_update called"); - trace!(hdl.log, "table: {name}"); - trace!(hdl.log, "match_data:\n{:#?}", match_data); - trace!(hdl.log, "action_data:\n{:#?}", action_data); - - //TODO implement in softnpu - Ok(()) + // Softnpu does not currently support in-place updates. + // Delete the old entry and re-add with the new action data. + // Both operations are currently fire-and-forget over the + // management channel, so neither can fail from DPD's + // perspective. + self.entry_del(hdl, key)?; + self.entry_add(hdl, key, data) } fn entry_del( @@ -563,26 +696,36 @@ impl TableOps for Table { hdl: &Handle, key: &M, ) -> AsicResult<()> { - let Some(table) = self.softnpu_table_name() else { + let Some(default_table) = self.softnpu_table_name() else { return Ok(()); }; let name = self.type_.to_string(); let match_data = key.key_to_ir().unwrap(); + #[cfg(feature = "multicast")] + let (table, fields) = { + let resolved = self + .resolve_vlan_table_id(&match_data.fields) + .unwrap_or(default_table); + let filtered = + self.filter_vlan_match_fields(match_data.fields, resolved); + (resolved.to_string(), filtered) + }; + #[cfg(not(feature = "multicast"))] + let (table, fields) = (default_table.to_string(), match_data.fields); + trace!(hdl.log, "entry_del called"); trace!(hdl.log, "table: {name}"); - trace!(hdl.log, "match_data:\n{:#?}", match_data); + trace!(hdl.log, "match_data (filtered): {fields:#?}"); - let keyset_data = keyset_data(match_data.fields, self.type_); + let keyset_data = keyset_data(fields, self.type_, &table); trace!(hdl.log, "sending request to softnpu"); - trace!(hdl.log, "table: {name}"); + trace!(hdl.log, "table: {table}"); trace!(hdl.log, "keyset_data:\n{:#?}", keyset_data); - let msg = ManagementRequest::TableRemove(TableRemove { - keyset_data, - table: table.to_string(), - }); + let msg = + ManagementRequest::TableRemove(TableRemove { keyset_data, table }); crate::softnpu::mgmt::write(msg, &hdl.mgmt_config); @@ -606,9 +749,127 @@ impl TableOps for Table { } } +/// Extract the forward_to_sled action parameters shared by unicast and +/// multicast NAT/attached-subnet actions. Returns the sidecar-lite action +/// name and serialized parameter bytes. +fn forward_to_sled_params( + hdl: &Handle, + name: &str, + action_data: aal::ActionData, +) -> AsicResult<(&'static str, Vec)> { + let mut target = Vec::new(); + let mut vni = Vec::new(); + let mut mac = Vec::new(); + for arg in action_data.args { + match arg.name.as_str() { + "target" => { + // "target" is 128 bits + let mut data: Vec = Vec::new(); + match &arg.value { + ValueTypes::U64(_) => { + // Currently the ValueType is always Ptr + error!( + hdl.log, + "expected ValueType::Ptr, \ + received ValueType::U64" + ); + return Ok(("forward_to_sled", Vec::new())); + } + ValueTypes::Ptr(v) => { + data.extend_from_slice(v.as_slice()); + } + } + let len = data.len(); + let buf = &mut data[len - 16..]; + buf.reverse(); + target.extend_from_slice(buf); + } + "vni" => { + // "vni" is 24 bits + let mut data: Vec = Vec::new(); + match &arg.value { + ValueTypes::U64(v) => { + data.extend_from_slice(&v.to_le_bytes()); + } + ValueTypes::Ptr(_) => { + // Currently the ValueType is always U64 + error!( + hdl.log, + "expected ValueType::U64, \ + received ValueType::Ptr" + ); + return Ok(("forward_to_sled", Vec::new())); + } + } + vni.extend_from_slice(&data[0..3]); + } + "inner_mac" => { + // "mac" is 48 bits + let mut data: Vec = Vec::new(); + match &arg.value { + ValueTypes::U64(v) => { + data.extend_from_slice(&v.to_le_bytes()); + } + ValueTypes::Ptr(_) => { + // Currently the ValueType is always U64 + error!( + hdl.log, + "expected ValueType::U64, \ + received ValueType::Ptr" + ); + return Ok(("forward_to_sled", Vec::new())); + } + } + mac.extend_from_slice(&data[0..6]) + } + _ => { + error!(hdl.log, "unknown argument: {} in {name}", arg.name); + return Ok(("forward_to_sled", Vec::new())); + } + } + } + let mut params = Vec::new(); + // Arguments currently don't arrive in the correct order, + // so we order them manually. + params.extend_from_slice(target.as_slice()); + params.extend_from_slice(vni.as_slice()); + params.extend_from_slice(mac.as_slice()); + Ok(("forward_to_sled", params)) +} + +/// Pack DPD's 8x32-bit decap port bitmap into a byte vector for +/// sidecar-lite's decap_bitmap field. All 8 chunks are serialized +/// little-endian and the P4 field width determines how many are consumed. +#[cfg(feature = "multicast")] +fn pack_decap_bitmap(args: &aal::ActionData) -> Vec { + let mut chunks = [0u32; 8]; + for arg in &args.args { + if let ValueTypes::U64(v) = &arg.value { + match arg.name.as_str() { + "ports_0" => chunks[0] = *v as u32, + "ports_1" => chunks[1] = *v as u32, + "ports_2" => chunks[2] = *v as u32, + "ports_3" => chunks[3] = *v as u32, + "ports_4" => chunks[4] = *v as u32, + "ports_5" => chunks[5] = *v as u32, + "ports_6" => chunks[6] = *v as u32, + "ports_7" => chunks[7] = *v as u32, + _ => {} + } + } + } + chunks.iter().flat_map(|c| c.to_le_bytes()).collect() +} + /// Extract keys from `match_data` and ensure that they are -/// in a data structure with the correct length -fn keyset_data(match_data: Vec, table: TableType) -> Vec { +/// in a data structure with the correct length. The `table_name` +/// parameter is the resolved sidecar-lite table name, which may +/// differ from the primary name for VLAN-dispatched tables. +fn keyset_data( + match_data: Vec, + table: TableType, + table_name: &str, +) -> Vec { let mut keyset_data: Vec = Vec::new(); for m in match_data { match m.value { @@ -622,7 +883,7 @@ fn keyset_data(match_data: Vec, table: TableType) -> Vec { keyset_data.extend_from_slice(&data[..4]); } TableType::NeighborIpv6 => { - // "nexthop_ipv4" => bit<128> + // "nexthop_ipv6" => bit<128> let mut buf = Vec::new(); serialize_value_type(&x, &mut buf); buf.reverse(); @@ -655,6 +916,53 @@ fn keyset_data(match_data: Vec, table: TableType) -> Vec { buf.reverse(); keyset_data.extend_from_slice(&buf); } + // Multicast replication: hdr.ipv6.dst => bit<128> + #[cfg(feature = "multicast")] + TableType::McastIpv6 => { + let mut buf = Vec::new(); + serialize_value_type(&x, &mut buf); + buf.reverse(); + keyset_data.extend_from_slice(&buf); + } + // Multicast source filter exact keys: inner dst => + // bit<32> or bit<128>. The LPM src key is handled + // in the Lpm arm. + #[cfg(feature = "multicast")] + TableType::McastIpv4SrcFilter => { + serialize_value_type(&x, &mut data); + keyset_data.extend_from_slice(&data[..4]); + } + #[cfg(feature = "multicast")] + TableType::McastIpv6SrcFilter => { + let mut buf = Vec::new(); + serialize_value_type(&x, &mut buf); + buf.reverse(); + keyset_data.extend_from_slice(&buf); + } + // Multicast NAT: dst (bit<32> or bit<128>) and + // optionally vlan_id (bit<12>) after VLAN field + // filtering. The resolved table_name determines + // whether the tagged or untagged variant is used; + // the keyset width is the same for both. + #[cfg(feature = "multicast")] + TableType::NatIngressIpv4Mcast => { + serialize_value_type(&x, &mut data); + keyset_data.extend_from_slice(&data[..4]); + } + #[cfg(feature = "multicast")] + TableType::NatIngressIpv6Mcast => { + let mut buf = Vec::new(); + serialize_value_type(&x, &mut buf); + buf.reverse(); + keyset_data.extend_from_slice(&buf); + } + // Multicast egress tables: port => bit<16> + #[cfg(feature = "multicast")] + TableType::McastEgressDecapPorts + | TableType::PortMacAddressMcast => { + serialize_value_type(&x, &mut data); + keyset_data.extend_from_slice(&data[..2]); + } _ => { serialize_value_type(&x, &mut keyset_data); } @@ -663,6 +971,8 @@ fn keyset_data(match_data: Vec, table: TableType) -> Vec { // Longest prefix MatchEntryValue::Lpm(x) => { let mut data: Vec = Vec::new(); + #[allow(unused_mut)] + let mut handled = false; match table { TableType::RouteIdxIpv4 | TableType::AttachedSubnetIpv4 => { // prefix for longest prefix match operation @@ -670,19 +980,29 @@ fn keyset_data(match_data: Vec, table: TableType) -> Vec { serialize_value_type_be(&x.prefix, &mut data); keyset_data.extend_from_slice(&data[data.len() - 4..]); // prefix length for longest prefix match operation - keyset_data.push(x.len as u8) + keyset_data.push(x.len as u8); + handled = true; } - _ => { - serialize_value_type_be(&x.prefix, &mut keyset_data); + #[cfg(feature = "multicast")] + TableType::McastIpv4SrcFilter => { + // "src_addr" => bit<32> lpm + serialize_value_type_be(&x.prefix, &mut data); + keyset_data.extend_from_slice(&data[data.len() - 4..]); keyset_data.push(x.len as u8); + handled = true; } + _ => {} + } + if !handled { + serialize_value_type_be(&x.prefix, &mut keyset_data); + keyset_data.push(x.len as u8); } } // Ranges (i.e. port ranges) MatchEntryValue::Range(x) => { match table { TableType::NatIngressIpv4 | TableType::NatIngressIpv6 => { - // "l4_dst_port" => ingress.nat_id: range => bit<16> + // "l4_dst_port" => ingress.nat_id: range => bit<16> let low = &x.low.to_le_bytes(); let high = &x.high.to_le_bytes(); keyset_data.extend_from_slice(&low[..2]); @@ -701,6 +1021,7 @@ fn keyset_data(match_data: Vec, table: TableType) -> Vec { } } } + let _ = table_name; keyset_data } diff --git a/common/src/illumos.rs b/common/src/illumos.rs index 5eca9c2b..095663bf 100644 --- a/common/src/illumos.rs +++ b/common/src/illumos.rs @@ -2,7 +2,7 @@ // 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/ // -// Copyright 2025 Oxide Computer Company +// Copyright 2026 Oxide Computer Company //! Illumos-specific common modules and operations. diff --git a/packet/src/eth.rs b/packet/src/eth.rs index 0cff359a..4cbdca8d 100644 --- a/packet/src/eth.rs +++ b/packet/src/eth.rs @@ -2,7 +2,7 @@ // 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/ // -// Copyright 2025 Oxide Computer Company +// Copyright 2026 Oxide Computer Company use std::fmt; diff --git a/swadm/src/main.rs b/swadm/src/main.rs index b5fd1221..69274944 100644 --- a/swadm/src/main.rs +++ b/swadm/src/main.rs @@ -212,7 +212,7 @@ async fn build_info(client: &Client) -> anyhow::Result<()> { fn main() -> anyhow::Result<()> { oxide_tokio_rt::run_builder( - &mut oxide_tokio_rt::Builder::new_current_thread(), + oxide_tokio_rt::Builder::new_current_thread(), main_impl(), ) }