# How Apple Container Integrates with vmnet for macOS Networking: A Technical Deep Dive

> Discover how Apple container uses vmnet for macOS networking. Learn about virtual network creation, IP allocation, and attaching namespaces via the C API.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: deep-dive
- Published: 2026-07-02

---

**Apple `container` leverages the macOS vmnet framework through the `container-network-vmnet` XPC helper plugin to create virtual networks, allocate IP addresses from a default 192.168.64.1/24 subnet, and attach container namespaces to vmnet interfaces using the native C API.**

The apple/container project provides Linux container support on macOS by integrating with the kernel-level vmnet framework for virtual network management. This apple container vmnet integration relies on a specialized XPC service that bridges the Swift-based container runtime with the underlying vmnet APIs, handling everything from network creation to IP address allocation and interface wiring.

## The vmnet Integration Architecture

The networking stack is split between a privileged XPC helper and the container runtime. The helper manages the lifecycle of vmnet networks, while the runtime requests allocations and attaches containers to these virtual interfaces.

- **XPC Helper (`container-network-vmnet`)**: Runs as a privileged service to create vmnet networks and manage IP reservations.
- **Network Strategies**: Two distinct approaches handle reserved networks versus standard container networks.
- **Runtime Wiring**: The Linux container runtime receives network attachments via XPC and links them to the container's network namespace.

## XPC Helper and Network Creation

The heart of the integration lives in [`Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift`](https://github.com/apple/container/blob/main/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift). This XPC service initializes vmnet networks by calling `vmnet_network_configuration_create` followed by `vmnet_network_create` or `vmnet_network_create_with_serialization` for reserved networks.

In [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift), the implementation configures the IPv4 subnet using `vmnet_network_configuration_set_ipv4_subnet` and optionally sets IPv6 prefixes with `vmnet_network_configuration_set_ipv6_prefix`. The code explicitly disables DHCP via `vmnet_network_configuration_disable_dhcp()` since the helper manages IP allocation directly.

The network reference (`vmnet_network_ref`) is serialized using `vmnet_network_copy_serialization` to persist the configuration across container restarts, ensuring that the virtual network survives individual container lifecycles.

## Interface Strategies: Reserved vs Nonisolated

The codebase implements two distinct strategies for vmnet network attachment:

**`ReservedInterfaceStrategy`** (found in [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift)): Used for reserved networks that require persistent configuration and serialization. This strategy calls `vmnet_network_create_with_serialization` to restore or create a network with specific parameters.

**`NonisolatedInterfaceStrategy`** (located in [`Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift)): Handles standard container networks without persistence requirements. It uses the standard `vmnet_network_create` API and configures the mode—either `VMNET_HOST_MODE` for host-only networking or `VMNET_SHARED_MODE` for NAT-backed connectivity.

Both strategies communicate with the same XPC helper but differ in how they allocate and maintain the underlying `vmnet_network_ref`.

## Container Runtime Wiring

When a container launches, the runtime requests a network allocation from the helper via the `container-network-vmnet allocate` command. The helper returns an XPC message containing:

- **Hostname**: The DNS name for the container
- **IP Address**: Assigned from the 192.168.64.0/24 range (e.g., 192.168.64.2/24)
- **Gateway**: Typically 192.168.64.1
- **Network ID**: The vmnet network identifier (usually "default")

The runtime then creates a virtual network interface in the container's Linux network namespace and wires it to the vmnet attachment. This process is visible in the helper logs:

```bash
container-network-vmnet: allocated attachment [hostname=my-web-server.test.] \
  [address=192.168.64.2/24] [gateway=192.168.64.1] [id=default]

```

## CLI and System Startup Integration

The [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift) file handles the `container network create` command, which forwards the `--plugin container-network-vmnet` flag to the helper. While this is the default plugin, explicit specification ensures the vmnet backend is used.

System initialization triggers network creation automatically:

```bash

# Creates the default vmnet network on first run

container system start

```

The first container start causes the helper to instantiate the vmnet network named "default" if it does not already exist. Subsequent containers receive allocations from this existing network rather than creating new virtual infrastructure.

## macOS 15 Constraints and Limitations

According to the technical documentation in the repository, several important constraints govern the apple container vmnet integration on macOS 15:

- **Single Network Limit**: macOS 15 supports only a single shared VMnet network. The `--network` flag is rejected if attempting to create additional networks.
- **Container Isolation**: The VMnet framework isolates each container's NIC, meaning **container-to-container communication is not supported** on macOS 15. Each container can reach the host and external networks (in shared mode) but cannot directly address other containers.
- **Subnet Synchronization**: All containers share the default 192.168.64.1/24 network. If the network helper and VMnet framework disagree on subnet configuration, containers may experience connectivity loss.

## Practical Configuration Examples

Start the container system to initialize the default vmnet network:

```bash
container system start

```

Verify the network is active and inspect allocations:

```bash
container network list

```

Run a container using the default vmnet network (no plugin flag required as it is the default):

```bash
container run -it --name demo alpine sh

```

Inside the container, verify the vmnet-assigned IP:

```bash
ip addr show eth0

# Expected output includes: inet 192.168.64.2/24 ...

```

## Summary

- The `container-network-vmnet` XPC helper in [`Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift`](https://github.com/apple/container/blob/main/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift) manages vmnet network lifecycle and IP allocation.
- Network creation uses `vmnet_network_create` or `vmnet_network_create_with_serialization` with explicit DHCP disabling via `vmnet_network_configuration_disable_dhcp()`.
- Two strategies—`ReservedInterfaceStrategy` and `NonisolatedInterfaceStrategy`—handle different persistence and isolation requirements.
- Containers receive IP addresses from the 192.168.64.0/24 subnet with the gateway at 192.168.64.1.
- macOS 15 limits deployments to a single vmnet network and does not support container-to-container traffic.

## Frequently Asked Questions

### How does the container runtime communicate with vmnet?

The runtime communicates through an XPC service called `container-network-vmnet`. This privileged helper translates high-level container network requests into vmnet framework API calls, creating network references and returning allocation details back to the runtime via XPC messages.

### Why is DHCP disabled in the vmnet configuration?

The apple/container implementation disables DHCP using `vmnet_network_configuration_disable_dhcp()` because the XPC helper manages IP allocation directly. This prevents conflicts between the vmnet framework's DHCP server and the container project's IP address management, ensuring consistent address assignments from the 192.168.64.0/24 range.

### Can I create multiple vmnet networks for different container groups?

On macOS 15, no. The current implementation only supports a single shared vmnet network named "default." Attempting to specify alternative networks via the `--network` flag results in rejection. All containers must share the same 192.168.64.1/24 subnet, though they remain isolated from each other at the network interface level.

### What happens if the vmnet helper and the framework disagree on the subnet?

If the `container-network-vmnet` helper's configured subnet conflicts with the vmnet framework's actual network configuration, containers may lose network connectivity entirely. Both components must agree on the 192.168.64.1/24 default (or any custom configured subnet) for traffic to flow correctly between the container, host, and external networks.