Skip to content

Commit d4691e2

Browse files
authored
Explicitly pass default subnets into network creation (apple#1424)
This changes the semantics around `ReservedVmnetNetwork` and `AllocationOnlyVmnetNetwork` to only create ipv4/6 subnets for networks when the values are explicitly passed in the `NetworkConfiguration`. Previously if the values in the `NetworkConfiguration` were not present it would attempt to source them via `DefaultsStore`. ## Type of Change - [X] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Documentation update ## Motivation and Context The change solves an issue that caused `container network create <name>` to fail when `UserDefaults` was set to a value that is identical to the hard coded default ("192.168.64.1/24"/"fd00::/64"). It would fail because a network with these parameters would already exist, and thus could not be reserved. ## Testing - [X] Tested locally - [ ] Added/updated tests - [ ] Added/updated docs
1 parent 0495700 commit d4691e2

3 files changed

Lines changed: 20 additions & 14 deletions

File tree

Sources/APIServer/APIServer+Start.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ import ContainerAPIClient
1919
import ContainerAPIService
2020
import ContainerLog
2121
import ContainerNetworkService
22+
import ContainerPersistence
2223
import ContainerPlugin
2324
import ContainerResource
2425
import ContainerXPC
26+
import ContainerizationExtras
2527
import DNSServer
2628
import Foundation
2729
import Logging
@@ -316,6 +318,8 @@ extension APIServer {
316318
let config = try NetworkConfiguration(
317319
id: NetworkClient.defaultNetworkName,
318320
mode: .nat,
321+
ipv4Subnet: try? DefaultsStore.getOptional(key: .defaultSubnet).map { try CIDRv4($0) },
322+
ipv6Subnet: try? DefaultsStore.getOptional(key: .defaultIPv6Subnet).map { try CIDRv6($0) },
319323
labels: try .init([ResourceLabelKeys.role: ResourceRoleValues.builtin]),
320324
pluginInfo: NetworkPluginInfo(plugin: "container-network-vmnet")
321325
)
@@ -324,9 +328,13 @@ extension APIServer {
324328

325329
let harness = NetworksHarness(service: service, log: log)
326330

327-
routes[XPCRoute.networkCreate] = harness.create
328-
routes[XPCRoute.networkDelete] = harness.delete
329-
routes[XPCRoute.networkList] = harness.list
331+
// network creation/deletion/list is not supported pre-macOS 26 (refer to AllocationOnlyVmnetNetwork)
332+
if #available(macOS 26, *) {
333+
routes[XPCRoute.networkCreate] = harness.create
334+
routes[XPCRoute.networkDelete] = harness.delete
335+
routes[XPCRoute.networkList] = harness.list
336+
}
337+
330338
return service
331339
}
332340

Sources/Services/ContainerNetworkService/Server/AllocationOnlyVmnetNetwork.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
// limitations under the License.
1515
//===----------------------------------------------------------------------===//
1616

17-
import ContainerPersistence
1817
import ContainerResource
1918
import ContainerXPC
2019
import ContainerizationError
@@ -23,6 +22,9 @@ import Foundation
2322
import Logging
2423

2524
public actor AllocationOnlyVmnetNetwork: Network {
25+
// The IPv4 subnet to be used if none explicitly passed in the `NetworkConfiguration`
26+
private static let defaultIPv4Subnet = try! CIDRv4("192.168.64.1/24")
27+
2628
private let log: Logger
2729
private var _state: NetworkState
2830

@@ -36,8 +38,8 @@ public actor AllocationOnlyVmnetNetwork: Network {
3638
throw ContainerizationError(.unsupported, message: "invalid network mode \(configuration.mode)")
3739
}
3840

39-
guard configuration.ipv4Subnet == nil else {
40-
throw ContainerizationError(.unsupported, message: "IPv4 subnet assignment is not yet implemented")
41+
guard configuration.ipv6Subnet == nil else {
42+
throw ContainerizationError(.unsupported, message: "IPv6 subnet assignment is not yet implemented")
4143
}
4244

4345
self.log = log
@@ -65,8 +67,8 @@ public actor AllocationOnlyVmnetNetwork: Network {
6567
]
6668
)
6769

68-
let defaultIPv4Subnet = try CIDRv4(DefaultsStore.get(key: .defaultSubnet))
69-
let ipv4Subnet = configuration.ipv4Subnet ?? defaultIPv4Subnet
70+
let ipv4Subnet = configuration.ipv4Subnet ?? Self.defaultIPv4Subnet
71+
7072
let gateway = IPv4Address(ipv4Subnet.lower.value + 1)
7173
let status = NetworkStatus(
7274
ipv4Subnet: ipv4Subnet,

Sources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
// limitations under the License.
1515
//===----------------------------------------------------------------------===//
1616

17-
import ContainerPersistence
1817
import ContainerResource
1918
import ContainerXPC
2019
import Containerization
@@ -117,11 +116,8 @@ public final class ReservedVmnetNetwork: Network {
117116

118117
vmnet_network_configuration_disable_dhcp(vmnetConfiguration)
119118

120-
// subnet priority is CLI argument, UserDefault, auto
121-
let defaultIpv4Subnet = try DefaultsStore.getOptional(key: .defaultSubnet).map { try CIDRv4($0) }
122-
let ipv4Subnet = configuration.ipv4Subnet ?? defaultIpv4Subnet
123-
let defaultIpv6Subnet = try DefaultsStore.getOptional(key: .defaultIPv6Subnet).map { try CIDRv6($0) }
124-
let ipv6Subnet = configuration.ipv6Subnet ?? defaultIpv6Subnet
119+
let ipv4Subnet = configuration.ipv4Subnet
120+
let ipv6Subnet = configuration.ipv6Subnet
125121

126122
// set the IPv4 subnet if the caller provided one
127123
if let ipv4Subnet {

0 commit comments

Comments
 (0)