Skip to content

Commit

Permalink
net/macos: implement vmnet-based netdev
Browse files Browse the repository at this point in the history
This patch implements a new netdev device, reachable via -netdev
vmnet-macos, that’s backed by macOS’s vmnet framework.

The vmnet framework provides native bridging support, and its usage in
this patch is intended as a replacement for attempts to use a tap device
via the tuntaposx kernel extension. Notably, the tap/tuntaposx approach
never would have worked in the first place, as QEMU interacts with the
tap device via poll(), and macOS does not support polling device files.

vmnet requires either a special entitlement, granted via a provisioning
profile, or root access. Otherwise attempts to create the virtual
interface will fail with a “generic error” status code. QEMU may not
currently be signed with an entitlement granted in a provisioning
profile, as this would necessitate pre-signed binary build distribution,
rather than source-code distribution. As such, using this netdev
currently requires that qemu be run with root access. I’ve opened a
feedback report with Apple to allow the use of the relevant entitlement
with this use case:
https://openradar.appspot.com/radar?id=5007417364447232

vmnet offers three operating modes, all of which are supported by this
patch via the “mode=host|shared|bridge” option:

* "Host" mode: Allows the vmnet interface to communicate with other
* vmnet
interfaces that are in host mode and also with the native host.
* "Shared" mode: Allows traffic originating from the vmnet interface to
reach the Internet through a NAT. The vmnet interface can also
communicate with the native host.
* "Bridged" mode: Bridges the vmnet interface with a physical network
interface.

Each of these modes also provide some extra configuration that’s
supported by this patch:

* "Bridged" mode: The user may specify the physical interface to bridge
with. Defaults to en0.
* "Host" mode / "Shared" mode: The user may specify the DHCP range and
subnet. Allocated by vmnet if not provided.

vmnet also offers some extra configuration options that are not
supported by this patch:

* Enable isolation from other VMs using vmnet
* Port forwarding rules
* Enabling TCP segmentation offload
* Only applicable in "shared" mode: specifying the NAT IPv6 prefix
* Only available in "host" mode: specifying the IP address for the VM
within an isolated network

Note that this patch requires macOS 10.15 as a minimum, as this is when
bridging support was implemented in vmnet.framework.

Rebased to commit 9aef095 by Akihiko
Odaki.

Signed-off-by: Phillip Tennen <phillip@axleos.com>
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Message-Id: <20210315103209.20870-1-akihiko.odaki@gmail.com>
  • Loading branch information
codyd51 authored and akihikodaki committed Jul 31, 2021
1 parent 7871b0b commit 72a35bb
Show file tree
Hide file tree
Showing 7 changed files with 586 additions and 2 deletions.
3 changes: 3 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ socket = []
version_res = []
coref = []
iokit = []
vmnet = not_found
emulator_link_args = []
nvmm =not_found
hvf = not_found
Expand All @@ -198,6 +199,7 @@ if targetos == 'windows'
elif targetos == 'darwin'
coref = dependency('appleframeworks', modules: 'CoreFoundation')
iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
vmnet = dependency('appleframeworks', modules: 'vmnet')
elif targetos == 'sunos'
socket = [cc.find_library('socket'),
cc.find_library('nsl'),
Expand Down Expand Up @@ -1298,6 +1300,7 @@ config_host_data.set('CONFIG_FUSE', fuse.found())
config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
config_host_data.set('CONFIG_X11', x11.found())
config_host_data.set('CONFIG_CFI', get_option('cfi'))
config_host_data.set('CONFIG_VMNET', vmnet.found())
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
Expand Down
5 changes: 5 additions & 0 deletions net/clients.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,9 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,

int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp);

#ifdef CONFIG_VMNET
int net_init_vmnet_macos(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp);
#endif
#endif /* QEMU_NET_CLIENTS_H */
1 change: 1 addition & 0 deletions net/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ endif
softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files(tap_posix))
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('tap-win32.c'))
softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
softmmu_ss.add(when: vmnet, if_true: files('vmnet-macos.c'))

subdir('can')
3 changes: 3 additions & 0 deletions net/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,9 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
#ifdef CONFIG_L2TPV3
[NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3,
#endif
#ifdef CONFIG_VMNET
[NET_CLIENT_DRIVER_VMNET_MACOS] = net_init_vmnet_macos,
#endif
};


Expand Down
Loading

0 comments on commit 72a35bb

Please sign in to comment.