How the vmnet Framework Enables Container Networking in macOS
The vmnet framework provides container networking in macOS by creating virtual network interfaces through an XPC helper service that translates high-level network configurations into kernel-level vmnet objects, supporting both NAT and host-only modes with automatic IP allocation.
The apple/container project implements container networking on macOS using the native vmnet framework. This integration allows containers to communicate through virtual network interfaces managed directly by the operating system's virtualization APIs. The architecture relies on a multi-layered design involving CLI tools, XPC services, and runtime components to create, serialize, and attach virtual networks to containers.
Architecture Overview
The vmnet framework integration consists of three distinct layers that handle network lifecycle management:
| Layer | Responsibility | Key Files |
|---|---|---|
| CLI | Parses container network commands and builds NetworkConfiguration |
Sources/ContainerCommands/Network/NetworkCreate.swift |
| XPC Helper | Translates configuration into vmnet networks and serves them to runtimes | Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift, Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift |
| Runtime | Deserializes vmnet references and connects container virtual NICs | Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift |
Network Creation and Configuration Workflow
CLI Layer and Network Definition
When a user executes container network create, the CLI tool defined in Sources/ContainerCommands/Network/NetworkCreate.swift constructs a NetworkConfiguration object. This configuration specifies the operating mode (NAT or host-only), optional IPv4/IPv6 subnets, labels, and the plugin name (defaulting to container-network-vmnet). The CLI then invokes the XPC service exported by the ContainerNetworkServer module declared in Package.swift.
XPC Helper and vmnet Instantiation
The container-network-vmnet helper receives the request via the ContainerNetworkServer API. Inside Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift, the ReservedVmnetNetwork class creates the underlying vmnet network object:
-
Mode Selection: The helper selects the operating mode based on the configuration. For host-only networks, it uses
.VMNET_HOST_MODE; for NAT networks, it uses.VMNET_SHARED_MODE(lines 10-14). -
DHCP Configuration: The framework's built-in DHCP is disabled because the helper manages its own address allocation (lines 16-18).
-
Subnet Configuration: If the user provided subnets, the helper populates the vmnet configuration using
vmnet_network_configuration_set_ipv4_subnetandvmnet_network_configuration_set_ipv6_prefix(lines 30-34 and 40-44). -
Network Creation: The network is instantiated with
vmnet_network_create, and the resultingvmnet_network_refis stored in the network's state (lines 54-58).
Runtime Attachment and Interface Creation
When a container runtime needs to attach to the network, the helper serializes the vmnet_network_ref using vmnet_network_copy_serialization (lines 92-99). This serialized reference is passed via XPC to the runtime component.
In Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift (lines 35-53), the runtime deserializes the reference with vmnet_network_create_with_serialization and constructs a NATNetworkInterface object. This interface encapsulates the container's IPv4 address, optional gateway, MAC address, MTU, and the vmnet reference.
vmnet Framework Configuration Details
Operating Modes
The vmnet framework supports two primary networking modes for containers:
- NAT Mode (
.VMNET_SHARED_MODE): Provides outbound network access through NAT translation. The first container attached to the network receives the gateway address. - Host-Only Mode (
.VMNET_HOST_MODE): Creates an isolated network where containers can communicate with the host but not external networks. This mode is available on macOS 15, though full functionality requires macOS 26+.
IP Address Allocation
The helper allocates container IP addresses from the configured subnet. For NAT mode, the first container gets the gateway address and subsequent containers receive the next available IPs. For host-only mode, the same allocation mechanism applies but without NAT translation.
Network Serialization
The serialization process is critical for passing network capabilities between processes. The helper uses vmnet_network_copy_serialization to convert the vmnet_network_ref into an XPC-compatible format. The runtime reconstructs this reference using vmnet_network_create_with_serialization, enabling the container process to create virtual interfaces without direct access to the original network configuration.
Platform Requirements and Limitations
Because the vmnet framework is only fully available on macOS 26+, the helper is compiled with @available(macOS 26, *). On macOS 15, the framework can only provide isolated host-only networks, which limits the networking capabilities available to containers. These limitations are documented in the technical overview at docs/technical-overview.md (lines 36-38 and 65-73).
Practical Usage Examples
Create a NAT network with default settings:
container network create \
--label env=dev \
--option mtu=1500 \
my-net
Create a host-only network with a specific subnet:
container network create \
--internal \
--subnet 10.0.0.0/24 \
host-only-net
Inspect an existing network to view subnet and gateway information:
container network inspect my-net
Deserialize a vmnet reference and create a network interface in the runtime:
// In container-runtime-linux
let additionalData: XPCMessage = // received from XPC helper
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)
Summary
- The vmnet framework integration provides container networking through a three-layer architecture: CLI, XPC helper, and runtime.
- The
ReservedVmnetNetworkclass inSources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swiftconfigures vmnet objects with specific modes (NAT or host-only) and custom subnets. - Network references are serialized using
vmnet_network_copy_serializationand reconstructed in the runtime usingvmnet_network_create_with_serialization. - Full functionality requires macOS 26+, while macOS 15 supports only limited host-only networking.
Frequently Asked Questions
What is the vmnet framework?
The vmnet framework is a macOS system API that provides virtual network interfaces for virtualization applications. According to the apple/container source code, it allows the creation of software-defined networks that can operate in NAT or host-only modes, with the kernel handling packet routing and interface management.
How does container networking differ between NAT and host-only modes?
NAT mode (.VMNET_SHARED_MODE) allows containers to access external networks through address translation, while host-only mode (.VMNET_HOST_MODE) restricts communication to the host and other containers on the same network. As implemented in ReservedVmnetNetwork.swift, NAT networks assign the first IP as a gateway, whereas host-only networks provide complete isolation without external routing.
Why is macOS 26+ required for full vmnet functionality?
The vmnet framework APIs necessary for shared network modes and advanced configuration are only available starting with macOS 26. The source code marks the helper implementation with @available(macOS 26, *) because earlier versions, such as macOS 15, only support isolated host-only networks, limiting the networking topology available to containers.
How does the runtime communicate with the network helper?
The runtime communicates through XPC (Inter-Process Communication) services. The ContainerNetworkServer API defines the protocol, and the container-network-vmnet helper serializes the vmnet_network_ref using vmnet_network_copy_serialization. The runtime receives this data and reconstructs the reference using vmnet_network_create_with_serialization to attach the container's virtual NIC.
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 →