Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vmnet.framework support on macOS #443

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

NattyNarwhal
Copy link

@NattyNarwhal NattyNarwhal commented Jan 26, 2025

macOS has no built-in tun/tap support; third-party extensions to do so require more hoops to jump through as Apple (justifiably) makes it harder to use third-party kexts. The situation for virtual networking is thus clumsy, relying on pcap/VDE, or dealing with the limitations of slirp or the UDP tunneling. This PR adds support for vmnet, an alternative built into the OS. It provides host-only and shared NAT layer 2 virtual networks, as well as bridging virtual interfaces to physical interfaces.

vmnet requires macOS 10.10 for basic functionality, and 10.15 for bridged networks.

Documentation and SCP help has also been updated.

This has been tested with the following scenarios on macOS 15:

  • Netbooting a MicroVAX 3900 in simh from an InfoServer 150 in simh (over MOP); the system was able to install OpenVMS 7.3.
  • Installing NetBSD/vax 10.1. NetBSD is able to acquire IPv4 and IPv6 addresses via DHCP, and I can telnet into the VAX via IPv6.

On macOS, tap devices for L2 networking are not supported out of the
box. While a kext can be added to provide tap support, the kext
experience is not very good; Apple has strongly recommended against
their usage.

As a replacement that's documented and recommended, Apple introduced the
vmnet framework, intended for emulators and virtualization software
explicitly. This API requires macOS 10.10, with bridged network support
coming in macOS 10.15.

This introduces basic support for vmnet.framework in SIMH. I've tested
it by booting an emulated MicroVAX 3800 from an emulated InfoServer 150,
where it was able to reach OpenVMS 7.3 standalone BACKUP.
Show the allowed bridged network devices SHOW ETHERNET, as well as the
shared/host networking modes. It also shows shared/host/device name for
bridge in i.e. "HELP XS" output as well.

Shared, bridged, and host modes have other options for configuration;
i.e. isolation, IP ranges, etc. Some of these are not well documented,
so should look into these. Bridged mode needs macOS 10.15.
Bridged devices require macOS 10.15 to work correctly. Check if we're on
macOS 10.15 at runtime (so a newer SDK can be used to make simh binaries
that target older macOS), and at compile time (so an older SDK can be
used to build simh).

Also make it so vmnet: for host only is deprecated; you must explicitly
provide either host, shared, or a bridged device name.
Require targeting macOS 10.10, in case the user builds with an older SDK
or sets the target version to an older release. This shouldn't be a
problem with modern macOS SDKs, but users using or targeting older macOS
should have a better message available rather than a compile message.
The check is ugly, but it should work.

A similar check is done for block support; this should only be a problem
with users using GCC instead of clang, which is default on macOS.

Also add a message for vmnet support when printing the build config.
I have not put as many checks as the CMake version has. Those may get
unwieldy.
@NattyNarwhal
Copy link
Author

The ethernet README mentions it, but it's possible to provide additional knobs; vmnet supports them, it's mostly an issue of figuring out how we want to provide the configuration for it.

@markpizz
Copy link
Contributor

If what you've proposed here is, in fact, functionally equivalent to existing ethernet functionality (i.e. pcap, tun/tap, nat), then the simh user commands used to configure these things should not be any different than the current configuration steps.
If along with what is mentioned in my first sentence additional capabilities are also available (i.e. bridging) then extended commands should be added for this functionality,

@NattyNarwhal
Copy link
Author

If what you've proposed here is, in fact, functionally equivalent to existing ethernet functionality (i.e. pcap, tun/tap, nat), then the simh user commands used to configure these things should not be any different than the current configuration steps.

Correct, like the other alternate ethernet backends, it's just prefixed (i.e. vmnet:host or vmnet:en0). It is a little different in that bridging and NAT are presented under the same interface (i.e. it can be used as a substitute for slirp or pcap).

If along with what is mentioned in my first sentence additional capabilities are also available (i.e. bridging) then extended commands should be added for this functionality,

Right, the vmnet API provides some additional configuration options, but I'm wondering how best to present the options (i.e. a larger connection string, or additional SET options?).


One thing I also forgot to mention is the MAC address behaviour. When creating a vmnet interface, it gets a MAC address assigned, and this can be overridden (vmnet_interface_id_key key on the interface description). It doesn't seem you need to have the emulated system use the vmnet interface's MAC address though. I've been using simh with the assigned MAC addresses for VAXen and it seems fine, so I'm not sure if overriding the automatically assigned vmnet MAC address is useful. It does make SHOW ETHERNET mildly more useful (since you can xref vmnet interfaces in i.e. ifconfig w/ it).

For the purposes of vmnet in simh, this does mean changing the MAC address handling as to set the MAC address when the interface is created (rather than look it up later).

The vmnet interface created for a simh instance has its own MAC address.
It doesn't seem too useful to for simh itself (you can just use whatever
MAC address and send/receive frames with that), but it does make
referencing it in other places (i.e. SHOW ETHERNET vs. ifconfig) easier.

The generated MAC address is provided at interface creation time; while
we could look it up earlier like with pcap, this seems more efficient.
@pkoning2
Copy link
Member

Looking at the "vmnet" web documentation you cited I wonder how it applies to SIMH. It's described as an API for hypervisors to construct virtual interfaces, which have their own IP addresses and other stuff. How does that fit what SIMH needs, which is an ethernet level send/receive service?
I agree that tun/tap has long been problematic which is why I stopped looking at it years ago. But pcap works just fine at least on Mac and Linux.

@NattyNarwhal
Copy link
Author

Looking at the "vmnet" web documentation you cited I wonder how it applies to SIMH. It's described as an API for hypervisors to construct virtual interfaces, which have their own IP addresses and other stuff. How does that fit what SIMH needs, which is an ethernet level send/receive service?

vmnet provides a virtual ethernet interface, SIMH is sending/receiving L2 frames over it. While the API documentation mentions hypervisors, SIMH needs the exact same thing as them. The L3 IP stuff vmnet does is for the purposes of subnet it uses for shared/host-only networking, where it handles the DHCP pool and NAT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants