Skip to content

Commit 2082942

Browse files
internet-diglettLevon Tarver
and
Levon Tarver
authored
RPW for OPTE v2p Mappings (#5568)
TODO --- - [x] Extend db view to include probe v2p mappings - [x] Update sagas to trigger rpw activation instead of directly configuring v2p mappings - [x] Test that the `delete` functionality cleans up v2p mappings Related --- Resolves #5214 Resolves #4259 Resolves #3107 - [x] Depends on oxidecomputer/opte#494 - [x] Depends on oxidecomputer/meta#409 - [x] Depends on oxidecomputer/maghemite#244 --------- Co-authored-by: Levon Tarver <[email protected]>
1 parent 82c77f2 commit 2082942

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+805
-590
lines changed

.github/buildomat/jobs/deploy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#:
33
#: name = "helios / deploy"
44
#: variety = "basic"
5-
#: target = "lab-2.0-opte-0.28"
5+
#: target = "lab-2.0-opte-0.29"
66
#: output_rules = [
77
#: "%/var/svc/log/oxide-sled-agent:default.log*",
88
#: "%/zone/oxz_*/root/var/svc/log/oxide-*.log*",

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,14 @@ omicron-sled-agent = { path = "sled-agent" }
347347
omicron-test-utils = { path = "test-utils" }
348348
omicron-zone-package = "0.11.0"
349349
oxide-client = { path = "clients/oxide-client" }
350-
oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "7ee353a470ea59529ee1b34729681da887aa88ce", features = [ "api", "std" ] }
350+
oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "4cc823b50d3e4a629cdfaab2b3d3382514174ba9", features = [ "api", "std" ] }
351351
once_cell = "1.19.0"
352352
openapi-lint = { git = "https://github.com/oxidecomputer/openapi-lint", branch = "main" }
353353
openapiv3 = "2.0.0"
354354
# must match samael's crate!
355355
openssl = "0.10"
356356
openssl-sys = "0.9"
357-
opte-ioctl = { git = "https://github.com/oxidecomputer/opte", rev = "7ee353a470ea59529ee1b34729681da887aa88ce" }
357+
opte-ioctl = { git = "https://github.com/oxidecomputer/opte", rev = "4cc823b50d3e4a629cdfaab2b3d3382514174ba9" }
358358
oso = "0.27"
359359
owo-colors = "4.0.0"
360360
oximeter = { path = "oximeter/oximeter" }

clients/sled-agent-client/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ progenitor::generate_api!(
3535
PortConfigV1 = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] },
3636
RouteConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] },
3737
IpNet = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] },
38-
OmicronPhysicalDiskConfig = { derives = [Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord] }
38+
VirtualNetworkInterfaceHost = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] },
39+
OmicronPhysicalDiskConfig = { derives = [Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord] },
3940
},
4041
//TODO trade the manual transformations later in this file for the
4142
// replace directives below?

dev-tools/omdb/tests/env.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ task: "switch_port_config_manager"
114114
manages switch port settings for rack switches
115115

116116

117+
task: "v2p_manager"
118+
manages opte v2p mappings for vpc networking
119+
120+
117121
---------------------------------------------
118122
stderr:
119123
note: using Nexus URL http://127.0.0.1:REDACTED_PORT
@@ -225,6 +229,10 @@ task: "switch_port_config_manager"
225229
manages switch port settings for rack switches
226230

227231

232+
task: "v2p_manager"
233+
manages opte v2p mappings for vpc networking
234+
235+
228236
---------------------------------------------
229237
stderr:
230238
note: Nexus URL not specified. Will pick one from DNS.
@@ -323,6 +331,10 @@ task: "switch_port_config_manager"
323331
manages switch port settings for rack switches
324332

325333

334+
task: "v2p_manager"
335+
manages opte v2p mappings for vpc networking
336+
337+
326338
---------------------------------------------
327339
stderr:
328340
note: Nexus URL not specified. Will pick one from DNS.

dev-tools/omdb/tests/successes.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ task: "switch_port_config_manager"
291291
manages switch port settings for rack switches
292292

293293

294+
task: "v2p_manager"
295+
manages opte v2p mappings for vpc networking
296+
297+
294298
---------------------------------------------
295299
stderr:
296300
note: using Nexus URL http://127.0.0.1:REDACTED_PORT/
@@ -471,6 +475,13 @@ task: "switch_port_config_manager"
471475
started at <REDACTED TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
472476
warning: unknown background task: "switch_port_config_manager" (don't know how to interpret details: Object {})
473477

478+
task: "v2p_manager"
479+
configured period: every 30s
480+
currently executing: no
481+
last completed activation: <REDACTED ITERATIONS>, triggered by an explicit signal
482+
started at <REDACTED TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
483+
warning: unknown background task: "v2p_manager" (don't know how to interpret details: Object {})
484+
474485
---------------------------------------------
475486
stderr:
476487
note: using Nexus URL http://127.0.0.1:REDACTED_PORT/

dev-tools/oxlog/src/bin/oxlog.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct FilterArgs {
4747
#[arg(short, long)]
4848
archived: bool,
4949

50-
// Print only the extra log files
50+
/// Print only the extra log files
5151
#[arg(short, long)]
5252
extra: bool,
5353

illumos-utils/src/opte/params.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,16 @@ pub struct VpcFirewallRule {
3131
}
3232

3333
/// A mapping from a virtual NIC to a physical host
34-
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
35-
pub struct SetVirtualNetworkInterfaceHost {
34+
#[derive(
35+
Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash,
36+
)]
37+
pub struct VirtualNetworkInterfaceHost {
3638
pub virtual_ip: IpAddr,
3739
pub virtual_mac: external::MacAddr,
3840
pub physical_host_ip: Ipv6Addr,
3941
pub vni: external::Vni,
4042
}
4143

42-
/// The data needed to identify a virtual IP for which a sled maintains an OPTE
43-
/// virtual-to-physical mapping such that that mapping can be deleted.
44-
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
45-
pub struct DeleteVirtualNetworkInterfaceHost {
46-
/// The virtual IP whose mapping should be deleted.
47-
pub virtual_ip: IpAddr,
48-
49-
/// The VNI for the network containing the virtual IP whose mapping should
50-
/// be deleted.
51-
pub vni: external::Vni,
52-
}
53-
5444
/// DHCP configuration for a port
5545
///
5646
/// Not present here: Hostname (DHCPv4 option 12; used in DHCPv6 option 39); we

illumos-utils/src/opte/port_manager.rs

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
//! Manager for all OPTE ports on a Helios system
66
77
use crate::opte::opte_firewall_rules;
8-
use crate::opte::params::DeleteVirtualNetworkInterfaceHost;
9-
use crate::opte::params::SetVirtualNetworkInterfaceHost;
8+
use crate::opte::params::VirtualNetworkInterfaceHost;
109
use crate::opte::params::VpcFirewallRule;
1110
use crate::opte::Error;
1211
use crate::opte::Gateway;
@@ -570,10 +569,62 @@ impl PortManager {
570569
Ok(())
571570
}
572571

572+
#[cfg(target_os = "illumos")]
573+
pub fn list_virtual_nics(
574+
&self,
575+
) -> Result<Vec<VirtualNetworkInterfaceHost>, Error> {
576+
use macaddr::MacAddr6;
577+
use opte_ioctl::OpteHdl;
578+
579+
let hdl = OpteHdl::open(OpteHdl::XDE_CTL)?;
580+
let v2p =
581+
hdl.dump_v2p(&oxide_vpc::api::DumpVirt2PhysReq { unused: 99 })?;
582+
let mut mappings: Vec<_> = vec![];
583+
584+
for mapping in v2p.mappings {
585+
let vni = mapping
586+
.vni
587+
.as_u32()
588+
.try_into()
589+
.expect("opte VNI should be 24 bits");
590+
591+
for entry in mapping.ip4 {
592+
mappings.push(VirtualNetworkInterfaceHost {
593+
virtual_ip: IpAddr::V4(entry.0.into()),
594+
virtual_mac: MacAddr6::from(entry.1.ether.bytes()).into(),
595+
physical_host_ip: entry.1.ip.into(),
596+
vni,
597+
});
598+
}
599+
600+
for entry in mapping.ip6 {
601+
mappings.push(VirtualNetworkInterfaceHost {
602+
virtual_ip: IpAddr::V6(entry.0.into()),
603+
virtual_mac: MacAddr6::from(entry.1.ether.bytes()).into(),
604+
physical_host_ip: entry.1.ip.into(),
605+
vni,
606+
});
607+
}
608+
}
609+
610+
Ok(mappings)
611+
}
612+
613+
#[cfg(not(target_os = "illumos"))]
614+
pub fn list_virtual_nics(
615+
&self,
616+
) -> Result<Vec<VirtualNetworkInterfaceHost>, Error> {
617+
info!(
618+
self.inner.log,
619+
"Listing virtual nics (ignored)";
620+
);
621+
Ok(vec![])
622+
}
623+
573624
#[cfg(target_os = "illumos")]
574625
pub fn set_virtual_nic_host(
575626
&self,
576-
mapping: &SetVirtualNetworkInterfaceHost,
627+
mapping: &VirtualNetworkInterfaceHost,
577628
) -> Result<(), Error> {
578629
use opte_ioctl::OpteHdl;
579630

@@ -600,7 +651,7 @@ impl PortManager {
600651
#[cfg(not(target_os = "illumos"))]
601652
pub fn set_virtual_nic_host(
602653
&self,
603-
mapping: &SetVirtualNetworkInterfaceHost,
654+
mapping: &VirtualNetworkInterfaceHost,
604655
) -> Result<(), Error> {
605656
info!(
606657
self.inner.log,
@@ -613,20 +664,41 @@ impl PortManager {
613664
#[cfg(target_os = "illumos")]
614665
pub fn unset_virtual_nic_host(
615666
&self,
616-
_mapping: &DeleteVirtualNetworkInterfaceHost,
667+
mapping: &VirtualNetworkInterfaceHost,
617668
) -> Result<(), Error> {
618-
// TODO requires https://github.com/oxidecomputer/opte/issues/332
669+
use opte_ioctl::OpteHdl;
670+
671+
info!(
672+
self.inner.log,
673+
"Clearing mapping of virtual NIC to physical host";
674+
"mapping" => ?&mapping,
675+
);
676+
677+
let hdl = OpteHdl::open(OpteHdl::XDE_CTL)?;
678+
hdl.clear_v2p(&oxide_vpc::api::ClearVirt2PhysReq {
679+
vip: mapping.virtual_ip.into(),
680+
phys: oxide_vpc::api::PhysNet {
681+
ether: oxide_vpc::api::MacAddr::from(
682+
(*mapping.virtual_mac).into_array(),
683+
),
684+
ip: mapping.physical_host_ip.into(),
685+
vni: Vni::new(mapping.vni).unwrap(),
686+
},
687+
})?;
619688

620-
slog::warn!(self.inner.log, "unset_virtual_nic_host unimplmented");
621689
Ok(())
622690
}
623691

624692
#[cfg(not(target_os = "illumos"))]
625693
pub fn unset_virtual_nic_host(
626694
&self,
627-
_mapping: &DeleteVirtualNetworkInterfaceHost,
695+
mapping: &VirtualNetworkInterfaceHost,
628696
) -> Result<(), Error> {
629-
info!(self.inner.log, "Ignoring unset of virtual NIC mapping");
697+
info!(
698+
self.inner.log,
699+
"Ignoring unset of virtual NIC mapping";
700+
"mapping" => ?&mapping,
701+
);
630702
Ok(())
631703
}
632704
}

nexus-config/src/nexus_config.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ pub struct BackgroundTaskConfig {
379379
pub instance_watcher: InstanceWatcherConfig,
380380
/// configuration for service VPC firewall propagation task
381381
pub service_firewall_propagation: ServiceFirewallPropagationConfig,
382+
/// configuration for v2p mapping propagation task
383+
pub v2p_mapping_propagation: V2PMappingPropagationConfig,
382384
}
383385

384386
#[serde_as]
@@ -539,6 +541,14 @@ pub struct ServiceFirewallPropagationConfig {
539541
pub period_secs: Duration,
540542
}
541543

544+
#[serde_as]
545+
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
546+
pub struct V2PMappingPropagationConfig {
547+
/// period (in seconds) for periodic activations of this background task
548+
#[serde_as(as = "DurationSeconds<u64>")]
549+
pub period_secs: Duration,
550+
}
551+
542552
/// Configuration for a nexus server
543553
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
544554
pub struct PackageConfig {
@@ -777,6 +787,7 @@ mod test {
777787
region_replacement.period_secs = 30
778788
instance_watcher.period_secs = 30
779789
service_firewall_propagation.period_secs = 300
790+
v2p_mapping_propagation.period_secs = 30
780791
[default_region_allocation_strategy]
781792
type = "random"
782793
seed = 0
@@ -911,7 +922,10 @@ mod test {
911922
service_firewall_propagation:
912923
ServiceFirewallPropagationConfig {
913924
period_secs: Duration::from_secs(300),
914-
}
925+
},
926+
v2p_mapping_propagation: V2PMappingPropagationConfig {
927+
period_secs: Duration::from_secs(30)
928+
},
915929
},
916930
default_region_allocation_strategy:
917931
crate::nexus_config::RegionAllocationStrategy::Random {
@@ -980,6 +994,7 @@ mod test {
980994
region_replacement.period_secs = 30
981995
instance_watcher.period_secs = 30
982996
service_firewall_propagation.period_secs = 300
997+
v2p_mapping_propagation.period_secs = 30
983998
[default_region_allocation_strategy]
984999
type = "random"
9851000
"##,

nexus/db-model/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ mod project;
5555
mod semver_version;
5656
mod switch_interface;
5757
mod switch_port;
58+
mod v2p_mapping;
5859
// These actually represent subqueries, not real table.
5960
// However, they must be defined in the same crate as our tables
6061
// for join-based marker trait generation.
@@ -188,6 +189,7 @@ pub use typed_uuid::to_db_typed_uuid;
188189
pub use upstairs_repair::*;
189190
pub use user_builtin::*;
190191
pub use utilization::*;
192+
pub use v2p_mapping::*;
191193
pub use virtual_provisioning_collection::*;
192194
pub use virtual_provisioning_resource::*;
193195
pub use vmm::*;

0 commit comments

Comments
 (0)