Skip to content

[Bug]: LinuxContainer installs a link-scope default route when ipv4Gateway is nil #825

Description

@bsaint9

I have done the following

  • I have searched the existing issues
  • I reproduced the issue with Containerization 0.33.1 and confirmed the same logic remains on main

Steps to reproduce

  1. Create a custom type conforming to Containerization.Interface.
  2. Supply an IPv4 address and return nil from ipv4Gateway:
struct GatewaylessInterface: Interface, VZInterface {
    let base: any Interface & VZInterface
    var ipv4Address: CIDRv4 { base.ipv4Address }
    var ipv4Gateway: IPv4Address? { nil }
    var macAddress: MACAddress? { base.macAddress }
    var mtu: UInt32 { base.mtu }
    func device() throws -> VZVirtioNetworkDeviceConfiguration { try base.device() }
}
  1. Start a LinuxContainer whose first and only interface is this gatewayless interface.
  2. Inside the guest, run:
ip -4 route show
ip route get 1.1.1.1

The issue is deterministic in a real Virtualization.framework Linux microVM.

The 0.33.1 public contract documents ipv4Gateway as “The IP address for the default route, or nil for no default route”:
https://github.com/apple/containerization/blob/0.33.1/Sources/Containerization/Interface.swift#L25-L26

However, LinuxContainer calls routeAddDefault(name:ipv4Gateway:) with nil for the first interface:
https://github.com/apple/containerization/blob/0.33.1/Sources/Containerization/LinuxContainer.swift#L631-L654

Current main retains the same semantic behavior through setupInterface: when both gateways are nil it logs “no gateway” and still calls routeAddDefault:
https://github.com/apple/containerization/blob/main/Sources/Containerization/VirtualMachineAgent%2BInterface.swift#L76-L82

Current behavior

The guest receives an on-link default route even though ipv4Gateway is nil:

default dev eth0 scope link
172.16.0.0/24 dev eth0 scope link src 172.16.0.3

Consequently, route lookup treats arbitrary external destinations as directly reachable on eth0 and attempts neighbor resolution on that link.

This does not necessarily provide external connectivity when the backing attachment is private and has no uplink, but it contradicts the public Interface contract and prevents callers from creating a first interface with no default route.

Expected behavior

When ipv4Gateway is nil, LinuxContainer should configure the IPv4 address and link route without installing an IPv4 default route. IPv4 and IPv6 default-route installation should follow their respective optional gateway values.

Environment

  • OS: macOS 26.5.2 (25F84)
  • Xcode: 26.6 (17F113)
  • Swift: Apple Swift 6.3.1
  • Containerization: 0.33.1
  • Architecture: Apple silicon / arm64

Relevant log output

default dev eth0 scope link
172.16.0.0/24 dev eth0 scope link src 172.16.0.3

Code of Conduct

  • I agree to follow this projects Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions