Conversation
petersen
force-pushed
the
network-fd-without-bridge
branch
from
September 21, 2026 20:39
2536a4b to
7e863c7
Compare
Makes Interface.ipv4Address optional (CIDRv4?) to accommodate interfaces whose address is not known at configuration time, such as an attachment where the address is assigned by an upstream DHCP server or by a service outside of our allocation pool. Updates all existing conformers (NATInterface, NATNetworkInterface, VmnetNetwork.Interface, TAPInterface) and guards the static address and route setup in VirtualMachineAgent+Interface behind an ipv4Address nil-check. The cctl call sites that render an interface address into /etc/hosts now skip the entry when no address is set. Co-authored-by: Curd Becker <me@curd-becker.de>
…e that has one setupInterface installs no default route for an interface without a static IPv4 address, but the loop marked the route as set after the first interface regardless. An address-less interface at eth0 therefore consumed the slot and a later interface with a gateway never got a default route. Only mark the default route as set when the interface actually has an address to install it from.
FileHandleNetworkInterface uses VZFileHandleNetworkDeviceAttachment to attach the container to a file handle where another service can provide an arbitrary network. This might be an entirely simulated network, a virtual network like a VPN, e.g. using Wireguard, but it could also be a bridged physical network from the host where the service will then take over the responsibility of bridging the traffic between the container and host. The guest address is optional: pass ipv4Address and ipv4Gateway to configure it statically, or leave them nil when the address is assigned out of band, for instance by a DHCP server reachable through the file handle. Co-authored-by: Tor Arne Vestbø <torarnv@gmail.com>
Covers the FileHandleNetworkInterface surface: that it defaults to no static address and picks up the Interface protocol defaults, that a caller-supplied address, gateway, and mac round-trip through Interface, and that device() attaches the file handle and applies the mac. Also covers an Interface conformer with no IPv4 address, which the protocol now permits.
Make the interface usable for a network provider whose link MTU is below the Ethernet default. `mtu` becomes a stored property rather than being inherited from the `Interface` extension, so the guest link can be brought up at the provider's MTU; without it the guest comes up at 1500 and full-size frames are dropped, which presents as working handshakes and stalled bulk transfers. The host-side attachment MTU deliberately stays at the framework default, because `VZFileHandleNetworkDeviceAttachment` rejects values below 1500. That property is a maximum, so smaller frames pass through it fine. Drop `@available(macOS 26, *)`: `VZFileHandleNetworkDeviceAttachment` is macOS 11+ and `maximumTransmissionUnit` is macOS 13+, so nothing here needs 26. `NATNetworkInterface` keeps its annotation because it depends on `vmnet_network_ref`. Document the socket contract on the initializer. The handle must wrap a connected `AF_UNIX` datagram socket that is also bound to a local path of its own: platforms without automatic binding for unix datagram sockets, macOS included, leave an unbound socket with no address for the peer to reply to, so the guest transmits and never receives. Correct the addressing comment. It suggested an address-less interface would be configured out of band by a DHCP server reachable through the handle, but `setupInterface` only performs static configuration and `vminitd` ships no DHCP client, so such an interface comes up with no address unless the guest image supplies a client of its own.
Making `ipv4Address` optional opened a state the guest setup path cannot express. `InterfaceAddress` requires an IPv4 address, so when a conformer supplies only an IPv6 address, `addressAdd` is skipped and the v6 address is never assigned; the default-route guard then returns early and no v6 default route is installed either. The link comes up unaddressed and the caller is left to debug a silently dead interface. Supporting IPv6-only interfaces means making `InterfaceAddress.ipv4Address` optional and changing the `ipAddrAdd` RPC, which is out of scope here. Refuse the combination instead, so the limitation surfaces as an error naming it. Add a recording `VirtualMachineAgent` to cover the setup paths the optional address introduced: an address-less interface brings the link up without an address and claims no default route even when asked, a static interface still gets both, and the interface MTU reaches `up`.
petersen
force-pushed
the
network-fd-without-bridge
branch
from
September 21, 2026 22:39
7e863c7 to
93e236d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a source-breaking change to
Interface:ipv4AddressbecomesCIDRv4?. In-tree conformers are updated here; out-of-tree ones need a one-line change. The reason is an interface whose address is not known when the containeris configured, because something other than our allocator assigns it.
FileHandleNetworkInterfaceis the first such interface. It attaches the guest NIC to aFileHandleviaVZFileHandleNetworkDeviceAttachment, so a host process supplies the network — a simulated network, a VPN, or a bridge onto a host interface. The handle must wrap a connectedAF_UNIXdatagram socket carrying one Ethernet frame per datagram, and must also be bound to a local path of its own: macOS does not auto-assign an address to a unix datagram socket, so an unbound one transmits and never receives.mtuis stored rather than inherited so the guest link can match a provider whose MTU is below 1500; otherwise handshakes succeed and bulk transfers stall. The host-side attachment MTU stays at the framework default, which rejects anything lower.Two follow-on fixes: only an interface that has an address claims the default route (previously an address-less
eth0consumed the slot), and an IPv6 address with no IPv4 address is now refused, sinceInterfaceAddressrequires v4 and thelink would otherwise come up silently unconfigured.
The first two commits are carried from #759 with authorship intact; this drops
BridgedNetworkInterfaceand the vminitd DNS fallback and adds MTU support, docs, and tests. Happy to fold it back into #759 instead if that is easier.