@@ -308,6 +308,7 @@ mpath="auto"
vnc="auto"
sparse="auto"
vde="$default_feature"
+vmnet="auto"
vnc_sasl="auto"
vnc_jpeg="auto"
vnc_png="auto"
@@ -1069,6 +1070,10 @@ for opt do
;;
--enable-vde) vde="yes"
;;
+ --disable-vmnet) vmnet="no"
+ ;;
+ --enable-vmnet) vmnet="yes"
+ ;;
--disable-netmap) netmap="no"
;;
--enable-netmap) netmap="yes"
@@ -1893,6 +1898,7 @@ disabled with --disable-FEATURE, default is enabled if available
rdma Enable RDMA-based migration
pvrdma Enable PVRDMA support
vde support for vde network
+ vmnet vmnet.framework support (macOS)
netmap support for netmap network
linux-aio Linux AIO support
linux-io-uring Linux io_uring support
@@ -2958,6 +2964,28 @@ EOF
fi
fi
+##########################################
+# vmnet.framework probe
+if test "$vmnet" != "no" ; then
+ vmnet_flags="-framework vmnet"
+ cat > $TMPC << EOF
+#include <vmnet/vmnet.h>
+int main(void)
+{
+ (void) vmnet_allocate_mac_address_key;
+ return 0;
+}
+EOF
+ if compile_prog "" "$vmnet_flags" ; then
+ vmnet=yes
+ else
+ if test "$vmnet" = "yes" ; then
+ feature_not_found "vmnet" "'vmnet.framework' in unsupported in this build"
+ fi
+ vmnet=no
+ fi
+fi
+
##########################################
# netmap support probe
# Apart from looking for netmap headers, we make sure that the host API version
@@ -4532,6 +4560,9 @@ if test "$vde" = "yes" ; then
echo "CONFIG_VDE=y" >> $config_host_mak
echo "VDE_LIBS=$vde_libs" >> $config_host_mak
fi
+if test "$vmnet" = "yes" ; then
+ echo "CONFIG_VMNET=y" >> $config_host_mak
+fi
if test "$netmap" = "yes" ; then
echo "CONFIG_NETMAP=y" >> $config_host_mak
fi
@@ -183,6 +183,7 @@ iokit = []
emulator_link_args = []
nvmm =not_found
hvf = not_found
+vmnet = not_found
if targetos == 'windows'
socket = cc.find_library('ws2_32')
winmm = cc.find_library('winmm')
@@ -194,6 +195,9 @@ if targetos == 'windows'
elif targetos == 'darwin'
coref = dependency('appleframeworks', modules: 'CoreFoundation')
iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
+ if config_host.has_key('CONFIG_VMNET')
+ vmnet = dependency('appleframeworks', modules: 'vmnet')
+ endif
elif targetos == 'sunos'
socket = [cc.find_library('socket'),
cc.find_library('nsl'),
@@ -2899,6 +2903,7 @@ summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
+summary_info += {'vmnet support': vmnet.found()}
summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
summary(summary_info, bool_yn: true, section: 'Configurable features')
@@ -63,4 +63,15 @@ 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_host(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp);
+
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp);
+
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp);
+#endif /* CONFIG_VMNET */
+
#endif /* QEMU_NET_CLIENTS_H */
@@ -38,4 +38,5 @@ 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: ['CONFIG_VMNET', vmnet], if_true: files('vmnet.c'))
subdir('can')
@@ -1003,6 +1003,11 @@ 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_HOST] = net_init_vmnet_host,
+ [NET_CLIENT_DRIVER_VMNET_SHARED] = net_init_vmnet_shared,
+ [NET_CLIENT_DRIVER_VMNET_BRIDGED] = net_init_vmnet_bridged,
+#endif /* CONFIG_VMNET */
};
@@ -1088,6 +1093,11 @@ void show_netdevs(void)
#endif
#ifdef CONFIG_VHOST_VDPA
"vhost-vdpa",
+#endif
+#ifdef CONFIG_VMNET
+ "vmnet-host",
+ "vmnet-shared",
+ "vmnet-bridged",
#endif
};
new file mode 100644
@@ -0,0 +1,34 @@
+/*
+ * vmnet.c - network client wrapper for Apple vmnet.framework
+ *
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp) {
+ error_setg(errp, "vmnet is not implemented yet");
+ return -1;
+}
+
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp) {
+ error_setg(errp, "vmnet is not implemented yet");
+ return -1;
+}
+
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp) {
+ error_setg(errp, "vmnet is not implemented yet");
+ return -1;
+}
@@ -452,6 +452,89 @@
'*vhostdev': 'str',
'*queues': 'int' } }
+##
+# @NetdevVmnetHostOptions:
+#
+# vmnet (host mode) network backend.
+#
+# Allows the vmnet interface to communicate with other vmnet
+# interfaces that are in host mode and also with the native host.
+#
+# @dhcpstart: The starting IPv4 address to use for the interface.
+# Must be in the private IP range (RFC 1918). Must be
+# specified along with @dhcpend and @subnetmask.
+# This address is used as the gateway address. The
+# subsequent address up to and including dhcpend are
+# placed in the DHCP pool.
+#
+# @dhcpend: The DHCP IPv4 range end address to use for the
+# interface. Must be in the private IP range (RFC 1918).
+# Must be specified along with @dhcpstart and @subnetmask.
+#
+# @subnetmask: The IPv4 subnet mask to use on the interface. Must
+# be specified along with @dhcpstart and @subnetmask.
+#
+# Since: 6.2
+##
+{ 'struct': 'NetdevVmnetHostOptions',
+ 'data': {
+ '*dhcpstart': 'str',
+ '*dhcpend': 'str',
+ '*subnetmask': 'str'
+ },
+ 'if': 'CONFIG_VMNET' }
+
+##
+# @NetdevVmnetSharedOptions:
+#
+# vmnet (shared mode) network backend.
+#
+# Allows traffic originating from the vmnet interface to reach the
+# Internet through a network address translator (NAT). The vmnet
+# interface can also communicate with the native host. By default,
+# the vmnet interface is able to communicate with other shared mode
+# interfaces. If a subnet range is specified, the vmnet interface can
+# communicate with other shared mode interfaces on the same subnet.
+#
+# @dhcpstart: The starting IPv4 address to use for the interface.
+# Must be in the private IP range (RFC 1918). Must be
+# specified along with @dhcpend and @subnetmask.
+# This address is used as the gateway address. The
+# subsequent address up to and including dhcpend are
+# placed in the DHCP pool.
+#
+# @dhcpend: The DHCP IPv4 range end address to use for the
+# interface. Must be in the private IP range (RFC 1918).
+# Must be specified along with @dhcpstart and @subnetmask.
+#
+# @subnetmask: The IPv4 subnet mask to use on the interface. Must
+# be specified along with @dhcpstart and @subnetmask.
+#
+# Since: 6.2
+##
+{ 'struct': 'NetdevVmnetSharedOptions',
+ 'data': {
+ '*dhcpstart': 'str',
+ '*dhcpend': 'str',
+ '*subnetmask': 'str'
+ },
+ 'if': 'CONFIG_VMNET' }
+
+##
+# @NetdevVmnetBridgedOptions:
+#
+# vmnet (bridged mode) network backend.
+#
+# Bridges the vmnet interface with a physical network interface.
+#
+# @ifname: The name of the physical interface to be bridged.
+#
+# Since: 6.2
+##
+{ 'struct': 'NetdevVmnetBridgedOptions',
+ 'data': { 'ifname': 'str' },
+ 'if': 'CONFIG_VMNET' }
+
##
# @NetClientDriver:
#
@@ -460,10 +543,16 @@
# Since: 2.7
#
# @vhost-vdpa since 5.1
+# @vmnet-host since 6.2
+# @vmnet-shared since 6.2
+# @vmnet-bridged since 6.2
##
{ 'enum': 'NetClientDriver',
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
- 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
+ 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
+ { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' },
+ { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' },
+ { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] }
##
# @Netdev:
@@ -477,6 +566,9 @@
# Since: 1.2
#
# 'l2tpv3' - since 2.1
+# 'vmnet-host' - since 6.2
+# 'vmnet-shared' - since 6.2
+# 'vmnet-bridged' - since 6.2
##
{ 'union': 'Netdev',
'base': { 'id': 'str', 'type': 'NetClientDriver' },
@@ -492,7 +584,10 @@
'hubport': 'NetdevHubPortOptions',
'netmap': 'NetdevNetmapOptions',
'vhost-user': 'NetdevVhostUserOptions',
- 'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
+ 'vhost-vdpa': 'NetdevVhostVDPAOptions',
+ 'vmnet-host': 'NetdevVmnetHostOptions',
+ 'vmnet-shared': 'NetdevVmnetSharedOptions',
+ 'vmnet-bridged': 'NetdevVmnetBridgedOptions' } }
##
# @RxState:
Add 'vmnet' customizable option and 'vmnet.framework' probe into configure; Create separate netdev per each vmnet operating mode because they use quite different settings. Especially since macOS 11.0 (vmnet.framework API gets lots of updates) Create source files for network client driver, update meson.build; Three new netdevs are added: - vmnet-host - vmnet-shared - vmnet-bridged Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> --- configure | 31 ++++++++++++++++ meson.build | 5 +++ net/clients.h | 11 ++++++ net/meson.build | 1 + net/net.c | 10 +++++ net/vmnet.c | 34 +++++++++++++++++ qapi/net.json | 99 ++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 net/vmnet.c