# How Container Integrates with the vmnet Framework for Container Networking

> Discover how container integrates with the vmnet framework. Learn about XPC helper services, macOS vmnet API calls, and network configurations for seamless container networking.

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

---

**Container integrates with the vmnet framework through an XPC helper service that translates high-level network configurations into macOS vmnet API calls, creating NAT or host-only networks and serializing the network references for container runtime attachment.**

The `apple/container` project implements container networking on macOS by leveraging the native **vmnet** framework, providing NAT and host-only connectivity for Linux containers. This integration bridges the gap between high-level network management commands and low-level macOS virtualization APIs through a carefully architected XPC service. Understanding this **container vmnet framework integration** reveals how the project achieves performant, native networking without requiring third-party kernel extensions.

## Architecture Overview

The container vmnet framework integration follows a three-layer architecture that separates user commands from privileged virtualization operations:

- **CLI Layer**: Parses `container network` commands and constructs `NetworkConfiguration` objects in [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift)
- **XPC Helper Layer**: The `container-network-vmnet` service receives configurations via the `ContainerNetworkServer` API and manages vmnet network lifecycle
- **Runtime Layer**: The `container-runtime-linux` helper deserializes network references and creates container interfaces

This design ensures that privileged vmnet operations remain isolated within the XPC service while the runtime handles container-specific network attachment.

## Network Creation and Configuration Flow

### CLI Network Definition

When a user executes `container network create`, the CLI builds a `NetworkConfiguration` structure that specifies the operating mode (NAT or host-only), IPv4/IPv6 subnets, labels, and the plugin name (defaulting to `container-network-vmnet`). In [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift), this configuration is validated and passed to the XPC helper via the `ContainerNetworkServer` module.

### XPC Helper Translation

The `container-network-vmnet` helper implements the `Network` protocol defined in the `ContainerNetworkServer` target. In [`Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift`](https://github.com/apple/container/blob/main/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift), the helper receives the configuration and instantiates `ReservedVmnetNetwork` to handle the low-level vmnet operations.

## vmnet Network Initialization

The `ReservedVmnetNetwork` class in [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift) manages the direct interaction with the vmnet framework.

### Operating Mode Selection

The helper selects the appropriate vmnet operating mode based on the configuration:

- **`.VMNET_SHARED_MODE`**: Used for NAT networking (default), allowing containers to access external networks through the host
- **`.VMNET_HOST_MODE`**: Used for host-only networking when the `--internal` flag is specified

### Subnet Configuration and DHCP Disablement

The implementation disables DHCP since the helper manages its own address allocation:

```swift
// ReservedVmnetNetwork.swift - Disabling DHCP
// Lines 16-18
config.ipv4_disable_dhcp = true
config.ipv6_disable_dhcp = true

```

When subnets are provided, the helper populates the vmnet configuration using native API calls:

```swift
// Lines 30-34
if let subnet = ipv4Subnet {
    guard vmnet_network_configuration_set_ipv4_subnet(&config, subnet) == VMNET_SUCCESS else {
        throw error
    }
}

// Lines 40-44
if let prefix = ipv6Prefix {
    guard vmnet_network_configuration_set_ipv6_prefix(&config, prefix) == VMNET_SUCCESS else {
        throw error
    }
}

```

### Network Creation and Reference Storage

After configuration, the network is created and stored:

```swift
// Lines 54-58
var status = vmnet_network_status_t()
let networkRef = vmnet_network_create(&config, &status)
guard status == VMNET_SUCCESS else {
    throw error
}
self.vmnetNetworkRef = networkRef

```

## Runtime Attachment and Interface Binding

### Serialization via vmnet_network_copy_serialization

When containers need to attach to the network, the helper serializes the `vmnet_network_ref` into an XPC message that can be transferred to the runtime:

```swift
// ReservedVmnetNetwork.swift - Lines 92-99
var serialization = vmnet_network_serialization_t()
var serializationLength = 0
guard vmnet_network_copy_serialization(vmnetNetworkRef, &serialization, &serializationLength) == VMNET_SUCCESS else {
    throw error
}
// Attach to XPC message for runtime transfer

```

### Deserialization and NATNetworkInterface Creation

In [`Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift), the runtime helper receives the XPC data and reconstructs the network reference:

```swift
// Lines 35-53
let networkRef = vmnet_network_create_with_serialization(additionalData.underlying, &status)
guard status == VMNET_SUCCESS else {
    throw error
}

let interface = NATNetworkInterface(
    ipv4Address: attachment.ipv4Address,
    ipv4Gateway: attachment.ipv4Gateway,
    reference: networkRef,
    macAddress: attachment.macAddress,
    mtu: attachment.mtu ?? 1280
)

```

This `NATNetworkInterface` encapsulates the container's IPv4 address, gateway, MAC address, and the underlying vmnet reference.

## Address Allocation and Network Lifecycle

The helper allocates IP addresses from the configured subnet automatically. In NAT mode, the first container receives the gateway address while subsequent containers receive sequential IPs. For host-only mode, the same allocation mechanism applies without NAT translation.

The network lifecycle supports inspect and stop operations via the `ContainerNetworkServer` API, reporting active subnets and gateway information back to the CLI.

## Practical Examples

Create a NAT network using the default vmnet plugin:

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

```

Create a host-only network with specific subnet:

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

```

Inspect network configuration:

```bash
container network inspect my-net

```

## Platform Requirements and Limitations

The vmnet framework integration requires **macOS 26+** for full functionality, marked with `@available(macOS 26, *)` in the source. On macOS 15, the framework supports only isolated host-only networks, reflecting the API limitations documented in the technical overview.

## Summary

- **Container vmnet framework integration** relies on an XPC helper service (`container-network-vmnet`) to proxy vmnet operations from the CLI to the macOS kernel
- The `ReservedVmnetNetwork` class configures vmnet using `VMNET_SHARED_MODE` for NAT or `VMNET_HOST_MODE` for host-only networking, always disabling DHCP
- Network references are serialized using `vmnet_network_copy_serialization` and deserialized in the runtime via `vmnet_network_create_with_serialization` to create `NATNetworkInterface` instances
- IP address allocation and gateway assignment are managed by the helper, not the vmnet DHCP server
- Full functionality requires macOS 26 or later, with limited host-only support on macOS 15

## Frequently Asked Questions

### What is the vmnet framework and why does Container use it?

The vmnet framework is Apple's native macOS API for creating virtual networks without kernel extensions. Container uses it to provide high-performance, NAT, and host-only networking for Linux containers while maintaining compatibility with macOS virtualization standards and security models.

### What is the difference between NAT and host-only networking modes in Container?

NAT mode (`VMNET_SHARED_MODE`) allows containers to access external networks through the host's internet connection, while host-only mode (`VMNET_HOST_MODE`) creates an isolated network where containers can only communicate with the host and other containers on the same network. The mode is selected via the `--internal` flag during network creation.

### How does the XPC helper service improve security in Container's vmnet integration?

The XPC helper isolates privileged vmnet operations (`vmnet_network_create`, interface configuration) into a separate service (`container-network-vmnet`) that runs with elevated privileges, while the main CLI and runtime operate with reduced permissions. This follows the principle of least privilege, ensuring that only the minimal necessary code interacts with low-level networking APIs.

### Why does Container require macOS 26+ for full vmnet functionality?

The complete vmnet API, including support for NAT networking and network serialization, requires macOS 26 or later. Earlier versions (macOS 15) only support isolated host-only networks without the serialization capabilities needed for the full container runtime integration, as implemented in [`ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/ReservedVmnetNetwork.swift) and [`NonisolatedInterfaceStrategy.swift`](https://github.com/apple/container/blob/main/NonisolatedInterfaceStrategy.swift).