Skip to content

Commit f062472

Browse files
authored
Add dual-stack IP config for internal NICs (#9389)
- Add dual-stack VPC private address configuration type and include it in the shared NetworkInterface type. - Add database model support for reading / writing the dual-stack NIC type to the database, handling serialization into optional fields. - Update all the callsites to handle the new dual-stack-aware type. - Add a bunch of conversions for the APIs which rely on that new type, of which there are many. This also adds the conversions and older types into the `sled-agent-types` crate, so they can be used in a few places that don't directly depend on the `sled-agent-api` crate itself, notably reconfigurator and `nexus-inventory`. - Update the sled-agent reconciler to deserialize previous versions of its sled-configuration ledgers, convert them, and write them out again as the new versions. - Updates the OPTE `PortManager` type with the new dual-stack support. This is only for private IP addresses, though. We still need some work to support OPTE ports with dual stack external addresses. This is about half of #9247, the VPC-private part. - Closes #9246
1 parent e4f7ca0 commit f062472

File tree

49 files changed

+12863
-1013
lines changed

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

+12863
-1013
lines changed

common/src/address.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,22 @@ pub const VPC_IPV6_PREFIX_LENGTH: u8 = 48;
156156
/// The prefix length for all VPC subnets
157157
pub const VPC_SUBNET_IPV6_PREFIX_LENGTH: u8 = 64;
158158

159+
/// Minimum prefix size supported in IPv4 VPC Subnets.
160+
///
161+
/// NOTE: This is the minimum _prefix_, which sets the maximum subnet size.
162+
pub const MIN_VPC_IPV4_SUBNET_PREFIX: u8 = 8;
163+
164+
/// The number of reserved addresses at the beginning of a subnet range.
165+
pub const NUM_INITIAL_RESERVED_IP_ADDRESSES: usize = 5;
166+
167+
/// The maximum prefix size by default.
168+
///
169+
/// There are 6 Oxide reserved IP addresses, 5 at the beginning for DNS and the
170+
/// like, and the broadcast address at the end of the subnet. This size provides
171+
/// room for 2 ** 6 - 6 = 58 IP addresses, which seems like a reasonable size
172+
/// for the smallest subnet that's still useful in many contexts.
173+
pub const MAX_VPC_IPV4_SUBNET_PREFIX: u8 = 26;
174+
159175
// The number of ports available to an SNAT IP.
160176
// Note that for static NAT, this value isn't used, and all ports are available.
161177
//

common/src/api/internal/shared.rs renamed to common/src/api/internal/shared/mod.rs

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
//! Types shared between Nexus and Sled Agent.
66
7+
use super::nexus::HostIdentifier;
78
use crate::{
89
address::NUM_SOURCE_NAT_PORTS,
910
api::external::{self, BfdMode, ImportExportPolicy, Name, Vni},
@@ -25,60 +26,11 @@ use std::{
2526
use strum::EnumCount;
2627
use uuid::Uuid;
2728

28-
use super::nexus::HostIdentifier;
29-
30-
/// The type of network interface
31-
#[derive(
32-
Clone,
33-
Copy,
34-
Debug,
35-
Eq,
36-
PartialEq,
37-
Ord,
38-
PartialOrd,
39-
Deserialize,
40-
Serialize,
41-
JsonSchema,
42-
Hash,
43-
Diffable,
44-
)]
45-
#[serde(tag = "type", rename_all = "snake_case")]
46-
pub enum NetworkInterfaceKind {
47-
/// A vNIC attached to a guest instance
48-
Instance { id: Uuid },
49-
/// A vNIC associated with an internal service
50-
Service { id: Uuid },
51-
/// A vNIC associated with a probe
52-
Probe { id: Uuid },
53-
}
29+
pub mod network_interface;
5430

55-
/// Information required to construct a virtual network interface
56-
#[derive(
57-
Clone,
58-
Debug,
59-
Deserialize,
60-
Serialize,
61-
JsonSchema,
62-
PartialEq,
63-
Eq,
64-
PartialOrd,
65-
Ord,
66-
Hash,
67-
Diffable,
68-
)]
69-
pub struct NetworkInterface {
70-
pub id: Uuid,
71-
pub kind: NetworkInterfaceKind,
72-
pub name: Name,
73-
pub ip: IpAddr,
74-
pub mac: external::MacAddr,
75-
pub subnet: IpNet,
76-
pub vni: Vni,
77-
pub primary: bool,
78-
pub slot: u8,
79-
#[serde(default)]
80-
pub transit_ips: Vec<IpNet>,
81-
}
31+
// Re-export latest version of all NIC-related types.
32+
pub use network_interface::NetworkInterfaceKind;
33+
pub use network_interface::*;
8234

8335
/// An IP address and port range used for source NAT, i.e., making
8436
/// outbound network connections from guests or services.
@@ -780,7 +732,7 @@ impl TryFrom<&[ipnetwork::IpNetwork]> for IpAllowList {
780732

781733
/// A VPC route resolved into a concrete target.
782734
#[derive(
783-
Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash,
735+
Clone, Copy, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash,
784736
)]
785737
pub struct ResolvedVpcRoute {
786738
pub dest: IpNet,

0 commit comments

Comments
 (0)