diff --git a/.github/buildomat/jobs/deploy.sh b/.github/buildomat/jobs/deploy.sh index 77fc9cbce4c..3585ab2778b 100755 --- a/.github/buildomat/jobs/deploy.sh +++ b/.github/buildomat/jobs/deploy.sh @@ -2,7 +2,7 @@ #: #: name = "helios / deploy" #: variety = "basic" -#: target = "lab-2.0-opte-0.38" +#: target = "lab-2.0-opte-0.39" #: output_rules = [ #: "%/var/svc/log/oxide-*.log*", #: "%/zone/oxz_*/root/var/svc/log/oxide-*.log*", diff --git a/Cargo.lock b/Cargo.lock index 0f7841aa212..60c4a6a7ee3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -759,7 +759,7 @@ dependencies = [ "bitflags 2.9.4", "cexpr", "clang-sys", - "itertools 0.10.5", + "itertools 0.12.1", "lazy_static", "lazycell", "log", @@ -1733,7 +1733,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -1742,7 +1742,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2499,7 +2499,7 @@ dependencies = [ [[package]] name = "ddm-admin-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/maghemite?rev=396bb3c570be65f4e8c73ea3243f4af6561a823a#396bb3c570be65f4e8c73ea3243f4af6561a823a" +source = "git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec#3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" dependencies = [ "oxnet", "progenitor 0.11.2", @@ -3483,7 +3483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4955,7 +4955,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.1", "system-configuration", "tokio", "tower-layer", @@ -5181,7 +5181,7 @@ dependencies = [ [[package]] name = "illumos-sys-hdrs" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" dependencies = [ "bitflags 2.9.4", ] @@ -5730,7 +5730,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5833,7 +5833,7 @@ dependencies = [ [[package]] name = "kstat-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" dependencies = [ "quote", "syn 2.0.114", @@ -6004,7 +6004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -6425,7 +6425,7 @@ dependencies = [ [[package]] name = "mg-admin-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/maghemite?rev=396bb3c570be65f4e8c73ea3243f4af6561a823a#396bb3c570be65f4e8c73ea3243f4af6561a823a" +source = "git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec#3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" dependencies = [ "chrono", "colored 3.0.0", @@ -9141,6 +9141,7 @@ dependencies = [ "ipnet", "ipnetwork", "itertools 0.10.5", + "itertools 0.12.1", "itertools 0.13.0", "lalrpop-util", "lazy_static", @@ -9228,7 +9229,7 @@ dependencies = [ "vergen", "vergen-lib", "winnow 0.6.26", - "winnow 0.7.13", + "winnow 0.7.14", "x509-cert", "zerocopy 0.7.35", "zerocopy 0.8.27", @@ -9361,7 +9362,7 @@ dependencies = [ [[package]] name = "opte" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" dependencies = [ "bitflags 2.9.4", "dyn-clone", @@ -9380,7 +9381,7 @@ dependencies = [ [[package]] name = "opte-api" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" dependencies = [ "illumos-sys-hdrs", "ingot", @@ -9393,7 +9394,7 @@ dependencies = [ [[package]] name = "opte-ioctl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" dependencies = [ "libc", "libnet", @@ -9495,7 +9496,7 @@ dependencies = [ [[package]] name = "oxide-vpc" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7#4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" +source = "git+https://github.com/oxidecomputer/opte?rev=e547d07b08c3f3d6c821c9eb7a958adcffce6e56#e547d07b08c3f3d6c821c9eb7a958adcffce6e56" dependencies = [ "cfg-if", "illumos-sys-hdrs", @@ -11520,7 +11521,7 @@ dependencies = [ [[package]] name = "rdb-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/maghemite?rev=396bb3c570be65f4e8c73ea3243f4af6561a823a#396bb3c570be65f4e8c73ea3243f4af6561a823a" +source = "git+https://github.com/oxidecomputer/maghemite?rev=3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec#3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" dependencies = [ "oxnet", "schemars 0.8.22", @@ -12117,7 +12118,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -13644,7 +13645,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.114", @@ -14289,7 +14290,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.3", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -14824,7 +14825,7 @@ dependencies = [ "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow 0.7.13", + "winnow 0.7.14", ] [[package]] @@ -14869,7 +14870,7 @@ dependencies = [ "serde_spanned 0.6.9", "toml_datetime 0.6.11", "toml_write", - "winnow 0.7.13", + "winnow 0.7.14", ] [[package]] @@ -14878,7 +14879,7 @@ version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ - "winnow 0.7.13", + "winnow 0.7.14", ] [[package]] @@ -16573,7 +16574,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -16937,9 +16938,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 91603943d06..ae285967bd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -569,8 +569,8 @@ ntp-admin-api = { path = "ntp-admin/api" } ntp-admin-client = { path = "clients/ntp-admin-client" } ntp-admin-types = { path = "ntp-admin/types" } ntp-admin-types-versions = { path = "ntp-admin/types/versions" } -mg-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "396bb3c570be65f4e8c73ea3243f4af6561a823a" } -ddm-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "396bb3c570be65f4e8c73ea3243f4af6561a823a" } +mg-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" } +ddm-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" } multimap = "0.10.1" nexus-auth = { path = "nexus/auth" } nexus-background-task-interface = { path = "nexus/background-task-interface" } @@ -629,7 +629,7 @@ omicron-workspace-hack = "0.1.0" omicron-zone-package = "0.12.2" oxide-client = { path = "clients/oxide-client" } oxide-tokio-rt = "0.1.2" -oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7", features = [ "api", "std" ] } +oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "e547d07b08c3f3d6c821c9eb7a958adcffce6e56", features = [ "api", "std" ] } oxlog = { path = "dev-tools/oxlog" } oxnet = "0.1.4" once_cell = "1.21.3" @@ -638,7 +638,7 @@ openapiv3 = "2.2.0" # must match samael's crate! openssl = "0.10" openssl-sys = "0.9" -opte-ioctl = { git = "https://github.com/oxidecomputer/opte", rev = "4bd8a40c0f5c05de7bb29b5f592f2dc99b4fd1d7" } +opte-ioctl = { git = "https://github.com/oxidecomputer/opte", rev = "e547d07b08c3f3d6c821c9eb7a958adcffce6e56" } oso = "0.27" owo-colors = "4.2.2" oximeter = { path = "oximeter/oximeter" } @@ -700,7 +700,7 @@ rats-corim = { git = "https://github.com/oxidecomputer/rats-corim.git", rev = "f raw-cpuid = { git = "https://github.com/oxidecomputer/rust-cpuid.git", rev = "a4cf01df76f35430ff5d39dc2fe470bcb953503b" } rayon = "1.10" rcgen = "0.12.1" -rdb-types = { git = "https://github.com/oxidecomputer/maghemite", rev = "396bb3c570be65f4e8c73ea3243f4af6561a823a" } +rdb-types = { git = "https://github.com/oxidecomputer/maghemite", rev = "3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" } reconfigurator-cli = { path = "dev-tools/reconfigurator-cli" } reedline = "0.40.0" ref-cast = "1.0" diff --git a/illumos-utils/src/opte/mod.rs b/illumos-utils/src/opte/mod.rs index c77b4632c90..e5a8c7058df 100644 --- a/illumos-utils/src/opte/mod.rs +++ b/illumos-utils/src/opte/mod.rs @@ -148,6 +148,18 @@ fn router_target_opte(target: &shared::RouterTarget) -> RouterTarget { } } +/// Configuration for a subnet attached to an instance's OPTE port. +#[derive(Clone, Copy, Debug)] +pub struct AttachedSubnet { + /// The IP subnet that's attached. + pub cidr: IpCidr, + /// True if this is an external subnet, and false if it's a VPC subnet. + /// + /// Traffic destined for external subnets do not undergo NAT in the same way + /// as VPC Subnets. + pub is_external: bool, +} + #[cfg(test)] mod tests { use super::Gateway; diff --git a/illumos-utils/src/opte/non_illumos.rs b/illumos-utils/src/opte/non_illumos.rs index 4b0204439c7..00b4e69a048 100644 --- a/illumos-utils/src/opte/non_illumos.rs +++ b/illumos-utils/src/opte/non_illumos.rs @@ -9,7 +9,6 @@ use omicron_common::api::internal::shared::NetworkInterfaceKind; use oxide_vpc::api::AddRouterEntryReq; use oxide_vpc::api::ClearVirt2PhysReq; use oxide_vpc::api::DelRouterEntryReq; -use oxide_vpc::api::DhcpCfg; use oxide_vpc::api::Direction; use oxide_vpc::api::DumpVirt2PhysResp; use oxide_vpc::api::IpCfg; @@ -192,7 +191,6 @@ impl Handle { &self, name: &str, cfg: VpcCfg, - _: DhcpCfg, _: bool, ) -> Result { let name = name.to_string(); diff --git a/illumos-utils/src/opte/port_manager.rs b/illumos-utils/src/opte/port_manager.rs index 08080cef320..c9f6b10b3d7 100644 --- a/illumos-utils/src/opte/port_manager.rs +++ b/illumos-utils/src/opte/port_manager.rs @@ -5,6 +5,7 @@ //! Manager for all OPTE ports on a Helios system use crate::dladm::OPTE_LINK_PREFIX; +use crate::opte::AttachedSubnet; use crate::opte::Error; use crate::opte::Gateway; use crate::opte::Handle; @@ -38,11 +39,12 @@ use omicron_common::api::internal::shared::RouterTarget as ApiRouterTarget; use omicron_common::api::internal::shared::RouterVersion; use omicron_common::api::internal::shared::VirtualNetworkInterfaceHost; use oxide_vpc::api::AddRouterEntryReq; +use oxide_vpc::api::AttachedSubnetConfig; use oxide_vpc::api::DelRouterEntryReq; use oxide_vpc::api::DhcpCfg; -use oxide_vpc::api::Direction; use oxide_vpc::api::ExternalIpCfg; use oxide_vpc::api::IpCfg; +use oxide_vpc::api::IpCidr; use oxide_vpc::api::Ipv4Cfg; use oxide_vpc::api::Ipv4Cidr; use oxide_vpc::api::Ipv6Cfg; @@ -52,6 +54,7 @@ use oxide_vpc::api::RouterClass; use oxide_vpc::api::SNat4Cfg; use oxide_vpc::api::SNat6Cfg; use oxide_vpc::api::SetExternalIpsReq; +use oxide_vpc::api::TransitIpConfig; use oxide_vpc::api::VpcCfg; use oxnet::IpNet; use oxnet::Ipv4Net; @@ -137,39 +140,53 @@ pub struct PortCreateParams<'a> { pub external_ips: &'a Option, pub firewall_rules: &'a [ResolvedVpcFirewallRule], pub dhcp_config: DhcpCfg, + pub attached_subnets: Vec, } impl<'a> TryFrom<&PortCreateParams<'a>> for IpCfg { type Error = Error; fn try_from(params: &PortCreateParams) -> Result { - omicron_to_opte_ip_config(¶ms.nic.ip_config, params.external_ips) + omicron_to_opte_ip_config( + ¶ms.nic.ip_config, + params.external_ips, + ¶ms.attached_subnets, + ) } } fn omicron_to_opte_ip_config( private_ips: &PrivateIpConfig, external_ips: &Option, + attached_subnets: &[AttachedSubnet], ) -> Result { let cfg = match (private_ips, external_ips) { // Private and public IPv4 configuration ( PrivateIpConfig::V4(private_v4), Some(ExternalIpConfig::V4(external_v4)), - ) => IpCfg::Ipv4(build_opte_ipv4_config(private_v4, Some(external_v4))), + ) => IpCfg::Ipv4(build_opte_ipv4_config( + private_v4, + Some(external_v4), + attached_subnets, + )), // Only private IPv4 configuration - (PrivateIpConfig::V4(private_v4), None) => { - IpCfg::Ipv4(build_opte_ipv4_config(private_v4, None)) - } + (PrivateIpConfig::V4(private_v4), None) => IpCfg::Ipv4( + build_opte_ipv4_config(private_v4, None, attached_subnets), + ), // Private and public IPv6 configuration ( PrivateIpConfig::V6(private_v6), Some(ExternalIpConfig::V6(external_v6)), - ) => IpCfg::Ipv6(build_opte_ipv6_config(private_v6, Some(external_v6))), + ) => IpCfg::Ipv6(build_opte_ipv6_config( + private_v6, + Some(external_v6), + attached_subnets, + )), // Only private IPv6 configuration - (PrivateIpConfig::V6(private_v6), None) => { - IpCfg::Ipv6(build_opte_ipv6_config(private_v6, None)) - } + (PrivateIpConfig::V6(private_v6), None) => IpCfg::Ipv6( + build_opte_ipv6_config(private_v6, None, attached_subnets), + ), // Private and public dual-stack configuration ( PrivateIpConfig::DualStack { v4: private_v4, v6: private_v6 }, @@ -178,8 +195,16 @@ fn omicron_to_opte_ip_config( v6: external_v6, }), ) => { - let ipv4 = build_opte_ipv4_config(private_v4, Some(external_v4)); - let ipv6 = build_opte_ipv6_config(private_v6, Some(external_v6)); + let ipv4 = build_opte_ipv4_config( + private_v4, + Some(external_v4), + attached_subnets, + ); + let ipv6 = build_opte_ipv6_config( + private_v6, + Some(external_v6), + attached_subnets, + ); IpCfg::DualStack { ipv4, ipv6 } } // Only private dual-stack configuration. @@ -187,8 +212,10 @@ fn omicron_to_opte_ip_config( PrivateIpConfig::DualStack { v4: private_v4, v6: private_v6 }, None, ) => { - let ipv4 = build_opte_ipv4_config(private_v4, None); - let ipv6 = build_opte_ipv6_config(private_v6, None); + let ipv4 = + build_opte_ipv4_config(private_v4, None, attached_subnets); + let ipv6 = + build_opte_ipv6_config(private_v6, None, attached_subnets); IpCfg::DualStack { ipv4, ipv6 } } // Private dual-stack, public IPv4 configuration. @@ -196,8 +223,13 @@ fn omicron_to_opte_ip_config( PrivateIpConfig::DualStack { v4: private_v4, v6: private_v6 }, Some(ExternalIpConfig::V4(external_v4)), ) => { - let ipv4 = build_opte_ipv4_config(private_v4, Some(external_v4)); - let ipv6 = build_opte_ipv6_config(private_v6, None); + let ipv4 = build_opte_ipv4_config( + private_v4, + Some(external_v4), + attached_subnets, + ); + let ipv6 = + build_opte_ipv6_config(private_v6, None, attached_subnets); IpCfg::DualStack { ipv4, ipv6 } } // Private dual-stack, public IPv6 configuration. @@ -205,8 +237,13 @@ fn omicron_to_opte_ip_config( PrivateIpConfig::DualStack { v4: private_v4, v6: private_v6 }, Some(ExternalIpConfig::V6(external_v6)), ) => { - let ipv4 = build_opte_ipv4_config(private_v4, None); - let ipv6 = build_opte_ipv6_config(private_v6, Some(external_v6)); + let ipv4 = + build_opte_ipv4_config(private_v4, None, attached_subnets); + let ipv6 = build_opte_ipv6_config( + private_v6, + Some(external_v6), + attached_subnets, + ); IpCfg::DualStack { ipv4, ipv6 } } // Cannot have external config of a different version, either @@ -225,23 +262,79 @@ fn omicron_to_opte_ip_config( fn build_opte_ipv4_config( private_v4: &PrivateIpv4Config, external_v4: Option<&ExternalIpv4Config>, + attached_subnets: &[AttachedSubnet], ) -> Ipv4Cfg { let gateway_ip = private_v4.opte_gateway().into(); let vpc_subnet = Ipv4Cidr::from(Ipv4Network::from(*private_v4.subnet())); let private_ip = (*private_v4.ip()).into(); let external_ips = build_external_ipv4_config(external_v4); - Ipv4Cfg { vpc_subnet, private_ip, gateway_ip, external_ips } + let transit_ips = private_v4 + .transit_ips + .iter() + .map(|ip| { + let cidr = + Ipv4Cidr::new(ip.addr().into(), ip.width().try_into().unwrap()); + let cfg = TransitIpConfig { allow_in: true, allow_out: true }; + (cidr, cfg) + }) + .collect(); + let attached_subnets = attached_subnets + .iter() + .filter_map(|subnet| match subnet.cidr { + IpCidr::Ip4(ipv4) => Some(( + ipv4, + AttachedSubnetConfig { is_external: subnet.is_external }, + )), + IpCidr::Ip6(_) => None, + }) + .collect(); + Ipv4Cfg { + vpc_subnet, + private_ip, + gateway_ip, + external_ips, + attached_subnets, + transit_ips, + } } fn build_opte_ipv6_config( private_v6: &PrivateIpv6Config, external_v6: Option<&ExternalIpv6Config>, + attached_subnets: &[AttachedSubnet], ) -> Ipv6Cfg { let gateway_ip = private_v6.opte_gateway().into(); let vpc_subnet = Ipv6Cidr::from(Ipv6Network::from(*private_v6.subnet())); let private_ip = (*private_v6.ip()).into(); let external_ips = build_external_ipv6_config(external_v6); - Ipv6Cfg { vpc_subnet, private_ip, gateway_ip, external_ips } + let transit_ips = private_v6 + .transit_ips + .iter() + .map(|ip| { + let cidr = + Ipv6Cidr::new(ip.addr().into(), ip.width().try_into().unwrap()); + let cfg = TransitIpConfig { allow_in: true, allow_out: true }; + (cidr, cfg) + }) + .collect(); + let attached_subnets = attached_subnets + .iter() + .filter_map(|subnet| match subnet.cidr { + IpCidr::Ip4(_) => None, + IpCidr::Ip6(ipv6) => Some(( + ipv6, + AttachedSubnetConfig { is_external: subnet.is_external }, + )), + }) + .collect(); + Ipv6Cfg { + vpc_subnet, + private_ip, + gateway_ip, + external_ips, + attached_subnets, + transit_ips, + } } // Build an ExternalIpCfg from parameters. @@ -317,8 +410,13 @@ impl PortManager { params: PortCreateParams, ) -> Result<(Port, PortTicket), Error> { let ip_cfg = IpCfg::try_from(¶ms)?; - let PortCreateParams { nic, external_ips, firewall_rules, dhcp_config } = - params; + let PortCreateParams { + nic, + external_ips, + firewall_rules, + dhcp_config, + attached_subnets: _, + } = params; let is_service = matches!(nic.kind, NetworkInterfaceKind::Service { .. }); let is_instance = @@ -332,6 +430,7 @@ impl PortManager { gateway_mac: MacAddr::from(gateway.mac.into_array()), vni, phys_ip: self.inner.underlay_ip.into(), + dhcp: dhcp_config, }; // Create the xde device. @@ -353,16 +452,10 @@ impl PortManager { "Creating xde device"; "port_name" => &port_name, "vpc_cfg" => ?&vpc_cfg, - "dhcp_config" => ?&dhcp_config, ); let hdl = { let hdl = Handle::new()?; - hdl.create_xde( - &port_name, - vpc_cfg, - dhcp_config, - /* passthru = */ false, - )?; + hdl.create_xde(&port_name, vpc_cfg, /* passthru = */ false)?; hdl }; let (port, ticket) = { @@ -497,36 +590,6 @@ impl PortManager { } drop(route_map); - // If there are any transit IPs set, allow them through. - // TODO: Currently set only in initial state. - // This, external IPs, and cfg'able state - // (DHCP?) are probably worth being managed by an RPW. - for block in nic.ip_config.all_transit_ips() { - // In principle if this were an operation on an existing - // port, we would explicitly undo the In addition if the - // Out addition fails. - // However, failure here will just destroy the port - // outright -- this should only happen if an excessive - // number of rules are specified. - hdl.allow_cidr( - &port_name, - super::net_to_cidr(block), - Direction::In, - )?; - hdl.allow_cidr( - &port_name, - super::net_to_cidr(block), - Direction::Out, - )?; - - debug!( - self.inner.log, - "Added CIDR to in/out allowlist"; - "port_name" => &port_name, - "cidr" => ?block, - ); - } - info!( self.inner.log, "Created OPTE port"; @@ -1138,6 +1201,7 @@ mod tests { dns4_servers: Vec::new(), dns6_servers: Vec::new(), }, + attached_subnets: vec![], }) .unwrap(); @@ -1316,6 +1380,7 @@ mod tests { dns4_servers: Vec::new(), dns6_servers: Vec::new(), }, + attached_subnets: vec![], }) .unwrap(); @@ -1486,6 +1551,7 @@ mod tests { dns4_servers: vec![], dns6_servers: vec![], }, + attached_subnets: vec![], }; let IpCfg::Ipv4(oxide_vpc::api::Ipv4Cfg { vpc_subnet, @@ -1493,6 +1559,8 @@ mod tests { gateway_ip, external_ips: oxide_vpc::api::ExternalIpCfg { snat, ephemeral_ip, floating_ips }, + attached_subnets, + transit_ips, }) = IpCfg::try_from(&prs).unwrap() else { panic!("Expected IPv4 config") @@ -1513,6 +1581,8 @@ mod tests { assert_eq!(ports, source_nat.port_range()); assert!(ephemeral_ip.is_none()); assert!(floating_ips.is_empty()); + assert!(attached_subnets.is_empty()); + assert!(transit_ips.is_empty()); } #[test] @@ -1554,6 +1624,7 @@ mod tests { dns4_servers: vec![], dns6_servers: vec![], }, + attached_subnets: vec![], }; let IpCfg::Ipv6(oxide_vpc::api::Ipv6Cfg { vpc_subnet, @@ -1561,6 +1632,8 @@ mod tests { gateway_ip, external_ips: oxide_vpc::api::ExternalIpCfg { snat, ephemeral_ip, floating_ips }, + attached_subnets: _, + transit_ips: _, }) = IpCfg::try_from(&prs).unwrap() else { panic!("Expected IPv4 config") @@ -1637,6 +1710,7 @@ mod tests { dns4_servers: vec![], dns6_servers: vec![], }, + attached_subnets: vec![], }; let IpCfg::DualStack { ipv4, ipv6 } = IpCfg::try_from(&prs).unwrap() else { @@ -1726,6 +1800,7 @@ mod tests { dns4_servers: vec![], dns6_servers: vec![], }, + attached_subnets: vec![], }; let _ = IpCfg::try_from(&prs).expect_err( "Should fail to convert with public IPv6 and private IPv4", @@ -1771,6 +1846,7 @@ mod tests { dns4_servers: vec![], dns6_servers: vec![], }, + attached_subnets: vec![], }; let _ = IpCfg::try_from(&prs).expect_err( "Should fail to convert with public IPv4 and private IPv6", diff --git a/package-manifest.toml b/package-manifest.toml index d667602795b..752363cb463 100644 --- a/package-manifest.toml +++ b/package-manifest.toml @@ -666,10 +666,10 @@ source.repo = "maghemite" # `tools/maghemite_openapi_version`. Failing to do so will cause a failure when # building `ddm-admin-client` (which will instruct you to update # `tools/maghemite_openapi_version`). -source.commit = "396bb3c570be65f4e8c73ea3243f4af6561a823a" +source.commit = "3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mg-ddm-gz.sha256.txt -source.sha256 = "784b738359699dfbb5f1b5ebb36f4e03ff4b121301d39854130a7c1d72670acf" +source.sha256 = "0ad7e7e3ad812f430889aba47d40f92b848dc88f19bd929fee611e5620effacf" output.type = "tarball" [package.mg-ddm] @@ -682,10 +682,10 @@ source.repo = "maghemite" # `tools/maghemite_openapi_version`. Failing to do so will cause a failure when # building `ddm-admin-client` (which will instruct you to update # `tools/maghemite_openapi_version`). -source.commit = "396bb3c570be65f4e8c73ea3243f4af6561a823a" +source.commit = "3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mg-ddm.sha256.txt -source.sha256 = "7cda5160f15e6cdded8d0cae546a8d6ee3147aa3becc0f754821b08dbc252770" +source.sha256 = "52cf8c07f187f2d72fec47ab67457b20da901827979bcf68d78dc1ef64f6068b" output.type = "zone" output.intermediate_only = true @@ -697,10 +697,10 @@ source.repo = "maghemite" # `tools/maghemite_openapi_version`. Failing to do so will cause a failure when # building `ddm-admin-client` (which will instruct you to update # `tools/maghemite_openapi_version`). -source.commit = "396bb3c570be65f4e8c73ea3243f4af6561a823a" +source.commit = "3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mgd.sha256.txt -source.sha256 = "404f968561f0021b395aa569c7e1e7bd6f4f2c2cdcbcfd4930665e9460a642aa" +source.sha256 = "424f32ff16fd7aa17c79feeab4b6cae23df713ce57722dd619c468347d37c55b" output.type = "zone" output.intermediate_only = true @@ -748,8 +748,8 @@ only_for_targets.image = "standard" # the other `source.*` keys. source.type = "prebuilt" source.repo = "dendrite" -source.commit = "7a66c1b2415122b821611fd51012032a03e14ada" -source.sha256 = "fd4edbbe2eb3050254198bf146c7e53e85cf52fdaa34ea827e1b1fe9e46dd982" +source.commit = "9f6b8f71c2b626e21dc03ea686abda3846dc44c2" +source.sha256 = "0d72f00a5b8cbe583b495d5875c9afe5ebf625d3634746b0b685d0ca139ce73c" output.type = "zone" output.intermediate_only = true diff --git a/sled-agent/src/instance.rs b/sled-agent/src/instance.rs index 9d66eb3be53..2227ce03780 100644 --- a/sled-agent/src/instance.rs +++ b/sled-agent/src/instance.rs @@ -2161,6 +2161,9 @@ impl InstanceRunner { external_ips: &self.external_ips, firewall_rules: &self.firewall_rules, dhcp_config: self.dhcp_config.clone(), + // TODO Accept these in the sled-agent API. See + // https://github.com/oxidecomputer/omicron/issues/9702. + attached_subnets: vec![], })?; opte_port_names.push(port.0.name().to_string()); opte_ports.push(port); diff --git a/sled-agent/src/probe_manager.rs b/sled-agent/src/probe_manager.rs index a4699ae2cbb..af54de782e9 100644 --- a/sled-agent/src/probe_manager.rs +++ b/sled-agent/src/probe_manager.rs @@ -374,6 +374,10 @@ impl ProbeManagerInner { priority: VpcFirewallRulePriority(100), }], dhcp_config: DhcpCfg::default(), + // TODO-completeness: Attached subnets are meant only for instances, + // but probes are supposed to mimic instances as closely as + // possible. We should consider if we want to support them here. + attached_subnets: vec![], })?; let installed_zone = ZoneBuilderFactory::new() diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 395dc6dd0dd..e968438116e 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -1210,6 +1210,8 @@ impl ServiceManager { external_ips: &external_ips, firewall_rules: &[], dhcp_config: DhcpCfg::default(), + // Services do not use attached subnets, only instances. + attached_subnets: vec![], }) .map_err(|err| Error::ServicePortCreation { service: zone_kind, diff --git a/tools/maghemite_ddm_openapi_version b/tools/maghemite_ddm_openapi_version index 0e346102b17..a7caa979859 100644 --- a/tools/maghemite_ddm_openapi_version +++ b/tools/maghemite_ddm_openapi_version @@ -1 +1 @@ -COMMIT="396bb3c570be65f4e8c73ea3243f4af6561a823a" +COMMIT="3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" diff --git a/tools/maghemite_mg_openapi_version b/tools/maghemite_mg_openapi_version index 0e346102b17..a7caa979859 100644 --- a/tools/maghemite_mg_openapi_version +++ b/tools/maghemite_mg_openapi_version @@ -1 +1 @@ -COMMIT="396bb3c570be65f4e8c73ea3243f4af6561a823a" +COMMIT="3abfb8eb7f6d4ca4658981b4a7a76759a0a3f8ec" diff --git a/tools/maghemite_mgd_checksums b/tools/maghemite_mgd_checksums index 2cca63e3cef..d50248bfa4f 100644 --- a/tools/maghemite_mgd_checksums +++ b/tools/maghemite_mgd_checksums @@ -1,2 +1,2 @@ -CIDL_SHA256="404f968561f0021b395aa569c7e1e7bd6f4f2c2cdcbcfd4930665e9460a642aa" -MGD_LINUX_SHA256="195684b07ebc5f6fe31568d7cae7bb8cd08e29049cbda1eca5cb4c8184a38826" \ No newline at end of file +CIDL_SHA256="424f32ff16fd7aa17c79feeab4b6cae23df713ce57722dd619c468347d37c55b" +MGD_LINUX_SHA256="363f6c0a45a3eeee661c9b99908a2b53230870f1ab47cdca34dc8f4899b707c2" \ No newline at end of file diff --git a/tools/opte_version b/tools/opte_version index 8fb249b5ac8..1742d1585d6 100644 --- a/tools/opte_version +++ b/tools/opte_version @@ -1 +1 @@ -0.38.452 +0.39.455 diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index 02ec30c3cf6..4986d3e371c 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -150,7 +150,7 @@ usdt = { version = "0.6.0" } usdt-impl-3b31131e45eafb45 = { package = "usdt-impl", version = "0.6.0", default-features = false, features = ["des"] } usdt-impl-d8f496e17d97b5cb = { package = "usdt-impl", version = "0.5.0", default-features = false, features = ["asm", "des"] } uuid = { version = "1.19.0", features = ["serde", "v4"] } -winnow-ca01ad9e24f5d932 = { package = "winnow", version = "0.7.13" } +winnow-ca01ad9e24f5d932 = { package = "winnow", version = "0.7.14" } x509-cert = { version = "0.2.5" } zerocopy-c38e5c1d305a1b54 = { package = "zerocopy", version = "0.8.27", default-features = false, features = ["derive", "simd"] } zeroize = { version = "1.8.1", features = ["std", "zeroize_derive"] } @@ -297,7 +297,7 @@ usdt-impl-d8f496e17d97b5cb = { package = "usdt-impl", version = "0.5.0", default uuid = { version = "1.19.0", features = ["serde", "v4"] } vergen = { version = "9.0.6", features = ["cargo", "rustc"] } vergen-lib = { version = "0.1.6", features = ["cargo", "git", "rustc"] } -winnow-ca01ad9e24f5d932 = { package = "winnow", version = "0.7.13" } +winnow-ca01ad9e24f5d932 = { package = "winnow", version = "0.7.14" } x509-cert = { version = "0.2.5" } zerocopy-c38e5c1d305a1b54 = { package = "zerocopy", version = "0.8.27", default-features = false, features = ["derive", "simd"] } zeroize = { version = "1.8.1", features = ["std", "zeroize_derive"] } @@ -386,6 +386,7 @@ dof-9fbad63c4bcf4a8f = { package = "dof", version = "0.4.0", default-features = getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.4", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.7", features = ["http2", "ring", "webpki-tokio"] } hyper-util = { version = "0.1.19", features = ["full"] } +itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10.5" } miniz_oxide = { version = "0.8.5", default-features = false, features = ["with-alloc"] } mio = { version = "1.0.2", features = ["net", "os-ext"] } @@ -405,6 +406,7 @@ dof-9fbad63c4bcf4a8f = { package = "dof", version = "0.4.0", default-features = getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.4", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.7", features = ["http2", "ring", "webpki-tokio"] } hyper-util = { version = "0.1.19", features = ["full"] } +itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10.5" } miniz_oxide = { version = "0.8.5", default-features = false, features = ["with-alloc"] } mio = { version = "1.0.2", features = ["net", "os-ext"] }