# How the vmnet Framework Enables Container Networking in macOS

> Discover how the vmnet framework enables container networking in macOS. Learn about virtual interfaces, NAT/host-only modes, and automatic IP allocation for seamless container integration.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: internals
- Published: 2026-06-19

---

**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`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift) |
| **XPC Helper** | Translates configuration into vmnet networks and serves them to runtimes | [`Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift`](https://github.com/apple/container/blob/main/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift), [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift) |
| **Runtime** | Deserializes vmnet references and connects container virtual NICs | [`Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift), the `ReservedVmnetNetwork` class creates the underlying vmnet network object:

1. **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).

2. **DHCP Configuration**: The framework's built-in DHCP is disabled because the helper manages its own address allocation (lines 16-18).

3. **Subnet Configuration**: If the user provided subnets, the helper populates the vmnet configuration using `vmnet_network_configuration_set_ipv4_subnet` and `vmnet_network_configuration_set_ipv6_prefix` (lines 30-34 and 40-44).

4. **Network Creation**: The network is instantiated with `vmnet_network_create`, and the resulting `vmnet_network_ref` is 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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/docs/technical-overview.md) (lines 36-38 and 65-73).

## Practical Usage Examples

Create a NAT network with default settings:

```bash
container network create \
    --label env=dev \
    --option mtu=1500 \
    my-net

```

Create a host-only network with a specific subnet:

```bash
container network create \
    --internal \
    --subnet 10.0.0.0/24 \
    host-only-net

```

Inspect an existing network to view subnet and gateway information:

```bash
container network inspect my-net

```

Deserialize a vmnet reference and create a network interface in the runtime:

```swift
// 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 `ReservedVmnetNetwork` class in [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift) configures vmnet objects with specific modes (NAT or host-only) and custom subnets.
- Network references are serialized using `vmnet_network_copy_serialization` and reconstructed in the runtime using `vmnet_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`](https://github.com/apple/container/blob/main/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.