Shared vmnet broker
Apple's macOS 26+ design requires VMs on one custom network to share the same vmnet_network_ref. FluxVM runs each VZ VM in its own
runner process, so a named network needs one owner process. That is fluxvm-vmnetd, in crates/fluxvm-apple/macos/vmnetd/.
Apple provides the supported cross-process mechanism: vmnet_network_copy_serialization over XPC, then
vmnet_network_create_with_serialization in the receiving process. The serialisation object is passed as an XPC object and is never
turned into JSON or text.
What exists
- Service.
fluxvm-vmnetdis a per-user launch agent that listens on the Mach servicedev.zyvor.fluxvm.vmnetd. It needs macOS 26+. - Commands. One XPC dictionary per request, with an
opof:acquire: create the named network from the request (mode,subnet,mask, optionalreserved_ipwithmac, andforwards), or return the existing one; the reply carries the serialised network (network) and the reference count (refs).release: drop one reference; the network is removed when the count reaches zero.list: names and reference counts of the networks the broker holds.
- Names. 1 to 64 characters from
[A-Za-z0-9._-], checked when the VM is admitted (validate_vmnet). The broker itself only checks for a non-empty name of at most 64 bytes. - Reuse. Acquiring an existing name with a different configuration (mode, subnet, mask, MAC, reserved address or forwards) is rejected with "network name already exists with a different configuration".
- State. The broker keeps networks in memory only. Nothing is persisted, so restarting it drops every named network.
- Runner side.
apple.vmnet.namemakes a network named and shareable; the runner acquires it throughVmnetSerialization.swiftand releases it when the VM stops. An unnamedapple.vmnetkeeps the existing per-runner network and does not touch the broker. If the broker is not running, a named network fails withvmnetd XPC connection failed. - Install.
crates/fluxvm-apple/macos/vmnetd/build-install.sheither builds from source (macOS 26 target, ad hoc signed with the virtualization entitlement only, installed to/usr/local/libexec/fluxvm-vmnetdwithsudo) or, withFLUXVM_PACKAGE_DIR, uses a release package's Developer ID signedlibexec/FluxVMNetworking.app, the only form that can holdcom.apple.vm.networking(macos-signing.md). Either way it bootstraps the launch agent withlaunchctl.
What is verified
On the test Mac (Apple M4, macOS 27.2, SIP on) the original build, ad-hoc signed with com.apple.vm.networking, was killed at
launch (exit 137): that entitlement is restricted and needs an Apple-issued provisioning profile. Signed with only
com.apple.security.virtualization the broker starts under launchd and vmnet_network_create succeeds in it. But a VM cannot use
the network: Virtualization starts the VM and then reports Internal Network Error (network-disconnected), the same for a
named network through the broker and for an unnamed one created inside the runner, so the cause is the runner lacking
com.apple.vm.networking, not the sharing. This is therefore unusable on a Mac without that entitlement's provisioning profile.
Admission now refuses apple.vmnet (and apple.bridge_interface) when the runner does not hold it. For networks shared between
guests without the entitlement use apple.networks (private layer-2 networks, fluxvm-vz-switch), and for a controlled NAT
apple.usernet.
Two runners sharing one apple.vmnet.name has never run, for that reason.