Summary
When spawning a unikernel using the DynamicNetwork configuration, urunc attempts to ensure that only a single unikernel is run inside the current network namespace. It checks for existing TAP interfaces by calling getTapIndex(). If tapIndex > 0, it aborts container startup and throws the following error:
unsupported operation: can't spawn multiple unikernels in the same network namespace
However, the current check in getTapIndex() is too broad because it scans for any network interface containing the substring "tap" in its name:
for _, iface := range ifaces {
if strings.Contains(iface.Name, "tap") {
tapCount++
}
}
Detailed Problem & Scenarios
This simplistic check introduces two main issues:
-
False Positives with Unrelated Interfaces:
In containerized or Kubernetes environments, CNI plugins or host systems often create virtual interfaces, bridges, or tunnels that contain the word "tap" (such as cni-tap0, vlan-tap, or tap-master). If any such interface is present in the network namespace, getTapIndex() will return 1, causing urunc to falsely believe a unikernel is already running and refuse to spawn the first container.
-
Blocking on Stale Interfaces:
If a previous urunc container execution crashes or is terminated uncleanly before it can delete its TAP device (tap0_urunc), the dead device remains in the namespace. On subsequent container launch attempts, getTapIndex() will detect the stale tap0_urunc device and fail to start any new containers, instead of reusing the name or cleaning it up.
Affected Code
getTapIndex() in pkg/network/network.go (around lines 65-80)
NetworkSetup() in pkg/network/network_dynamic.go (around lines 36-42)
Expected Behavior
urunc should only count TAP interfaces that match the naming pattern of its own created devices (i.e. ^tap\d+_urunc$).
Suggested Fix
Update getTapIndex() in pkg/network/network.go to compile and match the exact regex pattern of urunc tap devices (the same regex used in CleanupAllUruncTaps):
func getTapIndex() (int, error) {
ifaces, err := net.Interfaces()
if err != nil {
return 0, err
}
tapRe := regexp.MustCompile(`^tap\d+_urunc$`)
tapCount := 0
for _, iface := range ifaces {
if tapRe.MatchString(iface.Name) {
tapCount++
}
}
if tapCount > 255 {
return tapCount, fmt.Errorf("TAP interfaces count higher than 255")
}
return tapCount, nil
}
Summary
When spawning a unikernel using the
DynamicNetworkconfiguration,uruncattempts to ensure that only a single unikernel is run inside the current network namespace. It checks for existing TAP interfaces by callinggetTapIndex(). IftapIndex > 0, it aborts container startup and throws the following error:unsupported operation: can't spawn multiple unikernels in the same network namespaceHowever, the current check in
getTapIndex()is too broad because it scans for any network interface containing the substring"tap"in its name:Detailed Problem & Scenarios
This simplistic check introduces two main issues:
False Positives with Unrelated Interfaces:
In containerized or Kubernetes environments, CNI plugins or host systems often create virtual interfaces, bridges, or tunnels that contain the word
"tap"(such ascni-tap0,vlan-tap, ortap-master). If any such interface is present in the network namespace,getTapIndex()will return1, causinguruncto falsely believe a unikernel is already running and refuse to spawn the first container.Blocking on Stale Interfaces:
If a previous
urunccontainer execution crashes or is terminated uncleanly before it can delete its TAP device (tap0_urunc), the dead device remains in the namespace. On subsequent container launch attempts,getTapIndex()will detect the staletap0_uruncdevice and fail to start any new containers, instead of reusing the name or cleaning it up.Affected Code
getTapIndex()inpkg/network/network.go(around lines 65-80)NetworkSetup()inpkg/network/network_dynamic.go(around lines 36-42)Expected Behavior
uruncshould only count TAP interfaces that match the naming pattern of its own created devices (i.e.^tap\d+_urunc$).Suggested Fix
Update
getTapIndex()inpkg/network/network.goto compile and match the exact regex pattern ofurunctap devices (the same regex used inCleanupAllUruncTaps):