# How Container Networking Works with the vmnet Framework in Apple Container

> Discover how Apple's container networking uses the vmnet framework for virtual interfaces, supporting NAT and host-only modes with automatic IP allocation.

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

---

**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`](https://github.com/apple/container/blob/main/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.

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

```

The [`NetworkCreate.swift`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/Package.swift).

## vmnet Implementation in the XPC Helper

The `ReservedVmnetNetwork` class in [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/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_MODE` for host-only networks
- `.VMNET_SHARED_MODE` for 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:

```swift
// 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`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift), the runtime receives this data and reconstructs the network reference:

```swift
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:

```bash

# 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`](https://github.com/apple/container/blob/main/docs/technical-overview.md).

## Summary

- Container networking uses the vmnet framework through a three-layer architecture: CLI, XPC helper, and runtime.
- The `ReservedVmnetNetwork` class configures vmnet objects with `vmnet_network_create` and manages DHCP-disabled subnets.
- Network references serialize via `vmnet_network_copy_serialization` and deserialize in the runtime via `vmnet_network_create_with_serialization`.
- NAT and host-only modes map to `VMNET_SHARED_MODE` and `VMNET_HOST_MODE` respectively.
- 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.