Skip to content

Unikraft guest network ignores container subnet mask (hardcoded /24) in current-version args path #827

Description

@Aditya-132

Description

For Unikraft unikernels running version >= 0.16.1 (or with an undefined/unparsable version), urunc builds the guest network configuration in setCurrentArgs() inside configureUnikraftArgs() (pkg/unikontainers/unikernels/unikraft.go):

u.Net.Address = "netdev.ip=" + ethDeviceIP + "/24:" + ethDeviceGateway + ":8.8.8.8"

The CIDR prefix is hardcoded to /24 and the ethDeviceMask parameter is completely ignored on this code path. The legacy/compat path (setCompatArgs()) does pass the real mask via netdev.ipv4_subnet_mask=<mask>, so only the "current" path is affected.

Expected behavior

The guest should be configured with the same subnet mask as the container interface, exactly like the other unikernel targets do (Mirage, Hermit, Mewz all convert the mask with subnetMaskToCIDR() and use the real prefix). The same class of bug was already fixed for MirageOS in #693.

Actual behavior

Any container network with a prefix other than /24 produces a guest with a wrong netmask. For example, with a Calico or Flannel CNI subnet of 10.244.0.0/16 the guest is still configured as /24, so guest routing decisions (what is on-link vs behind the gateway) diverge from the actual network topology, which can break pod-to-pod traffic.

Steps to reproduce

  1. Run a Unikraft (>= 0.16.1) unikernel container on a network whose subnet is not /24, e.g. docker network create --subnet 172.20.0.0/26 ... or any /16 CNI setup.
  2. Inspect the kernel command line urunc passes to the monitor (debug logs).
  3. The netdev.ip= argument always ends up with /24 regardless of the actual mask.

Proposed fix

Convert ethDeviceMask with the existing subnetMaskToCIDR() helper and use the resulting prefix in setCurrentArgs(). Keep /24 only as fallback when no mask is provided (no-network case), and return an error for a malformed mask, consistent with how Mirage/Hermit/Mewz handle it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions