From c064bb6676d248b1e29ce3d8d19c0221c2823932 Mon Sep 17 00:00:00 2001 From: Paul Koning Date: Wed, 27 Aug 2025 15:52:55 -0400 Subject: [PATCH] Revert vmnet support, PR #443 This reverts commits 361ef76d through 6fd146ae. --- 0readme_ethernet.txt | 73 ------------- CMakeLists.txt | 3 - cmake/dep-link.cmake | 30 ------ makefile | 7 -- sim_ether.c | 236 ------------------------------------------- sim_ether.h | 1 - 6 files changed, 350 deletions(-) diff --git a/0readme_ethernet.txt b/0readme_ethernet.txt index 0d8910c7..62357a7c 100644 --- a/0readme_ethernet.txt +++ b/0readme_ethernet.txt @@ -213,79 +213,6 @@ Note: As mentioned above, NAT networking is specifically capable of providing packets. -------------------------------------------------------------------------------- -Another alternative to pcap and tun/tap on macOS is using the vmnet framework. -The vmnet framework provides simh a way to provide emulated systems networking, -without requiring any additional software. Because tun/tap support requires -third-party kernel extensions (which is heavily discouraged by Apple), this -provides an equivalent that doesn't require reducing OS security. - -vmnet provides Layer 2 networking, so things like DECnet and MOP will work -properly, even across multiple systems. It can be used to either bridge to a -physical network, or provide a virtual network for systems, including NAT. - -simh must be running as root. (Running without root is possible if simh is a -notarized application. You're very unlikely to be building simh like this, so -de facto it needs root.) vmnet.framework requires macOS 10.10; macOS 10.15 is -required for bridged networking. - -When attaching an ethernet device, you have three options available: - - - "vmnet:host": This provides "host-only" networking. It allows the system to - talk to the host Mac, as well as other emulated systems on the host-only VM - network. - - "vmnet:shared": This extends the host-only network to add NAT, using the - host as a gateway. - - "vmnet:": This bridges vmnet to a physical network. You must - specify a valid network device to use. - - You can use SHOW ETHERNET in SCP to see what devices are allowed to be - bridged; these are likely your Ethernet and Wi-Fi devices. - - sim> show eth - ETH devices: - eth0 vmnet:en0 - eth1 vmnet:en7 - eth2 udp:sourceport:remotehost:remoteport - sim> attach xq vmnet:en0 - - You can verify with i.e. "ifconfig" to see if this is the correct interface - to bridge to. - -When using the host and shared modes, the host system create an IPv4 and v6 -subnet for the emulated systems. macOS will provide DHCP and other discovery -protocols on the virtual network as well. To see what IP and subnet the host -has claimed, you can use "ifconfig" to display it; macOS will bind its IP to -the bridgeN device, with the simh instance having its own vmenetN device joined -to that bridgeN device: - -vmenet0: flags=8963 mtu 1500 - options=60 - ether a6:94:63:7e:f3:04 - media: autoselect - status: active -bridge100: flags=8a63 mtu 1500 - options=3 - ether b2:f1:d8:65:66:64 - inet 192.168.67.1 netmask 0xffffff00 broadcast 192.168.67.255 - inet6 fe80::b0f1:d8ff:fe65:6664%bridge100 prefixlen 64 scopeid 0x23 - inet6 fd91:d62b:63cd:ec3d:4ad:c40c:d0b8:5826 prefixlen 64 autoconf secured - Configuration: - id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0 - maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200 - root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0 - ipfilter disabled flags 0x0 - member: vmenet0 flags=3 - ifmaxaddr 0 port 34 priority 0 path cost 0 - nd6 options=201 - media: autoselect - status: active - -Currently, settings like the subnet ranges nor port forwarding are controllable -via simh. For finer grained control over how systems are addressed, you can use -a bridged network instead of a host-only or shared network. These settings are -provided by macOS, so a future version of simh may be able to adopt these. - ------------------------------------------------------------------------------- Windows notes: diff --git a/CMakeLists.txt b/CMakeLists.txt index c206d4f0..120da396 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,9 +199,6 @@ option(WITH_VDE option(WITH_TAP "Enable (=1)/disable (=0) TAP/TUN device network support. (def: enabled)" TRUE) -option(WITH_VMNET - "Enable (=1)/disable (=0) macOS vmnet.framework network support. (def: enabled)" - TRUE) option(WITH_VIDEO "Enable (=1)/disable (=0) simulator display and graphics support (def: enabled)" TRUE) diff --git a/cmake/dep-link.cmake b/cmake/dep-link.cmake index 0dec7bcf..90c7707e 100644 --- a/cmake/dep-link.cmake +++ b/cmake/dep-link.cmake @@ -351,36 +351,6 @@ if (WITH_NETWORK) list(APPEND NETWORK_PKG_STATUS "NAT(SLiRP)") endif (WITH_SLIRP) - if (WITH_VMNET AND APPLE) - # CMAKE_OSX_DEPLOYMENT_TARGET is attractive, but not set by default. - # See what we're using, either by default or what the user has set. - check_c_source_compiles( - " - #include - #if TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000 - #error macOS too old - #endif - int main(int argc, char **argv) { return 0; } - " TARGETING_MACOS_10_10) - if (NOT TARGETING_MACOS_10_10) - message(FATAL_ERROR "vmnet.framework requires targeting macOS 10.10 or newer") - endif() - - # vmnet requires blocks for its callback parameter, even in vanilla C. - # This is only supported in clang, not by GCC. It's default in clang, - # but we should be clear about it. Do a feature instead of compiler - # check anyways though, in case GCC does add it eventually. - check_c_compiler_flag(-fblocks HAVE_C_BLOCKS) - if (NOT HAVE_C_BLOCKS) - message(FATAL_ERROR "vmnet.framework requires blocks support in the C compiler") - endif() - target_compile_options(simh_network INTERFACE -fblocks) - - target_link_libraries(simh_network INTERFACE "-framework vmnet") - target_compile_definitions(simh_network INTERFACE HAVE_VMNET_NETWORK) - list(APPEND NETWORK_PKG_STATUS "macOS vmnet.framework") - endif(WITH_VMNET AND APPLE) - ## Finally, set the network runtime if (NOT network_runtime) ## Default to USE_SHARED... USE_NETWORK is deprecated. diff --git a/makefile b/makefile index 6eeba103..b60a6fee 100644 --- a/makefile +++ b/makefile @@ -1063,13 +1063,6 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) NETWORK_CCDEFS += -DUSE_NETWORK endif endif - # XXX: Check for the target version of macOS, check for -fblocks - ifeq (Darwin,$(OSTYPE)) - # Provide support for macOS vmnet.framework (requires 10.10) - NETWORK_CCDEFS += -fblocks -DHAVE_VMNET_NETWORK - NETWORK_LAN_FEATURES += vmnet.framework - NETWORK_LDFLAGS += -framework vmnet - endif ifeq (slirp,$(shell if ${TEST} -e slirp_glue/sim_slirp.c; then echo slirp; fi)) NETWORK_CCDEFS += -Islirp -Islirp_glue -Islirp_glue/qemu -DHAVE_SLIRP_NETWORK -DUSE_SIMH_SLIRP_DEBUG slirp/*.c slirp_glue/*.c NETWORK_LAN_FEATURES += NAT(SLiRP) diff --git a/sim_ether.c b/sim_ether.c index 6e612184..2311664a 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -381,11 +381,6 @@ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) -// Declare earlier than other implementations -#ifdef HAVE_VMNET_NETWORK -#include -#endif - /* Internal routine - forward declaration */ static int _eth_get_system_id (char *buf, size_t buf_size); static void eth_get_nic_hw_addr(ETH_DEV* dev, const char *devname, int set_on); @@ -1018,9 +1013,6 @@ const char *eth_capabilities(void) #endif #if defined (HAVE_SLIRP_NETWORK) ":NAT" -#endif -#if defined (HAVE_VMNET_NETWORK) - ":VMNET" #endif ":UDP"; } @@ -1212,42 +1204,6 @@ if (used < max) { ++used; } #endif -#ifdef HAVE_VMNET_NETWORK -if (used < max) { - sprintf(list[used].name, "%s", "vmnet:shared"); - sprintf(list[used].desc, "%s", "Integrated NAT (vmnet.framework) support"); - list[used].eth_api = ETH_API_VMN; - ++used; -} -if (used < max) { - sprintf(list[used].name, "%s", "vmnet:host"); - sprintf(list[used].desc, "%s", "Integrated host-only network (vmnet.framework) support"); - list[used].eth_api = ETH_API_VMN; - ++used; -} -// vmnet.framework has an allowed list of devices for bridging -// handy for user if we list them since ifconfig is noisy -#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500) -if (__builtin_available(macOS 10.15, *)) { - // avoid putting a __block marker on used on other platforms - __block int used_block; - xpc_object_t bridge_list = vmnet_copy_shared_interface_list(); - - xpc_array_apply(bridge_list, ^bool(size_t index, xpc_object_t value) { - if (used_block < max) { - sprintf(list[used_block].name, "%s%s", "vmnet:", xpc_string_get_string_ptr(value)); - sprintf(list[used_block].desc, "%s", "Integrated bridged network (vmnet.framework) support"); - list[used_block].eth_api = ETH_API_VMN; - ++used_block; - } - return true; - }); - used = used_block; - - xpc_release(bridge_list); -} -#endif -#endif if (used < max) { sprintf(list[used].name, "%s", "udp:sourceport:remotehost:remoteport"); @@ -1813,10 +1769,6 @@ return tool; static void eth_get_nic_hw_addr(ETH_DEV* dev, const char *devname, int set_on) { - // we set this at interface creation time in open_port for vmnet - if (dev->eth_api == ETH_API_VMN) { - return; - } memset(&dev->host_nic_phy_hw_addr, 0, sizeof(dev->host_nic_phy_hw_addr)); dev->have_host_nic_phy_addr = 0; if (dev->eth_api != ETH_API_PCAP) @@ -2116,37 +2068,6 @@ while (dev->handle) { } break; #endif /* HAVE_VDE_NETWORK */ -#ifdef HAVE_VMNET_NETWORK - case ETH_API_VMN: - { - vmnet_return_t ret; - int count = 1; - struct pcap_pkthdr header; - struct vmpktdesc pkt_desc; - struct iovec iov; - - // XXX: Should be MTU returned from vmnet startup? - u_char buf[ETH_MAX_JUMBO_FRAME]; - - iov.iov_base = buf; - iov.iov_len = ETH_MAX_JUMBO_FRAME; - - pkt_desc.vm_pkt_size = ETH_MAX_JUMBO_FRAME; - pkt_desc.vm_pkt_iov = &iov; - pkt_desc.vm_pkt_iovcnt = 1; - pkt_desc.vm_flags = 0; - - ret = vmnet_read((interface_ref)dev->handle, &pkt_desc, &count); - if (ret == VMNET_SUCCESS && count > 0) { - status = 1; - header.caplen = header.len = pkt_desc.vm_pkt_size; - _eth_callback((u_char *)dev, &header, buf); - } else { - status = ret == VMNET_SUCCESS ? 0 : -1; - } - } - break; -#endif #ifdef HAVE_SLIRP_NETWORK case ETH_API_NAT: sim_slirp_dispatch ((SLIRP*)dev->handle); @@ -2331,87 +2252,6 @@ if (bufsz < ETH_MAX_JUMBO_FRAME) /* attempt to connect device */ memset(errbuf, 0, PCAP_ERRBUF_SIZE); - - if (0 == strncmp("vmnet:", savname, 6)) { -#if defined(HAVE_VMNET_NETWORK) - xpc_object_t if_desc; - dispatch_queue_t vmn_queue; - interface_ref vmn_interface; - // __block is used so it can be captured in the callback - __block vmnet_return_t vmn_status; - // Because vmnet operates via callbacks, set up a semaphore to block on - dispatch_semaphore_t cb_finished; - - const char *devname = savname + sizeof("vmnet:") - 1; - - if_desc = xpc_dictionary_create(NULL, NULL, 0); - if (0 == strcmp(devname, "shared")) { - xpc_dictionary_set_uint64(if_desc, vmnet_operation_mode_key, VMNET_SHARED_MODE); - } else if (0 == strcmp(devname, "host")) { - xpc_dictionary_set_uint64(if_desc, vmnet_operation_mode_key, VMNET_HOST_MODE); -#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500) - } else if (strlen(devname) > 0) { // Bridged, this is the device name - if (__builtin_available(macOS 10.15, *)) { - xpc_dictionary_set_uint64(if_desc, vmnet_operation_mode_key, VMNET_BRIDGED_MODE); - xpc_dictionary_set_string(if_desc, vmnet_shared_interface_name_key, devname); - } else { - xpc_release(if_desc); - return sim_messagef (SCPE_OPENERR, "Eth: You must be using macOS 10.15 or newer for bridged devices\n"); - } -#endif - } else { - if (__builtin_available(macOS 10.15, *)) { - xpc_release(if_desc); - return sim_messagef (SCPE_OPENERR, "Eth: You must pick either shared, host, or an allowed bridge device\n"); - } else { - xpc_release(if_desc); - return sim_messagef (SCPE_OPENERR, "Eth: You must pick either shared or host\n"); - } - } - - vmn_queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); - - cb_finished = dispatch_semaphore_create(0); - - // Set the MAC address - __block ETH_DEV *eth_dev = (ETH_DEV*)opaque; - - vmn_interface = vmnet_start_interface(if_desc, vmn_queue, ^(vmnet_return_t status, xpc_object_t params){ - vmn_status = status; - - if (vmn_status == VMNET_SUCCESS) { - // Scan like eth_scan_mac but simplified (only one format) - const char *mac_string = xpc_dictionary_get_string(params, vmnet_mac_address_key); - int a[6]; - if (6 == sscanf(mac_string, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5])) { - eth_dev->have_host_nic_phy_addr = 1; - eth_dev->host_nic_phy_hw_addr[0] = a[0]; - eth_dev->host_nic_phy_hw_addr[1] = a[1]; - eth_dev->host_nic_phy_hw_addr[2] = a[2]; - eth_dev->host_nic_phy_hw_addr[3] = a[3]; - eth_dev->host_nic_phy_hw_addr[4] = a[4]; - eth_dev->host_nic_phy_hw_addr[5] = a[5]; - } - } - - dispatch_semaphore_signal(cb_finished); - }); - dispatch_semaphore_wait(cb_finished, DISPATCH_TIME_FOREVER); - dispatch_release(cb_finished); - xpc_release(if_desc); - - if (vmn_status != VMNET_SUCCESS) { - return sim_messagef (SCPE_OPENERR, "Eth: Failed to create vmnet (vmnet_return_t: %d)\n", vmn_status); - } - - *eth_api = ETH_API_VMN; - *handle = (void *)vmn_interface; /* Flag used to indicated open */ - return SCPE_OK; -#else - return sim_messagef (SCPE_OPENERR, "Eth: No support for vmnet devices\n"); -#endif - } - if (0 == strncmp("tap:", savname, 4)) { int tun = -1; /* TUN/TAP Socket */ int on = 1; @@ -2814,15 +2654,6 @@ switch (eth_api) { case ETH_API_NAT: sim_slirp_close((SLIRP*)pcap); break; -#endif -#ifdef HAVE_VMNET_NETWORK - case ETH_API_VMN: - { - dispatch_queue_t stop_queue; - stop_queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); - vmnet_stop_interface((interface_ref)pcap, stop_queue, ^(vmnet_return_t status){}); - } - break; #endif case ETH_API_UDP: sim_close_sock(pcap_fd); @@ -2920,11 +2751,6 @@ fprintf (st, " eth2 vde:device{:switch-port-number} (Integrated VDE su fprintf (st, " eth3 nat:{optional-nat-parameters} (Integrated NAT (SLiRP) support)\n"); #endif fprintf (st, " eth4 udp:sourceport:remotehost:remoteport (Integrated UDP bridge support)\n"); -#if defined(HAVE_VMNET_NETWORK) -fprintf (st, " eth6 vmnet:shared (Integrated NAT (vmnet.framework) support)\n"); -fprintf (st, " eth7 vmnet:host (Integrated host-only (vmnet.framework) support)\n"); -fprintf (st, " eth8 vmnet:device-name (Integrated bridged (vmnet.framework) support)\n"); -#endif fprintf (st, " sim> ATTACH %s eth0\n\n", dptr->name); fprintf (st, "or equivalently:\n\n"); fprintf (st, " sim> ATTACH %s en0\n\n", dptr->name); @@ -3141,9 +2967,6 @@ switch (dev->eth_api) { case ETH_API_NAT: netname = "nat"; break; - case ETH_API_VMN: - netname = "vmnet"; - break; } sprintf(msg, "%s(%s): ", where, netname); switch (dev->eth_api) { @@ -3151,12 +2974,6 @@ switch (dev->eth_api) { case ETH_API_PCAP: sim_printf ("%s%s\n", msg, pcap_geterr ((pcap_t*)dev->handle)); break; -#endif -#if defined(HAVE_VMNET_NETWORK) - case ETH_API_VMN: - /* XXX: vmnet errors aren't global */ - sim_printf ("%s\n", msg); - break; #endif default: sim_err_sock (INVALID_SOCKET, msg); @@ -3278,27 +3095,6 @@ if ((packet->len >= ETH_MIN_PACKET) && (packet->len <= ETH_MAX_PACKET)) { else status = 1; break; -#endif -#ifdef HAVE_VMNET_NETWORK - case ETH_API_VMN: - { - vmnet_return_t ret; - int count = 1; - struct vmpktdesc pkt_desc; - struct iovec iov; - - iov.iov_base = packet->msg; - iov.iov_len = packet->len; - - pkt_desc.vm_pkt_size = packet->len; - pkt_desc.vm_pkt_iov = &iov; - pkt_desc.vm_pkt_iovcnt = 1; - pkt_desc.vm_flags = 0; - - ret = vmnet_write((interface_ref)dev->handle, &pkt_desc, &count); - status = (ret == VMNET_SUCCESS && count > 0) ? 0 : 1; - } - break; #endif case ETH_API_UDP: status = (((int32)packet->len == sim_write_sock (dev->fd_handle, (char *)packet->msg, (int32)packet->len)) ? 0 : -1); @@ -3919,7 +3715,6 @@ switch (dev->eth_api) { case ETH_API_VDE: case ETH_API_UDP: case ETH_API_NAT: - case ETH_API_VMN: bpf_used = 0; to_me = 0; eth_packet_trace (dev, data, header->len, "received"); @@ -4116,37 +3911,6 @@ do { } break; #endif /* HAVE_VDE_NETWORK */ -#ifdef HAVE_VMNET_NETWORK - case ETH_API_VMN: - { - vmnet_return_t ret; - int count = 1; - struct pcap_pkthdr header; - struct vmpktdesc pkt_desc; - struct iovec iov; - - // XXX: Should be MTU returned from vmnet startup? - u_char buf[ETH_MAX_JUMBO_FRAME]; - - iov.iov_base = buf; - iov.iov_len = ETH_MAX_JUMBO_FRAME; - - pkt_desc.vm_pkt_size = ETH_MAX_JUMBO_FRAME; - pkt_desc.vm_pkt_iov = &iov; - pkt_desc.vm_pkt_iovcnt = 1; - pkt_desc.vm_flags = 0; - - ret = vmnet_read((interface_ref)dev->handle, &pkt_desc, &count); - if (ret == VMNET_SUCCESS && count > 0) { - status = 1; - header.caplen = header.len = pkt_desc.vm_pkt_size; - _eth_callback((u_char *)dev, &header, buf); - } else { - status = ret == VMNET_SUCCESS ? 0 : -1; - } - } - break; -#endif case ETH_API_UDP: if (1) { struct pcap_pkthdr header; diff --git a/sim_ether.h b/sim_ether.h index f0ecb292..9cca60a3 100644 --- a/sim_ether.h +++ b/sim_ether.h @@ -265,7 +265,6 @@ struct eth_device { #define ETH_API_VDE 3 /* VDE API in use */ #define ETH_API_UDP 4 /* UDP API in use */ #define ETH_API_NAT 5 /* NAT (SLiRP) API in use */ -#define ETH_API_VMN 6 /* Apple vmnet.framework in use */ ETH_PCALLBACK read_callback; /* read callback function */ ETH_PCALLBACK write_callback; /* write callback function */ ETH_PACK* read_packet; /* read packet */