From a9e6abc23718fa20ee5b6dd9da373213f56cb932 Mon Sep 17 00:00:00 2001 From: Nils Nieuwejaar Date: Wed, 15 May 2024 02:48:30 +0000 Subject: [PATCH 1/4] Add vlan support to uplink configuration --- .github/buildomat/jobs/a4x2-deploy.sh | 2 +- .github/buildomat/jobs/a4x2-prepare.sh | 2 +- .github/buildomat/jobs/deploy.sh | 2 +- clients/sled-agent-client/src/lib.rs | 1 + common/src/api/external/mod.rs | 3 + common/src/api/internal/shared.rs | 84 +++++++++++++++++-- dev-tools/xtask/src/virtual_hardware.rs | 2 +- docs/how-to-run.adoc | 2 +- nexus/db-model/src/schema.rs | 1 + nexus/db-model/src/switch_port.rs | 4 + .../src/db/datastore/switch_port.rs | 1 + .../background/sync_switch_configuration.rs | 12 ++- nexus/src/app/rack.rs | 5 +- nexus/tests/integration_tests/switch_port.rs | 1 + nexus/types/src/external_api/params.rs | 3 + openapi/bootstrap-agent.json | 23 ++++- openapi/nexus-internal.json | 23 ++++- openapi/nexus.json | 14 ++++ openapi/sled-agent.json | 27 +++++- openapi/wicketd.json | 21 ++++- package-manifest.toml | 24 +++--- schema/rss-sled-plan.json | 25 +++++- sled-agent/src/bootstrap/early_networking.rs | 6 +- sled-agent/src/rack_setup/service.rs | 11 ++- sled-agent/src/services.rs | 2 + sled-agent/tests/data/early_network_blobs.txt | 4 +- .../madrid-rss-sled-plan.json | 2 +- .../madrid-rss-sled-plan.json | 10 ++- .../gimlet-standalone/config-rss.toml | 2 +- smf/sled-agent/non-gimlet/config-rss.toml | 2 +- tools/dendrite_openapi_version | 4 +- tools/dendrite_stub_checksums | 6 +- wicket-common/src/rack_setup.rs | 4 +- wicket/src/cli/rack_setup/config_toml.rs | 9 +- wicket/tests/output/example_non_empty.toml | 4 +- wicketd/src/rss_config.rs | 10 ++- 36 files changed, 299 insertions(+), 59 deletions(-) diff --git a/.github/buildomat/jobs/a4x2-deploy.sh b/.github/buildomat/jobs/a4x2-deploy.sh index 8f0f24c8d16..dfc9191611b 100755 --- a/.github/buildomat/jobs/a4x2-deploy.sh +++ b/.github/buildomat/jobs/a4x2-deploy.sh @@ -13,7 +13,7 @@ #: "%/out/dhcp-server.log", #: ] #: skip_clone = true -#: enable = false +#: enable = true #: #: [dependencies.a4x2] #: job = "a4x2-prepare" diff --git a/.github/buildomat/jobs/a4x2-prepare.sh b/.github/buildomat/jobs/a4x2-prepare.sh index bc88ddd4c04..79fa037139f 100755 --- a/.github/buildomat/jobs/a4x2-prepare.sh +++ b/.github/buildomat/jobs/a4x2-prepare.sh @@ -20,7 +20,7 @@ #: access_repos = [ #: "oxidecomputer/testbed", #: ] -#: enable = false +#: enable = true source ./env.sh diff --git a/.github/buildomat/jobs/deploy.sh b/.github/buildomat/jobs/deploy.sh index 8d3e94cd5ec..3a9f166012c 100755 --- a/.github/buildomat/jobs/deploy.sh +++ b/.github/buildomat/jobs/deploy.sh @@ -246,7 +246,7 @@ infra_ip_last = \"$UPLINK_IP\" /^routes/c\\ routes = \\[{nexthop = \"$GATEWAY_IP\", destination = \"0.0.0.0/0\"}\\] /^addresses/c\\ -addresses = \\[\"$UPLINK_IP/24\"\\] +addresses = \\[{address = \"$UPLINK_IP/24\"} \\] } " pkg/config-rss.toml diff -u pkg/config-rss.toml{~,} || true diff --git a/clients/sled-agent-client/src/lib.rs b/clients/sled-agent-client/src/lib.rs index bfb97ec9cd9..2878ccf1da0 100644 --- a/clients/sled-agent-client/src/lib.rs +++ b/clients/sled-agent-client/src/lib.rs @@ -34,6 +34,7 @@ progenitor::generate_api!( BgpPeerConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, PortConfigV1 = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, RouteConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, + UplinkAddressConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, IpNet = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, }, //TODO trade the manual transformations later in this file for the diff --git a/common/src/api/external/mod.rs b/common/src/api/external/mod.rs index 9d55522af8e..4c4819b2ff1 100644 --- a/common/src/api/external/mod.rs +++ b/common/src/api/external/mod.rs @@ -2897,6 +2897,9 @@ pub struct SwitchPortAddressConfig { /// The IP address and prefix. pub address: IpNet, + /// An optional VLAN ID + pub vlan_id: Option, + /// The interface name this address belongs to. // TODO: https://github.com/oxidecomputer/omicron/issues/3050 // Use `Name` instead of `String` for `interface_name` type diff --git a/common/src/api/internal/shared.rs b/common/src/api/internal/shared.rs index 6bd40d3ff0a..3b5b5878f96 100644 --- a/common/src/api/internal/shared.rs +++ b/common/src/api/internal/shared.rs @@ -299,12 +299,81 @@ pub struct RouteConfig { pub vlan_id: Option, } +#[derive( + Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema, Hash, +)] +pub struct UplinkAddressConfig { + pub address: IpNetwork, + /// The VLAN id associated with this route. + #[serde(default)] + pub vlan_id: Option, +} + +impl UplinkAddressConfig { + pub fn ip(&self) -> IpAddr { + self.address.ip() + } +} + +impl std::fmt::Display for UplinkAddressConfig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.vlan_id { + None => write!(f, "{}", self.address), + Some(v) => write!(f, "{};{}", self.address, v), + } + } +} + +#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct UplinkAddressConfigError(String); + +impl std::fmt::Display for UplinkAddressConfigError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "parse switch location error: {}", self.0) + } +} + +/// Convert a string into an UplinkAddressConfig. +/// 192.168.1.1/24 => UplinkAddressConfig { 192.168.1.1/24, None } +/// 192.168.1.1/24;200 => UplinkAddressConfig { 192.168.1.1/24, Some(200) } +impl FromStr for UplinkAddressConfig { + type Err = UplinkAddressConfigError; + + fn from_str(s: &str) -> Result { + let fields: Vec<&str> = s.split(';').collect(); + let (address, vlan_id) = match fields.len() { + 1 => Ok((fields[0], None)), + 2 => Ok((fields[0], Some(fields[1]))), + _ => Err(UplinkAddressConfigError(format!( + "not a valid uplink address: {s}" + ))), + }?; + let address = address.parse().map_err(|_| { + UplinkAddressConfigError(format!( + "not a valid ip address: {address}" + )) + })?; + let vlan_id = match vlan_id { + None => Ok(None), + Some(v) => match v.parse() { + Err(_) => Err(format!("invalid vlan id: {v}")), + Ok(vlan_id) if vlan_id > 1 && vlan_id < 4096 => { + Ok(Some(vlan_id)) + } + Ok(vlan_id) => Err(format!("vlan id out of range: {vlan_id}")), + }, + } + .map_err(|e| UplinkAddressConfigError(e))?; + Ok(UplinkAddressConfig { address, vlan_id }) + } +} + #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct PortConfigV1 { /// The set of routes associated with this port. pub routes: Vec, - /// This port's addresses. - pub addresses: Vec, + /// This port's addresses and optional vlan IDs + pub addresses: Vec, /// Switch the port belongs to. pub switch: SwitchLocation, /// Nmae of the port this config applies to. @@ -326,9 +395,12 @@ impl From for PortConfigV1 { routes: vec![RouteConfig { destination: "0.0.0.0/0".parse().unwrap(), nexthop: value.gateway_ip.into(), - vlan_id: None, + vlan_id: value.uplink_vid, + }], + addresses: vec![UplinkAddressConfig { + address: value.uplink_cidr.into(), + vlan_id: value.uplink_vid, }], - addresses: vec![value.uplink_cidr.into()], switch: value.switch, port: value.uplink_port, uplink_port_speed: value.uplink_port_speed, @@ -372,8 +444,8 @@ pub struct HostPortConfig { pub port: String, /// IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport - /// (must be in infra_ip pool) - pub addrs: Vec, + /// (must be in infra_ip pool). May also include an optional VLAN ID. + pub addrs: Vec, } impl From for HostPortConfig { diff --git a/dev-tools/xtask/src/virtual_hardware.rs b/dev-tools/xtask/src/virtual_hardware.rs index d013ff6505e..c540056d368 100644 --- a/dev-tools/xtask/src/virtual_hardware.rs +++ b/dev-tools/xtask/src/virtual_hardware.rs @@ -113,7 +113,7 @@ const ZPOOL: &'static str = "/usr/sbin/zpool"; const ZONEADM: &'static str = "/usr/sbin/zoneadm"; const SIDECAR_LITE_COMMIT: &'static str = - "960f11afe859e0316088e04578aedb700fba6159"; + "25a024af758371b5bfb655e58f4b7bb3e6968d7b"; const SOFTNPU_COMMIT: &'static str = "3203c51cf4473d30991b522062ac0df2e045c2f2"; const PXA_MAC_DEFAULT: &'static str = "a8:e1:de:01:70:1d"; diff --git a/docs/how-to-run.adoc b/docs/how-to-run.adoc index c904dca757b..2d8dd4ad123 100644 --- a/docs/how-to-run.adoc +++ b/docs/how-to-run.adoc @@ -292,7 +292,7 @@ routes = [{nexthop = "192.168.1.199", destination = "0.0.0.0/0"}] # Addresses associated with this port. # For softnpu, an address within the "infra" block above that will be used for # the softnpu uplink port. You can just pick the first address in that pool. -addresses = ["192.168.1.30/24"] +addresses = [{address = "192.168.1.30/24"}] # Name of the uplink port. This should always be "qsfp0" when using softnpu. port = "qsfp0" # The speed of this port. diff --git a/nexus/db-model/src/schema.rs b/nexus/db-model/src/schema.rs index 3d16b978f62..31da85e57ad 100644 --- a/nexus/db-model/src/schema.rs +++ b/nexus/db-model/src/schema.rs @@ -311,6 +311,7 @@ table! { rsvd_address_lot_block_id -> Uuid, address -> Inet, interface_name -> Text, + vlan_id -> Nullable, } } diff --git a/nexus/db-model/src/switch_port.rs b/nexus/db-model/src/switch_port.rs index b10f6ba6793..48afd7b52ae 100644 --- a/nexus/db-model/src/switch_port.rs +++ b/nexus/db-model/src/switch_port.rs @@ -722,6 +722,7 @@ pub struct SwitchPortAddressConfig { pub rsvd_address_lot_block_id: Uuid, pub address: IpNetwork, pub interface_name: String, + pub vlan_id: Option, } impl SwitchPortAddressConfig { @@ -731,6 +732,7 @@ impl SwitchPortAddressConfig { rsvd_address_lot_block_id: Uuid, address: IpNetwork, interface_name: String, + vlan_id: Option, ) -> Self { Self { port_settings_id, @@ -738,6 +740,7 @@ impl SwitchPortAddressConfig { rsvd_address_lot_block_id, address, interface_name, + vlan_id: vlan_id.map(|x| x.into()), } } } @@ -749,6 +752,7 @@ impl Into for SwitchPortAddressConfig { address_lot_block_id: self.address_lot_block_id, address: self.address.into(), interface_name: self.interface_name, + vlan_id: self.vlan_id.map(|x| x.into()), } } } diff --git a/nexus/db-queries/src/db/datastore/switch_port.rs b/nexus/db-queries/src/db/datastore/switch_port.rs index 3f3717a9c49..fc7dc8e68e0 100644 --- a/nexus/db-queries/src/db/datastore/switch_port.rs +++ b/nexus/db-queries/src/db/datastore/switch_port.rs @@ -549,6 +549,7 @@ impl DataStore { rsvd_block.id, address.address.into(), interface_name.clone(), + address.vlan_id )); } diff --git a/nexus/src/app/background/sync_switch_configuration.rs b/nexus/src/app/background/sync_switch_configuration.rs index dc7aa745760..cd8bdd9f866 100644 --- a/nexus/src/app/background/sync_switch_configuration.rs +++ b/nexus/src/app/background/sync_switch_configuration.rs @@ -52,6 +52,7 @@ use sled_agent_client::types::{ BgpConfig as SledBgpConfig, BgpPeerConfig as SledBgpPeerConfig, EarlyNetworkConfig, EarlyNetworkConfigBody, HostPortConfig, Ipv4Network, PortConfigV1, RackNetworkConfigV1, RouteConfig as SledRouteConfig, + UplinkAddressConfig, }; use std::{ collections::{hash_map::Entry, HashMap, HashSet}, @@ -922,7 +923,7 @@ impl BackgroundTask for SwitchPortSettingsManager { }; let mut port_config = PortConfigV1 { - addresses: info.addresses.iter().map(|a| a.address).collect(), + addresses: info.addresses.iter().map(|a| UplinkAddressConfig {address: a.address, vlan_id: a.vlan_id.map(|v| v.into())}).collect(), autoneg: info .links .get(0) //TODO breakout support @@ -1400,7 +1401,14 @@ fn uplinks( }; let config = HostPortConfig { port: port.port_name.clone(), - addrs: config.addresses.iter().map(|a| a.address).collect(), + addrs: config + .addresses + .iter() + .map(|a| UplinkAddressConfig { + address: a.address, + vlan_id: a.vlan_id.map(|v| v.into()), + }) + .collect(), }; match uplinks.entry(*location) { diff --git a/nexus/src/app/rack.rs b/nexus/src/app/rack.rs index 25c0824ce64..22923d75684 100644 --- a/nexus/src/app/rack.rs +++ b/nexus/src/app/rack.rs @@ -523,7 +523,8 @@ impl super::Nexus { .iter() .map(|a| Address { address_lot: NameOrId::Name(address_lot_name.clone()), - address: (*a).into(), + address: a.address.into(), + vlan_id: a.vlan_id, }) .collect(); @@ -537,7 +538,7 @@ impl super::Nexus { .map(|r| Route { dst: r.destination.into(), gw: r.nexthop, - vid: None, + vid: r.vlan_id, }) .collect(); diff --git a/nexus/tests/integration_tests/switch_port.rs b/nexus/tests/integration_tests/switch_port.rs index 41542d85547..0b71ddb2cfe 100644 --- a/nexus/tests/integration_tests/switch_port.rs +++ b/nexus/tests/integration_tests/switch_port.rs @@ -149,6 +149,7 @@ async fn test_port_settings_basic_crud(ctx: &ControlPlaneTestContext) { AddressConfig { addresses: vec![Address { address: "203.0.113.10/24".parse().unwrap(), + vlan_id: None, address_lot: NameOrId::Name("parkinglot".parse().unwrap()), }], }, diff --git a/nexus/types/src/external_api/params.rs b/nexus/types/src/external_api/params.rs index 1b252c77cb5..29861a7db9c 100644 --- a/nexus/types/src/external_api/params.rs +++ b/nexus/types/src/external_api/params.rs @@ -1752,6 +1752,9 @@ pub struct Address { /// The address and prefix length of this address. pub address: IpNet, + + /// Optional VLAN ID for this address + pub vlan_id: Option, } /// Select a port settings object by an optional name or id. diff --git a/openapi/bootstrap-agent.json b/openapi/bootstrap-agent.json index 6ac9c034e2d..c90c32ce22b 100644 --- a/openapi/bootstrap-agent.json +++ b/openapi/bootstrap-agent.json @@ -765,10 +765,10 @@ "type": "object", "properties": { "addresses": { - "description": "This port's addresses.", + "description": "This port's addresses and optional vlan IDs", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/UplinkAddressConfig" } }, "autoneg": { @@ -1250,6 +1250,25 @@ } ] }, + "UplinkAddressConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/IpNetwork" + }, + "vlan_id": { + "nullable": true, + "description": "The VLAN id associated with this route.", + "default": null, + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "address" + ] + }, "UserId": { "description": "Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'. Names cannot be a UUID though they may contain a UUID.\n\n
JSON schema\n\n```json { \"title\": \"A name unique within the parent collection\", \"description\": \"Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'. Names cannot be a UUID though they may contain a UUID.\", \"type\": \"string\", \"maxLength\": 63, \"minLength\": 1, \"pattern\": \"^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z]([a-zA-Z0-9-]*[a-zA-Z0-9]+)?$\" } ```
", "type": "string" diff --git a/openapi/nexus-internal.json b/openapi/nexus-internal.json index d694e5ee0de..80cf96f8fbd 100644 --- a/openapi/nexus-internal.json +++ b/openapi/nexus-internal.json @@ -3738,10 +3738,10 @@ "type": "object", "properties": { "addresses": { - "description": "This port's addresses.", + "description": "This port's addresses and optional vlan IDs", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/UplinkAddressConfig" } }, "autoneg": { @@ -4906,6 +4906,25 @@ "items" ] }, + "UplinkAddressConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/IpNetwork" + }, + "vlan_id": { + "nullable": true, + "description": "The VLAN id associated with this route.", + "default": null, + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "address" + ] + }, "UpstairsRepairType": { "type": "string", "enum": [ diff --git a/openapi/nexus.json b/openapi/nexus.json index c50291cf38a..46d5d430f8a 100644 --- a/openapi/nexus.json +++ b/openapi/nexus.json @@ -8996,6 +8996,13 @@ "$ref": "#/components/schemas/NameOrId" } ] + }, + "vlan_id": { + "nullable": true, + "description": "Optional VLAN ID for this address", + "type": "integer", + "format": "uint16", + "minimum": 0 } }, "required": [ @@ -17268,6 +17275,13 @@ "description": "The port settings object this address configuration belongs to.", "type": "string", "format": "uuid" + }, + "vlan_id": { + "nullable": true, + "description": "An optional VLAN ID", + "type": "integer", + "format": "uint16", + "minimum": 0 } }, "required": [ diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index fab597a7610..e40ad3053e2 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -2734,10 +2734,10 @@ "type": "object", "properties": { "addrs": { - "description": "IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport (must be in infra_ip pool)", + "description": "IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport (must be in infra_ip pool). May also include an optional VLAN ID.", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/UplinkAddressConfig" } }, "port": { @@ -4096,10 +4096,10 @@ "type": "object", "properties": { "addresses": { - "description": "This port's addresses.", + "description": "This port's addresses and optional vlan IDs", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/UplinkAddressConfig" } }, "autoneg": { @@ -4588,6 +4588,25 @@ "version" ] }, + "UplinkAddressConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/IpNetwork" + }, + "vlan_id": { + "nullable": true, + "description": "The VLAN id associated with this route.", + "default": null, + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "address" + ] + }, "VmmRuntimeState": { "description": "The dynamic runtime properties of an individual VMM process.", "type": "object", diff --git a/openapi/wicketd.json b/openapi/wicketd.json index 934069fb549..4be1ca588cf 100644 --- a/openapi/wicketd.json +++ b/openapi/wicketd.json @@ -4897,6 +4897,25 @@ } ] }, + "UplinkAddressConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/IpNetwork" + }, + "vlan_id": { + "nullable": true, + "description": "The VLAN id associated with this route.", + "default": null, + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "address" + ] + }, "UserSpecifiedBgpPeerConfig": { "description": "User-specified version of [`BgpPeerConfig`].\n\nThis is similar to [`BgpPeerConfig`], except it doesn't have the sensitive `md5_auth_key` parameter, instead requiring that the user provide the key separately.\n\n[`BgpPeerConfig`]: omicron_common::api::internal::shared::BgpPeerConfig", "type": "object", @@ -5056,7 +5075,7 @@ "addresses": { "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/UplinkAddressConfig" } }, "autoneg": { diff --git a/package-manifest.toml b/package-manifest.toml index 5da7ed68677..c50c75f3a32 100644 --- a/package-manifest.toml +++ b/package-manifest.toml @@ -533,10 +533,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 = "025389ff39d594bf2b815377e2c1dc4dd23b1f96" +source.commit = "6c4c6b2b7c22d38bc463c9582b71f4f6e8b92074" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//maghemite.sha256.txt -source.sha256 = "f2ee54b6a654daa1c1f817440317e9b11c5ddc71249df261bb5cfa0e6057dc24" +source.sha256 = "378bff5c41f302f8409a0b26c0c367df97a40cd2a4be798f5d03c1834657a986" output.type = "tarball" [package.mg-ddm] @@ -549,10 +549,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 = "025389ff39d594bf2b815377e2c1dc4dd23b1f96" +source.commit = "6c4c6b2b7c22d38bc463c9582b71f4f6e8b92074" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mg-ddm.sha256.txt -source.sha256 = "bb98815f759f38abee9f5aea0978cd33e66e75079cc8c171036be21bf9049c96" +source.sha256 = "dcb1439153f86e7d911ab10007295b9a43ae68093fafd05190e4f91ac5c53c71" output.type = "zone" output.intermediate_only = true @@ -564,10 +564,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 = "025389ff39d594bf2b815377e2c1dc4dd23b1f96" +source.commit = "6c4c6b2b7c22d38bc463c9582b71f4f6e8b92074" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mg-ddm.sha256.txt -source.sha256 = "e0907de39ca9f8ab45d40d361a1dbeed4bd8e9b157f8d3d8fe0a4bc259d933bd" +source.sha256 = "3343afedcb2a583615384a193a1479ff2c8d06b7398775bbe039a8fad8c862c2" output.type = "zone" output.intermediate_only = true @@ -613,8 +613,8 @@ only_for_targets.image = "standard" # 2. Copy dendrite.tar.gz from dendrite/out to omicron/out source.type = "prebuilt" source.repo = "dendrite" -source.commit = "3b84ea6516cafb4595a6f2a668df16c1a501b687" -source.sha256 = "1a18379522da75c034d66d15cf2e50a0d7289a746ef7c8a0ad98c4f61403f29b" +source.commit = "c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" +source.sha256 = "93f8fa61bb6bbccc06e7abb626e843213c794a2869d6de3f6517dae41c69ee11" output.type = "zone" output.intermediate_only = true @@ -638,8 +638,8 @@ only_for_targets.image = "standard" # 2. Copy the output zone image from dendrite/out to omicron/out source.type = "prebuilt" source.repo = "dendrite" -source.commit = "3b84ea6516cafb4595a6f2a668df16c1a501b687" -source.sha256 = "470e61b4652992da882ef10dd1511599a9cffe885d75c9924ee38e0900677ba7" +source.commit = "c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" +source.sha256 = "dd1add5ae79f7bba33541d1a133b56ce6ba8ae522d121e9588b645dd5f2d81f3" output.type = "zone" output.intermediate_only = true @@ -656,8 +656,8 @@ only_for_targets.image = "standard" # 2. Copy dendrite.tar.gz from dendrite/out to omicron/out/dendrite-softnpu.tar.gz source.type = "prebuilt" source.repo = "dendrite" -source.commit = "3b84ea6516cafb4595a6f2a668df16c1a501b687" -source.sha256 = "8a7cc20bcca7498c1e83eb6f898e967635e69089c1bb4f86f7acdf99f7b1f353" +source.commit = "c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" +source.sha256 = "31120ec4e7287e361f4d9a94006800057b3bc8d2e7afc121d3dcba3991e3d246" output.type = "zone" output.intermediate_only = true diff --git a/schema/rss-sled-plan.json b/schema/rss-sled-plan.json index a349fbb6058..d1d7e6e69f5 100644 --- a/schema/rss-sled-plan.json +++ b/schema/rss-sled-plan.json @@ -646,10 +646,10 @@ ], "properties": { "addresses": { - "description": "This port's addresses.", + "description": "This port's addresses and optional vlan IDs", "type": "array", "items": { - "$ref": "#/definitions/IpNetwork" + "$ref": "#/definitions/UplinkAddressConfig" } }, "autoneg": { @@ -1011,6 +1011,27 @@ } ] }, + "UplinkAddressConfig": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "$ref": "#/definitions/IpNetwork" + }, + "vlan_id": { + "description": "The VLAN id associated with this route.", + "default": null, + "type": [ + "integer", + "null" + ], + "format": "uint16", + "minimum": 0.0 + } + } + }, "UserId": { "description": "Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'. Names cannot be a UUID though they may contain a UUID.\n\n
JSON schema\n\n```json { \"title\": \"A name unique within the parent collection\", \"description\": \"Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'. Names cannot be a UUID though they may contain a UUID.\", \"type\": \"string\", \"maxLength\": 63, \"minLength\": 1, \"pattern\": \"^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z]([a-zA-Z0-9-]*[a-zA-Z0-9]+)?$\" } ```
", "type": "string" diff --git a/sled-agent/src/bootstrap/early_networking.rs b/sled-agent/src/bootstrap/early_networking.rs index 2714c220c7c..ee2894ef428 100644 --- a/sled-agent/src/bootstrap/early_networking.rs +++ b/sled-agent/src/bootstrap/early_networking.rs @@ -929,6 +929,7 @@ fn convert_fec(fec: &PortFec) -> dpd_client::types::PortFec { mod tests { use super::*; use omicron_common::api::internal::shared::RouteConfig; + use omicron_common::api::internal::shared::UplinkAddressConfig; use omicron_test_utils::dev::test_setup_log; #[test] @@ -981,7 +982,10 @@ mod tests { nexthop: uplink.gateway_ip.into(), vlan_id: None, }], - addresses: vec![uplink.uplink_cidr.into()], + addresses: vec![UplinkAddressConfig { + address: uplink.uplink_cidr.into(), + vlan_id: None, + }], switch: uplink.switch, port: uplink.uplink_port, uplink_port_speed: uplink.uplink_port_speed, diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 27435686e74..5ef2a55c57e 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -742,7 +742,7 @@ impl ServiceInner { .iter() .map(|config| NexusTypes::PortConfigV1 { port: config.port.clone(), - routes: config + routes: config .routes .iter() .map(|r| NexusTypes::RouteConfig { @@ -751,7 +751,14 @@ impl ServiceInner { vlan_id: r.vlan_id, }) .collect(), - addresses: config.addresses.clone(), + addresses: config + .addresses + .iter() + .map(|a| NexusTypes::UplinkAddressConfig { + address: a.address, + vlan_id: a.vlan_id + }) + .collect(), switch: config.switch.into(), uplink_port_speed: config.uplink_port_speed.into(), uplink_port_fec: config.uplink_port_fec.into(), diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index c9a50144026..1bd5c913ce4 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -3773,6 +3773,7 @@ impl ServiceManager { } }; + info!(self.inner.log, "Setting up uplinkd service"); let smfh = SmfHelper::new(&zone, &SwitchService::Uplink); // We want to delete all the properties in the `uplinks` group, but we @@ -3783,6 +3784,7 @@ impl ServiceManager { for port_config in &our_ports { for addr in &port_config.addrs { + info!(self.inner.log, "configuring port: {port_config:?}"); smfh.addpropvalue_type( &format!("uplinks/{}_0", port_config.port,), &addr.to_string(), diff --git a/sled-agent/tests/data/early_network_blobs.txt b/sled-agent/tests/data/early_network_blobs.txt index c968d4010b2..e9b9927e866 100644 --- a/sled-agent/tests/data/early_network_blobs.txt +++ b/sled-agent/tests/data/early_network_blobs.txt @@ -1,2 +1,2 @@ -2023-11-30 mupdate failing blob,{"generation":15,"schema_version":1,"body":{"ntp_servers":[],"rack_network_config":{"rack_subnet":"fd00:1122:3344:100::/56","infra_ip_first":"0.0.0.0","infra_ip_last":"0.0.0.0","ports":[{"routes":[],"addresses":[],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]},{"routes":[],"addresses":["172.20.15.53/29"],"switch":"switch1","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.51","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":["172.20.15.45/29"],"switch":"switch0","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.43","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":[],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]}],"bgp":[{"asn":65002,"originate":["172.20.26.0/24"]},{"asn":65002,"originate":["172.20.26.0/24"]}]}}} -2023-12-06 config,{"generation":20,"schema_version":1,"body":{"ntp_servers":["ntp.example.com"],"rack_network_config":{"rack_subnet":"ff01::/32","infra_ip_first":"127.0.0.1","infra_ip_last":"127.1.0.1","ports":[{"routes":[{"destination":"10.1.9.32/16","nexthop":"10.1.9.32"}],"addresses":["2001:db8::/96"],"switch":"switch0","port":"foo","uplink_port_speed":"speed200_g","uplink_port_fec":"firecode","bgp_peers":[{"asn":65000,"port":"bar","addr":"1.2.3.4","hold_time":20,"idle_hold_time":50,"delay_open":null,"connect_retry":30,"keepalive":10}],"autoneg":true}],"bgp":[{"asn":20000,"originate":["192.168.0.0/24"]}]}}} +2023-11-30 mupdate failing blob,{"generation":15,"schema_version":1,"body":{"ntp_servers":[],"rack_network_config":{"rack_subnet":"fd00:1122:3344:100::/56","infra_ip_first":"0.0.0.0","infra_ip_last":"0.0.0.0","ports":[{"routes":[],"addresses":[],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]},{"routes":[],"addresses":[{"address":"172.20.15.53/29"}],"switch":"switch1","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.51","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":[{"address":"172.20.15.45/29"}],"switch":"switch0","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.43","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":[],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]}],"bgp":[{"asn":65002,"originate":["172.20.26.0/24"]},{"asn":65002,"originate":["172.20.26.0/24"]}]}}} +2023-12-06 config,{"generation":20,"schema_version":1,"body":{"ntp_servers":["ntp.example.com"],"rack_network_config":{"rack_subnet":"ff01::/32","infra_ip_first":"127.0.0.1","infra_ip_last":"127.1.0.1","ports":[{"routes":[{"destination":"10.1.9.32/16","nexthop":"10.1.9.32"}],"addresses":[{"address":"2001:db8::/96"}],"switch":"switch0","port":"foo","uplink_port_speed":"speed200_g","uplink_port_fec":"firecode","bgp_peers":[{"asn":65000,"port":"bar","addr":"1.2.3.4","hold_time":20,"idle_hold_time":50,"delay_open":null,"connect_retry":30,"keepalive":10}],"autoneg":true}],"bgp":[{"asn":20000,"originate":["192.168.0.0/24"]}]}}} diff --git a/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json b/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json index 5512247ee87..683e8fb833e 100644 --- a/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json +++ b/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json @@ -1 +1 @@ -{"rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","sleds":{"[fdb0:a840:2504:396::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b3e78a88-0f2e-476e-a8a9-2d8c90a169d6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:103::/64"}}},"[fdb0:a840:2504:157::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"168e1ad6-1e4b-4f7a-b894-157974bd8bb8","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:104::/64"}}},"[fdb0:a840:2504:355::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b9877212-212b-4588-b818-9c7b53c5b143","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:102::/64"}}},"[fdb0:a840:2504:3d2::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"c3a0f8be-5b05-4ee8-8c4e-2514de6501b6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:101::/64"}}}},"config":{"rack_subnet":"fd00:1122:3344:100::","trust_quorum_peers":[{"type":"gimlet","identifier":"BRM42220081","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220046","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM44220001","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220004","model":"913-0000019","revision":6}],"bootstrap_discovery":{"type":"only_these","addrs":["fdb0:a840:2504:3d2::1","fdb0:a840:2504:355::1","fdb0:a840:2504:396::1","fdb0:a840:2504:157::1"]},"ntp_servers":["ntp.eng.oxide.computer"],"dns_servers":["1.1.1.1","9.9.9.9"],"internal_services_ip_pool_ranges":[{"first":"172.20.28.1","last":"172.20.28.10"}],"external_dns_ips":["172.20.28.1"],"external_dns_zone_name":"madrid.eng.oxide.computer","external_certificates":[{"cert":"","key":""}],"recovery_silo":{"silo_name":"recovery","user_name":"recovery","user_password_hash":"$argon2id$v=19$m=98304,t=13,p=1$RUlWc0ZxaHo0WFdrN0N6ZQ$S8p52j85GPvMhR/ek3GL0el/oProgTwWpHJZ8lsQQoY"},"rack_network_config":{"rack_subnet":"fd00:1122:3344:1::/56","infra_ip_first":"172.20.15.37","infra_ip_last":"172.20.15.38","ports":[{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":["172.20.15.38/29"],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false},{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":["172.20.15.37/29"],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false}],"bgp":[]}}} +{"rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","sleds":{"[fdb0:a840:2504:396::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b3e78a88-0f2e-476e-a8a9-2d8c90a169d6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:103::/64"}}},"[fdb0:a840:2504:157::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"168e1ad6-1e4b-4f7a-b894-157974bd8bb8","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:104::/64"}}},"[fdb0:a840:2504:355::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b9877212-212b-4588-b818-9c7b53c5b143","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:102::/64"}}},"[fdb0:a840:2504:3d2::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"c3a0f8be-5b05-4ee8-8c4e-2514de6501b6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:101::/64"}}}},"config":{"rack_subnet":"fd00:1122:3344:100::","trust_quorum_peers":[{"type":"gimlet","identifier":"BRM42220081","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220046","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM44220001","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220004","model":"913-0000019","revision":6}],"bootstrap_discovery":{"type":"only_these","addrs":["fdb0:a840:2504:3d2::1","fdb0:a840:2504:355::1","fdb0:a840:2504:396::1","fdb0:a840:2504:157::1"]},"ntp_servers":["ntp.eng.oxide.computer"],"dns_servers":["1.1.1.1","9.9.9.9"],"internal_services_ip_pool_ranges":[{"first":"172.20.28.1","last":"172.20.28.10"}],"external_dns_ips":["172.20.28.1"],"external_dns_zone_name":"madrid.eng.oxide.computer","external_certificates":[{"cert":"","key":""}],"recovery_silo":{"silo_name":"recovery","user_name":"recovery","user_password_hash":"$argon2id$v=19$m=98304,t=13,p=1$RUlWc0ZxaHo0WFdrN0N6ZQ$S8p52j85GPvMhR/ek3GL0el/oProgTwWpHJZ8lsQQoY"},"rack_network_config":{"rack_subnet":"fd00:1122:3344:1::/56","infra_ip_first":"172.20.15.37","infra_ip_last":"172.20.15.38","ports":[{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":[{"address":"172.20.15.38/29"}],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false},{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":[{"address":"172.20.15.37/29"}],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false}],"bgp":[]}}} diff --git a/sled-agent/tests/output/new-rss-sled-plans/madrid-rss-sled-plan.json b/sled-agent/tests/output/new-rss-sled-plans/madrid-rss-sled-plan.json index 108914a26f6..efd1a3c1671 100644 --- a/sled-agent/tests/output/new-rss-sled-plans/madrid-rss-sled-plan.json +++ b/sled-agent/tests/output/new-rss-sled-plans/madrid-rss-sled-plan.json @@ -132,7 +132,10 @@ } ], "addresses": [ - "172.20.15.38/29" + { + "address": "172.20.15.38/29", + "vlan_id": null + } ], "switch": "switch0", "port": "qsfp0", @@ -150,7 +153,10 @@ } ], "addresses": [ - "172.20.15.37/29" + { + "address": "172.20.15.37/29", + "vlan_id": null + } ], "switch": "switch1", "port": "qsfp0", diff --git a/smf/sled-agent/gimlet-standalone/config-rss.toml b/smf/sled-agent/gimlet-standalone/config-rss.toml index 616d8d496b0..b33c9e04b1c 100644 --- a/smf/sled-agent/gimlet-standalone/config-rss.toml +++ b/smf/sled-agent/gimlet-standalone/config-rss.toml @@ -102,7 +102,7 @@ bgp = [] # Routes associated with this port. routes = [{nexthop = "192.168.1.199", destination = "0.0.0.0/0"}] # Addresses associated with this port. -addresses = ["192.168.1.30/32"] +addresses = [{address = "192.168.1.30/24"}] # Name of the uplink port. This should always be "qsfp0" when using softnpu. port = "qsfp0" # The speed of this port. diff --git a/smf/sled-agent/non-gimlet/config-rss.toml b/smf/sled-agent/non-gimlet/config-rss.toml index d897f7ba4b7..90f5339e849 100644 --- a/smf/sled-agent/non-gimlet/config-rss.toml +++ b/smf/sled-agent/non-gimlet/config-rss.toml @@ -102,7 +102,7 @@ bgp = [] # Routes associated with this port. routes = [{nexthop = "192.168.1.199", destination = "0.0.0.0/0"}] # Addresses associated with this port. -addresses = ["192.168.1.30/24"] +addresses = [{address = "192.168.1.30/24"}] # Name of the uplink port. This should always be "qsfp0" when using softnpu. port = "qsfp0" # The speed of this port. diff --git a/tools/dendrite_openapi_version b/tools/dendrite_openapi_version index a00d2be7a1f..31d4a63d6f2 100644 --- a/tools/dendrite_openapi_version +++ b/tools/dendrite_openapi_version @@ -1,2 +1,2 @@ -COMMIT="3b84ea6516cafb4595a6f2a668df16c1a501b687" -SHA2="fc397e254dc150850fba12013df147aa9b23296056fb4d93f65c1806e25b0823" +COMMIT="c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" +SHA2="213031aa058f0aa355964e4a5ca350db30110454bad5c77cbc94ab77fdcbe013" diff --git a/tools/dendrite_stub_checksums b/tools/dendrite_stub_checksums index 18cfd54470c..31344a615e4 100644 --- a/tools/dendrite_stub_checksums +++ b/tools/dendrite_stub_checksums @@ -1,3 +1,3 @@ -CIDL_SHA256_ILLUMOS="1a18379522da75c034d66d15cf2e50a0d7289a746ef7c8a0ad98c4f61403f29b" -CIDL_SHA256_LINUX_DPD="c255370062ce616f6fce5630fad7a1fbfa63aa7db964aeb6de410ba4a4bc3193" -CIDL_SHA256_LINUX_SWADM="7899b1603518489b2276f9d9043107a267060e3b05be51f08002adf3d118a7c9" +CIDL_SHA256_ILLUMOS="93f8fa61bb6bbccc06e7abb626e843213c794a2869d6de3f6517dae41c69ee11" +CIDL_SHA256_LINUX_DPD="ba7d49edfd206841966c7dbead5de9121fbcda290c85f4d31963b9c21d97eeeb" +CIDL_SHA256_LINUX_SWADM="8fd60d4db6cb54f749a4ee7f32b2a1651e62200408b87d208869b6130631af30" diff --git a/wicket-common/src/rack_setup.rs b/wicket-common/src/rack_setup.rs index 5e89bfdde27..4f0427c0675 100644 --- a/wicket-common/src/rack_setup.rs +++ b/wicket-common/src/rack_setup.rs @@ -6,7 +6,6 @@ pub use gateway_client::types::SpIdentifier as GatewaySpIdentifier; pub use gateway_client::types::SpType as GatewaySpType; -use ipnetwork::IpNetwork; use omicron_common::address; use omicron_common::api::external::ImportExportPolicy; use omicron_common::api::external::IpNet; @@ -18,6 +17,7 @@ use omicron_common::api::internal::shared::BgpPeerConfig; use omicron_common::api::internal::shared::PortFec; use omicron_common::api::internal::shared::PortSpeed; use omicron_common::api::internal::shared::RouteConfig; +use omicron_common::api::internal::shared::UplinkAddressConfig; use omicron_common::update::ArtifactHash; use owo_colors::OwoColorize; use owo_colors::Style; @@ -182,7 +182,7 @@ impl UserSpecifiedRackNetworkConfig { #[serde(deny_unknown_fields)] pub struct UserSpecifiedPortConfig { pub routes: Vec, - pub addresses: Vec, + pub addresses: Vec, pub uplink_port_speed: PortSpeed, pub uplink_port_fec: PortFec, pub autoneg: bool, diff --git a/wicket/src/cli/rack_setup/config_toml.rs b/wicket/src/cli/rack_setup/config_toml.rs index aa1a384efbd..8b56722e0ed 100644 --- a/wicket/src/cli/rack_setup/config_toml.rs +++ b/wicket/src/cli/rack_setup/config_toml.rs @@ -8,6 +8,7 @@ use omicron_common::address::IpRange; use omicron_common::api::internal::shared::BgpConfig; use omicron_common::api::internal::shared::RouteConfig; +use omicron_common::api::internal::shared::UplinkAddressConfig; use serde::Serialize; use sled_hardware_types::Baseboard; use std::borrow::Cow; @@ -287,7 +288,13 @@ fn populate_uplink_table(cfg: &UserSpecifiedPortConfig) -> Table { // addresses = [] let mut addresses_out = Array::new(); for a in addresses { - addresses_out.push(string_value(a)); + let UplinkAddressConfig { address, vlan_id } = a; + let mut x = InlineTable::new(); + x.insert("address", string_value(address)); + if let Some(vlan_id) = vlan_id { + x.insert("vlan_id", i64_value(i64::from(*vlan_id))); + } + addresses_out.push(Value::InlineTable(x)); } uplink.insert("addresses", Item::Value(Value::Array(addresses_out))); diff --git a/wicket/tests/output/example_non_empty.toml b/wicket/tests/output/example_non_empty.toml index daed13d0622..f92d382572c 100644 --- a/wicket/tests/output/example_non_empty.toml +++ b/wicket/tests/output/example_non_empty.toml @@ -68,7 +68,7 @@ infra_ip_last = "172.30.0.10" [rack_network_config.switch0.port0] routes = [{ nexthop = "172.30.0.10", destination = "0.0.0.0/0", vlan_id = 1 }] -addresses = ["172.30.0.1/24"] +addresses = [{ address = "172.30.0.1/24" }] uplink_port_speed = "speed400_g" uplink_port_fec = "firecode" autoneg = true @@ -107,7 +107,7 @@ enforce_first_as = true [rack_network_config.switch1.port0] routes = [{ nexthop = "172.33.0.10", destination = "0.0.0.0/0", vlan_id = 1 }] -addresses = ["172.32.0.1/24"] +addresses = [{ address = "172.32.0.1/24" }] uplink_port_speed = "speed400_g" uplink_port_fec = "firecode" autoneg = true diff --git a/wicketd/src/rss_config.rs b/wicketd/src/rss_config.rs index 0160aa7c77b..9d4f022a918 100644 --- a/wicketd/src/rss_config.rs +++ b/wicketd/src/rss_config.rs @@ -689,6 +689,7 @@ fn build_port_config( use bootstrap_agent_client::types::PortSpeed as BaPortSpeed; use bootstrap_agent_client::types::RouteConfig as BaRouteConfig; use bootstrap_agent_client::types::SwitchLocation as BaSwitchLocation; + use bootstrap_agent_client::types::UplinkAddressConfig as BaUplinkAddressConfig; use omicron_common::api::internal::shared::PortFec; use omicron_common::api::internal::shared::PortSpeed; @@ -703,7 +704,14 @@ fn build_port_config( vlan_id: r.vlan_id, }) .collect(), - addresses: config.addresses.clone(), + addresses: config + .addresses + .iter() + .map(|a| BaUplinkAddressConfig { + address: a.address, + vlan_id: a.vlan_id, + }) + .collect(), bgp_peers: config .bgp_peers .iter() From e8a7a3495c1fdb18318ecc3d42e124ed13ca5a8b Mon Sep 17 00:00:00 2001 From: Nils Nieuwejaar Date: Thu, 30 May 2024 21:10:43 +0000 Subject: [PATCH 2/4] bump dendrite to get vlan API update --- package-manifest.toml | 12 ++++++------ tools/dendrite_openapi_version | 4 ++-- tools/dendrite_stub_checksums | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-manifest.toml b/package-manifest.toml index c50c75f3a32..04a330bcb89 100644 --- a/package-manifest.toml +++ b/package-manifest.toml @@ -613,8 +613,8 @@ only_for_targets.image = "standard" # 2. Copy dendrite.tar.gz from dendrite/out to omicron/out source.type = "prebuilt" source.repo = "dendrite" -source.commit = "c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" -source.sha256 = "93f8fa61bb6bbccc06e7abb626e843213c794a2869d6de3f6517dae41c69ee11" +source.commit = "0eec6b168e2331441f0ba8bab38760da6e674fb5" +source.sha256 = "55aadb9f7f9eff353149d56f2c2186e4bfba48a9b01e1cc6758a252d58e9d1f1" output.type = "zone" output.intermediate_only = true @@ -638,8 +638,8 @@ only_for_targets.image = "standard" # 2. Copy the output zone image from dendrite/out to omicron/out source.type = "prebuilt" source.repo = "dendrite" -source.commit = "c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" -source.sha256 = "dd1add5ae79f7bba33541d1a133b56ce6ba8ae522d121e9588b645dd5f2d81f3" +source.commit = "0eec6b168e2331441f0ba8bab38760da6e674fb5" +source.sha256 = "d0a3f8bcfb8cfdd5cf114b1f5cd21af61fe0ac6f457a51e334f47fc3f8a38727" output.type = "zone" output.intermediate_only = true @@ -656,8 +656,8 @@ only_for_targets.image = "standard" # 2. Copy dendrite.tar.gz from dendrite/out to omicron/out/dendrite-softnpu.tar.gz source.type = "prebuilt" source.repo = "dendrite" -source.commit = "c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" -source.sha256 = "31120ec4e7287e361f4d9a94006800057b3bc8d2e7afc121d3dcba3991e3d246" +source.commit = "0eec6b168e2331441f0ba8bab38760da6e674fb5" +source.sha256 = "52077b695d278032d35e7728cab67db391c93f4f6373fb70f4b4413a3ad0602d" output.type = "zone" output.intermediate_only = true diff --git a/tools/dendrite_openapi_version b/tools/dendrite_openapi_version index 31d4a63d6f2..26c0a6cbfbe 100644 --- a/tools/dendrite_openapi_version +++ b/tools/dendrite_openapi_version @@ -1,2 +1,2 @@ -COMMIT="c08a3fa3c9362810fbf84ceaa17fc8ae241c2094" -SHA2="213031aa058f0aa355964e4a5ca350db30110454bad5c77cbc94ab77fdcbe013" +COMMIT="0eec6b168e2331441f0ba8bab38760da6e674fb5" +SHA2="a9305b44ad70a00d699ef8720ea15431679e8fc5e549220c30e510e1d9e80036" diff --git a/tools/dendrite_stub_checksums b/tools/dendrite_stub_checksums index 31344a615e4..7f153aaa8fa 100644 --- a/tools/dendrite_stub_checksums +++ b/tools/dendrite_stub_checksums @@ -1,3 +1,3 @@ -CIDL_SHA256_ILLUMOS="93f8fa61bb6bbccc06e7abb626e843213c794a2869d6de3f6517dae41c69ee11" -CIDL_SHA256_LINUX_DPD="ba7d49edfd206841966c7dbead5de9121fbcda290c85f4d31963b9c21d97eeeb" -CIDL_SHA256_LINUX_SWADM="8fd60d4db6cb54f749a4ee7f32b2a1651e62200408b87d208869b6130631af30" +CIDL_SHA256_ILLUMOS="55aadb9f7f9eff353149d56f2c2186e4bfba48a9b01e1cc6758a252d58e9d1f1" +CIDL_SHA256_LINUX_DPD="cbda4b9f4ec4485e803445ec2c9a33d3b3f8cac85d4aded9303a799909ef2c1c" +CIDL_SHA256_LINUX_SWADM="e614de71aa93cfc611cc3228ccb3d48f497413495d10342af38948cea0efbbaa" From 8084bc891683f53126026a0d04e1b4471afd0e3c Mon Sep 17 00:00:00 2001 From: Nils Nieuwejaar Date: Wed, 29 May 2024 20:21:01 +0000 Subject: [PATCH 3/4] a few updates to get things to come up in a4x2 --- Cargo.lock | 24 ++++++------------------ Cargo.toml | 4 ++-- tools/opte_version | 2 +- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11dd1839a5c..e2e1b13cc46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1748,17 +1748,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derror-macro" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.60", -] - [[package]] name = "dhcproto" version = "0.11.0" @@ -3490,7 +3479,7 @@ dependencies = [ [[package]] name = "illumos-sys-hdrs" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" +source = "git+https://github.com/oxidecomputer/opte?rev=d6177ca84f23e60a661461bb4cece475689502d2#d6177ca84f23e60a661461bb4cece475689502d2" [[package]] name = "illumos-utils" @@ -3897,7 +3886,7 @@ dependencies = [ [[package]] name = "kstat-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" +source = "git+https://github.com/oxidecomputer/opte?rev=d6177ca84f23e60a661461bb4cece475689502d2#d6177ca84f23e60a661461bb4cece475689502d2" dependencies = [ "quote", "syn 2.0.60", @@ -5979,10 +5968,9 @@ dependencies = [ [[package]] name = "opte" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" +source = "git+https://github.com/oxidecomputer/opte?rev=d6177ca84f23e60a661461bb4cece475689502d2#d6177ca84f23e60a661461bb4cece475689502d2" dependencies = [ "cfg-if", - "derror-macro", "dyn-clone", "illumos-sys-hdrs", "kstat-macro", @@ -5997,7 +5985,7 @@ dependencies = [ [[package]] name = "opte-api" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" +source = "git+https://github.com/oxidecomputer/opte?rev=d6177ca84f23e60a661461bb4cece475689502d2#d6177ca84f23e60a661461bb4cece475689502d2" dependencies = [ "illumos-sys-hdrs", "ipnetwork", @@ -6009,7 +5997,7 @@ dependencies = [ [[package]] name = "opte-ioctl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" +source = "git+https://github.com/oxidecomputer/opte?rev=d6177ca84f23e60a661461bb4cece475689502d2#d6177ca84f23e60a661461bb4cece475689502d2" dependencies = [ "libc", "libnet 0.1.0 (git+https://github.com/oxidecomputer/netadm-sys)", @@ -6083,7 +6071,7 @@ dependencies = [ [[package]] name = "oxide-vpc" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=7ee353a470ea59529ee1b34729681da887aa88ce#7ee353a470ea59529ee1b34729681da887aa88ce" +source = "git+https://github.com/oxidecomputer/opte?rev=d6177ca84f23e60a661461bb4cece475689502d2#d6177ca84f23e60a661461bb4cece475689502d2" dependencies = [ "cfg-if", "illumos-sys-hdrs", diff --git a/Cargo.toml b/Cargo.toml index 7f778c01975..980f164c40c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -346,14 +346,14 @@ omicron-sled-agent = { path = "sled-agent" } omicron-test-utils = { path = "test-utils" } omicron-zone-package = "0.11.0" oxide-client = { path = "clients/oxide-client" } -oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "7ee353a470ea59529ee1b34729681da887aa88ce", features = [ "api", "std" ] } +oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "d6177ca84f23e60a661461bb4cece475689502d2", features = [ "api", "std" ] } once_cell = "1.19.0" openapi-lint = { git = "https://github.com/oxidecomputer/openapi-lint", branch = "main" } openapiv3 = "2.0.0" # must match samael's crate! openssl = "0.10" openssl-sys = "0.9" -opte-ioctl = { git = "https://github.com/oxidecomputer/opte", rev = "7ee353a470ea59529ee1b34729681da887aa88ce" } +opte-ioctl = { git = "https://github.com/oxidecomputer/opte", rev = "d6177ca84f23e60a661461bb4cece475689502d2" } oso = "0.27" owo-colors = "4.0.0" oximeter = { path = "oximeter/oximeter" } diff --git a/tools/opte_version b/tools/opte_version index e1b3e114995..6126a52eb43 100644 --- a/tools/opte_version +++ b/tools/opte_version @@ -1 +1 @@ -0.28.233 +0.31.259 From 73b2265ad42c6e51ad156b4183377018254f8e6c Mon Sep 17 00:00:00 2001 From: Ryan Goodfellow Date: Thu, 30 May 2024 22:58:28 -0700 Subject: [PATCH 4/4] add missing database table column --- schema/crdb/dbinit.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/schema/crdb/dbinit.sql b/schema/crdb/dbinit.sql index e66f28d74f6..08c6e39d705 100644 --- a/schema/crdb/dbinit.sql +++ b/schema/crdb/dbinit.sql @@ -2721,6 +2721,7 @@ CREATE TABLE IF NOT EXISTS omicron.public.switch_port_settings_address_config ( rsvd_address_lot_block_id UUID NOT NULL, address INET, interface_name TEXT, + vlan_id INT4, /* TODO https://github.com/oxidecomputer/omicron/issues/3013 */ PRIMARY KEY (port_settings_id, address, interface_name)