How Container Networking Works with the vmnet Framework in Apple Container
Container networking in the apple/container project leverages macOS's vmnet framework through an XPC-based architecture that translates network configurations into virtual interfaces, supporting both NAT and host-only modes with automatic IP allocation.
The apple/container repository implements container networking on macOS using the native vmnet framework. This integration enables Linux containers to communicate through virtual network interfaces managed by an XPC helper service. The architecture bridges high-level CLI commands with low-level macOS virtualization APIs through a deterministic three-layer design.
Three-Layer Architecture
The implementation consists of three distinct layers that handle network lifecycle management from creation to container attachment.
CLI Layer – Parses container network … commands and constructs NetworkConfiguration objects. The NetworkCreate.swift file handles user input and validates subnet allocations and network modes.
XPC Helper Layer – The container-network-vmnet service receives configuration via the ContainerNetworkServer API. It implements the Network protocol and manages the actual vmnet objects through the ReservedVmnetNetwork class.
Runtime Layer – The container-runtime-linux helper deserializes vmnet references and creates NATNetworkInterface instances for container attachment.
Network Creation and CLI Configuration
When users execute container network create, the CLI builds a complete configuration that specifies the networking mode and addressing scheme.
container network create \
--label env=dev \
--option mtu=1500 \
my-net
The NetworkCreate.swift implementation constructs a NetworkConfiguration containing the operating mode (NAT or host-only), optional IPv4/IPv6 subnets, and the plugin name (default container-network-vmnet). This configuration passes to the XPC helper through the ContainerNetworkServer interface defined in Package.swift.
vmnet Implementation in the XPC Helper
The ReservedVmnetNetwork class in Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift translates high-level configuration into vmnet framework calls.
Mode Selection – The helper selects the appropriate operating constant:
.VMNET_HOST_MODEfor host-only networks.VMNET_SHARED_MODEfor NAT networks
DHCP Handling – The implementation explicitly disables DHCP since the helper manages its own address allocation using vmnet_network_configuration_set_dhcp_disabled.
Subnet Configuration – When users specify subnets, the helper populates the configuration using vmnet_network_configuration_set_ipv4_subnet and vmnet_network_configuration_set_ipv6_prefix.
Network Instantiation – The network is created through the framework's creation function:
// From ReservedVmnetNetwork.swift
let network = vmnet_network_create(&config, &status)
The resulting vmnet_network_ref is stored in the network's state for later serialization and attachment.
Runtime Integration and Interface Attachment
When a container starts, the runtime must attach to the pre-created network. The helper serializes the vmnet_network_ref using vmnet_network_copy_serialization into an XPC message that crosses process boundaries.
In Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift, the runtime receives this data and reconstructs the network reference:
let networkRef = vmnet_network_create_with_serialization(additionalData.underlying, &status)
let iface = NATNetworkInterface(
ipv4Address: attachment.ipv4Address,
ipv4Gateway: attachment.ipv4Gateway,
reference: networkRef,
macAddress: attachment.macAddress,
mtu: attachment.mtu ?? 1280)
This creates a fully configured network interface within the container's namespace, complete with MAC address and MTU settings.
Network Modes and Address Allocation
The framework supports two primary operating modes with distinct networking behaviors.
NAT Mode (VMNET_SHARED_MODE) – Allows containers to access external networks through address translation. The first container receives the gateway address, with subsequent containers allocated sequential IPs from the configured subnet.
Host-Only Mode (VMNET_HOST_MODE) – Creates isolated networks without external connectivity. The same allocation mechanism applies, but traffic remains confined to the host system.
Users specify modes through CLI flags:
# Host-only network with specific subnet
container network create \
--internal \
--subnet 10.0.0.0/24 \
host-only-net
Platform Requirements and Limitations
The vmnet framework integration requires macOS 26 or later, indicated by the @available(macOS 26, *) compiler attribute throughout the codebase. On macOS 15, the framework only supports isolated host-only networks without the full serialization capabilities required for runtime attachment, as documented in docs/technical-overview.md.
Summary
- Container networking uses the vmnet framework through a three-layer architecture: CLI, XPC helper, and runtime.
- The
ReservedVmnetNetworkclass configures vmnet objects withvmnet_network_createand manages DHCP-disabled subnets. - Network references serialize via
vmnet_network_copy_serializationand deserialize in the runtime viavmnet_network_create_with_serialization. - NAT and host-only modes map to
VMNET_SHARED_MODEandVMNET_HOST_MODErespectively. - Full functionality requires macOS 26+, while macOS 15 supports limited host-only networking.
Frequently Asked Questions
What is the vmnet framework's role in container networking?
The vmnet framework provides the underlying virtual network interface infrastructure on macOS. In the apple/container project, it creates isolated network segments that bridge container traffic to the host system, enabling both NAT-based external connectivity and host-only internal communication without requiring third-party kernel extensions.
How does the container runtime connect to a vmnet network?
The runtime connects through serialized network references. The XPC helper creates a vmnet network and serializes the reference using vmnet_network_copy_serialization. The runtime receives this data through XPC, deserializes it with vmnet_network_create_with_serialization, and constructs a NATNetworkInterface that binds the container's virtual NIC to the network.
What are the differences between NAT and host-only modes?
NAT mode (VMNET_SHARED_MODE) allows containers to access external networks via address translation, while host-only mode (VMNET_HOST_MODE) restricts communication to the host machine only. Both modes use the same IP allocation mechanism in ReservedVmnetNetwork, but NAT mode configures a gateway address for external traffic routing.
Why does container networking require macOS 26 or later?
The complete vmnet framework API, including network creation and serialization functions used by ReservedVmnetNetwork, requires macOS 26. Earlier versions like macOS 15 support only limited host-only networking capabilities without the full serialization API needed for runtime attachment and reference sharing between the XPC helper and runtime processes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →