All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v13 0/7] Add vmnet.framework based network backend
@ 2022-01-13 17:22 Vladislav Yaroshchuk
  2022-01-13 17:22 ` [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option Vladislav Yaroshchuk
                   ` (6 more replies)
  0 siblings, 7 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

macOS provides networking API for VMs called 'vmnet.framework':
https://developer.apple.com/documentation/vmnet

We can provide its support as the new QEMU network backends which
represent three different vmnet.framework interface usage modes:

  * `vmnet-shared`:
    allows the guest to communicate with other guests in shared mode and
    also with external network (Internet) via NAT. Has (macOS-provided)
    DHCP server; subnet mask and IP range can be configured;

  * `vmnet-host`:
    allows the guest to communicate with other guests in host mode.
    By default has enabled DHCP as `vmnet-shared`, but providing
    network unique id (uuid) can make `vmnet-host` interfaces isolated
    from each other and also disables DHCP.

  * `vmnet-bridged`:
    bridges the guest with a physical network interface.

This backends cannot work on macOS Catalina 10.15 cause we use
vmnet.framework API provided only with macOS 11 and newer. Seems
that it is not a problem, because QEMU guarantees to work on two most
recent versions of macOS which now are Big Sur (11) and Monterey (12).

Also, we have one inconvenient restriction: vmnet.framework interfaces
can create only privileged user:
`$ sudo qemu-system-x86_64 -nic vmnet-shared`

Attempt of `vmnet-*` netdev creation being unprivileged user fails with
vmnet's 'general failure'.

This happens because vmnet.framework requires `com.apple.vm.networking`
entitlement which is: "restricted to developers of virtualization software.
To request this entitlement, contact your Apple representative." as Apple
documentation says:
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_networking

One more note: we still have quite useful but not supported
'vmnet.framework' features as creating port forwarding rules, IPv6
NAT prefix specifying and so on.

Nevertheless, new backends work fine and tested within `qemu-system-x86-64`
on macOS Bir Sur 11.5.2 host with such nic models:
  * e1000-82545em
  * virtio-net-pci
  * vmxnet3

The guests were:
  * macOS 10.15.7
  * Ubuntu Bionic (server cloudimg)


This series partially reuses patches by Phillip Tennen:
https://patchew.org/QEMU/20210218134947.1860-1-phillip.ennen@gmail.com/
So I included them signed-off line into one of the commit messages and
also here.

v1 -> v2:
 Since v1 minor typos were fixed, patches rebased onto latest master,
 redundant changes removed (small commits squashed)
v2 -> v3:
 - QAPI style fixes
 - Typos fixes in comments
 - `#include`'s updated to be in sync with recent master
v3 -> v4:
 - Support vmnet interfaces isolation feature
 - Support vmnet-host network uuid setting feature
 - Refactored sources a bit
v4 -> v5:
 - Missed 6.2 boat, now 7.0 candidate
 - Fix qapi netdev descriptions and styles
   (@subnetmask -> @subnet-mask)
 - Support vmnet-shared IPv6 prefix setting feature
v5 -> v6
 - provide detailed commit messages for commits of
   many changes
 - rename properties @dhcpstart and @dhcpend to
   @start-address and @end-address
 - improve qapi documentation about isolation
   features (@isolated, @net-uuid)
v6 -> v7:
 - update MAINTAINERS list
v7 -> v8
 - QAPI code style fixes
v8 -> v9
 - Fix building on Linux: add missing qapi
   `'if': 'CONFIG_VMNET'` statement to Netdev union
v9 -> v10
 - Disable vmnet feature for macOS < 11.0: add
   vmnet.framework API probe into meson.build.
   This fixes QEMU building on macOS < 11.0:
   https://patchew.org/QEMU/20220110034000.20221-1-jasowang@redhat.com/
v10 -> v11
 - Enable vmnet for macOS 10.15 with subset of available
   features. Disable vmnet for macOS < 10.15.
 - Fix typos
v11 -> v12
 - use more general macOS version check with
   MAC_OS_VERSION_11_0 instead of manual
   definition creating.
v12 -> v13
 - fix incorrect macOS version bound while
   'feature available since 11.0' check.
   Use MAC_OS_X_VERSION_MIN_REQUIRED instead of
   MAC_OS_X_VERSION_MAX_ALLOWED.

Vladislav Yaroshchuk (7):
  net/vmnet: add vmnet dependency and customizable option
  net/vmnet: add vmnet backends to qapi/net
  net/vmnet: implement shared mode (vmnet-shared)
  net/vmnet: implement host mode (vmnet-host)
  net/vmnet: implement bridged mode (vmnet-bridged)
  net/vmnet: update qemu-options.hx
  net/vmnet: update MAINTAINERS list

 MAINTAINERS                   |   5 +
 meson.build                   |  16 +-
 meson_options.txt             |   2 +
 net/clients.h                 |  11 ++
 net/meson.build               |   7 +
 net/net.c                     |  10 +
 net/vmnet-bridged.m           | 120 ++++++++++++
 net/vmnet-common.m            | 333 ++++++++++++++++++++++++++++++++++
 net/vmnet-host.c              | 122 +++++++++++++
 net/vmnet-shared.c            | 100 ++++++++++
 net/vmnet_int.h               |  48 +++++
 qapi/net.json                 | 133 +++++++++++++-
 qemu-options.hx               |  25 +++
 scripts/meson-buildoptions.sh |   3 +
 14 files changed, 932 insertions(+), 3 deletions(-)
 create mode 100644 net/vmnet-bridged.m
 create mode 100644 net/vmnet-common.m
 create mode 100644 net/vmnet-host.c
 create mode 100644 net/vmnet-shared.c
 create mode 100644 net/vmnet_int.h

-- 
2.23.0



^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  2022-01-20  7:14   ` Roman Bolshakov
  2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

vmnet.framework dependency is added with 'vmnet' option
to enable or disable it. Default value is 'auto'.

vmnet features to be used are available since macOS 11.0,
corresponding probe is created into meson.build.

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 meson.build                   | 16 +++++++++++++++-
 meson_options.txt             |  2 ++
 scripts/meson-buildoptions.sh |  3 +++
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index c1b1db1e28..285fb7bc41 100644
--- a/meson.build
+++ b/meson.build
@@ -496,6 +496,18 @@ if cocoa.found() and get_option('gtk').enabled()
   error('Cocoa and GTK+ cannot be enabled at the same time')
 endif
 
+vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
+if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
+                                              'VMNET_BRIDGED_MODE',
+                                              dependencies: vmnet)
+  vmnet = not_found
+  if get_option('vmnet').enabled()
+    error('vmnet.framework API is outdated')
+  else
+    warning('vmnet.framework API is outdated, disabling')
+  endif
+endif
+
 seccomp = not_found
 if not get_option('seccomp').auto() or have_system or have_tools
   seccomp = dependency('libseccomp', version: '>=2.3.0',
@@ -1492,6 +1504,7 @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found())
 config_host_data.set('CONFIG_SNAPPY', snappy.found())
 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
 config_host_data.set('CONFIG_VDE', vde.found())
+config_host_data.set('CONFIG_VMNET', vmnet.found())
 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
 config_host_data.set('CONFIG_VNC', vnc.found())
 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
@@ -3406,7 +3419,8 @@ summary(summary_info, bool_yn: true, section: 'Crypto')
 # Libraries
 summary_info = {}
 if targetos == 'darwin'
-  summary_info += {'Cocoa support':   cocoa}
+  summary_info += {'Cocoa support':           cocoa}
+  summary_info += {'vmnet.framework support': vmnet}
 endif
 summary_info += {'SDL support':       sdl}
 summary_info += {'SDL image support': sdl_image}
diff --git a/meson_options.txt b/meson_options.txt
index 921967eddb..701e1381f9 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -151,6 +151,8 @@ option('netmap', type : 'feature', value : 'auto',
        description: 'netmap network backend support')
 option('vde', type : 'feature', value : 'auto',
        description: 'vde network backend support')
+option('vmnet', type : 'feature', value : 'auto',
+       description: 'vmnet.framework network backend support')
 option('virglrenderer', type : 'feature', value : 'auto',
        description: 'virgl rendering support')
 option('vnc', type : 'feature', value : 'auto',
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 50bd7bed4d..cdcece4b05 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -84,6 +84,7 @@ meson_options_help() {
   printf "%s\n" '  u2f             U2F emulation support'
   printf "%s\n" '  usb-redir       libusbredir support'
   printf "%s\n" '  vde             vde network backend support'
+  printf "%s\n" '  vmnet           vmnet.framework network backend support'
   printf "%s\n" '  vhost-user-blk-server'
   printf "%s\n" '                  build vhost-user-blk server'
   printf "%s\n" '  virglrenderer   virgl rendering support'
@@ -248,6 +249,8 @@ _meson_option_parse() {
     --disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
     --enable-vde) printf "%s" -Dvde=enabled ;;
     --disable-vde) printf "%s" -Dvde=disabled ;;
+    --enable-vmnet) printf "%s" -Dvmnet=enabled ;;
+    --disable-vmnet) printf "%s" -Dvmnet=disabled ;;
     --enable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=enabled ;;
     --disable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=disabled ;;
     --enable-virglrenderer) printf "%s" -Dvirglrenderer=enabled ;;
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
  2022-01-13 17:22 ` [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  2022-01-14  8:43   ` Akihiko Odaki
                     ` (3 more replies)
  2022-01-13 17:22 ` [PATCH v13 3/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
                   ` (4 subsequent siblings)
  6 siblings, 4 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

Create separate netdevs for each vmnet operating mode:
- vmnet-host
- vmnet-shared
- vmnet-bridged

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/clients.h       |  11 ++++
 net/meson.build     |   7 +++
 net/net.c           |  10 ++++
 net/vmnet-bridged.m |  25 +++++++++
 net/vmnet-common.m  |  20 +++++++
 net/vmnet-host.c    |  24 ++++++++
 net/vmnet-shared.c  |  25 +++++++++
 net/vmnet_int.h     |  25 +++++++++
 qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
 9 files changed, 278 insertions(+), 2 deletions(-)
 create mode 100644 net/vmnet-bridged.m
 create mode 100644 net/vmnet-common.m
 create mode 100644 net/vmnet-host.c
 create mode 100644 net/vmnet-shared.c
 create mode 100644 net/vmnet_int.h

diff --git a/net/clients.h b/net/clients.h
index 92f9b59aed..c9157789f2 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -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 */
diff --git a/net/meson.build b/net/meson.build
index 847bc2ac85..00a88c4951 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -42,4 +42,11 @@ 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'))
 
+vmnet_files = files(
+  'vmnet-common.m',
+  'vmnet-bridged.m',
+  'vmnet-host.c',
+  'vmnet-shared.c'
+)
+softmmu_ss.add(when: vmnet, if_true: vmnet_files)
 subdir('can')
diff --git a/net/net.c b/net/net.c
index f0d14dbfc1..1dbb64b935 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1021,6 +1021,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 */
 };
 
 
@@ -1106,6 +1111,11 @@ void show_netdevs(void)
 #endif
 #ifdef CONFIG_VHOST_VDPA
         "vhost-vdpa",
+#endif
+#ifdef CONFIG_VMNET
+        "vmnet-host",
+        "vmnet-shared",
+        "vmnet-bridged",
 #endif
     };
 
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
new file mode 100644
index 0000000000..4e42a90391
--- /dev/null
+++ b/net/vmnet-bridged.m
@@ -0,0 +1,25 @@
+/*
+ * vmnet-bridged.m
+ *
+ * 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 "qapi/qapi-types-net.h"
+#include "vmnet_int.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
+                           NetClientState *peer, Error **errp)
+{
+  error_setg(errp, "vmnet-bridged is not implemented yet");
+  return -1;
+}
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
new file mode 100644
index 0000000000..532d152840
--- /dev/null
+++ b/net/vmnet-common.m
@@ -0,0 +1,20 @@
+/*
+ * vmnet-common.m - network client wrapper for Apple vmnet.framework
+ *
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
+ * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
+#include "vmnet_int.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
new file mode 100644
index 0000000000..4a5ef99dc7
--- /dev/null
+++ b/net/vmnet-host.c
@@ -0,0 +1,24 @@
+/*
+ * vmnet-host.c
+ *
+ * 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 "qapi/qapi-types-net.h"
+#include "vmnet_int.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-host is not implemented yet");
+  return -1;
+}
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
new file mode 100644
index 0000000000..f8c4a4f3b8
--- /dev/null
+++ b/net/vmnet-shared.c
@@ -0,0 +1,25 @@
+/*
+ * vmnet-shared.c
+ *
+ * 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 "qapi/qapi-types-net.h"
+#include "vmnet_int.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
+                          NetClientState *peer, Error **errp)
+{
+  error_setg(errp, "vmnet-shared is not implemented yet");
+  return -1;
+}
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
new file mode 100644
index 0000000000..c5982259a4
--- /dev/null
+++ b/net/vmnet_int.h
@@ -0,0 +1,25 @@
+/*
+ * vmnet_int.h
+ *
+ * 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.
+ *
+ */
+#ifndef VMNET_INT_H
+#define VMNET_INT_H
+
+#include "qemu/osdep.h"
+#include "vmnet_int.h"
+#include "clients.h"
+
+#include <vmnet/vmnet.h>
+
+typedef struct VmnetCommonState {
+  NetClientState nc;
+
+} VmnetCommonState;
+
+
+#endif /* VMNET_INT_H */
diff --git a/qapi/net.json b/qapi/net.json
index 7fab2e7cd8..b922e2e34f 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -452,6 +452,120 @@
     '*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 host.
+#
+# @start-address: The starting IPv4 address to use for the interface.
+#                 Must be in the private IP range (RFC 1918). Must be
+#                 specified along with @end-address and @subnet-mask.
+#                 This address is used as the gateway address. The
+#                 subsequent address up to and including end-address are
+#                 placed in the DHCP pool.
+#
+# @end-address: 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 @start-address and
+#               @subnet-mask.
+#
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
+#               be specified along with @start-address and @subnet-mask.
+#
+# @isolated: Enable isolation for this interface. Interface isolation
+#            ensures that vmnet interface is not able to communicate
+#            with any other vmnet interfaces. Only communication with
+#            host is allowed. Available since macOS Big Sur 11.0.
+#
+# @net-uuid: The identifier (UUID) to uniquely identify the isolated
+#            network vmnet interface should be added to. If
+#            set, no DHCP service is provided for this interface and
+#            network communication is allowed only with other interfaces
+#            added to this network identified by the UUID. Available
+#            since macOS Big Sur 11.0.
+#
+# Since: 7.0
+##
+{ 'struct': 'NetdevVmnetHostOptions',
+  'data': {
+    '*start-address': 'str',
+    '*end-address':   'str',
+    '*subnet-mask':   'str',
+    '*isolated':      'bool',
+    '*net-uuid':      '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 communicate with the host and with
+# other shared mode interfaces on the same subnet. If no DHCP
+# settings, subnet mask and IPv6 prefix specified, the interface can
+# communicate with any of other interfaces in shared mode.
+#
+# @start-address: The starting IPv4 address to use for the interface.
+#                 Must be in the private IP range (RFC 1918). Must be
+#                 specified along with @end-address and @subnet-mask.
+#                 This address is used as the gateway address. The
+#                 subsequent address up to and including end-address are
+#                 placed in the DHCP pool.
+#
+# @end-address: 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 @start-address and @subnet-mask.
+#
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
+#                be specified along with @start-address and @subnet-mask.
+#
+# @isolated: Enable isolation for this interface. Interface isolation
+#            ensures that vmnet interface is not able to communicate
+#            with any other vmnet interfaces. Only communication with
+#            host is allowed. Available since macOS Big Sur 11.0.
+#
+# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
+#                unique local address i.e. start with fd00::/8 and have
+#                length of 64.
+#
+# Since: 7.0
+##
+{ 'struct': 'NetdevVmnetSharedOptions',
+  'data': {
+    '*start-address': 'str',
+    '*end-address':   'str',
+    '*subnet-mask':   'str',
+    '*isolated':      'bool',
+    '*nat66-prefix':  '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.
+#
+# @isolated: Enable isolation for this interface. Interface isolation
+#            ensures that vmnet interface is not able to communicate
+#            with any other vmnet interfaces. Only communication with
+#            host is allowed. Available since macOS Big Sur 11.0.
+#
+# Since: 7.0
+##
+{ 'struct': 'NetdevVmnetBridgedOptions',
+  'data': {
+    'ifname':     'str',
+    '*isolated':  'bool' },
+  'if': 'CONFIG_VMNET' }
+
 ##
 # @NetClientDriver:
 #
@@ -460,10 +574,16 @@
 # Since: 2.7
 #
 #        @vhost-vdpa since 5.1
+#        @vmnet-host since 7.0
+#        @vmnet-shared since 7.0
+#        @vmnet-bridged since 7.0
 ##
 { '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 +597,9 @@
 # Since: 1.2
 #
 #        'l2tpv3' - since 2.1
+#        'vmnet-host' - since 7.0
+#        'vmnet-shared' - since 7.0
+#        'vmnet-bridged' - since 7.0
 ##
 { 'union': 'Netdev',
   'base': { 'id': 'str', 'type': 'NetClientDriver' },
@@ -492,7 +615,13 @@
     'hubport':  'NetdevHubPortOptions',
     'netmap':   'NetdevNetmapOptions',
     'vhost-user': 'NetdevVhostUserOptions',
-    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
+    'vhost-vdpa': 'NetdevVhostVDPAOptions',
+    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
+                    'if': 'CONFIG_VMNET' },
+    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
+                      'if': 'CONFIG_VMNET' },
+    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
+                       'if': 'CONFIG_VMNET' } } }
 
 ##
 # @RxState:
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v13 3/7] net/vmnet: implement shared mode (vmnet-shared)
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
  2022-01-13 17:22 ` [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option Vladislav Yaroshchuk
  2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  2022-01-14  8:43   ` Akihiko Odaki
  2022-01-13 17:22 ` [PATCH v13 4/7] net/vmnet: implement host mode (vmnet-host) Vladislav Yaroshchuk
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

Interaction with vmnet.framework in different modes
differs only on configuration stage, so we can create
common `send`, `receive`, etc. procedures and reuse them.

vmnet.framework supports iov, but writing more than
one iov into vmnet interface fails with
'VMNET_INVALID_ARGUMENT'. Collecting provided iovs into
one and passing it to vmnet works fine. That's the
reason why receive_iov() left unimplemented. But it still
works with good enough performance having .receive()
implemented only.

Also, there is no way to unsubscribe from vmnet packages
receiving except registering and unregistering event
callback or simply drop packages just ignoring and
not processing them when related flag is set. Here we do
using the second way.

Signed-off-by: Phillip Tennen <phillip@axleos.com>
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/vmnet-common.m | 313 +++++++++++++++++++++++++++++++++++++++++++++
 net/vmnet-shared.c |  83 +++++++++++-
 net/vmnet_int.h    |  23 ++++
 3 files changed, 415 insertions(+), 4 deletions(-)

diff --git a/net/vmnet-common.m b/net/vmnet-common.m
index 532d152840..e780985891 100644
--- a/net/vmnet-common.m
+++ b/net/vmnet-common.m
@@ -10,6 +10,8 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qemu/log.h"
 #include "qapi/qapi-types-net.h"
 #include "vmnet_int.h"
 #include "clients.h"
@@ -17,4 +19,315 @@
 #include "qapi/error.h"
 
 #include <vmnet/vmnet.h>
+#include <dispatch/dispatch.h>
 
+#ifdef DEBUG
+#define D(x) x
+#define D_LOG(...) qemu_log(__VA_ARGS__)
+#else
+#define D(x) do { } while (0)
+#define D_LOG(...) do { } while (0)
+#endif
+
+typedef struct vmpktdesc vmpktdesc_t;
+typedef struct iovec iovec_t;
+
+static void vmnet_set_send_enabled(VmnetCommonState *s, bool enable)
+{
+    s->send_enabled = enable;
+}
+
+
+static void vmnet_send_completed(NetClientState *nc, ssize_t len)
+{
+    VmnetCommonState *s = DO_UPCAST(VmnetCommonState, nc, nc);
+    vmnet_set_send_enabled(s, true);
+}
+
+
+static void vmnet_send(NetClientState *nc,
+                       interface_event_t event_id,
+                       xpc_object_t event)
+{
+    assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
+
+    VmnetCommonState *s;
+    uint64_t packets_available;
+
+    struct iovec *iov;
+    struct vmpktdesc *packets;
+    int pkt_cnt;
+    int i;
+
+    vmnet_return_t if_status;
+    ssize_t size;
+
+    s = DO_UPCAST(VmnetCommonState, nc, nc);
+
+    packets_available = xpc_dictionary_get_uint64(
+        event,
+        vmnet_estimated_packets_available_key
+    );
+
+    pkt_cnt = (packets_available < VMNET_PACKETS_LIMIT) ?
+              packets_available :
+              VMNET_PACKETS_LIMIT;
+
+
+    iov = s->iov_buf;
+    packets = s->packets_buf;
+
+    for (i = 0; i < pkt_cnt; ++i) {
+        packets[i].vm_pkt_size = s->max_packet_size;
+        packets[i].vm_pkt_iovcnt = 1;
+        packets[i].vm_flags = 0;
+    }
+
+    if_status = vmnet_read(s->vmnet_if, packets, &pkt_cnt);
+    if (if_status != VMNET_SUCCESS) {
+        error_printf("vmnet: read failed: %s\n",
+                     vmnet_status_map_str(if_status));
+    }
+    qemu_mutex_lock_iothread();
+    for (i = 0; i < pkt_cnt; ++i) {
+        size = qemu_send_packet_async(nc,
+                                      iov[i].iov_base,
+                                      packets[i].vm_pkt_size,
+                                      vmnet_send_completed);
+        if (size == 0) {
+            vmnet_set_send_enabled(s, false);
+        } else if (size < 0) {
+            break;
+        }
+    }
+    qemu_mutex_unlock_iothread();
+
+}
+
+
+static void vmnet_register_event_callback(VmnetCommonState *s)
+{
+    dispatch_queue_t avail_pkt_q = dispatch_queue_create(
+        "org.qemu.vmnet.if_queue",
+        DISPATCH_QUEUE_SERIAL
+    );
+
+    vmnet_interface_set_event_callback(
+        s->vmnet_if,
+        VMNET_INTERFACE_PACKETS_AVAILABLE,
+        avail_pkt_q,
+        ^(interface_event_t event_id, xpc_object_t event) {
+          if (s->send_enabled) {
+              vmnet_send(&s->nc, event_id, event);
+          }
+        });
+}
+
+
+static void vmnet_bufs_init(VmnetCommonState *s)
+{
+    int i;
+    struct vmpktdesc *packets;
+    struct iovec *iov;
+
+    packets = s->packets_buf;
+    iov = s->iov_buf;
+
+    for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
+        iov[i].iov_len = s->max_packet_size;
+        iov[i].iov_base = g_malloc0(iov[i].iov_len);
+        packets[i].vm_pkt_iov = iov + i;
+    }
+}
+
+
+const char *vmnet_status_map_str(vmnet_return_t status)
+{
+    switch (status) {
+    case VMNET_SUCCESS:
+        return "success";
+    case VMNET_FAILURE:
+        return "general failure";
+    case VMNET_MEM_FAILURE:
+        return "memory allocation failure";
+    case VMNET_INVALID_ARGUMENT:
+        return "invalid argument specified";
+    case VMNET_SETUP_INCOMPLETE:
+        return "interface setup is not complete";
+    case VMNET_INVALID_ACCESS:
+        return "invalid access, permission denied";
+    case VMNET_PACKET_TOO_BIG:
+        return "packet size is larger than MTU";
+    case VMNET_BUFFER_EXHAUSTED:
+        return "buffers exhausted in kernel";
+    case VMNET_TOO_MANY_PACKETS:
+        return "packet count exceeds limit";
+#if defined(MAC_OS_VERSION_11_0) && \
+    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+    case VMNET_SHARING_SERVICE_BUSY:
+        return "conflict, sharing service is in use";
+#endif
+    default:
+        return "unknown vmnet error";
+    }
+}
+
+
+int vmnet_if_create(NetClientState *nc,
+                    xpc_object_t if_desc,
+                    Error **errp,
+                    void (*completion_callback)(xpc_object_t interface_param))
+{
+    VmnetCommonState *s;
+
+    dispatch_queue_t if_create_q;
+    dispatch_semaphore_t if_created_sem;
+
+    __block vmnet_return_t if_status;
+
+    if_create_q = dispatch_queue_create("org.qemu.vmnet.create",
+                                        DISPATCH_QUEUE_SERIAL);
+    if_created_sem = dispatch_semaphore_create(0);
+
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_allocate_mac_address_key,
+        false
+    );
+
+    D(D_LOG("vmnet.start.interface_desc:\n");
+    xpc_dictionary_apply(if_desc,
+                         ^bool(const char *k, xpc_object_t v) {
+                           char *desc = xpc_copy_description(v);
+                           D_LOG("  %s=%s\n", k, desc);
+                           free(desc);
+                           return true;
+                         }));
+
+    s = DO_UPCAST(VmnetCommonState, nc, nc);
+    s->vmnet_if = vmnet_start_interface(
+        if_desc,
+        if_create_q,
+        ^(vmnet_return_t status, xpc_object_t interface_param) {
+          if_status = status;
+          if (status != VMNET_SUCCESS || !interface_param) {
+              dispatch_semaphore_signal(if_created_sem);
+              return;
+          }
+
+          D(D_LOG("vmnet.start.interface_param:\n");
+                xpc_dictionary_apply(interface_param,
+                                     ^bool(const char *k, xpc_object_t v) {
+                                       char *desc = xpc_copy_description(v);
+                                       D_LOG("  %s=%s\n", k, desc);
+                                       free(desc);
+                                       return true;
+                                     }));
+
+          s->mtu = xpc_dictionary_get_uint64(
+              interface_param,
+              vmnet_mtu_key);
+          s->max_packet_size = xpc_dictionary_get_uint64(
+              interface_param,
+              vmnet_max_packet_size_key);
+
+          if (completion_callback) {
+              completion_callback(interface_param);
+          }
+          dispatch_semaphore_signal(if_created_sem);
+        });
+
+    if (s->vmnet_if == NULL) {
+        error_setg(errp, "unable to create interface with requested params");
+        return -1;
+    }
+
+    dispatch_semaphore_wait(if_created_sem, DISPATCH_TIME_FOREVER);
+    dispatch_release(if_create_q);
+
+    if (if_status != VMNET_SUCCESS) {
+        error_setg(errp,
+                   "cannot create vmnet interface: %s",
+                   vmnet_status_map_str(if_status));
+        return -1;
+    }
+
+    vmnet_register_event_callback(s);
+    vmnet_bufs_init(s);
+    vmnet_set_send_enabled(s, true);
+
+    return 0;
+}
+
+
+ssize_t vmnet_receive_common(NetClientState *nc,
+                             const uint8_t *buf,
+                             size_t size)
+{
+    VmnetCommonState *s;
+    vmpktdesc_t packet;
+    iovec_t iov;
+    int pkt_cnt;
+    vmnet_return_t if_status;
+
+    s = DO_UPCAST(VmnetCommonState, nc, nc);
+
+    if (size > s->max_packet_size) {
+        warn_report("vmnet: packet is too big, %zu > %llu\n",
+                    packet.vm_pkt_size,
+                    s->max_packet_size);
+        return -1;
+    }
+
+    iov.iov_base = (char *) buf;
+    iov.iov_len = size;
+
+    packet.vm_pkt_iovcnt = 1;
+    packet.vm_flags = 0;
+    packet.vm_pkt_size = size;
+    packet.vm_pkt_iov = &iov;
+
+    pkt_cnt = 1;
+    if_status = vmnet_write(s->vmnet_if, &packet, &pkt_cnt);
+
+    if (if_status != VMNET_SUCCESS) {
+        error_report("vmnet: write error: %s\n",
+                     vmnet_status_map_str(if_status));
+    }
+
+    if (if_status == VMNET_SUCCESS && pkt_cnt) {
+        return size;
+    }
+    return 0;
+}
+
+
+void vmnet_cleanup_common(NetClientState *nc)
+{
+    VmnetCommonState *s;
+    dispatch_queue_t if_destroy_q;
+
+    s = DO_UPCAST(VmnetCommonState, nc, nc);
+
+    qemu_purge_queued_packets(nc);
+    vmnet_set_send_enabled(s, false);
+
+    if (s->vmnet_if == NULL) {
+        return;
+    }
+
+    if_destroy_q = dispatch_queue_create(
+        "org.qemu.vmnet.destroy",
+        DISPATCH_QUEUE_SERIAL
+    );
+
+    vmnet_stop_interface(
+        s->vmnet_if,
+        if_destroy_q,
+        ^(vmnet_return_t status) {
+        });
+
+    for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
+        g_free(s->iov_buf[i].iov_base);
+    }
+}
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
index f8c4a4f3b8..61f3e9201f 100644
--- a/net/vmnet-shared.c
+++ b/net/vmnet-shared.c
@@ -10,16 +10,91 @@
 
 #include "qemu/osdep.h"
 #include "qapi/qapi-types-net.h"
+#include "qapi/error.h"
 #include "vmnet_int.h"
 #include "clients.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
 
 #include <vmnet/vmnet.h>
 
+typedef struct VmnetSharedState {
+  VmnetCommonState cs;
+} VmnetSharedState;
+
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
+{
+    const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
+    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
+
+    xpc_dictionary_set_uint64(
+        if_desc,
+        vmnet_operation_mode_key,
+        VMNET_SHARED_MODE
+    );
+
+#if defined(MAC_OS_VERSION_11_0) && \
+    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_enable_isolation_key,
+        options->isolated
+    );
+#else
+    if (options->has_isolated) {
+        error_setg(errp,
+                   "vmnet-shared.isolated feature is "
+                   "unavailable: outdated vmnet.framework API");
+    }
+#endif
+
+    if (options->has_nat66_prefix) {
+        xpc_dictionary_set_string(if_desc,
+                                  vmnet_nat66_prefix_key,
+                                  options->nat66_prefix);
+    }
+
+    if (options->has_start_address ||
+        options->has_end_address ||
+        options->has_subnet_mask) {
+
+        if (options->has_start_address &&
+            options->has_end_address &&
+            options->has_subnet_mask) {
+
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_start_address_key,
+                                      options->start_address);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_end_address_key,
+                                      options->end_address);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_subnet_mask_key,
+                                      options->subnet_mask);
+        } else {
+            error_setg(
+                errp,
+                "'start-address', 'end-address', 'subnet-mask' "
+                "should be provided together"
+            );
+        }
+    }
+
+    return if_desc;
+}
+
+static NetClientInfo net_vmnet_shared_info = {
+    .type = NET_CLIENT_DRIVER_VMNET_SHARED,
+    .size = sizeof(VmnetSharedState),
+    .receive = vmnet_receive_common,
+    .cleanup = vmnet_cleanup_common,
+};
+
 int net_init_vmnet_shared(const Netdev *netdev, const char *name,
                           NetClientState *peer, Error **errp)
 {
-  error_setg(errp, "vmnet-shared is not implemented yet");
-  return -1;
+    NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
+                                             peer, "vmnet-shared", name);
+    xpc_object_t if_desc = create_if_desc(netdev, errp);
+
+    return vmnet_if_create(nc, if_desc, errp, NULL);
 }
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
index c5982259a4..3979fe4678 100644
--- a/net/vmnet_int.h
+++ b/net/vmnet_int.h
@@ -16,10 +16,33 @@
 
 #include <vmnet/vmnet.h>
 
+#define VMNET_PACKETS_LIMIT 50
+
 typedef struct VmnetCommonState {
   NetClientState nc;
+  interface_ref vmnet_if;
+
+  bool send_enabled;
+
+  uint64_t mtu;
+  uint64_t max_packet_size;
+
+  struct vmpktdesc packets_buf[VMNET_PACKETS_LIMIT];
+  struct iovec iov_buf[VMNET_PACKETS_LIMIT];
 
 } VmnetCommonState;
 
+const char *vmnet_status_map_str(vmnet_return_t status);
+
+int vmnet_if_create(NetClientState *nc,
+                    xpc_object_t if_desc,
+                    Error **errp,
+                    void (*completion_callback)(xpc_object_t interface_param));
+
+ssize_t vmnet_receive_common(NetClientState *nc,
+                             const uint8_t *buf,
+                             size_t size);
+
+void vmnet_cleanup_common(NetClientState *nc);
 
 #endif /* VMNET_INT_H */
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v13 4/7] net/vmnet: implement host mode (vmnet-host)
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (2 preceding siblings ...)
  2022-01-13 17:22 ` [PATCH v13 3/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  2022-01-13 17:22 ` [PATCH v13 5/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/vmnet-host.c | 110 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 6 deletions(-)

diff --git a/net/vmnet-host.c b/net/vmnet-host.c
index 4a5ef99dc7..501b677cb6 100644
--- a/net/vmnet-host.c
+++ b/net/vmnet-host.c
@@ -9,16 +9,114 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/uuid.h"
 #include "qapi/qapi-types-net.h"
-#include "vmnet_int.h"
-#include "clients.h"
-#include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "clients.h"
+#include "vmnet_int.h"
 
 #include <vmnet/vmnet.h>
 
+typedef struct VmnetHostState {
+  VmnetCommonState cs;
+  QemuUUID network_uuid;
+} VmnetHostState;
+
+static xpc_object_t create_if_desc(const Netdev *netdev,
+                                   NetClientState *nc,
+                                   Error **errp)
+{
+    const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
+
+    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
+
+    xpc_dictionary_set_uint64(
+        if_desc,
+        vmnet_operation_mode_key,
+        VMNET_HOST_MODE
+    );
+
+#if defined(MAC_OS_VERSION_11_0) && \
+    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+
+    VmnetCommonState *cs = DO_UPCAST(VmnetCommonState, nc, nc);
+    VmnetHostState *hs = DO_UPCAST(VmnetHostState, cs, cs);
+
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_enable_isolation_key,
+        options->isolated
+    );
+
+    if (options->has_net_uuid) {
+        if (qemu_uuid_parse(options->net_uuid, &hs->network_uuid) < 0) {
+            error_setg(errp, "Invalid UUID provided in 'net-uuid'");
+        }
+
+        xpc_dictionary_set_uuid(
+            if_desc,
+            vmnet_network_identifier_key,
+            hs->network_uuid.data
+        );
+    }
+#else
+    if (options->has_isolated) {
+        error_setg(errp,
+                   "vmnet-host.isolated feature is "
+                   "unavailable: outdated vmnet.framework API");
+    }
+
+    if (options->has_net_uuid) {
+        error_setg(errp,
+                   "vmnet-host.net-uuid feature is "
+                   "unavailable: outdated vmnet.framework API");
+    }
+#endif
+
+    if (options->has_start_address ||
+        options->has_end_address ||
+        options->has_subnet_mask) {
+
+        if (options->has_start_address &&
+            options->has_end_address &&
+            options->has_subnet_mask) {
+
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_start_address_key,
+                                      options->start_address);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_end_address_key,
+                                      options->end_address);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_subnet_mask_key,
+                                      options->subnet_mask);
+        } else {
+            error_setg(
+                errp,
+                "'start-address', 'end-address', 'subnet-mask' "
+                "should be provided together"
+            );
+        }
+    }
+
+    return if_desc;
+}
+
+static NetClientInfo net_vmnet_host_info = {
+    .type = NET_CLIENT_DRIVER_VMNET_HOST,
+    .size = sizeof(VmnetHostState),
+    .receive = vmnet_receive_common,
+    .cleanup = vmnet_cleanup_common,
+};
+
 int net_init_vmnet_host(const Netdev *netdev, const char *name,
-                        NetClientState *peer, Error **errp) {
-  error_setg(errp, "vmnet-host is not implemented yet");
-  return -1;
+                        NetClientState *peer, Error **errp)
+{
+    NetClientState *nc;
+    xpc_object_t if_desc;
+
+    nc = qemu_new_net_client(&net_vmnet_host_info,
+                             peer, "vmnet-host", name);
+    if_desc = create_if_desc(netdev, nc, errp);
+    return vmnet_if_create(nc, if_desc, errp, NULL);
 }
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v13 5/7] net/vmnet: implement bridged mode (vmnet-bridged)
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (3 preceding siblings ...)
  2022-01-13 17:22 ` [PATCH v13 4/7] net/vmnet: implement host mode (vmnet-host) Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  2022-01-14  8:43   ` Akihiko Odaki
  2022-01-13 17:22 ` [PATCH v13 6/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
  2022-01-13 17:22 ` [PATCH v13 7/7] net/vmnet: update MAINTAINERS list Vladislav Yaroshchuk
  6 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/vmnet-bridged.m | 105 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 100 insertions(+), 5 deletions(-)

diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
index 4e42a90391..bc499c6195 100644
--- a/net/vmnet-bridged.m
+++ b/net/vmnet-bridged.m
@@ -10,16 +10,111 @@
 
 #include "qemu/osdep.h"
 #include "qapi/qapi-types-net.h"
-#include "vmnet_int.h"
-#include "clients.h"
-#include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "clients.h"
+#include "vmnet_int.h"
 
 #include <vmnet/vmnet.h>
 
+typedef struct VmnetBridgedState {
+  VmnetCommonState cs;
+} VmnetBridgedState;
+
+static bool validate_ifname(const char *ifname)
+{
+    xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
+    __block bool match = false;
+
+    xpc_array_apply(
+        shared_if_list,
+        ^bool(size_t index, xpc_object_t value) {
+          if (strcmp(xpc_string_get_string_ptr(value), ifname) == 0) {
+              match = true;
+              return false;
+          }
+          return true;
+        });
+
+    return match;
+}
+
+static const char *get_valid_ifnames(void)
+{
+    xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
+    __block char *if_list = NULL;
+
+    xpc_array_apply(
+        shared_if_list,
+        ^bool(size_t index, xpc_object_t value) {
+          if_list = g_strconcat(xpc_string_get_string_ptr(value),
+                                " ",
+                                if_list,
+                                NULL);
+          return true;
+        });
+
+    if (if_list) {
+        return if_list;
+    }
+    return "[no interfaces]";
+}
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
+{
+    const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
+    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
+
+    xpc_dictionary_set_uint64(
+        if_desc,
+        vmnet_operation_mode_key,
+        VMNET_BRIDGED_MODE
+    );
+
+#if defined(MAC_OS_VERSION_11_0) && \
+    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_enable_isolation_key,
+        options->isolated
+    );
+#else
+    if (options->has_isolated) {
+        error_setg(errp,
+                   "vmnet-bridged.isolated feature is "
+                   "unavailable: outdated vmnet.framework API");
+    }
+#endif
+
+    if (validate_ifname(options->ifname)) {
+        xpc_dictionary_set_string(if_desc,
+                                  vmnet_shared_interface_name_key,
+                                  options->ifname);
+    } else {
+        return NULL;
+    }
+    return if_desc;
+}
+
+static NetClientInfo net_vmnet_bridged_info = {
+    .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
+    .size = sizeof(VmnetBridgedState),
+    .receive = vmnet_receive_common,
+    .cleanup = vmnet_cleanup_common,
+};
+
 int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
                            NetClientState *peer, Error **errp)
 {
-  error_setg(errp, "vmnet-bridged is not implemented yet");
-  return -1;
+    NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
+                                             peer, "vmnet-bridged", name);
+    xpc_object_t if_desc = create_if_desc(netdev, errp);;
+
+    if (!if_desc) {
+        error_setg(errp,
+                   "unsupported ifname, should be one of: %s",
+                   get_valid_ifnames());
+        return -1;
+    }
+
+    return vmnet_if_create(nc, if_desc, errp, NULL);
 }
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v13 6/7] net/vmnet: update qemu-options.hx
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (4 preceding siblings ...)
  2022-01-13 17:22 ` [PATCH v13 5/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  2022-01-14  8:43   ` Akihiko Odaki
  2022-01-13 17:22 ` [PATCH v13 7/7] net/vmnet: update MAINTAINERS list Vladislav Yaroshchuk
  6 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 qemu-options.hx | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index ec90505d84..81dd34f550 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2732,6 +2732,25 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 #ifdef __linux__
     "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
     "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
+#endif
+#ifdef CONFIG_VMNET
+    "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n"
+    "         [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
+    "                configure a vmnet network backend in host mode with ID 'str',\n"
+    "                isolate this interface from others with 'isolated',\n"
+    "                configure the address range and choose a subnet mask,\n"
+    "                specify network UUID 'uuid' to disable DHCP and interact with\n"
+    "                vmnet-host interfaces within this isolated network\n"
+    "-netdev vmnet-shared,id=str[,isolated=on|off][,nat66-prefix=addr]\n"
+    "         [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
+    "                configure a vmnet network backend in shared mode with ID 'str',\n"
+    "                configure the address range and choose a subnet mask,\n"
+    "                set IPv6 ULA prefix (of length 64) to use for internal network,\n"
+    "                isolate this interface from others with 'isolated'\n"
+    "-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]\n"
+    "                configure a vmnet network backend in bridged mode with ID 'str',\n"
+    "                use 'ifname=name' to select a physical network interface to be bridged,\n"
+    "                isolate this interface from others with 'isolated'\n"
 #endif
     "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
     "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
@@ -2751,6 +2770,9 @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
 #endif
 #ifdef CONFIG_POSIX
     "vhost-user|"
+#endif
+#ifdef CONFIG_VMNET
+    "vmnet-host|vmnet-shared|vmnet-bridged|"
 #endif
     "socket][,option][,...][mac=macaddr]\n"
     "                initialize an on-board / default host NIC (using MAC address\n"
@@ -2773,6 +2795,9 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
 #endif
 #ifdef CONFIG_NETMAP
     "netmap|"
+#endif
+#ifdef CONFIG_VMNET
+    "vmnet-host|vmnet-shared|vmnet-bridged|"
 #endif
     "socket][,option][,option][,...]\n"
     "                old way to initialize a host network interface\n"
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v13 7/7] net/vmnet: update MAINTAINERS list
  2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (5 preceding siblings ...)
  2022-01-13 17:22 ` [PATCH v13 6/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
@ 2022-01-13 17:22 ` Vladislav Yaroshchuk
  6 siblings, 0 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-13 17:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Vladislav Yaroshchuk, alex.bennee, jasowang,
	phillip.ennen, armbru, dirty, f4bug, roman, r.bolshakov, agraf,
	phillip, akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake,
	kraxel

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c98a61caee..638d129305 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2641,6 +2641,11 @@ W: http://info.iet.unipi.it/~luigi/netmap/
 S: Maintained
 F: net/netmap.c
 
+Apple vmnet network backends
+M: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
+S: Maintained
+F: net/vmnet*
+
 Host Memory Backends
 M: David Hildenbrand <david@redhat.com>
 M: Igor Mammedov <imammedo@redhat.com>
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
@ 2022-01-14  8:43   ` Akihiko Odaki
  2022-01-15 13:00     ` Vladislav Yaroshchuk
  2022-01-18 15:00   ` Markus Armbruster
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-14  8:43 UTC (permalink / raw)
  To: Vladislav Yaroshchuk, qemu-devel
  Cc: peter.maydell, alex.bennee, jasowang, phillip.ennen, armbru,
	dirty, f4bug, r.bolshakov, agraf, phillip, roman, hsp.cat7,
	hello, qemu_oss, eblake, kraxel

Hi,

Thank you for fixing the feature availability check.

I decided to just check the series thoroughly before adding Reviewed-By, 
and unfortunately ended up finding minor memory leaks and style 
problems. I'm sorry for adding comments so late.

Particulalry, his patch has several 2-space indents. They should be 
4-space. Reviews for other patch will shortly follow.

Regards,
Akihiko Odaki

On 2022/01/14 2:22, Vladislav Yaroshchuk wrote:
> Create separate netdevs for each vmnet operating mode:
> - vmnet-host
> - vmnet-shared
> - vmnet-bridged
> 
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>   net/clients.h       |  11 ++++
>   net/meson.build     |   7 +++
>   net/net.c           |  10 ++++
>   net/vmnet-bridged.m |  25 +++++++++
>   net/vmnet-common.m  |  20 +++++++
>   net/vmnet-host.c    |  24 ++++++++
>   net/vmnet-shared.c  |  25 +++++++++
>   net/vmnet_int.h     |  25 +++++++++
>   qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
>   9 files changed, 278 insertions(+), 2 deletions(-)
>   create mode 100644 net/vmnet-bridged.m
>   create mode 100644 net/vmnet-common.m
>   create mode 100644 net/vmnet-host.c
>   create mode 100644 net/vmnet-shared.c
>   create mode 100644 net/vmnet_int.h
> 
> diff --git a/net/clients.h b/net/clients.h
> index 92f9b59aed..c9157789f2 100644
> --- a/net/clients.h
> +++ b/net/clients.h
> @@ -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 */
> diff --git a/net/meson.build b/net/meson.build
> index 847bc2ac85..00a88c4951 100644
> --- a/net/meson.build
> +++ b/net/meson.build
> @@ -42,4 +42,11 @@ 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'))
>   
> +vmnet_files = files(
> +  'vmnet-common.m',
> +  'vmnet-bridged.m',
> +  'vmnet-host.c',
> +  'vmnet-shared.c'
> +)
> +softmmu_ss.add(when: vmnet, if_true: vmnet_files)
>   subdir('can')
> diff --git a/net/net.c b/net/net.c
> index f0d14dbfc1..1dbb64b935 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1021,6 +1021,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 */
>   };
>   
>   
> @@ -1106,6 +1111,11 @@ void show_netdevs(void)
>   #endif
>   #ifdef CONFIG_VHOST_VDPA
>           "vhost-vdpa",
> +#endif
> +#ifdef CONFIG_VMNET
> +        "vmnet-host",
> +        "vmnet-shared",
> +        "vmnet-bridged",
>   #endif
>       };
>   
> diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> new file mode 100644
> index 0000000000..4e42a90391
> --- /dev/null
> +++ b/net/vmnet-bridged.m
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet-bridged.m
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
> +                           NetClientState *peer, Error **errp)
> +{
> +  error_setg(errp, "vmnet-bridged is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> new file mode 100644
> index 0000000000..532d152840
> --- /dev/null
> +++ b/net/vmnet-common.m
> @@ -0,0 +1,20 @@
> +/*
> + * vmnet-common.m - network client wrapper for Apple vmnet.framework
> + *
> + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> diff --git a/net/vmnet-host.c b/net/vmnet-host.c
> new file mode 100644
> index 0000000000..4a5ef99dc7
> --- /dev/null
> +++ b/net/vmnet-host.c
> @@ -0,0 +1,24 @@
> +/*
> + * vmnet-host.c
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.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-host is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> new file mode 100644
> index 0000000000..f8c4a4f3b8
> --- /dev/null
> +++ b/net/vmnet-shared.c
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet-shared.c
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
> +                          NetClientState *peer, Error **errp)
> +{
> +  error_setg(errp, "vmnet-shared is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> new file mode 100644
> index 0000000000..c5982259a4
> --- /dev/null
> +++ b/net/vmnet_int.h
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet_int.h
> + *
> + * 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.
> + *
> + */
> +#ifndef VMNET_INT_H
> +#define VMNET_INT_H
> +
> +#include "qemu/osdep.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +typedef struct VmnetCommonState {
> +  NetClientState nc;
> +
> +} VmnetCommonState;
> +
> +
> +#endif /* VMNET_INT_H */
> diff --git a/qapi/net.json b/qapi/net.json
> index 7fab2e7cd8..b922e2e34f 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -452,6 +452,120 @@
>       '*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 host.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and
> +#               @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#               be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> +#            network vmnet interface should be added to. If
> +#            set, no DHCP service is provided for this interface and
> +#            network communication is allowed only with other interfaces
> +#            added to this network identified by the UUID. Available
> +#            since macOS Big Sur 11.0.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetHostOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*net-uuid':      '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 communicate with the host and with
> +# other shared mode interfaces on the same subnet. If no DHCP
> +# settings, subnet mask and IPv6 prefix specified, the interface can
> +# communicate with any of other interfaces in shared mode.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#                be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> +#                unique local address i.e. start with fd00::/8 and have
> +#                length of 64.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetSharedOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*nat66-prefix':  '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.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetBridgedOptions',
> +  'data': {
> +    'ifname':     'str',
> +    '*isolated':  'bool' },
> +  'if': 'CONFIG_VMNET' }
> +
>   ##
>   # @NetClientDriver:
>   #
> @@ -460,10 +574,16 @@
>   # Since: 2.7
>   #
>   #        @vhost-vdpa since 5.1
> +#        @vmnet-host since 7.0
> +#        @vmnet-shared since 7.0
> +#        @vmnet-bridged since 7.0
>   ##
>   { '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 +597,9 @@
>   # Since: 1.2
>   #
>   #        'l2tpv3' - since 2.1
> +#        'vmnet-host' - since 7.0
> +#        'vmnet-shared' - since 7.0
> +#        'vmnet-bridged' - since 7.0
>   ##
>   { 'union': 'Netdev',
>     'base': { 'id': 'str', 'type': 'NetClientDriver' },
> @@ -492,7 +615,13 @@
>       'hubport':  'NetdevHubPortOptions',
>       'netmap':   'NetdevNetmapOptions',
>       'vhost-user': 'NetdevVhostUserOptions',
> -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> +                    'if': 'CONFIG_VMNET' },
> +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> +                      'if': 'CONFIG_VMNET' },
> +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> +                       'if': 'CONFIG_VMNET' } } }
>   
>   ##
>   # @RxState:


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 3/7] net/vmnet: implement shared mode (vmnet-shared)
  2022-01-13 17:22 ` [PATCH v13 3/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
@ 2022-01-14  8:43   ` Akihiko Odaki
  0 siblings, 0 replies; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-14  8:43 UTC (permalink / raw)
  To: Vladislav Yaroshchuk, qemu-devel
  Cc: peter.maydell, alex.bennee, jasowang, phillip.ennen, armbru,
	dirty, f4bug, r.bolshakov, agraf, phillip, roman, hsp.cat7,
	hello, qemu_oss, eblake, kraxel

On 2022/01/14 2:22, Vladislav Yaroshchuk wrote:
> Interaction with vmnet.framework in different modes
> differs only on configuration stage, so we can create
> common `send`, `receive`, etc. procedures and reuse them.
> 
> vmnet.framework supports iov, but writing more than
> one iov into vmnet interface fails with
> 'VMNET_INVALID_ARGUMENT'. Collecting provided iovs into
> one and passing it to vmnet works fine. That's the
> reason why receive_iov() left unimplemented. But it still
> works with good enough performance having .receive()
> implemented only.
> 
> Also, there is no way to unsubscribe from vmnet packages
> receiving except registering and unregistering event
> callback or simply drop packages just ignoring and
> not processing them when related flag is set. Here we do
> using the second way.
> 
> Signed-off-by: Phillip Tennen <phillip@axleos.com>
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>   net/vmnet-common.m | 313 +++++++++++++++++++++++++++++++++++++++++++++
>   net/vmnet-shared.c |  83 +++++++++++-
>   net/vmnet_int.h    |  23 ++++
>   3 files changed, 415 insertions(+), 4 deletions(-)
> 
> diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> index 532d152840..e780985891 100644
> --- a/net/vmnet-common.m
> +++ b/net/vmnet-common.m
> @@ -10,6 +10,8 @@
>    */
>   
>   #include "qemu/osdep.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/log.h"
>   #include "qapi/qapi-types-net.h"
>   #include "vmnet_int.h"
>   #include "clients.h"
> @@ -17,4 +19,315 @@
>   #include "qapi/error.h"
>   
>   #include <vmnet/vmnet.h>
> +#include <dispatch/dispatch.h>
>   
> +#ifdef DEBUG
> +#define D(x) x
> +#define D_LOG(...) qemu_log(__VA_ARGS__)
> +#else
> +#define D(x) do { } while (0)
> +#define D_LOG(...) do { } while (0)
> +#endif
> +
> +typedef struct vmpktdesc vmpktdesc_t;
> +typedef struct iovec iovec_t;

The uses of these typedefs are inconsistent and some use struct 
vmpktdesc and struct iovec and the other use vmpktdesc_t and iovec_t. 
They should be at least consistent, and I also don't think adding 
typedefs for types provided by an external library is a good idea in 
general.

> +
> +static void vmnet_set_send_enabled(VmnetCommonState *s, bool enable)
> +{
> +    s->send_enabled = enable;
> +}
> +
> +
> +static void vmnet_send_completed(NetClientState *nc, ssize_t len)
> +{
> +    VmnetCommonState *s = DO_UPCAST(VmnetCommonState, nc, nc);
> +    vmnet_set_send_enabled(s, true);
> +}
> +
> +
> +static void vmnet_send(NetClientState *nc,
> +                       interface_event_t event_id,
> +                       xpc_object_t event)
> +{
> +    assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
> +
> +    VmnetCommonState *s;
> +    uint64_t packets_available;
> +
> +    struct iovec *iov;
> +    struct vmpktdesc *packets;
> +    int pkt_cnt;
> +    int i;
> +
> +    vmnet_return_t if_status;
> +    ssize_t size;
> +
> +    s = DO_UPCAST(VmnetCommonState, nc, nc);
> +
> +    packets_available = xpc_dictionary_get_uint64(
> +        event,
> +        vmnet_estimated_packets_available_key
> +    );
> +
> +    pkt_cnt = (packets_available < VMNET_PACKETS_LIMIT) ?
> +              packets_available :
> +              VMNET_PACKETS_LIMIT;
> +
> +
> +    iov = s->iov_buf;
> +    packets = s->packets_buf;
> +
> +    for (i = 0; i < pkt_cnt; ++i) {
> +        packets[i].vm_pkt_size = s->max_packet_size;
> +        packets[i].vm_pkt_iovcnt = 1;
> +        packets[i].vm_flags = 0;
> +    }
> +
> +    if_status = vmnet_read(s->vmnet_if, packets, &pkt_cnt);
> +    if (if_status != VMNET_SUCCESS) {
> +        error_printf("vmnet: read failed: %s\n",
> +                     vmnet_status_map_str(if_status));
> +    }
> +    qemu_mutex_lock_iothread();
> +    for (i = 0; i < pkt_cnt; ++i) {
> +        size = qemu_send_packet_async(nc,
> +                                      iov[i].iov_base,
> +                                      packets[i].vm_pkt_size,
> +                                      vmnet_send_completed);
> +        if (size == 0) {
> +            vmnet_set_send_enabled(s, false);
> +        } else if (size < 0) {
> +            break;
> +        }
> +    }
> +    qemu_mutex_unlock_iothread();
> +
> +}
> +
> +
> +static void vmnet_register_event_callback(VmnetCommonState *s)
> +{
> +    dispatch_queue_t avail_pkt_q = dispatch_queue_create(
> +        "org.qemu.vmnet.if_queue",
> +        DISPATCH_QUEUE_SERIAL
> +    );
> +
> +    vmnet_interface_set_event_callback(
> +        s->vmnet_if,
> +        VMNET_INTERFACE_PACKETS_AVAILABLE,
> +        avail_pkt_q,
> +        ^(interface_event_t event_id, xpc_object_t event) {
> +          if (s->send_enabled) {
> +              vmnet_send(&s->nc, event_id, event);
> +          }
> +        });
> +}

avail_pkt_q leaks even after vmnet_cleanup_common. Note:
- that you can dynamically add and delete interfaces with HMP and QMP.
- that vmnet_interface_set_event_callback somehow does not manage the 
reference counter by itself so you cannot just call dispatch_release 
immediately after vmnet_interface_set_event_callback and you have to 
call it after making sure everything is done.

> +
> +
> +static void vmnet_bufs_init(VmnetCommonState *s)
> +{
> +    int i;
> +    struct vmpktdesc *packets;
> +    struct iovec *iov;
> +
> +    packets = s->packets_buf;
> +    iov = s->iov_buf;
> +
> +    for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
> +        iov[i].iov_len = s->max_packet_size;
> +        iov[i].iov_base = g_malloc0(iov[i].iov_len);
> +        packets[i].vm_pkt_iov = iov + i;
> +    }
> +}
> +
> +
> +const char *vmnet_status_map_str(vmnet_return_t status)
> +{
> +    switch (status) {
> +    case VMNET_SUCCESS:
> +        return "success";
> +    case VMNET_FAILURE:
> +        return "general failure";
> +    case VMNET_MEM_FAILURE:
> +        return "memory allocation failure";
> +    case VMNET_INVALID_ARGUMENT:
> +        return "invalid argument specified";
> +    case VMNET_SETUP_INCOMPLETE:
> +        return "interface setup is not complete";
> +    case VMNET_INVALID_ACCESS:
> +        return "invalid access, permission denied";
> +    case VMNET_PACKET_TOO_BIG:
> +        return "packet size is larger than MTU";
> +    case VMNET_BUFFER_EXHAUSTED:
> +        return "buffers exhausted in kernel";
> +    case VMNET_TOO_MANY_PACKETS:
> +        return "packet count exceeds limit";
> +#if defined(MAC_OS_VERSION_11_0) && \
> +    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
> +    case VMNET_SHARING_SERVICE_BUSY:
> +        return "conflict, sharing service is in use";
> +#endif
> +    default:
> +        return "unknown vmnet error";
> +    }
> +}
> +
> +
> +int vmnet_if_create(NetClientState *nc,
> +                    xpc_object_t if_desc,
> +                    Error **errp,
> +                    void (*completion_callback)(xpc_object_t interface_param))

completion_callback parameter is apparently unused in this series and 
can be removed.

> +{
> +    VmnetCommonState *s;
> +
> +    dispatch_queue_t if_create_q;
> +    dispatch_semaphore_t if_created_sem
> +
> +    __block vmnet_return_t if_status;
> +
> +    if_create_q = dispatch_queue_create("org.qemu.vmnet.create",
> +                                        DISPATCH_QUEUE_SERIAL);
> +    if_created_sem = dispatch_semaphore_create(0);

if_created_sem leaks. Add dispatch_release(if_created_sem); later.

> +
> +    xpc_dictionary_set_bool(
> +        if_desc,
> +        vmnet_allocate_mac_address_key,
> +        false
> +    );
> +
> +    D(D_LOG("vmnet.start.interface_desc:\n");
> +    xpc_dictionary_apply(if_desc,
> +                         ^bool(const char *k, xpc_object_t v) {
> +                           char *desc = xpc_copy_description(v);
> +                           D_LOG("  %s=%s\n", k, desc);
> +                           free(desc);
> +                           return true;
> +                         }));
> +
> +    s = DO_UPCAST(VmnetCommonState, nc, nc);
> +    s->vmnet_if = vmnet_start_interface(
> +        if_desc,
> +        if_create_q,
> +        ^(vmnet_return_t status, xpc_object_t interface_param) {
> +          if_status = status;
> +          if (status != VMNET_SUCCESS || !interface_param) {
> +              dispatch_semaphore_signal(if_created_sem);
> +              return;
> +          }
> +
> +          D(D_LOG("vmnet.start.interface_param:\n");
> +                xpc_dictionary_apply(interface_param,
> +                                     ^bool(const char *k, xpc_object_t v) {
> +                                       char *desc = xpc_copy_description(v);
> +                                       D_LOG("  %s=%s\n", k, desc);
> +                                       free(desc);
> +                                       return true;
> +                                     }));

The indents in `D()` in this function is inconsistent. In my opinion, 
having a few statements in `()` is inherently confusing and just using 
`#ifdef DEBUG` is preferred.

Using a normal `if` instead of #ifdef would be even better, but you 
don't have to do that because apparently QEMU doesn't have a common 
infrastructure for this. c.f. 
https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation

> +
> +          s->mtu = xpc_dictionary_get_uint64(
> +              interface_param,
> +              vmnet_mtu_key);
> +          s->max_packet_size = xpc_dictionary_get_uint64(
> +              interface_param,
> +              vmnet_max_packet_size_key);
> +
> +          if (completion_callback) {
> +              completion_callback(interface_param);
> +          }
> +          dispatch_semaphore_signal(if_created_sem);
> +        });
> +
> +    if (s->vmnet_if == NULL) {
> +        error_setg(errp, "unable to create interface with requested params");
> +        return -1;

if_create_q leaks here. You may just use a global queue here to entirely 
eliminate the need of calling dispatch_release(if_create_q).

> +    }
> +
> +    dispatch_semaphore_wait(if_created_sem, DISPATCH_TIME_FOREVER);
> +    dispatch_release(if_create_q);
> +
> +    if (if_status != VMNET_SUCCESS) {
> +        error_setg(errp,
> +                   "cannot create vmnet interface: %s",
> +                   vmnet_status_map_str(if_status));
> +        return -1;
> +    }
> +
> +    vmnet_register_event_callback(s);
> +    vmnet_bufs_init(s);
> +    vmnet_set_send_enabled(s, true);
> +
> +    return 0;
> +}
> +
> +
> +ssize_t vmnet_receive_common(NetClientState *nc,
> +                             const uint8_t *buf,
> +                             size_t size)
> +{
> +    VmnetCommonState *s;
> +    vmpktdesc_t packet;
> +    iovec_t iov;
> +    int pkt_cnt;
> +    vmnet_return_t if_status;
> +
> +    s = DO_UPCAST(VmnetCommonState, nc, nc);
> +
> +    if (size > s->max_packet_size) {
> +        warn_report("vmnet: packet is too big, %zu > %llu\n",
> +                    packet.vm_pkt_size,
> +                    s->max_packet_size);
> +        return -1;
> +    }
> +
> +    iov.iov_base = (char *) buf;
> +    iov.iov_len = size;
> +
> +    packet.vm_pkt_iovcnt = 1;
> +    packet.vm_flags = 0;
> +    packet.vm_pkt_size = size;
> +    packet.vm_pkt_iov = &iov;
> +
> +    pkt_cnt = 1;
> +    if_status = vmnet_write(s->vmnet_if, &packet, &pkt_cnt);
> +
> +    if (if_status != VMNET_SUCCESS) {
> +        error_report("vmnet: write error: %s\n",
> +                     vmnet_status_map_str(if_status));
> +    }
> +
> +    if (if_status == VMNET_SUCCESS && pkt_cnt) {
> +        return size;
> +    }
> +    return 0;
> +}
> +
> +
> +void vmnet_cleanup_common(NetClientState *nc)
> +{
> +    VmnetCommonState *s;
> +    dispatch_queue_t if_destroy_q;
> +
> +    s = DO_UPCAST(VmnetCommonState, nc, nc);
> +
> +    qemu_purge_queued_packets(nc);
> +    vmnet_set_send_enabled(s, false);
> +
> +    if (s->vmnet_if == NULL) {
> +        return;
> +    }
> +
> +    if_destroy_q = dispatch_queue_create(
> +        "org.qemu.vmnet.destroy",
> +        DISPATCH_QUEUE_SERIAL
> +    );
> +
> +    vmnet_stop_interface(
> +        s->vmnet_if,
> +        if_destroy_q,
> +        ^(vmnet_return_t status) {
> +        });
> +
> +    for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
> +        g_free(s->iov_buf[i].iov_base);
> +    }

Not sure it is safe to free things without waiting the callback of 
vmnet_stop_interface. I think a semaphore should be added as it is in 
vmnet_if_create.

> +}
> diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> index f8c4a4f3b8..61f3e9201f 100644
> --- a/net/vmnet-shared.c
> +++ b/net/vmnet-shared.c
> @@ -10,16 +10,91 @@
>   
>   #include "qemu/osdep.h"
>   #include "qapi/qapi-types-net.h"
> +#include "qapi/error.h"
>   #include "vmnet_int.h"
>   #include "clients.h"
> -#include "qemu/error-report.h"
> -#include "qapi/error.h"
>   
>   #include <vmnet/vmnet.h>
>   
> +typedef struct VmnetSharedState {
> +  VmnetCommonState cs;
> +} VmnetSharedState;
> +
> +
> +static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
> +{
> +    const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
> +    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
> +
> +    xpc_dictionary_set_uint64(
> +        if_desc,
> +        vmnet_operation_mode_key,
> +        VMNET_SHARED_MODE
> +    );
> +
> +#if defined(MAC_OS_VERSION_11_0) && \
> +    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
> +    xpc_dictionary_set_bool(
> +        if_desc,
> +        vmnet_enable_isolation_key,
> +        options->isolated
> +    );
> +#else
> +    if (options->has_isolated) {
> +        error_setg(errp,
> +                   "vmnet-shared.isolated feature is "
> +                   "unavailable: outdated vmnet.framework API");
> +    }
> +#endif
> +
> +    if (options->has_nat66_prefix) {
> +        xpc_dictionary_set_string(if_desc,
> +                                  vmnet_nat66_prefix_key,
> +                                  options->nat66_prefix);
> +    }
> +
> +    if (options->has_start_address ||
> +        options->has_end_address ||
> +        options->has_subnet_mask) {
> +
> +        if (options->has_start_address &&
> +            options->has_end_address &&
> +            options->has_subnet_mask) {
> +
> +            xpc_dictionary_set_string(if_desc,
> +                                      vmnet_start_address_key,
> +                                      options->start_address);
> +            xpc_dictionary_set_string(if_desc,
> +                                      vmnet_end_address_key,
> +                                      options->end_address);
> +            xpc_dictionary_set_string(if_desc,
> +                                      vmnet_subnet_mask_key,
> +                                      options->subnet_mask);
> +        } else {
> +            error_setg(
> +                errp,
> +                "'start-address', 'end-address', 'subnet-mask' "
> +                "should be provided together"
> +            );
> +        }
> +    }

I think the following is simpler and the intention is still clear:
// if you have all the options...
if (options->has_start_address &&
     options->has_end_address &&
     options->has_subnet_mask) {
   // ... set relevant entries in the dictionary
// otherwise, if you still have some of the options...
} else if (options->has_start_address ||
            options->has_end_address ||
            options->has_subnet_mask) {
   // error
}

> +
> +    return if_desc;
> +}
> +
> +static NetClientInfo net_vmnet_shared_info = {
> +    .type = NET_CLIENT_DRIVER_VMNET_SHARED,
> +    .size = sizeof(VmnetSharedState),
> +    .receive = vmnet_receive_common,
> +    .cleanup = vmnet_cleanup_common,
> +};
> +
>   int net_init_vmnet_shared(const Netdev *netdev, const char *name,
>                             NetClientState *peer, Error **errp)
>   {
> -  error_setg(errp, "vmnet-shared is not implemented yet");
> -  return -1;
> +    NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
> +                                             peer, "vmnet-shared", name);
> +    xpc_object_t if_desc = create_if_desc(netdev, errp);
> +
> +    return vmnet_if_create(nc, if_desc, errp, NULL);

if_desc leaks here. Add xpc_release(if_desc);

qemu_del_net_client(nc) should also be called if the interface creation 
failed.

>   }
> diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> index c5982259a4..3979fe4678 100644
> --- a/net/vmnet_int.h
> +++ b/net/vmnet_int.h
> @@ -16,10 +16,33 @@
>   
>   #include <vmnet/vmnet.h>
>   
> +#define VMNET_PACKETS_LIMIT 50 > +

This value has no reasoning. I found this:
https://developer.apple.com/documentation/vmnet
> Each read/write call allows up to 200 packets to be read or written
 > for a maximum of 256KB.

If 200 is the correct value for this, the URI to the page should also 
added as a comment.

>   typedef struct VmnetCommonState {
>     NetClientState nc;
> +  interface_ref vmnet_if;
> +
> +  bool send_enabled;
> +
> +  uint64_t mtu;
> +  uint64_t max_packet_size;
> +
> +  struct vmpktdesc packets_buf[VMNET_PACKETS_LIMIT];
> +  struct iovec iov_buf[VMNET_PACKETS_LIMIT];
>   
>   } VmnetCommonState;
>   
> +const char *vmnet_status_map_str(vmnet_return_t status);
> +
> +int vmnet_if_create(NetClientState *nc,
> +                    xpc_object_t if_desc,
> +                    Error **errp,
> +                    void (*completion_callback)(xpc_object_t interface_param));
> +
> +ssize_t vmnet_receive_common(NetClientState *nc,
> +                             const uint8_t *buf,
> +                             size_t size);
> +
> +void vmnet_cleanup_common(NetClientState *nc);
>   
>   #endif /* VMNET_INT_H */


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 5/7] net/vmnet: implement bridged mode (vmnet-bridged)
  2022-01-13 17:22 ` [PATCH v13 5/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
@ 2022-01-14  8:43   ` Akihiko Odaki
  0 siblings, 0 replies; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-14  8:43 UTC (permalink / raw)
  To: Vladislav Yaroshchuk, qemu-devel
  Cc: peter.maydell, alex.bennee, jasowang, phillip.ennen, armbru,
	dirty, f4bug, r.bolshakov, agraf, phillip, roman, hsp.cat7,
	hello, qemu_oss, eblake, kraxel

On 2022/01/14 2:22, Vladislav Yaroshchuk wrote:
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>   net/vmnet-bridged.m | 105 +++++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 100 insertions(+), 5 deletions(-)
> 
> diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> index 4e42a90391..bc499c6195 100644
> --- a/net/vmnet-bridged.m
> +++ b/net/vmnet-bridged.m
> @@ -10,16 +10,111 @@
>   
>   #include "qemu/osdep.h"
>   #include "qapi/qapi-types-net.h"
> -#include "vmnet_int.h"
> -#include "clients.h"
> -#include "qemu/error-report.h"
>   #include "qapi/error.h"
> +#include "clients.h"
> +#include "vmnet_int.h"
>   
>   #include <vmnet/vmnet.h>
>   
> +typedef struct VmnetBridgedState {
> +  VmnetCommonState cs;
> +} VmnetBridgedState;
> +
> +static bool validate_ifname(const char *ifname)
> +{
> +    xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
> +    __block bool match = false;
> +
> +    xpc_array_apply(
> +        shared_if_list,
> +        ^bool(size_t index, xpc_object_t value) {
> +          if (strcmp(xpc_string_get_string_ptr(value), ifname) == 0) {
> +              match = true;
> +              return false;
> +          }
> +          return true;
> +        });
> +
> +    return match;
> +}

shared_if_list leaks here. Add xpc_release(shared_if_list);

It can be simpler like the following:
return !xpc_array_apply(
     shared_if_list,
     ^bool(size_t index, xpc_object_t value) {
         return strcmp(xpc_string_get_string_ptr(value), ifname) != 0;
     });

> +
> +static const char *get_valid_ifnames(void)
> +{
> +    xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
> +    __block char *if_list = NULL;
> +
> +    xpc_array_apply(
> +        shared_if_list,
> +        ^bool(size_t index, xpc_object_t value) {
> +          if_list = g_strconcat(xpc_string_get_string_ptr(value),
> +                                " ",
> +                                if_list,
> +                                NULL);
> +          return true;
> +        });
> +
> +    if (if_list) {
> +        return if_list;
> +    }
> +    return "[no interfaces]";
> +}
> +
> +static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
> +{
> +    const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
> +    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
> +
> +    xpc_dictionary_set_uint64(
> +        if_desc,
> +        vmnet_operation_mode_key,
> +        VMNET_BRIDGED_MODE
> +    );
> +
> +#if defined(MAC_OS_VERSION_11_0) && \
> +    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
> +    xpc_dictionary_set_bool(
> +        if_desc,
> +        vmnet_enable_isolation_key,
> +        options->isolated
> +    );
> +#else
> +    if (options->has_isolated) {
> +        error_setg(errp,
> +                   "vmnet-bridged.isolated feature is "
> +                   "unavailable: outdated vmnet.framework API");
> +    }
> +#endif
> +
> +    if (validate_ifname(options->ifname)) {
> +        xpc_dictionary_set_string(if_desc,
> +                                  vmnet_shared_interface_name_key,
> +                                  options->ifname);
> +    } else {
> +        return NULL;
> +    }

The dictionary leaks if the validation fails. The validation should 
happen as early as possible.

> +    return if_desc;
> +}
> +
> +static NetClientInfo net_vmnet_bridged_info = {
> +    .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
> +    .size = sizeof(VmnetBridgedState),
> +    .receive = vmnet_receive_common,
> +    .cleanup = vmnet_cleanup_common,
> +};
> +
>   int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
>                              NetClientState *peer, Error **errp)
>   {
> -  error_setg(errp, "vmnet-bridged is not implemented yet");
> -  return -1;
> +    NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
> +                                             peer, "vmnet-bridged", name);
> +    xpc_object_t if_desc = create_if_desc(netdev, errp);;

Duplicate semicolon.

> +
> +    if (!if_desc) {
> +        error_setg(errp,
> +                   "unsupported ifname, should be one of: %s",
> +                   get_valid_ifnames());

nc and get_valid_ifnames() leaks.

> +        return -1;
> +    }
> +
> +    return vmnet_if_create(nc, if_desc, errp, NULL);
>   }


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 6/7] net/vmnet: update qemu-options.hx
  2022-01-13 17:22 ` [PATCH v13 6/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
@ 2022-01-14  8:43   ` Akihiko Odaki
  0 siblings, 0 replies; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-14  8:43 UTC (permalink / raw)
  To: Vladislav Yaroshchuk, qemu-devel
  Cc: peter.maydell, alex.bennee, jasowang, phillip.ennen, armbru,
	dirty, f4bug, r.bolshakov, agraf, phillip, roman, hsp.cat7,
	hello, qemu_oss, eblake, kraxel

The corresponding change for hmp-commands.hx is missing (Look for 
hmp_netdev_add).

Regards,
Akihiko Odaki

On 2022/01/14 2:22, Vladislav Yaroshchuk wrote:
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>   qemu-options.hx | 25 +++++++++++++++++++++++++
>   1 file changed, 25 insertions(+)
> 
> diff --git a/qemu-options.hx b/qemu-options.hx
> index ec90505d84..81dd34f550 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2732,6 +2732,25 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>   #ifdef __linux__
>       "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
>       "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
> +#endif
> +#ifdef CONFIG_VMNET
> +    "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n"
> +    "         [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
> +    "                configure a vmnet network backend in host mode with ID 'str',\n"
> +    "                isolate this interface from others with 'isolated',\n"
> +    "                configure the address range and choose a subnet mask,\n"
> +    "                specify network UUID 'uuid' to disable DHCP and interact with\n"
> +    "                vmnet-host interfaces within this isolated network\n"
> +    "-netdev vmnet-shared,id=str[,isolated=on|off][,nat66-prefix=addr]\n"
> +    "         [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
> +    "                configure a vmnet network backend in shared mode with ID 'str',\n"
> +    "                configure the address range and choose a subnet mask,\n"
> +    "                set IPv6 ULA prefix (of length 64) to use for internal network,\n"
> +    "                isolate this interface from others with 'isolated'\n"
> +    "-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]\n"
> +    "                configure a vmnet network backend in bridged mode with ID 'str',\n"
> +    "                use 'ifname=name' to select a physical network interface to be bridged,\n"
> +    "                isolate this interface from others with 'isolated'\n"
>   #endif
>       "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
>       "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
> @@ -2751,6 +2770,9 @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
>   #endif
>   #ifdef CONFIG_POSIX
>       "vhost-user|"
> +#endif
> +#ifdef CONFIG_VMNET
> +    "vmnet-host|vmnet-shared|vmnet-bridged|"
>   #endif
>       "socket][,option][,...][mac=macaddr]\n"
>       "                initialize an on-board / default host NIC (using MAC address\n"
> @@ -2773,6 +2795,9 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
>   #endif
>   #ifdef CONFIG_NETMAP
>       "netmap|"
> +#endif
> +#ifdef CONFIG_VMNET
> +    "vmnet-host|vmnet-shared|vmnet-bridged|"
>   #endif
>       "socket][,option][,option][,...]\n"
>       "                old way to initialize a host network interface\n"


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-14  8:43   ` Akihiko Odaki
@ 2022-01-15 13:00     ` Vladislav Yaroshchuk
  0 siblings, 0 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-15 13:00 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	phillip.ennen, qemu-devel, Cameron Esfahani, Markus Armbruster,
	Roman Bolshakov, Alexander Graf, Phillip Tennen, Roman Bolshakov,
	Howard Spoelstra, Alessio Dionisi, Christian Schoenebeck,
	Eric Blake, Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 15601 bytes --]

Hi Akihiko,

Thank you for the review! I will fix the problems and resubmit as v14.

---
Best regards,
Vladislav Yaroshchuk

пт, 14 янв. 2022 г. в 11:43, Akihiko Odaki <akihiko.odaki@gmail.com>:

> Hi,
>
> Thank you for fixing the feature availability check.
>
> I decided to just check the series thoroughly before adding Reviewed-By,
> and unfortunately ended up finding minor memory leaks and style
> problems. I'm sorry for adding comments so late.
>
> Particulalry, his patch has several 2-space indents. They should be
> 4-space. Reviews for other patch will shortly follow.
>
> Regards,
> Akihiko Odaki
>
> On 2022/01/14 2:22, Vladislav Yaroshchuk wrote:
> > Create separate netdevs for each vmnet operating mode:
> > - vmnet-host
> > - vmnet-shared
> > - vmnet-bridged
> >
> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > ---
> >   net/clients.h       |  11 ++++
> >   net/meson.build     |   7 +++
> >   net/net.c           |  10 ++++
> >   net/vmnet-bridged.m |  25 +++++++++
> >   net/vmnet-common.m  |  20 +++++++
> >   net/vmnet-host.c    |  24 ++++++++
> >   net/vmnet-shared.c  |  25 +++++++++
> >   net/vmnet_int.h     |  25 +++++++++
> >   qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
> >   9 files changed, 278 insertions(+), 2 deletions(-)
> >   create mode 100644 net/vmnet-bridged.m
> >   create mode 100644 net/vmnet-common.m
> >   create mode 100644 net/vmnet-host.c
> >   create mode 100644 net/vmnet-shared.c
> >   create mode 100644 net/vmnet_int.h
> >
> > diff --git a/net/clients.h b/net/clients.h
> > index 92f9b59aed..c9157789f2 100644
> > --- a/net/clients.h
> > +++ b/net/clients.h
> > @@ -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 */
> > diff --git a/net/meson.build b/net/meson.build
> > index 847bc2ac85..00a88c4951 100644
> > --- a/net/meson.build
> > +++ b/net/meson.build
> > @@ -42,4 +42,11 @@ 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'))
> >
> > +vmnet_files = files(
> > +  'vmnet-common.m',
> > +  'vmnet-bridged.m',
> > +  'vmnet-host.c',
> > +  'vmnet-shared.c'
> > +)
> > +softmmu_ss.add(when: vmnet, if_true: vmnet_files)
> >   subdir('can')
> > diff --git a/net/net.c b/net/net.c
> > index f0d14dbfc1..1dbb64b935 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -1021,6 +1021,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 */
> >   };
> >
> >
> > @@ -1106,6 +1111,11 @@ void show_netdevs(void)
> >   #endif
> >   #ifdef CONFIG_VHOST_VDPA
> >           "vhost-vdpa",
> > +#endif
> > +#ifdef CONFIG_VMNET
> > +        "vmnet-host",
> > +        "vmnet-shared",
> > +        "vmnet-bridged",
> >   #endif
> >       };
> >
> > diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> > new file mode 100644
> > index 0000000000..4e42a90391
> > --- /dev/null
> > +++ b/net/vmnet-bridged.m
> > @@ -0,0 +1,25 @@
> > +/*
> > + * vmnet-bridged.m
> > + *
> > + * 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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
> > +                           NetClientState *peer, Error **errp)
> > +{
> > +  error_setg(errp, "vmnet-bridged is not implemented yet");
> > +  return -1;
> > +}
> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> > new file mode 100644
> > index 0000000000..532d152840
> > --- /dev/null
> > +++ b/net/vmnet-common.m
> > @@ -0,0 +1,20 @@
> > +/*
> > + * vmnet-common.m - network client wrapper for Apple vmnet.framework
> > + *
> > + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > diff --git a/net/vmnet-host.c b/net/vmnet-host.c
> > new file mode 100644
> > index 0000000000..4a5ef99dc7
> > --- /dev/null
> > +++ b/net/vmnet-host.c
> > @@ -0,0 +1,24 @@
> > +/*
> > + * vmnet-host.c
> > + *
> > + * 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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.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-host is not implemented yet");
> > +  return -1;
> > +}
> > diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> > new file mode 100644
> > index 0000000000..f8c4a4f3b8
> > --- /dev/null
> > +++ b/net/vmnet-shared.c
> > @@ -0,0 +1,25 @@
> > +/*
> > + * vmnet-shared.c
> > + *
> > + * 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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
> > +                          NetClientState *peer, Error **errp)
> > +{
> > +  error_setg(errp, "vmnet-shared is not implemented yet");
> > +  return -1;
> > +}
> > diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> > new file mode 100644
> > index 0000000000..c5982259a4
> > --- /dev/null
> > +++ b/net/vmnet_int.h
> > @@ -0,0 +1,25 @@
> > +/*
> > + * vmnet_int.h
> > + *
> > + * 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.
> > + *
> > + */
> > +#ifndef VMNET_INT_H
> > +#define VMNET_INT_H
> > +
> > +#include "qemu/osdep.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > +typedef struct VmnetCommonState {
> > +  NetClientState nc;
> > +
> > +} VmnetCommonState;
> > +
> > +
> > +#endif /* VMNET_INT_H */
> > diff --git a/qapi/net.json b/qapi/net.json
> > index 7fab2e7cd8..b922e2e34f 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -452,6 +452,120 @@
> >       '*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 host.
> > +#
> > +# @start-address: The starting IPv4 address to use for the interface.
> > +#                 Must be in the private IP range (RFC 1918). Must be
> > +#                 specified along with @end-address and @subnet-mask.
> > +#                 This address is used as the gateway address. The
> > +#                 subsequent address up to and including end-address are
> > +#                 placed in the DHCP pool.
> > +#
> > +# @end-address: 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 @start-address and
> > +#               @subnet-mask.
> > +#
> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> > +#               be specified along with @start-address and @subnet-mask.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
> > +#
> > +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> > +#            network vmnet interface should be added to. If
> > +#            set, no DHCP service is provided for this interface and
> > +#            network communication is allowed only with other interfaces
> > +#            added to this network identified by the UUID. Available
> > +#            since macOS Big Sur 11.0.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetHostOptions',
> > +  'data': {
> > +    '*start-address': 'str',
> > +    '*end-address':   'str',
> > +    '*subnet-mask':   'str',
> > +    '*isolated':      'bool',
> > +    '*net-uuid':      '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 communicate with the host and with
> > +# other shared mode interfaces on the same subnet. If no DHCP
> > +# settings, subnet mask and IPv6 prefix specified, the interface can
> > +# communicate with any of other interfaces in shared mode.
> > +#
> > +# @start-address: The starting IPv4 address to use for the interface.
> > +#                 Must be in the private IP range (RFC 1918). Must be
> > +#                 specified along with @end-address and @subnet-mask.
> > +#                 This address is used as the gateway address. The
> > +#                 subsequent address up to and including end-address are
> > +#                 placed in the DHCP pool.
> > +#
> > +# @end-address: 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 @start-address and
> @subnet-mask.
> > +#
> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> > +#                be specified along with @start-address and
> @subnet-mask.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
> > +#
> > +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> > +#                unique local address i.e. start with fd00::/8 and have
> > +#                length of 64.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetSharedOptions',
> > +  'data': {
> > +    '*start-address': 'str',
> > +    '*end-address':   'str',
> > +    '*subnet-mask':   'str',
> > +    '*isolated':      'bool',
> > +    '*nat66-prefix':  '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.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetBridgedOptions',
> > +  'data': {
> > +    'ifname':     'str',
> > +    '*isolated':  'bool' },
> > +  'if': 'CONFIG_VMNET' }
> > +
> >   ##
> >   # @NetClientDriver:
> >   #
> > @@ -460,10 +574,16 @@
> >   # Since: 2.7
> >   #
> >   #        @vhost-vdpa since 5.1
> > +#        @vmnet-host since 7.0
> > +#        @vmnet-shared since 7.0
> > +#        @vmnet-bridged since 7.0
> >   ##
> >   { '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 +597,9 @@
> >   # Since: 1.2
> >   #
> >   #        'l2tpv3' - since 2.1
> > +#        'vmnet-host' - since 7.0
> > +#        'vmnet-shared' - since 7.0
> > +#        'vmnet-bridged' - since 7.0
> >   ##
> >   { 'union': 'Netdev',
> >     'base': { 'id': 'str', 'type': 'NetClientDriver' },
> > @@ -492,7 +615,13 @@
> >       'hubport':  'NetdevHubPortOptions',
> >       'netmap':   'NetdevNetmapOptions',
> >       'vhost-user': 'NetdevVhostUserOptions',
> > -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> > +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> > +                    'if': 'CONFIG_VMNET' },
> > +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> > +                      'if': 'CONFIG_VMNET' },
> > +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> > +                       'if': 'CONFIG_VMNET' } } }
> >
> >   ##
> >   # @RxState:
>

[-- Attachment #2: Type: text/html, Size: 20512 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
  2022-01-14  8:43   ` Akihiko Odaki
@ 2022-01-18 15:00   ` Markus Armbruster
  2022-01-18 16:16     ` Vladislav Yaroshchuk
  2022-01-20  8:32   ` Roman Bolshakov
  2022-01-24  9:56   ` Roman Bolshakov
  3 siblings, 1 reply; 35+ messages in thread
From: Markus Armbruster @ 2022-01-18 15:00 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: peter.maydell, alex.bennee, jasowang, phillip.ennen, qemu-devel,
	dirty, f4bug, roman, r.bolshakov, agraf, phillip, akihiko.odaki,
	hsp.cat7, hello, qemu_oss, eblake, kraxel

Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> writes:

> Create separate netdevs for each vmnet operating mode:
> - vmnet-host
> - vmnet-shared
> - vmnet-bridged
>
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>

I acked v8 of the QAPI schema part.  You should add Acked-by and
Reviewed-by you receive in later revisions, unless you make changes that
invalidate them.  When in doubt, drop them.

> diff --git a/qapi/net.json b/qapi/net.json
> index 7fab2e7cd8..b922e2e34f 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -452,6 +452,120 @@
>      '*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 host.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and
> +#               @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#               be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.

What happens when the host is too old?

> +#
> +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> +#            network vmnet interface should be added to. If
> +#            set, no DHCP service is provided for this interface and
> +#            network communication is allowed only with other interfaces
> +#            added to this network identified by the UUID. Available
> +#            since macOS Big Sur 11.0.

Same question.

> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetHostOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*net-uuid':      '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 communicate with the host and with
> +# other shared mode interfaces on the same subnet. If no DHCP
> +# settings, subnet mask and IPv6 prefix specified, the interface can
> +# communicate with any of other interfaces in shared mode.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#                be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.

Same question.

> +#
> +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> +#                unique local address i.e. start with fd00::/8 and have
> +#                length of 64.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetSharedOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*nat66-prefix':  '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.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.

Same question.

> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetBridgedOptions',
> +  'data': {
> +    'ifname':     'str',
> +    '*isolated':  'bool' },
> +  'if': 'CONFIG_VMNET' }
> +
>  ##
>  # @NetClientDriver:
>  #
> @@ -460,10 +574,16 @@
>  # Since: 2.7
>  #
>  #        @vhost-vdpa since 5.1
> +#        @vmnet-host since 7.0
> +#        @vmnet-shared since 7.0
> +#        @vmnet-bridged since 7.0
>  ##
>  { '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 +597,9 @@
>  # Since: 1.2
>  #
>  #        'l2tpv3' - since 2.1
> +#        'vmnet-host' - since 7.0
> +#        'vmnet-shared' - since 7.0
> +#        'vmnet-bridged' - since 7.0
>  ##
>  { 'union': 'Netdev',
>    'base': { 'id': 'str', 'type': 'NetClientDriver' },
> @@ -492,7 +615,13 @@
>      'hubport':  'NetdevHubPortOptions',
>      'netmap':   'NetdevNetmapOptions',
>      'vhost-user': 'NetdevVhostUserOptions',
> -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> +                    'if': 'CONFIG_VMNET' },
> +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> +                      'if': 'CONFIG_VMNET' },
> +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> +                       'if': 'CONFIG_VMNET' } } }
>  
>  ##
>  # @RxState:



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-18 15:00   ` Markus Armbruster
@ 2022-01-18 16:16     ` Vladislav Yaroshchuk
  2022-01-18 16:26       ` Markus Armbruster
  0 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-18 16:16 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Peter Maydell, Alex Bennée, Jason Wang, phillip.ennen,
	qemu-devel, Cameron Esfahani, Philippe Mathieu-Daudé,
	Roman Bolshakov, Roman Bolshakov, Alexander Graf, Phillip Tennen,
	Akihiko Odaki, Howard Spoelstra, Alessio Dionisi,
	Christian Schoenebeck, Eric Blake, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 7972 bytes --]

вт, 18 янв. 2022 г. в 18:01, Markus Armbruster <armbru@redhat.com>:

> Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> writes:
>
> > Create separate netdevs for each vmnet operating mode:
> > - vmnet-host
> > - vmnet-shared
> > - vmnet-bridged
> >
> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
>
> I acked v8 of the QAPI schema part.  You should add Acked-by and
> Reviewed-by you receive in later revisions, unless you make changes that
> invalidate them.  When in doubt, drop them.
>
>
Oh ok, I'll do that next time.


> > diff --git a/qapi/net.json b/qapi/net.json
> > index 7fab2e7cd8..b922e2e34f 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -452,6 +452,120 @@
> >      '*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 host.
> > +#
> > +# @start-address: The starting IPv4 address to use for the interface.
> > +#                 Must be in the private IP range (RFC 1918). Must be
> > +#                 specified along with @end-address and @subnet-mask.
> > +#                 This address is used as the gateway address. The
> > +#                 subsequent address up to and including end-address are
> > +#                 placed in the DHCP pool.
> > +#
> > +# @end-address: 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 @start-address and
> > +#               @subnet-mask.
> > +#
> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> > +#               be specified along with @start-address and @subnet-mask.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
>
> What happens when the host is too old?
>
>
In this case netdev creation will fail with
corresponding message (error_setg() used).

> +#
> > +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> > +#            network vmnet interface should be added to. If
> > +#            set, no DHCP service is provided for this interface and
> > +#            network communication is allowed only with other interfaces
> > +#            added to this network identified by the UUID. Available
> > +#            since macOS Big Sur 11.0.
>
> Same question.
>
>
The same behavior here.


> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetHostOptions',
> > +  'data': {
> > +    '*start-address': 'str',
> > +    '*end-address':   'str',
> > +    '*subnet-mask':   'str',
> > +    '*isolated':      'bool',
> > +    '*net-uuid':      '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 communicate with the host and with
> > +# other shared mode interfaces on the same subnet. If no DHCP
> > +# settings, subnet mask and IPv6 prefix specified, the interface can
> > +# communicate with any of other interfaces in shared mode.
> > +#
> > +# @start-address: The starting IPv4 address to use for the interface.
> > +#                 Must be in the private IP range (RFC 1918). Must be
> > +#                 specified along with @end-address and @subnet-mask.
> > +#                 This address is used as the gateway address. The
> > +#                 subsequent address up to and including end-address are
> > +#                 placed in the DHCP pool.
> > +#
> > +# @end-address: 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 @start-address and
> @subnet-mask.
> > +#
> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> > +#                be specified along with @start-address and
> @subnet-mask.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
>
> Same question.
>
>
The same behavior here.



> > +#
> > +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> > +#                unique local address i.e. start with fd00::/8 and have
> > +#                length of 64.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetSharedOptions',
> > +  'data': {
> > +    '*start-address': 'str',
> > +    '*end-address':   'str',
> > +    '*subnet-mask':   'str',
> > +    '*isolated':      'bool',
> > +    '*nat66-prefix':  '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.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
>
> Same question.
>
>
The same behavior here.


> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetBridgedOptions',
> > +  'data': {
> > +    'ifname':     'str',
> > +    '*isolated':  'bool' },
> > +  'if': 'CONFIG_VMNET' }
> > +
> >  ##
> >  # @NetClientDriver:
> >  #
> > @@ -460,10 +574,16 @@
> >  # Since: 2.7
> >  #
> >  #        @vhost-vdpa since 5.1
> > +#        @vmnet-host since 7.0
> > +#        @vmnet-shared since 7.0
> > +#        @vmnet-bridged since 7.0
> >  ##
> >  { '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 +597,9 @@
> >  # Since: 1.2
> >  #
> >  #        'l2tpv3' - since 2.1
> > +#        'vmnet-host' - since 7.0
> > +#        'vmnet-shared' - since 7.0
> > +#        'vmnet-bridged' - since 7.0
> >  ##
> >  { 'union': 'Netdev',
> >    'base': { 'id': 'str', 'type': 'NetClientDriver' },
> > @@ -492,7 +615,13 @@
> >      'hubport':  'NetdevHubPortOptions',
> >      'netmap':   'NetdevNetmapOptions',
> >      'vhost-user': 'NetdevVhostUserOptions',
> > -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> > +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> > +                    'if': 'CONFIG_VMNET' },
> > +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> > +                      'if': 'CONFIG_VMNET' },
> > +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> > +                       'if': 'CONFIG_VMNET' } } }
> >
> >  ##
> >  # @RxState:
>
>

-- 
Best Regards,

Vladislav Yaroshchuk

[-- Attachment #2: Type: text/html, Size: 11754 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-18 16:16     ` Vladislav Yaroshchuk
@ 2022-01-18 16:26       ` Markus Armbruster
  2022-01-18 16:46         ` Vladislav Yaroshchuk
  0 siblings, 1 reply; 35+ messages in thread
From: Markus Armbruster @ 2022-01-18 16:26 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	phillip.ennen, Markus Armbruster, Cameron Esfahani, qemu-devel,
	Roman Bolshakov, Roman Bolshakov, Alexander Graf, Phillip Tennen,
	Akihiko Odaki, Howard Spoelstra, Alessio Dionisi,
	Christian Schoenebeck, Eric Blake, Philippe Mathieu-Daudé

Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> writes:

> вт, 18 янв. 2022 г. в 18:01, Markus Armbruster <armbru@redhat.com>:
>
>> Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> writes:
>>
>> > Create separate netdevs for each vmnet operating mode:
>> > - vmnet-host
>> > - vmnet-shared
>> > - vmnet-bridged
>> >
>> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
>>
>> I acked v8 of the QAPI schema part.  You should add Acked-by and
>> Reviewed-by you receive in later revisions, unless you make changes that
>> invalidate them.  When in doubt, drop them.
>>
>>
> Oh ok, I'll do that next time.

Thanks :)

>> > diff --git a/qapi/net.json b/qapi/net.json
>> > index 7fab2e7cd8..b922e2e34f 100644
>> > --- a/qapi/net.json
>> > +++ b/qapi/net.json
>> > @@ -452,6 +452,120 @@
>> >      '*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 host.
>> > +#
>> > +# @start-address: The starting IPv4 address to use for the interface.
>> > +#                 Must be in the private IP range (RFC 1918). Must be
>> > +#                 specified along with @end-address and @subnet-mask.
>> > +#                 This address is used as the gateway address. The
>> > +#                 subsequent address up to and including end-address are
>> > +#                 placed in the DHCP pool.
>> > +#
>> > +# @end-address: 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 @start-address and
>> > +#               @subnet-mask.
>> > +#
>> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
>> > +#               be specified along with @start-address and @subnet-mask.
>> > +#
>> > +# @isolated: Enable isolation for this interface. Interface isolation
>> > +#            ensures that vmnet interface is not able to communicate
>> > +#            with any other vmnet interfaces. Only communication with
>> > +#            host is allowed. Available since macOS Big Sur 11.0.
>>
>> What happens when the host is too old?
>>
>>
> In this case netdev creation will fail with
> corresponding message (error_setg() used).

"Available" feels slightly misleading.  It's always available, it just
doesn't work unless the host OS is new enough.  Suggest something like
"Requires at least macOS Big Sur 11.0."

Same for the others.

QAPI schema
Acked-by: Markus Armbruster <armbru@redhat.com>

[...]



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-18 16:26       ` Markus Armbruster
@ 2022-01-18 16:46         ` Vladislav Yaroshchuk
  0 siblings, 0 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-18 16:46 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Peter Maydell, Alex Bennée, Jason Wang, phillip.ennen,
	qemu-devel, Cameron Esfahani, Philippe Mathieu-Daudé,
	Roman Bolshakov, Roman Bolshakov, Alexander Graf, Phillip Tennen,
	Akihiko Odaki, Howard Spoelstra, Alessio Dionisi,
	Christian Schoenebeck, Eric Blake, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 3177 bytes --]

вт, 18 янв. 2022 г. в 19:35, Markus Armbruster <armbru@redhat.com>:

> Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> writes:
>
> > вт, 18 янв. 2022 г. в 18:01, Markus Armbruster <armbru@redhat.com>:
> >
> >> Vladislav Yaroshchuk <yaroshchuk2000@gmail.com> writes:
> >>
> >> > Create separate netdevs for each vmnet operating mode:
> >> > - vmnet-host
> >> > - vmnet-shared
> >> > - vmnet-bridged
> >> >
> >> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> >>
> >> I acked v8 of the QAPI schema part.  You should add Acked-by and
> >> Reviewed-by you receive in later revisions, unless you make changes that
> >> invalidate them.  When in doubt, drop them.
> >>
> >>
> > Oh ok, I'll do that next time.
>
> Thanks :)
>
> >> > diff --git a/qapi/net.json b/qapi/net.json
> >> > index 7fab2e7cd8..b922e2e34f 100644
> >> > --- a/qapi/net.json
> >> > +++ b/qapi/net.json
> >> > @@ -452,6 +452,120 @@
> >> >      '*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 host.
> >> > +#
> >> > +# @start-address: The starting IPv4 address to use for the interface.
> >> > +#                 Must be in the private IP range (RFC 1918). Must be
> >> > +#                 specified along with @end-address and @subnet-mask.
> >> > +#                 This address is used as the gateway address. The
> >> > +#                 subsequent address up to and including end-address
> are
> >> > +#                 placed in the DHCP pool.
> >> > +#
> >> > +# @end-address: 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 @start-address and
> >> > +#               @subnet-mask.
> >> > +#
> >> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> >> > +#               be specified along with @start-address and
> @subnet-mask.
> >> > +#
> >> > +# @isolated: Enable isolation for this interface. Interface isolation
> >> > +#            ensures that vmnet interface is not able to communicate
> >> > +#            with any other vmnet interfaces. Only communication with
> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
> >>
> >> What happens when the host is too old?
> >>
> >>
> > In this case netdev creation will fail with
> > corresponding message (error_setg() used).
>
> "Available" feels slightly misleading.  It's always available, it just
> doesn't work unless the host OS is new enough.  Suggest something like
> "Requires at least macOS Big Sur 11.0."
>
>
Yep, "Requires" sounds much more suitable. Will update
the description in the next version along with other fixes.

Thank you!

Same for the others.
>
> QAPI schema
> Acked-by: Markus Armbruster <armbru@redhat.com>
>
> [...]
>
>

-- 
Best Regards,

Vladislav Yaroshchuk

[-- Attachment #2: Type: text/html, Size: 4946 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option
  2022-01-13 17:22 ` [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option Vladislav Yaroshchuk
@ 2022-01-20  7:14   ` Roman Bolshakov
  2022-01-21 11:58     ` Vladislav Yaroshchuk
  0 siblings, 1 reply; 35+ messages in thread
From: Roman Bolshakov @ 2022-01-20  7:14 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: peter.maydell, kraxel, alex.bennee, jasowang, phillip.ennen,
	qemu-devel, dirty, armbru, r.bolshakov, agraf, phillip,
	akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake, f4bug

On Thu, Jan 13, 2022 at 08:22:13PM +0300, Vladislav Yaroshchuk wrote:
> vmnet.framework dependency is added with 'vmnet' option
> to enable or disable it. Default value is 'auto'.
> 
> vmnet features to be used are available since macOS 11.0,

Hi Vladislav,

I'm not sure if the comment belongs here. Perhaps you mean that bridged
mode is available from 10.15:

        VMNET_BRIDGED_MODE API_AVAILABLE(macos(10.15))  = 1002

This means vmnet.framework is supported on all macbooks starting from 2012.

With this fixed,
Tested-by: Roman Bolshakov <roman@roolebo.dev>
Reviewed-by: Roman Bolshakov <roman@roolebo.dev>

The other two modes - shared and host are supported on earlier versions
of macOS (from 10.10). But port forwarding is only available from macOS
10.15.

Theoretically it should possible to support the framework on the earlier
models from 2010 or 2007 on Yosemite up to High Sierra with less
features using MacPorts but I don't think it'd be reasonable to ask
that.

Thanks,
Roman

> corresponding probe is created into meson.build.
> 
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>  meson.build                   | 16 +++++++++++++++-
>  meson_options.txt             |  2 ++
>  scripts/meson-buildoptions.sh |  3 +++
>  3 files changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/meson.build b/meson.build
> index c1b1db1e28..285fb7bc41 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -496,6 +496,18 @@ if cocoa.found() and get_option('gtk').enabled()
>    error('Cocoa and GTK+ cannot be enabled at the same time')
>  endif
>  
> +vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
> +if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
> +                                              'VMNET_BRIDGED_MODE',
> +                                              dependencies: vmnet)
> +  vmnet = not_found
> +  if get_option('vmnet').enabled()
> +    error('vmnet.framework API is outdated')
> +  else
> +    warning('vmnet.framework API is outdated, disabling')
> +  endif
> +endif
> +
>  seccomp = not_found
>  if not get_option('seccomp').auto() or have_system or have_tools
>    seccomp = dependency('libseccomp', version: '>=2.3.0',
> @@ -1492,6 +1504,7 @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found())
>  config_host_data.set('CONFIG_SNAPPY', snappy.found())
>  config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
>  config_host_data.set('CONFIG_VDE', vde.found())
> +config_host_data.set('CONFIG_VMNET', vmnet.found())
>  config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
>  config_host_data.set('CONFIG_VNC', vnc.found())
>  config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
> @@ -3406,7 +3419,8 @@ summary(summary_info, bool_yn: true, section: 'Crypto')
>  # Libraries
>  summary_info = {}
>  if targetos == 'darwin'
> -  summary_info += {'Cocoa support':   cocoa}
> +  summary_info += {'Cocoa support':           cocoa}
> +  summary_info += {'vmnet.framework support': vmnet}
>  endif
>  summary_info += {'SDL support':       sdl}
>  summary_info += {'SDL image support': sdl_image}
> diff --git a/meson_options.txt b/meson_options.txt
> index 921967eddb..701e1381f9 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -151,6 +151,8 @@ option('netmap', type : 'feature', value : 'auto',
>         description: 'netmap network backend support')
>  option('vde', type : 'feature', value : 'auto',
>         description: 'vde network backend support')
> +option('vmnet', type : 'feature', value : 'auto',
> +       description: 'vmnet.framework network backend support')
>  option('virglrenderer', type : 'feature', value : 'auto',
>         description: 'virgl rendering support')
>  option('vnc', type : 'feature', value : 'auto',
> diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
> index 50bd7bed4d..cdcece4b05 100644
> --- a/scripts/meson-buildoptions.sh
> +++ b/scripts/meson-buildoptions.sh
> @@ -84,6 +84,7 @@ meson_options_help() {
>    printf "%s\n" '  u2f             U2F emulation support'
>    printf "%s\n" '  usb-redir       libusbredir support'
>    printf "%s\n" '  vde             vde network backend support'
> +  printf "%s\n" '  vmnet           vmnet.framework network backend support'
>    printf "%s\n" '  vhost-user-blk-server'
>    printf "%s\n" '                  build vhost-user-blk server'
>    printf "%s\n" '  virglrenderer   virgl rendering support'
> @@ -248,6 +249,8 @@ _meson_option_parse() {
>      --disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
>      --enable-vde) printf "%s" -Dvde=enabled ;;
>      --disable-vde) printf "%s" -Dvde=disabled ;;
> +    --enable-vmnet) printf "%s" -Dvmnet=enabled ;;
> +    --disable-vmnet) printf "%s" -Dvmnet=disabled ;;
>      --enable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=enabled ;;
>      --disable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=disabled ;;
>      --enable-virglrenderer) printf "%s" -Dvirglrenderer=enabled ;;
> -- 
> 2.23.0
> 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
  2022-01-14  8:43   ` Akihiko Odaki
  2022-01-18 15:00   ` Markus Armbruster
@ 2022-01-20  8:32   ` Roman Bolshakov
  2022-01-21 12:19     ` Vladislav Yaroshchuk
  2022-01-24  9:56   ` Roman Bolshakov
  3 siblings, 1 reply; 35+ messages in thread
From: Roman Bolshakov @ 2022-01-20  8:32 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: peter.maydell, kraxel, alex.bennee, jasowang, phillip.ennen,
	qemu-devel, dirty, armbru, r.bolshakov, agraf, phillip,
	akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake, f4bug

On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> Create separate netdevs for each vmnet operating mode:
> - vmnet-host
> - vmnet-shared
> - vmnet-bridged
> 

Sure I'm late to the party but what if we add only one backend - vmnet
with default mode set to shared and all parameters are added there?

The CLI would look more reasonable for the most typical use case:
 -netdev vmnet,id=if1 -device virtio-net,netdev=if1

That would remove duplication of options in QAPI schema (e.g. isolated
is available in all backends now, altough I'm not sure if it makes sense
for bridged mode):

 -netdev vmnet,id=if1,isolated=yes

start-address, end-address and subnet-mask are also used by both shared
and host modes.

Bridged netdev would lool like:

 -netdev vmnet,id=if1,mode=bridged,ifname=en1

Checksum offloading also seems to be available for all backends from
Monterey.

The approach might simplify integration of the changes to libvirt and
discovery of upcoming vmnet features via qapi.

Thanks,
Roman

> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>  net/clients.h       |  11 ++++
>  net/meson.build     |   7 +++
>  net/net.c           |  10 ++++
>  net/vmnet-bridged.m |  25 +++++++++
>  net/vmnet-common.m  |  20 +++++++
>  net/vmnet-host.c    |  24 ++++++++
>  net/vmnet-shared.c  |  25 +++++++++
>  net/vmnet_int.h     |  25 +++++++++
>  qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
>  9 files changed, 278 insertions(+), 2 deletions(-)
>  create mode 100644 net/vmnet-bridged.m
>  create mode 100644 net/vmnet-common.m
>  create mode 100644 net/vmnet-host.c
>  create mode 100644 net/vmnet-shared.c
>  create mode 100644 net/vmnet_int.h
> 
> diff --git a/net/net.c b/net/net.c
> index f0d14dbfc1..1dbb64b935 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1021,6 +1021,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 */
>  };
>  
>  
> @@ -1106,6 +1111,11 @@ void show_netdevs(void)
>  #endif
>  #ifdef CONFIG_VHOST_VDPA
>          "vhost-vdpa",
> +#endif
> +#ifdef CONFIG_VMNET
> +        "vmnet-host",
> +        "vmnet-shared",
> +        "vmnet-bridged",
>  #endif
>      };
>  
> diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> new file mode 100644
> index 0000000000..4e42a90391
> --- /dev/null
> +++ b/net/vmnet-bridged.m
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet-bridged.m
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
> +                           NetClientState *peer, Error **errp)
> +{
> +  error_setg(errp, "vmnet-bridged is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> new file mode 100644
> index 0000000000..532d152840
> --- /dev/null
> +++ b/net/vmnet-common.m
> @@ -0,0 +1,20 @@
> +/*
> + * vmnet-common.m - network client wrapper for Apple vmnet.framework
> + *
> + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> diff --git a/net/vmnet-host.c b/net/vmnet-host.c
> new file mode 100644
> index 0000000000..4a5ef99dc7
> --- /dev/null
> +++ b/net/vmnet-host.c
> @@ -0,0 +1,24 @@
> +/*
> + * vmnet-host.c
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.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-host is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> new file mode 100644
> index 0000000000..f8c4a4f3b8
> --- /dev/null
> +++ b/net/vmnet-shared.c
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet-shared.c
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
> +                          NetClientState *peer, Error **errp)
> +{
> +  error_setg(errp, "vmnet-shared is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> new file mode 100644
> index 0000000000..c5982259a4
> --- /dev/null
> +++ b/net/vmnet_int.h
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet_int.h
> + *
> + * 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.
> + *
> + */
> +#ifndef VMNET_INT_H
> +#define VMNET_INT_H
> +
> +#include "qemu/osdep.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +typedef struct VmnetCommonState {
> +  NetClientState nc;
> +
> +} VmnetCommonState;
> +
> +
> +#endif /* VMNET_INT_H */
> diff --git a/qapi/net.json b/qapi/net.json
> index 7fab2e7cd8..b922e2e34f 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -452,6 +452,120 @@
>      '*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 host.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and
> +#               @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#               be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> +#            network vmnet interface should be added to. If
> +#            set, no DHCP service is provided for this interface and
> +#            network communication is allowed only with other interfaces
> +#            added to this network identified by the UUID. Available
> +#            since macOS Big Sur 11.0.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetHostOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*net-uuid':      '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 communicate with the host and with
> +# other shared mode interfaces on the same subnet. If no DHCP
> +# settings, subnet mask and IPv6 prefix specified, the interface can
> +# communicate with any of other interfaces in shared mode.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#                be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> +#                unique local address i.e. start with fd00::/8 and have
> +#                length of 64.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetSharedOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*nat66-prefix':  '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.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetBridgedOptions',
> +  'data': {
> +    'ifname':     'str',
> +    '*isolated':  'bool' },
> +  'if': 'CONFIG_VMNET' }
> +
>  ##
>  # @NetClientDriver:
>  #
> @@ -460,10 +574,16 @@
>  # Since: 2.7
>  #
>  #        @vhost-vdpa since 5.1
> +#        @vmnet-host since 7.0
> +#        @vmnet-shared since 7.0
> +#        @vmnet-bridged since 7.0
>  ##
>  { '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 +597,9 @@
>  # Since: 1.2
>  #
>  #        'l2tpv3' - since 2.1
> +#        'vmnet-host' - since 7.0
> +#        'vmnet-shared' - since 7.0
> +#        'vmnet-bridged' - since 7.0
>  ##
>  { 'union': 'Netdev',
>    'base': { 'id': 'str', 'type': 'NetClientDriver' },
> @@ -492,7 +615,13 @@
>      'hubport':  'NetdevHubPortOptions',
>      'netmap':   'NetdevNetmapOptions',
>      'vhost-user': 'NetdevVhostUserOptions',
> -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> +                    'if': 'CONFIG_VMNET' },
> +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> +                      'if': 'CONFIG_VMNET' },
> +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> +                       'if': 'CONFIG_VMNET' } } }
>  
>  ##
>  # @RxState:
> -- 
> 2.23.0
> 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option
  2022-01-20  7:14   ` Roman Bolshakov
@ 2022-01-21 11:58     ` Vladislav Yaroshchuk
  0 siblings, 0 replies; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-21 11:58 UTC (permalink / raw)
  To: Roman Bolshakov
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	phillip.ennen, qemu-devel, Cameron Esfahani, Markus Armbruster,
	Roman Bolshakov, Alexander Graf, Phillip Tennen, Akihiko Odaki,
	Howard Spoelstra, Alessio Dionisi, Christian Schoenebeck,
	Eric Blake, Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 5754 bytes --]

Hi Roman,

чт, 20 янв. 2022 г. в 10:14, Roman Bolshakov <roman@roolebo.dev>:

> On Thu, Jan 13, 2022 at 08:22:13PM +0300, Vladislav Yaroshchuk wrote:
> > vmnet.framework dependency is added with 'vmnet' option
> > to enable or disable it. Default value is 'auto'.
> >
> > vmnet features to be used are available since macOS 11.0,
>
> Hi Vladislav,
>
> I'm not sure if the comment belongs here. Perhaps you mean that bridged
> mode is available from 10.15:
>
>         VMNET_BRIDGED_MODE API_AVAILABLE(macos(10.15))  = 1002
>
>
Yes, I forgot to update this part of the cover letter, thank you.


> This means vmnet.framework is supported on all macbooks starting from 2012.
>
> With this fixed,
> Tested-by: Roman Bolshakov <roman@roolebo.dev>
> Reviewed-by: Roman Bolshakov <roman@roolebo.dev>
>
> The other two modes - shared and host are supported on earlier versions
> of macOS (from 10.10). But port forwarding is only available from macOS
> 10.15.
>
> Theoretically it should possible to support the framework on the earlier
> models from 2010 or 2007 on Yosemite up to High Sierra with less
> features using MacPorts but I don't think it'd be reasonable to ask
> that.
>
>
I'm not sure it's necessary to support such old models. Compatibility with
10.15 on 2012+ macs is enough I think.

Thanks,
> Roman
>
> > corresponding probe is created into meson.build.
> >
> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > ---
> >  meson.build                   | 16 +++++++++++++++-
> >  meson_options.txt             |  2 ++
> >  scripts/meson-buildoptions.sh |  3 +++
> >  3 files changed, 20 insertions(+), 1 deletion(-)
> >
> > diff --git a/meson.build b/meson.build
> > index c1b1db1e28..285fb7bc41 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -496,6 +496,18 @@ if cocoa.found() and get_option('gtk').enabled()
> >    error('Cocoa and GTK+ cannot be enabled at the same time')
> >  endif
> >
> > +vmnet = dependency('appleframeworks', modules: 'vmnet', required:
> get_option('vmnet'))
> > +if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
> > +                                              'VMNET_BRIDGED_MODE',
> > +                                              dependencies: vmnet)
> > +  vmnet = not_found
> > +  if get_option('vmnet').enabled()
> > +    error('vmnet.framework API is outdated')
> > +  else
> > +    warning('vmnet.framework API is outdated, disabling')
> > +  endif
> > +endif
> > +
> >  seccomp = not_found
> >  if not get_option('seccomp').auto() or have_system or have_tools
> >    seccomp = dependency('libseccomp', version: '>=2.3.0',
> > @@ -1492,6 +1504,7 @@ config_host_data.set('CONFIG_SECCOMP',
> seccomp.found())
> >  config_host_data.set('CONFIG_SNAPPY', snappy.found())
> >  config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
> >  config_host_data.set('CONFIG_VDE', vde.found())
> > +config_host_data.set('CONFIG_VMNET', vmnet.found())
> >  config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER',
> have_vhost_user_blk_server)
> >  config_host_data.set('CONFIG_VNC', vnc.found())
> >  config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
> > @@ -3406,7 +3419,8 @@ summary(summary_info, bool_yn: true, section:
> 'Crypto')
> >  # Libraries
> >  summary_info = {}
> >  if targetos == 'darwin'
> > -  summary_info += {'Cocoa support':   cocoa}
> > +  summary_info += {'Cocoa support':           cocoa}
> > +  summary_info += {'vmnet.framework support': vmnet}
> >  endif
> >  summary_info += {'SDL support':       sdl}
> >  summary_info += {'SDL image support': sdl_image}
> > diff --git a/meson_options.txt b/meson_options.txt
> > index 921967eddb..701e1381f9 100644
> > --- a/meson_options.txt
> > +++ b/meson_options.txt
> > @@ -151,6 +151,8 @@ option('netmap', type : 'feature', value : 'auto',
> >         description: 'netmap network backend support')
> >  option('vde', type : 'feature', value : 'auto',
> >         description: 'vde network backend support')
> > +option('vmnet', type : 'feature', value : 'auto',
> > +       description: 'vmnet.framework network backend support')
> >  option('virglrenderer', type : 'feature', value : 'auto',
> >         description: 'virgl rendering support')
> >  option('vnc', type : 'feature', value : 'auto',
> > diff --git a/scripts/meson-buildoptions.sh
> b/scripts/meson-buildoptions.sh
> > index 50bd7bed4d..cdcece4b05 100644
> > --- a/scripts/meson-buildoptions.sh
> > +++ b/scripts/meson-buildoptions.sh
> > @@ -84,6 +84,7 @@ meson_options_help() {
> >    printf "%s\n" '  u2f             U2F emulation support'
> >    printf "%s\n" '  usb-redir       libusbredir support'
> >    printf "%s\n" '  vde             vde network backend support'
> > +  printf "%s\n" '  vmnet           vmnet.framework network backend
> support'
> >    printf "%s\n" '  vhost-user-blk-server'
> >    printf "%s\n" '                  build vhost-user-blk server'
> >    printf "%s\n" '  virglrenderer   virgl rendering support'
> > @@ -248,6 +249,8 @@ _meson_option_parse() {
> >      --disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
> >      --enable-vde) printf "%s" -Dvde=enabled ;;
> >      --disable-vde) printf "%s" -Dvde=disabled ;;
> > +    --enable-vmnet) printf "%s" -Dvmnet=enabled ;;
> > +    --disable-vmnet) printf "%s" -Dvmnet=disabled ;;
> >      --enable-vhost-user-blk-server) printf "%s"
> -Dvhost_user_blk_server=enabled ;;
> >      --disable-vhost-user-blk-server) printf "%s"
> -Dvhost_user_blk_server=disabled ;;
> >      --enable-virglrenderer) printf "%s" -Dvirglrenderer=enabled ;;
> > --
> > 2.23.0
> >
>


-- 
Best Regards,

Vladislav Yaroshchuk

[-- Attachment #2: Type: text/html, Size: 8053 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-20  8:32   ` Roman Bolshakov
@ 2022-01-21 12:19     ` Vladislav Yaroshchuk
  2022-01-21 13:03       ` Akihiko Odaki
  0 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-21 12:19 UTC (permalink / raw)
  To: Roman Bolshakov
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	phillip.ennen, qemu-devel, Cameron Esfahani, Markus Armbruster,
	Roman Bolshakov, Alexander Graf, Phillip Tennen, Akihiko Odaki,
	Howard Spoelstra, Alessio Dionisi, Christian Schoenebeck,
	Eric Blake, Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 15160 bytes --]

чт, 20 янв. 2022 г. в 11:32, Roman Bolshakov <roman@roolebo.dev>:

> On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> > Create separate netdevs for each vmnet operating mode:
> > - vmnet-host
> > - vmnet-shared
> > - vmnet-bridged
> >
>
> Sure I'm late to the party but what if we add only one backend - vmnet
> with default mode set to shared and all parameters are added there?
>
> The CLI would look more reasonable for the most typical use case:
>  -netdev vmnet,id=if1 -device virtio-net,netdev=if1
>
> That would remove duplication of options in QAPI schema (e.g. isolated
> is available in all backends now, altough I'm not sure if it makes sense
> for bridged mode):
>
>  -netdev vmnet,id=if1,isolated=yes
>
> start-address, end-address and subnet-mask are also used by both shared
> and host modes.
>
> Bridged netdev would lool like:
>
>  -netdev vmnet,id=if1,mode=bridged,ifname=en1
>
> Checksum offloading also seems to be available for all backends from
> Monterey.
>
> The approach might simplify integration of the changes to libvirt and
> discovery of upcoming vmnet features via qapi.
>
>
I can rewrite this if it sounds more suitable to use
single `vmnet` netdev instead of three different ones.
We can discuss this with Markus as a QAPI reviewer.
Markus, what is your opinion about single netdev?

P.S. Seems we have enough time for discussion:
I started fixing memory leaks found by Akihiko and
met a strange deadlock on QEMU shutdown on
`qemu_mutex_lock_iothread()` during careful
interface destruction with added semaphore.
Need to go deeper to understand what's the
problem, it will take some time.

Mentioned part of Akihiko's review:
https://patchew.org/QEMU/20220113172219.66372-1-yaroshchuk2000@gmail.com/20220113172219.66372-4-yaroshchuk2000@gmail.com/


Thanks,
> Roman
>
> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > ---
> >  net/clients.h       |  11 ++++
> >  net/meson.build     |   7 +++
> >  net/net.c           |  10 ++++
> >  net/vmnet-bridged.m |  25 +++++++++
> >  net/vmnet-common.m  |  20 +++++++
> >  net/vmnet-host.c    |  24 ++++++++
> >  net/vmnet-shared.c  |  25 +++++++++
> >  net/vmnet_int.h     |  25 +++++++++
> >  qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
> >  9 files changed, 278 insertions(+), 2 deletions(-)
> >  create mode 100644 net/vmnet-bridged.m
> >  create mode 100644 net/vmnet-common.m
> >  create mode 100644 net/vmnet-host.c
> >  create mode 100644 net/vmnet-shared.c
> >  create mode 100644 net/vmnet_int.h
> >
> > diff --git a/net/net.c b/net/net.c
> > index f0d14dbfc1..1dbb64b935 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -1021,6 +1021,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 */
> >  };
> >
> >
> > @@ -1106,6 +1111,11 @@ void show_netdevs(void)
> >  #endif
> >  #ifdef CONFIG_VHOST_VDPA
> >          "vhost-vdpa",
> > +#endif
> > +#ifdef CONFIG_VMNET
> > +        "vmnet-host",
> > +        "vmnet-shared",
> > +        "vmnet-bridged",
> >  #endif
> >      };
> >
> > diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> > new file mode 100644
> > index 0000000000..4e42a90391
> > --- /dev/null
> > +++ b/net/vmnet-bridged.m
> > @@ -0,0 +1,25 @@
> > +/*
> > + * vmnet-bridged.m
> > + *
> > + * 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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
> > +                           NetClientState *peer, Error **errp)
> > +{
> > +  error_setg(errp, "vmnet-bridged is not implemented yet");
> > +  return -1;
> > +}
> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> > new file mode 100644
> > index 0000000000..532d152840
> > --- /dev/null
> > +++ b/net/vmnet-common.m
> > @@ -0,0 +1,20 @@
> > +/*
> > + * vmnet-common.m - network client wrapper for Apple vmnet.framework
> > + *
> > + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > diff --git a/net/vmnet-host.c b/net/vmnet-host.c
> > new file mode 100644
> > index 0000000000..4a5ef99dc7
> > --- /dev/null
> > +++ b/net/vmnet-host.c
> > @@ -0,0 +1,24 @@
> > +/*
> > + * vmnet-host.c
> > + *
> > + * 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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.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-host is not implemented yet");
> > +  return -1;
> > +}
> > diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> > new file mode 100644
> > index 0000000000..f8c4a4f3b8
> > --- /dev/null
> > +++ b/net/vmnet-shared.c
> > @@ -0,0 +1,25 @@
> > +/*
> > + * vmnet-shared.c
> > + *
> > + * 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 "qapi/qapi-types-net.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
> > +                          NetClientState *peer, Error **errp)
> > +{
> > +  error_setg(errp, "vmnet-shared is not implemented yet");
> > +  return -1;
> > +}
> > diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> > new file mode 100644
> > index 0000000000..c5982259a4
> > --- /dev/null
> > +++ b/net/vmnet_int.h
> > @@ -0,0 +1,25 @@
> > +/*
> > + * vmnet_int.h
> > + *
> > + * 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.
> > + *
> > + */
> > +#ifndef VMNET_INT_H
> > +#define VMNET_INT_H
> > +
> > +#include "qemu/osdep.h"
> > +#include "vmnet_int.h"
> > +#include "clients.h"
> > +
> > +#include <vmnet/vmnet.h>
> > +
> > +typedef struct VmnetCommonState {
> > +  NetClientState nc;
> > +
> > +} VmnetCommonState;
> > +
> > +
> > +#endif /* VMNET_INT_H */
> > diff --git a/qapi/net.json b/qapi/net.json
> > index 7fab2e7cd8..b922e2e34f 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -452,6 +452,120 @@
> >      '*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 host.
> > +#
> > +# @start-address: The starting IPv4 address to use for the interface.
> > +#                 Must be in the private IP range (RFC 1918). Must be
> > +#                 specified along with @end-address and @subnet-mask.
> > +#                 This address is used as the gateway address. The
> > +#                 subsequent address up to and including end-address are
> > +#                 placed in the DHCP pool.
> > +#
> > +# @end-address: 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 @start-address and
> > +#               @subnet-mask.
> > +#
> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> > +#               be specified along with @start-address and @subnet-mask.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
> > +#
> > +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> > +#            network vmnet interface should be added to. If
> > +#            set, no DHCP service is provided for this interface and
> > +#            network communication is allowed only with other interfaces
> > +#            added to this network identified by the UUID. Available
> > +#            since macOS Big Sur 11.0.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetHostOptions',
> > +  'data': {
> > +    '*start-address': 'str',
> > +    '*end-address':   'str',
> > +    '*subnet-mask':   'str',
> > +    '*isolated':      'bool',
> > +    '*net-uuid':      '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 communicate with the host and with
> > +# other shared mode interfaces on the same subnet. If no DHCP
> > +# settings, subnet mask and IPv6 prefix specified, the interface can
> > +# communicate with any of other interfaces in shared mode.
> > +#
> > +# @start-address: The starting IPv4 address to use for the interface.
> > +#                 Must be in the private IP range (RFC 1918). Must be
> > +#                 specified along with @end-address and @subnet-mask.
> > +#                 This address is used as the gateway address. The
> > +#                 subsequent address up to and including end-address are
> > +#                 placed in the DHCP pool.
> > +#
> > +# @end-address: 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 @start-address and
> @subnet-mask.
> > +#
> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> > +#                be specified along with @start-address and
> @subnet-mask.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
> > +#
> > +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> > +#                unique local address i.e. start with fd00::/8 and have
> > +#                length of 64.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetSharedOptions',
> > +  'data': {
> > +    '*start-address': 'str',
> > +    '*end-address':   'str',
> > +    '*subnet-mask':   'str',
> > +    '*isolated':      'bool',
> > +    '*nat66-prefix':  '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.
> > +#
> > +# @isolated: Enable isolation for this interface. Interface isolation
> > +#            ensures that vmnet interface is not able to communicate
> > +#            with any other vmnet interfaces. Only communication with
> > +#            host is allowed. Available since macOS Big Sur 11.0.
> > +#
> > +# Since: 7.0
> > +##
> > +{ 'struct': 'NetdevVmnetBridgedOptions',
> > +  'data': {
> > +    'ifname':     'str',
> > +    '*isolated':  'bool' },
> > +  'if': 'CONFIG_VMNET' }
> > +
> >  ##
> >  # @NetClientDriver:
> >  #
> > @@ -460,10 +574,16 @@
> >  # Since: 2.7
> >  #
> >  #        @vhost-vdpa since 5.1
> > +#        @vmnet-host since 7.0
> > +#        @vmnet-shared since 7.0
> > +#        @vmnet-bridged since 7.0
> >  ##
> >  { '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 +597,9 @@
> >  # Since: 1.2
> >  #
> >  #        'l2tpv3' - since 2.1
> > +#        'vmnet-host' - since 7.0
> > +#        'vmnet-shared' - since 7.0
> > +#        'vmnet-bridged' - since 7.0
> >  ##
> >  { 'union': 'Netdev',
> >    'base': { 'id': 'str', 'type': 'NetClientDriver' },
> > @@ -492,7 +615,13 @@
> >      'hubport':  'NetdevHubPortOptions',
> >      'netmap':   'NetdevNetmapOptions',
> >      'vhost-user': 'NetdevVhostUserOptions',
> > -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> > +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> > +                    'if': 'CONFIG_VMNET' },
> > +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> > +                      'if': 'CONFIG_VMNET' },
> > +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> > +                       'if': 'CONFIG_VMNET' } } }
> >
> >  ##
> >  # @RxState:
> > --
> > 2.23.0
> >
>


-- 
Best Regards,

Vladislav Yaroshchuk

[-- Attachment #2: Type: text/html, Size: 20338 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-21 12:19     ` Vladislav Yaroshchuk
@ 2022-01-21 13:03       ` Akihiko Odaki
  2022-01-28 14:29         ` Vladislav Yaroshchuk
  0 siblings, 1 reply; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-21 13:03 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	Christian Schoenebeck, phillip.ennen, qemu-devel,
	Cameron Esfahani, Markus Armbruster, Roman Bolshakov,
	Alexander Graf, Phillip Tennen, Howard Spoelstra,
	Roman Bolshakov, Alessio Dionisi, Eric Blake,
	Philippe Mathieu-Daudé

On Fri, Jan 21, 2022 at 9:19 PM Vladislav Yaroshchuk
<yaroshchuk2000@gmail.com> wrote:
>
>
> чт, 20 янв. 2022 г. в 11:32, Roman Bolshakov <roman@roolebo.dev>:
>>
>> On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
>> > Create separate netdevs for each vmnet operating mode:
>> > - vmnet-host
>> > - vmnet-shared
>> > - vmnet-bridged
>> >
>>
>> Sure I'm late to the party but what if we add only one backend - vmnet
>> with default mode set to shared and all parameters are added there?
>>
>> The CLI would look more reasonable for the most typical use case:
>>  -netdev vmnet,id=if1 -device virtio-net,netdev=if1
>>
>> That would remove duplication of options in QAPI schema (e.g. isolated
>> is available in all backends now, altough I'm not sure if it makes sense
>> for bridged mode):
>>
>>  -netdev vmnet,id=if1,isolated=yes
>>
>> start-address, end-address and subnet-mask are also used by both shared
>> and host modes.
>>
>> Bridged netdev would lool like:
>>
>>  -netdev vmnet,id=if1,mode=bridged,ifname=en1
>>
>> Checksum offloading also seems to be available for all backends from
>> Monterey.
>>
>> The approach might simplify integration of the changes to libvirt and
>> discovery of upcoming vmnet features via qapi.
>>
>
> I can rewrite this if it sounds more suitable to use
> single `vmnet` netdev instead of three different ones.
> We can discuss this with Markus as a QAPI reviewer.
> Markus, what is your opinion about single netdev?
>
> P.S. Seems we have enough time for discussion:
> I started fixing memory leaks found by Akihiko and
> met a strange deadlock on QEMU shutdown on
> `qemu_mutex_lock_iothread()` during careful
> interface destruction with added semaphore.
> Need to go deeper to understand what's the
> problem, it will take some time.
>
> Mentioned part of Akihiko's review:
> https://patchew.org/QEMU/20220113172219.66372-1-yaroshchuk2000@gmail.com/20220113172219.66372-4-yaroshchuk2000@gmail.com/

Actually I thought it would be tricky to implement. A deadlock will
occur in a simple implementation if vmnet_send is already queued but
not executed yet when destructing:
- vmnet_send tries to lock the iothread and waits for the destructor to unlock.
- vmnet_stop_interface waits for vmnet_send finishing.

Though I doubt it is the cause of your deadlock. This deadlock would
not happen frequently since vmnet_send will not be queued if the
device is not used.

Regards,
Akihiko Odaki

>
>
>> Thanks,
>> Roman
>>
>> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
>> > ---
>> >  net/clients.h       |  11 ++++
>> >  net/meson.build     |   7 +++
>> >  net/net.c           |  10 ++++
>> >  net/vmnet-bridged.m |  25 +++++++++
>> >  net/vmnet-common.m  |  20 +++++++
>> >  net/vmnet-host.c    |  24 ++++++++
>> >  net/vmnet-shared.c  |  25 +++++++++
>> >  net/vmnet_int.h     |  25 +++++++++
>> >  qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
>> >  9 files changed, 278 insertions(+), 2 deletions(-)
>> >  create mode 100644 net/vmnet-bridged.m
>> >  create mode 100644 net/vmnet-common.m
>> >  create mode 100644 net/vmnet-host.c
>> >  create mode 100644 net/vmnet-shared.c
>> >  create mode 100644 net/vmnet_int.h
>> >
>> > diff --git a/net/net.c b/net/net.c
>> > index f0d14dbfc1..1dbb64b935 100644
>> > --- a/net/net.c
>> > +++ b/net/net.c
>> > @@ -1021,6 +1021,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 */
>> >  };
>> >
>> >
>> > @@ -1106,6 +1111,11 @@ void show_netdevs(void)
>> >  #endif
>> >  #ifdef CONFIG_VHOST_VDPA
>> >          "vhost-vdpa",
>> > +#endif
>> > +#ifdef CONFIG_VMNET
>> > +        "vmnet-host",
>> > +        "vmnet-shared",
>> > +        "vmnet-bridged",
>> >  #endif
>> >      };
>> >
>> > diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
>> > new file mode 100644
>> > index 0000000000..4e42a90391
>> > --- /dev/null
>> > +++ b/net/vmnet-bridged.m
>> > @@ -0,0 +1,25 @@
>> > +/*
>> > + * vmnet-bridged.m
>> > + *
>> > + * 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 "qapi/qapi-types-net.h"
>> > +#include "vmnet_int.h"
>> > +#include "clients.h"
>> > +#include "qemu/error-report.h"
>> > +#include "qapi/error.h"
>> > +
>> > +#include <vmnet/vmnet.h>
>> > +
>> > +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
>> > +                           NetClientState *peer, Error **errp)
>> > +{
>> > +  error_setg(errp, "vmnet-bridged is not implemented yet");
>> > +  return -1;
>> > +}
>> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
>> > new file mode 100644
>> > index 0000000000..532d152840
>> > --- /dev/null
>> > +++ b/net/vmnet-common.m
>> > @@ -0,0 +1,20 @@
>> > +/*
>> > + * vmnet-common.m - network client wrapper for Apple vmnet.framework
>> > + *
>> > + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
>> > + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
>> > +#include "vmnet_int.h"
>> > +#include "clients.h"
>> > +#include "qemu/error-report.h"
>> > +#include "qapi/error.h"
>> > +
>> > +#include <vmnet/vmnet.h>
>> > +
>> > diff --git a/net/vmnet-host.c b/net/vmnet-host.c
>> > new file mode 100644
>> > index 0000000000..4a5ef99dc7
>> > --- /dev/null
>> > +++ b/net/vmnet-host.c
>> > @@ -0,0 +1,24 @@
>> > +/*
>> > + * vmnet-host.c
>> > + *
>> > + * 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 "qapi/qapi-types-net.h"
>> > +#include "vmnet_int.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-host is not implemented yet");
>> > +  return -1;
>> > +}
>> > diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
>> > new file mode 100644
>> > index 0000000000..f8c4a4f3b8
>> > --- /dev/null
>> > +++ b/net/vmnet-shared.c
>> > @@ -0,0 +1,25 @@
>> > +/*
>> > + * vmnet-shared.c
>> > + *
>> > + * 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 "qapi/qapi-types-net.h"
>> > +#include "vmnet_int.h"
>> > +#include "clients.h"
>> > +#include "qemu/error-report.h"
>> > +#include "qapi/error.h"
>> > +
>> > +#include <vmnet/vmnet.h>
>> > +
>> > +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
>> > +                          NetClientState *peer, Error **errp)
>> > +{
>> > +  error_setg(errp, "vmnet-shared is not implemented yet");
>> > +  return -1;
>> > +}
>> > diff --git a/net/vmnet_int.h b/net/vmnet_int.h
>> > new file mode 100644
>> > index 0000000000..c5982259a4
>> > --- /dev/null
>> > +++ b/net/vmnet_int.h
>> > @@ -0,0 +1,25 @@
>> > +/*
>> > + * vmnet_int.h
>> > + *
>> > + * 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.
>> > + *
>> > + */
>> > +#ifndef VMNET_INT_H
>> > +#define VMNET_INT_H
>> > +
>> > +#include "qemu/osdep.h"
>> > +#include "vmnet_int.h"
>> > +#include "clients.h"
>> > +
>> > +#include <vmnet/vmnet.h>
>> > +
>> > +typedef struct VmnetCommonState {
>> > +  NetClientState nc;
>> > +
>> > +} VmnetCommonState;
>> > +
>> > +
>> > +#endif /* VMNET_INT_H */
>> > diff --git a/qapi/net.json b/qapi/net.json
>> > index 7fab2e7cd8..b922e2e34f 100644
>> > --- a/qapi/net.json
>> > +++ b/qapi/net.json
>> > @@ -452,6 +452,120 @@
>> >      '*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 host.
>> > +#
>> > +# @start-address: The starting IPv4 address to use for the interface.
>> > +#                 Must be in the private IP range (RFC 1918). Must be
>> > +#                 specified along with @end-address and @subnet-mask.
>> > +#                 This address is used as the gateway address. The
>> > +#                 subsequent address up to and including end-address are
>> > +#                 placed in the DHCP pool.
>> > +#
>> > +# @end-address: 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 @start-address and
>> > +#               @subnet-mask.
>> > +#
>> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
>> > +#               be specified along with @start-address and @subnet-mask.
>> > +#
>> > +# @isolated: Enable isolation for this interface. Interface isolation
>> > +#            ensures that vmnet interface is not able to communicate
>> > +#            with any other vmnet interfaces. Only communication with
>> > +#            host is allowed. Available since macOS Big Sur 11.0.
>> > +#
>> > +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
>> > +#            network vmnet interface should be added to. If
>> > +#            set, no DHCP service is provided for this interface and
>> > +#            network communication is allowed only with other interfaces
>> > +#            added to this network identified by the UUID. Available
>> > +#            since macOS Big Sur 11.0.
>> > +#
>> > +# Since: 7.0
>> > +##
>> > +{ 'struct': 'NetdevVmnetHostOptions',
>> > +  'data': {
>> > +    '*start-address': 'str',
>> > +    '*end-address':   'str',
>> > +    '*subnet-mask':   'str',
>> > +    '*isolated':      'bool',
>> > +    '*net-uuid':      '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 communicate with the host and with
>> > +# other shared mode interfaces on the same subnet. If no DHCP
>> > +# settings, subnet mask and IPv6 prefix specified, the interface can
>> > +# communicate with any of other interfaces in shared mode.
>> > +#
>> > +# @start-address: The starting IPv4 address to use for the interface.
>> > +#                 Must be in the private IP range (RFC 1918). Must be
>> > +#                 specified along with @end-address and @subnet-mask.
>> > +#                 This address is used as the gateway address. The
>> > +#                 subsequent address up to and including end-address are
>> > +#                 placed in the DHCP pool.
>> > +#
>> > +# @end-address: 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 @start-address and @subnet-mask.
>> > +#
>> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
>> > +#                be specified along with @start-address and @subnet-mask.
>> > +#
>> > +# @isolated: Enable isolation for this interface. Interface isolation
>> > +#            ensures that vmnet interface is not able to communicate
>> > +#            with any other vmnet interfaces. Only communication with
>> > +#            host is allowed. Available since macOS Big Sur 11.0.
>> > +#
>> > +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
>> > +#                unique local address i.e. start with fd00::/8 and have
>> > +#                length of 64.
>> > +#
>> > +# Since: 7.0
>> > +##
>> > +{ 'struct': 'NetdevVmnetSharedOptions',
>> > +  'data': {
>> > +    '*start-address': 'str',
>> > +    '*end-address':   'str',
>> > +    '*subnet-mask':   'str',
>> > +    '*isolated':      'bool',
>> > +    '*nat66-prefix':  '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.
>> > +#
>> > +# @isolated: Enable isolation for this interface. Interface isolation
>> > +#            ensures that vmnet interface is not able to communicate
>> > +#            with any other vmnet interfaces. Only communication with
>> > +#            host is allowed. Available since macOS Big Sur 11.0.
>> > +#
>> > +# Since: 7.0
>> > +##
>> > +{ 'struct': 'NetdevVmnetBridgedOptions',
>> > +  'data': {
>> > +    'ifname':     'str',
>> > +    '*isolated':  'bool' },
>> > +  'if': 'CONFIG_VMNET' }
>> > +
>> >  ##
>> >  # @NetClientDriver:
>> >  #
>> > @@ -460,10 +574,16 @@
>> >  # Since: 2.7
>> >  #
>> >  #        @vhost-vdpa since 5.1
>> > +#        @vmnet-host since 7.0
>> > +#        @vmnet-shared since 7.0
>> > +#        @vmnet-bridged since 7.0
>> >  ##
>> >  { '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 +597,9 @@
>> >  # Since: 1.2
>> >  #
>> >  #        'l2tpv3' - since 2.1
>> > +#        'vmnet-host' - since 7.0
>> > +#        'vmnet-shared' - since 7.0
>> > +#        'vmnet-bridged' - since 7.0
>> >  ##
>> >  { 'union': 'Netdev',
>> >    'base': { 'id': 'str', 'type': 'NetClientDriver' },
>> > @@ -492,7 +615,13 @@
>> >      'hubport':  'NetdevHubPortOptions',
>> >      'netmap':   'NetdevNetmapOptions',
>> >      'vhost-user': 'NetdevVhostUserOptions',
>> > -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
>> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
>> > +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
>> > +                    'if': 'CONFIG_VMNET' },
>> > +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
>> > +                      'if': 'CONFIG_VMNET' },
>> > +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
>> > +                       'if': 'CONFIG_VMNET' } } }
>> >
>> >  ##
>> >  # @RxState:
>> > --
>> > 2.23.0
>> >
>
>
>
> --
> Best Regards,
>
> Vladislav Yaroshchuk


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
                     ` (2 preceding siblings ...)
  2022-01-20  8:32   ` Roman Bolshakov
@ 2022-01-24  9:56   ` Roman Bolshakov
  2022-01-24 11:27     ` Christian Schoenebeck
  3 siblings, 1 reply; 35+ messages in thread
From: Roman Bolshakov @ 2022-01-24  9:56 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: peter.maydell, kraxel, alex.bennee, jasowang, phillip.ennen,
	qemu-devel, dirty, armbru, r.bolshakov, agraf, phillip,
	akihiko.odaki, hsp.cat7, hello, qemu_oss, eblake, f4bug

On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> Create separate netdevs for each vmnet operating mode:
> - vmnet-host
> - vmnet-shared
> - vmnet-bridged
> 
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>  net/clients.h       |  11 ++++
>  net/meson.build     |   7 +++
>  net/net.c           |  10 ++++
>  net/vmnet-bridged.m |  25 +++++++++
>  net/vmnet-common.m  |  20 +++++++

Hi Vladislav,

It seems the last two files should have .c extension rather than .m.

Unlike Cocoa UI code, the files do not contain Objective-C classes. They are
just C code with blocks (which is supported by compilers shipped with Xcode
SDK), e.g this program can be compiled without extra compiler flags:

$ cat block.c
int main() {
        int (^x)(void) = ^{
                return 0;
        };

        return x();
}
$ cc block.c && ./a.out
$

Regards,
Roman

>  net/vmnet-host.c    |  24 ++++++++
>  net/vmnet-shared.c  |  25 +++++++++
>  net/vmnet_int.h     |  25 +++++++++
>  qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
>  9 files changed, 278 insertions(+), 2 deletions(-)
>  create mode 100644 net/vmnet-bridged.m
>  create mode 100644 net/vmnet-common.m
>  create mode 100644 net/vmnet-host.c
>  create mode 100644 net/vmnet-shared.c
>  create mode 100644 net/vmnet_int.h
> 
> diff --git a/net/clients.h b/net/clients.h
> index 92f9b59aed..c9157789f2 100644
> --- a/net/clients.h
> +++ b/net/clients.h
> @@ -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 */
> diff --git a/net/meson.build b/net/meson.build
> index 847bc2ac85..00a88c4951 100644
> --- a/net/meson.build
> +++ b/net/meson.build
> @@ -42,4 +42,11 @@ 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'))
>  
> +vmnet_files = files(
> +  'vmnet-common.m',
> +  'vmnet-bridged.m',
> +  'vmnet-host.c',
> +  'vmnet-shared.c'
> +)
> +softmmu_ss.add(when: vmnet, if_true: vmnet_files)
>  subdir('can')
> diff --git a/net/net.c b/net/net.c
> index f0d14dbfc1..1dbb64b935 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1021,6 +1021,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 */
>  };
>  
>  
> @@ -1106,6 +1111,11 @@ void show_netdevs(void)
>  #endif
>  #ifdef CONFIG_VHOST_VDPA
>          "vhost-vdpa",
> +#endif
> +#ifdef CONFIG_VMNET
> +        "vmnet-host",
> +        "vmnet-shared",
> +        "vmnet-bridged",
>  #endif
>      };
>  
> diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> new file mode 100644
> index 0000000000..4e42a90391
> --- /dev/null
> +++ b/net/vmnet-bridged.m
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet-bridged.m
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
> +                           NetClientState *peer, Error **errp)
> +{
> +  error_setg(errp, "vmnet-bridged is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> new file mode 100644
> index 0000000000..532d152840
> --- /dev/null
> +++ b/net/vmnet-common.m
> @@ -0,0 +1,20 @@
> +/*
> + * vmnet-common.m - network client wrapper for Apple vmnet.framework
> + *
> + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> diff --git a/net/vmnet-host.c b/net/vmnet-host.c
> new file mode 100644
> index 0000000000..4a5ef99dc7
> --- /dev/null
> +++ b/net/vmnet-host.c
> @@ -0,0 +1,24 @@
> +/*
> + * vmnet-host.c
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.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-host is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> new file mode 100644
> index 0000000000..f8c4a4f3b8
> --- /dev/null
> +++ b/net/vmnet-shared.c
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet-shared.c
> + *
> + * 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 "qapi/qapi-types-net.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
> +                          NetClientState *peer, Error **errp)
> +{
> +  error_setg(errp, "vmnet-shared is not implemented yet");
> +  return -1;
> +}
> diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> new file mode 100644
> index 0000000000..c5982259a4
> --- /dev/null
> +++ b/net/vmnet_int.h
> @@ -0,0 +1,25 @@
> +/*
> + * vmnet_int.h
> + *
> + * 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.
> + *
> + */
> +#ifndef VMNET_INT_H
> +#define VMNET_INT_H
> +
> +#include "qemu/osdep.h"
> +#include "vmnet_int.h"
> +#include "clients.h"
> +
> +#include <vmnet/vmnet.h>
> +
> +typedef struct VmnetCommonState {
> +  NetClientState nc;
> +
> +} VmnetCommonState;
> +
> +
> +#endif /* VMNET_INT_H */
> diff --git a/qapi/net.json b/qapi/net.json
> index 7fab2e7cd8..b922e2e34f 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -452,6 +452,120 @@
>      '*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 host.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and
> +#               @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#               be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> +#            network vmnet interface should be added to. If
> +#            set, no DHCP service is provided for this interface and
> +#            network communication is allowed only with other interfaces
> +#            added to this network identified by the UUID. Available
> +#            since macOS Big Sur 11.0.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetHostOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*net-uuid':      '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 communicate with the host and with
> +# other shared mode interfaces on the same subnet. If no DHCP
> +# settings, subnet mask and IPv6 prefix specified, the interface can
> +# communicate with any of other interfaces in shared mode.
> +#
> +# @start-address: The starting IPv4 address to use for the interface.
> +#                 Must be in the private IP range (RFC 1918). Must be
> +#                 specified along with @end-address and @subnet-mask.
> +#                 This address is used as the gateway address. The
> +#                 subsequent address up to and including end-address are
> +#                 placed in the DHCP pool.
> +#
> +# @end-address: 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 @start-address and @subnet-mask.
> +#
> +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> +#                be specified along with @start-address and @subnet-mask.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> +#                unique local address i.e. start with fd00::/8 and have
> +#                length of 64.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetSharedOptions',
> +  'data': {
> +    '*start-address': 'str',
> +    '*end-address':   'str',
> +    '*subnet-mask':   'str',
> +    '*isolated':      'bool',
> +    '*nat66-prefix':  '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.
> +#
> +# @isolated: Enable isolation for this interface. Interface isolation
> +#            ensures that vmnet interface is not able to communicate
> +#            with any other vmnet interfaces. Only communication with
> +#            host is allowed. Available since macOS Big Sur 11.0.
> +#
> +# Since: 7.0
> +##
> +{ 'struct': 'NetdevVmnetBridgedOptions',
> +  'data': {
> +    'ifname':     'str',
> +    '*isolated':  'bool' },
> +  'if': 'CONFIG_VMNET' }
> +
>  ##
>  # @NetClientDriver:
>  #
> @@ -460,10 +574,16 @@
>  # Since: 2.7
>  #
>  #        @vhost-vdpa since 5.1
> +#        @vmnet-host since 7.0
> +#        @vmnet-shared since 7.0
> +#        @vmnet-bridged since 7.0
>  ##
>  { '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 +597,9 @@
>  # Since: 1.2
>  #
>  #        'l2tpv3' - since 2.1
> +#        'vmnet-host' - since 7.0
> +#        'vmnet-shared' - since 7.0
> +#        'vmnet-bridged' - since 7.0
>  ##
>  { 'union': 'Netdev',
>    'base': { 'id': 'str', 'type': 'NetClientDriver' },
> @@ -492,7 +615,13 @@
>      'hubport':  'NetdevHubPortOptions',
>      'netmap':   'NetdevNetmapOptions',
>      'vhost-user': 'NetdevVhostUserOptions',
> -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> +                    'if': 'CONFIG_VMNET' },
> +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> +                      'if': 'CONFIG_VMNET' },
> +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> +                       'if': 'CONFIG_VMNET' } } }
>  
>  ##
>  # @RxState:
> -- 
> 2.23.0
> 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-24  9:56   ` Roman Bolshakov
@ 2022-01-24 11:27     ` Christian Schoenebeck
  2022-01-24 17:49       ` Roman Bolshakov
  0 siblings, 1 reply; 35+ messages in thread
From: Christian Schoenebeck @ 2022-01-24 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Vladislav Yaroshchuk, peter.maydell, kraxel,
	alex.bennee, jasowang, phillip.ennen, dirty, armbru, r.bolshakov,
	agraf, phillip, akihiko.odaki, hsp.cat7, hello, eblake, f4bug

On Montag, 24. Januar 2022 10:56:00 CET Roman Bolshakov wrote:
> On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> > Create separate netdevs for each vmnet operating mode:
> > - vmnet-host
> > - vmnet-shared
> > - vmnet-bridged
> > 
> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > ---
> > 
> >  net/clients.h       |  11 ++++
> >  net/meson.build     |   7 +++
> >  net/net.c           |  10 ++++
> >  net/vmnet-bridged.m |  25 +++++++++
> >  net/vmnet-common.m  |  20 +++++++
> 
> Hi Vladislav,
> 
> It seems the last two files should have .c extension rather than .m.

I would not do that. Mind cross-compilers, please.

> Unlike Cocoa UI code, the files do not contain Objective-C classes. They are
> just C code with blocks (which is supported by compilers shipped with Xcode
> SDK), e.g this program can be compiled without extra compiler flags:
> 
> $ cat block.c
> int main() {
>         int (^x)(void) = ^{
>                 return 0;
>         };
> 
>         return x();
> }
> $ cc block.c && ./a.out
> $
> 
> Regards,
> Roman

Such blocks are still Objective-C language specific, they are not C and 
therefore won't work with GCC.

$ gcc block.c

block.c: In function ‘main’:
block.c:2:14: error: expected identifier or ‘(’ before ‘^’ token
         int (^x)(void) = ^{
              ^
block.c:6:16: warning: implicit declaration of function ‘x’ [-Wimplicit-
function-declaration]
         return x();
                ^
Best regards,
Christian Schoenebeck




^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-24 11:27     ` Christian Schoenebeck
@ 2022-01-24 17:49       ` Roman Bolshakov
  2022-01-24 20:00         ` Christian Schoenebeck
  2022-01-24 20:14         ` Peter Maydell
  0 siblings, 2 replies; 35+ messages in thread
From: Roman Bolshakov @ 2022-01-24 17:49 UTC (permalink / raw)
  To: Christian Schoenebeck
  Cc: peter.maydell, f4bug, Vladislav Yaroshchuk, eblake, jasowang,
	phillip.ennen, qemu-devel, dirty, armbru, r.bolshakov, agraf,
	kraxel, akihiko.odaki, hsp.cat7, hello, alex.bennee, phillip

On Mon, Jan 24, 2022 at 12:27:40PM +0100, Christian Schoenebeck wrote:
> On Montag, 24. Januar 2022 10:56:00 CET Roman Bolshakov wrote:
> > On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> > >  net/vmnet-bridged.m |  25 +++++++++
> > >  net/vmnet-common.m  |  20 +++++++
> > 
> > It seems the last two files should have .c extension rather than .m.
> 
> I would not do that. Mind cross-compilers, please.
> 

Hi Christian,

Cross-compilers for Apple platforms can be constructed using à la carte
approach where toolchain comes from the source, SDK from Apple and a
port of cctools from GitHub (mind all library dependencies of QEMU).
That's quite an effort!

I very much doubt this is a relevant and typical case for QEMU on macOS.
And if cross-compiler is constructed properly it'll pass required flags
that enable blocks and will link block runtime in its default build
recipe like all cross-compilers do for the platform of interest.

Gladly, there's osxcross [1] and crossbuild image with Darwin support [2].
They can deal with blocks just fine:

  # CROSS_TRIPLE=i386-apple-darwin
  $ cc block.c && file a.out
  a.out: Mach-O i386 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|NO_HEAP_EXECUTION>

  # CROSS_TRIPLE=x86_64-apple-darwin
  $ cc block.c && file a.out
  $ file a.out
  a.out: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>

> > Unlike Cocoa UI code, the files do not contain Objective-C classes. They are
> > just C code with blocks (which is supported by compilers shipped with Xcode
> > SDK), e.g this program can be compiled without extra compiler flags:
> > 
> > $ cat block.c
> > int main() {
> >         int (^x)(void) = ^{
> >                 return 0;
> >         };
> > 
> >         return x();
> > }
> > $ cc block.c && ./a.out
> > $
> > 
> 
> Such blocks are still Objective-C language specific, they are not C and 
> therefore won't work with GCC.
> 

I'm not sure why blocks are Objective-C specific. All the data I have
shows the opposite [3][4][5]. They're just extensively used in Apple APIs.

> $ gcc block.c
> 
> block.c: In function ‘main’:
> block.c:2:14: error: expected identifier or ‘(’ before ‘^’ token
>          int (^x)(void) = ^{
>               ^
> block.c:6:16: warning: implicit declaration of function ‘x’ [-Wimplicit-
> function-declaration]
>          return x();
>                 ^

You might do this on Linux and it'll work:

$ clang -g -fblocks -lBlocksRuntime block.c && ./a.out

However, vmnet code won't be compiled on non-Apple platforms because the
compilation happens only if vmnet is available which happens only if
appleframeworks dependency is available, that is not available on
non-OSX hosts [6]:

  "These dependencies can never be found for non-OSX hosts."

1. https://github.com/tpoechtrager/osxcross
2. https://github.com/multiarch/crossbuild
3. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1370.pdf
4. https://clang.llvm.org/docs/BlockLanguageSpec.html
5. https://clang.llvm.org/docs/Block-ABI-Apple.html
6. https://mesonbuild.com/Dependencies.html#appleframeworks

Regards,
Roman


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-24 17:49       ` Roman Bolshakov
@ 2022-01-24 20:00         ` Christian Schoenebeck
  2022-01-24 20:14         ` Peter Maydell
  1 sibling, 0 replies; 35+ messages in thread
From: Christian Schoenebeck @ 2022-01-24 20:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, peter.maydell, f4bug, Vladislav Yaroshchuk,
	eblake, jasowang, phillip.ennen, dirty, armbru, r.bolshakov,
	agraf, kraxel, akihiko.odaki, hsp.cat7, hello, alex.bennee,
	phillip

On Montag, 24. Januar 2022 18:49:53 CET Roman Bolshakov wrote:
> On Mon, Jan 24, 2022 at 12:27:40PM +0100, Christian Schoenebeck wrote:
> > On Montag, 24. Januar 2022 10:56:00 CET Roman Bolshakov wrote:
> > > On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> > > >  net/vmnet-bridged.m |  25 +++++++++
> > > >  net/vmnet-common.m  |  20 +++++++
> > > 
> > > It seems the last two files should have .c extension rather than .m.
> > 
> > I would not do that. Mind cross-compilers, please.
> 
> Hi Christian,
> 
> Cross-compilers for Apple platforms can be constructed using à la carte
> approach where toolchain comes from the source, SDK from Apple and a
> port of cctools from GitHub (mind all library dependencies of QEMU).
> That's quite an effort!
> 
> I very much doubt this is a relevant and typical case for QEMU on macOS.
> And if cross-compiler is constructed properly it'll pass required flags
> that enable blocks and will link block runtime in its default build
> recipe like all cross-compilers do for the platform of interest.
> 
> Gladly, there's osxcross [1] and crossbuild image with Darwin support [2].
> They can deal with blocks just fine:
> 
>   # CROSS_TRIPLE=i386-apple-darwin
>   $ cc block.c && file a.out
>   a.out: Mach-O i386 executable,
> flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|NO_HEAP_EXECUTION>
> 
>   # CROSS_TRIPLE=x86_64-apple-darwin
>   $ cc block.c && file a.out
>   $ file a.out
>   a.out: Mach-O 64-bit x86_64 executable,
> flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>
> > > Unlike Cocoa UI code, the files do not contain Objective-C classes. They
> > > are just C code with blocks (which is supported by compilers shipped
> > > with Xcode SDK), e.g this program can be compiled without extra
> > > compiler flags:
> > > 
> > > $ cat block.c
> > > int main() {
> > > 
> > >         int (^x)(void) = ^{
> > >         
> > >                 return 0;
> > >         
> > >         };
> > >         
> > >         return x();
> > > 
> > > }
> > > $ cc block.c && ./a.out
> > > $
> > 
> > Such blocks are still Objective-C language specific, they are not C and
> > therefore won't work with GCC.
> 
> I'm not sure why blocks are Objective-C specific. All the data I have
> shows the opposite [3][4][5]. They're just extensively used in Apple APIs.

Because blocks are automatically available if you are using an Objective-C or 
Objective-C++ frontend, but not necessarily if you use a C or C++ frontend.

> > $ gcc block.c
> > 
> > block.c: In function ‘main’:
> > block.c:2:14: error: expected identifier or ‘(’ before ‘^’ token
> > 
> >          int (^x)(void) = ^{
> >          
> >               ^
> > 
> > block.c:6:16: warning: implicit declaration of function ‘x’ [-Wimplicit-
> > function-declaration]
> > 
> >          return x();
> >          
> >                 ^
> 
> You might do this on Linux and it'll work:
> 
> $ clang -g -fblocks -lBlocksRuntime block.c && ./a.out

Yes, which is an unnecesary complicated & limiting variant of just:

	clang/gcc block.m

Don't get me wrong, I don't care too much about this issue. It's just that I 
really see no advantage in renaming this into a C file, but I do see 
disadvantages. That's all.

> However, vmnet code won't be compiled on non-Apple platforms because the
> compilation happens only if vmnet is available which happens only if
> appleframeworks dependency is available, that is not available on
> non-OSX hosts [6]:
> 
>   "These dependencies can never be found for non-OSX hosts."
> 
> 1. https://github.com/tpoechtrager/osxcross
> 2. https://github.com/multiarch/crossbuild
> 3. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1370.pdf
> 4. https://clang.llvm.org/docs/BlockLanguageSpec.html
> 5. https://clang.llvm.org/docs/Block-ABI-Apple.html
> 6. https://mesonbuild.com/Dependencies.html#appleframeworks
> 
> Regards,
> Roman




^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-24 17:49       ` Roman Bolshakov
  2022-01-24 20:00         ` Christian Schoenebeck
@ 2022-01-24 20:14         ` Peter Maydell
  2022-01-24 23:00           ` Roman Bolshakov
  1 sibling, 1 reply; 35+ messages in thread
From: Peter Maydell @ 2022-01-24 20:14 UTC (permalink / raw)
  To: Roman Bolshakov
  Cc: f4bug, Vladislav Yaroshchuk, phillip.ennen, jasowang,
	Christian Schoenebeck, qemu-devel, dirty, armbru, r.bolshakov,
	agraf, kraxel, akihiko.odaki, hsp.cat7, hello, alex.bennee,
	eblake, phillip

On Mon, 24 Jan 2022 at 17:49, Roman Bolshakov <roman@roolebo.dev> wrote:
> I'm not sure why blocks are Objective-C specific. All the data I have
> shows the opposite [3][4][5]. They're just extensively used in Apple APIs.

This is true, but for the purposes of our build machinery it is
simpler to have three types of source files that it deals
with (C, C++, ObjC) rather than four (C, C++, ObjC, C-that-uses-blocks).
So unless there's a clear benefit from adding the extra category
I think we should do the simple thing and keep these files named
with a ".m" extension.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-24 20:14         ` Peter Maydell
@ 2022-01-24 23:00           ` Roman Bolshakov
  2022-01-25  4:14             ` Akihiko Odaki
  0 siblings, 1 reply; 35+ messages in thread
From: Roman Bolshakov @ 2022-01-24 23:00 UTC (permalink / raw)
  To: Peter Maydell
  Cc: f4bug, Vladislav Yaroshchuk, phillip.ennen, jasowang,
	Christian Schoenebeck, qemu-devel, dirty, armbru, r.bolshakov,
	agraf, kraxel, akihiko.odaki, hsp.cat7, hello, alex.bennee,
	eblake, phillip

On Mon, Jan 24, 2022 at 08:14:31PM +0000, Peter Maydell wrote:
> On Mon, 24 Jan 2022 at 17:49, Roman Bolshakov <roman@roolebo.dev> wrote:
> > I'm not sure why blocks are Objective-C specific. All the data I have
> > shows the opposite [3][4][5]. They're just extensively used in Apple APIs.
> 
> This is true, but for the purposes of our build machinery it is
> simpler to have three types of source files that it deals
> with (C, C++, ObjC) rather than four (C, C++, ObjC, C-that-uses-blocks).
> So unless there's a clear benefit from adding the extra category
> I think we should do the simple thing and keep these files named
> with a ".m" extension.
> 

Fine by me as long as majority finds it's simpler :) Perhaps it's just a
matter of personal preference.

I've used to the fact that platform-specific code uses platform-specific
extensions or some sort of weird "GCC attributes". Therefore C with an
extension is easier to reason for me than Objective-C with ARC and other
kinds of implicit behaviour without an actual Objective-C code.

Thanks,
Roman


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-24 23:00           ` Roman Bolshakov
@ 2022-01-25  4:14             ` Akihiko Odaki
  2022-01-25 10:32               ` Peter Maydell
  2022-01-29 21:03               ` Roman Bolshakov
  0 siblings, 2 replies; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-25  4:14 UTC (permalink / raw)
  To: Roman Bolshakov
  Cc: Peter Maydell, Philippe Mathieu-Daudé,
	Vladislav Yaroshchuk, phillip.ennen, Jason Wang,
	Christian Schoenebeck, qemu Developers, Cameron Esfahani,
	Markus Armbruster, Roman Bolshakov, Alexander Graf,
	Gerd Hoffmann, Howard Spoelstra, Alessio Dionisi,
	Alex Bennée, Eric Blake, Phillip Tennen

On Tue, Jan 25, 2022 at 8:00 AM Roman Bolshakov <roman@roolebo.dev> wrote:
>
> On Mon, Jan 24, 2022 at 08:14:31PM +0000, Peter Maydell wrote:
> > On Mon, 24 Jan 2022 at 17:49, Roman Bolshakov <roman@roolebo.dev> wrote:
> > > I'm not sure why blocks are Objective-C specific. All the data I have
> > > shows the opposite [3][4][5]. They're just extensively used in Apple APIs.
> >
> > This is true, but for the purposes of our build machinery it is
> > simpler to have three types of source files that it deals
> > with (C, C++, ObjC) rather than four (C, C++, ObjC, C-that-uses-blocks).
> > So unless there's a clear benefit from adding the extra category
> > I think we should do the simple thing and keep these files named
> > with a ".m" extension.
> >
>
> Fine by me as long as majority finds it's simpler :) Perhaps it's just a
> matter of personal preference.
>
> I've used to the fact that platform-specific code uses platform-specific
> extensions or some sort of weird "GCC attributes". Therefore C with an
> extension is easier to reason for me than Objective-C with ARC and other
> kinds of implicit behaviour without an actual Objective-C code.
>
> Thanks,
> Roman

Being technically pedantic, actually this vmnet implementation uses
Objective-C and there is a file with .c which uses blocks.
If a file is named .m, dispatch_retain(o) will be redefined as [o
retain], and effectively makes it Objective-C code. Therefore, vmnet
involves Objective-C as long as its files are named .m. It will be C
with blocks if they are named .c.
Speaking of use of blocks, actually audio/coreaudio.c involves blocks
in header files; Core Audio has functions which accept blocks.

I'm neutral about the decision. I think QEMU should avoid using
Objective-C code except for interactions with Apple's APIs, and .c is
superior in terms of that as it would prevent accidental introduction
of Objective-C code. On the other hand, naming them .m will allow the
introduction of Automatic Reference Counting to manage dispatch queue
objects. In fact, I have found a few memory leaks in vmnet in the last
review and ui/cocoa.m has a suspicious construction of the object
management (Particularly it has asynchronous dispatches wrapped with
NSAutoreleasePool, which does not make sense). Introduction of
Automatic Reference Counting would greatly help addressing those
issues, but that would require significant rewriting of ui/cocoa.m.
Personally I'm concerned with ui/cocoa.m and do want to do that
rewriting, but I'm being busy so it would not happen anytime soon.

Regards,
Akihiko Odaki


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-25  4:14             ` Akihiko Odaki
@ 2022-01-25 10:32               ` Peter Maydell
  2022-01-25 11:08                 ` Akihiko Odaki
  2022-01-29 21:03               ` Roman Bolshakov
  1 sibling, 1 reply; 35+ messages in thread
From: Peter Maydell @ 2022-01-25 10:32 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Philippe Mathieu-Daudé,
	Vladislav Yaroshchuk, phillip.ennen, Jason Wang,
	Christian Schoenebeck, qemu Developers, Cameron Esfahani,
	Markus Armbruster, Roman Bolshakov, Alexander Graf,
	Gerd Hoffmann, Howard Spoelstra, Roman Bolshakov,
	Alessio Dionisi, Alex Bennée, Eric Blake, Phillip Tennen

On Tue, 25 Jan 2022 at 04:14, Akihiko Odaki <akihiko.odaki@gmail.com> wrote:
> I'm neutral about the decision. I think QEMU should avoid using
> Objective-C code except for interactions with Apple's APIs, and .c is
> superior in terms of that as it would prevent accidental introduction
> of Objective-C code. On the other hand, naming them .m will allow the
> introduction of Automatic Reference Counting to manage dispatch queue
> objects. In fact, I have found a few memory leaks in vmnet in the last
> review and ui/cocoa.m has a suspicious construction of the object
> management (Particularly it has asynchronous dispatches wrapped with
> NSAutoreleasePool, which does not make sense).

I think those are probably my fault -- in commit 6e657e64cd (in 2013)
we added NSAutoReleasePools to fix leaks that happened because
we were calling into Cocoa APIs from threads other than the UI
thread that didn't have their own automatically created autorelease
pool. Much later in commit 5588840ff778 (in 2019) we put in the
dispatch_async stuff because newer macOS was stricter about
requiring Cocoa API calls to be only on the UI thread. So
I think that means the requirement for the autorelease pools
has now gone away in those functions and we could simply delete
them -- does that sound right? (I freely admit that I'm not a macOS
expert -- I just look stuff up in the documentation; historically
we haven't really had many expert macOS people around to work on
cocoa.m...)

On the subject of cocoa.m, while we have various macOS-interested
people in this thread, can I ask if anybody would like to
review a couple of patches that came in at the beginning of the
year?

https://patchew.org/QEMU/20220102174153.70043-1-carwynellis@gmail.com/
("ui/cocoa: Add option to disable left command and hide cursor on click")
and
https://patchew.org/QEMU/20220103114515.24020-1-carwynellis@gmail.com/
("Show/hide the menu bar in fullscreen on mouse")

either from the point of view of "is this a sensible change to
the macOS UI experience" or for the actual code changes, or both.

We've been very short on upstream macOS code reviewers so if people
interested in that host platform are able to chip in by
reviewing each others' code that helps a lot.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-25 10:32               ` Peter Maydell
@ 2022-01-25 11:08                 ` Akihiko Odaki
  2022-01-25 17:30                   ` Christian Schoenebeck
  0 siblings, 1 reply; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-25 11:08 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Philippe Mathieu-Daudé,
	Vladislav Yaroshchuk, phillip.ennen, Jason Wang,
	Christian Schoenebeck, qemu Developers, Cameron Esfahani,
	Markus Armbruster, Roman Bolshakov, Alexander Graf,
	Gerd Hoffmann, Howard Spoelstra, Roman Bolshakov,
	Alessio Dionisi, Alex Bennée, Eric Blake, Phillip Tennen

On Tue, Jan 25, 2022 at 7:32 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Tue, 25 Jan 2022 at 04:14, Akihiko Odaki <akihiko.odaki@gmail.com> wrote:
> > I'm neutral about the decision. I think QEMU should avoid using
> > Objective-C code except for interactions with Apple's APIs, and .c is
> > superior in terms of that as it would prevent accidental introduction
> > of Objective-C code. On the other hand, naming them .m will allow the
> > introduction of Automatic Reference Counting to manage dispatch queue
> > objects. In fact, I have found a few memory leaks in vmnet in the last
> > review and ui/cocoa.m has a suspicious construction of the object
> > management (Particularly it has asynchronous dispatches wrapped with
> > NSAutoreleasePool, which does not make sense).
>
> I think those are probably my fault -- in commit 6e657e64cd (in 2013)
> we added NSAutoReleasePools to fix leaks that happened because
> we were calling into Cocoa APIs from threads other than the UI
> thread that didn't have their own automatically created autorelease
> pool. Much later in commit 5588840ff778 (in 2019) we put in the
> dispatch_async stuff because newer macOS was stricter about
> requiring Cocoa API calls to be only on the UI thread. So
> I think that means the requirement for the autorelease pools
> has now gone away in those functions and we could simply delete
> them -- does that sound right? (I freely admit that I'm not a macOS
> expert -- I just look stuff up in the documentation; historically
> we haven't really had many expert macOS people around to work on
> cocoa.m...)

Removing them would be an improvement. Enabling ARC is a long-term
solution and would allow clang to analyze object management code and
answer such a question semi-automatically.

Regards,
Akihiko Odaki

>
> On the subject of cocoa.m, while we have various macOS-interested
> people in this thread, can I ask if anybody would like to
> review a couple of patches that came in at the beginning of the
> year?
>
> https://patchew.org/QEMU/20220102174153.70043-1-carwynellis@gmail.com/
> ("ui/cocoa: Add option to disable left command and hide cursor on click")
> and
> https://patchew.org/QEMU/20220103114515.24020-1-carwynellis@gmail.com/
> ("Show/hide the menu bar in fullscreen on mouse")
>
> either from the point of view of "is this a sensible change to
> the macOS UI experience" or for the actual code changes, or both.
>
> We've been very short on upstream macOS code reviewers so if people
> interested in that host platform are able to chip in by
> reviewing each others' code that helps a lot.
>
> thanks
> -- PMM


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-25 11:08                 ` Akihiko Odaki
@ 2022-01-25 17:30                   ` Christian Schoenebeck
  0 siblings, 0 replies; 35+ messages in thread
From: Christian Schoenebeck @ 2022-01-25 17:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Akihiko Odaki, Peter Maydell, Philippe Mathieu-Daudé,
	Vladislav Yaroshchuk, phillip.ennen, Jason Wang,
	Cameron Esfahani, Markus Armbruster, Roman Bolshakov,
	Alexander Graf, Gerd Hoffmann, Howard Spoelstra, Roman Bolshakov,
	Alessio Dionisi, Alex Bennée, Eric Blake, Phillip Tennen

On Dienstag, 25. Januar 2022 12:08:21 CET Akihiko Odaki wrote:
> On Tue, Jan 25, 2022 at 7:32 PM Peter Maydell <peter.maydell@linaro.org> 
wrote:
> > On Tue, 25 Jan 2022 at 04:14, Akihiko Odaki <akihiko.odaki@gmail.com> 
wrote:
> > > I'm neutral about the decision. I think QEMU should avoid using
> > > Objective-C code except for interactions with Apple's APIs, and .c is
> > > superior in terms of that as it would prevent accidental introduction
> > > of Objective-C code. On the other hand, naming them .m will allow the
> > > introduction of Automatic Reference Counting to manage dispatch queue
> > > objects. In fact, I have found a few memory leaks in vmnet in the last
> > > review and ui/cocoa.m has a suspicious construction of the object
> > > management (Particularly it has asynchronous dispatches wrapped with
> > > NSAutoreleasePool, which does not make sense).
> > 
> > I think those are probably my fault -- in commit 6e657e64cd (in 2013)
> > we added NSAutoReleasePools to fix leaks that happened because
> > we were calling into Cocoa APIs from threads other than the UI
> > thread that didn't have their own automatically created autorelease
> > pool. Much later in commit 5588840ff778 (in 2019) we put in the
> > dispatch_async stuff because newer macOS was stricter about
> > requiring Cocoa API calls to be only on the UI thread. So
> > I think that means the requirement for the autorelease pools
> > has now gone away in those functions and we could simply delete
> > them -- does that sound right? (I freely admit that I'm not a macOS
> > expert -- I just look stuff up in the documentation; historically
> > we haven't really had many expert macOS people around to work on
> > cocoa.m...)
> 
> Removing them would be an improvement. 

Yes, AFAICS those NSAutoReleasePools in ui/cocoa.m can safely be removed, as 
they were apparently just fighting the symptoms of having called cocoa APIs 
from non-main thread(s) in the past, which is not allowed.

There is actually a "main thread checker" for that. In Xcode it's just a 
checkbox away, but I don't see a corresponding clang parameter. Maybe it's in 
a separate toolchain by Apple.

However I don't think the NSAutoReleasePools were the cause of the memory leak 
you saw.

> Enabling ARC is a long-term
> solution and would allow clang to analyze object management code and
> answer such a question semi-automatically.

Yeah, that's not trivial and would be a long way. Personally I would say, for 
new targets, sure use ARC. But for already existing, large projects like QEMU, 
I would not switch to ARC. Because it is not just refactoring, you have to 
understand each component and make proper decisions for references (weak, 
strong, copy, bridge transfers, adjust blocks, ... ) and avoid cyclic 
references, otherwise you just replace existing issues with new ones, 
including new leaks.

> Regards,
> Akihiko Odaki
> 
> > On the subject of cocoa.m, while we have various macOS-interested
> > people in this thread, can I ask if anybody would like to
> > review a couple of patches that came in at the beginning of the
> > year?
> > 
> > https://patchew.org/QEMU/20220102174153.70043-1-carwynellis@gmail.com/
> > ("ui/cocoa: Add option to disable left command and hide cursor on click")
> > and
> > https://patchew.org/QEMU/20220103114515.24020-1-carwynellis@gmail.com/
> > ("Show/hide the menu bar in fullscreen on mouse")

I didn't spot anything negative, but I can't test those patches ATM.

> > either from the point of view of "is this a sensible change to
> > the macOS UI experience" or for the actual code changes, or both.
> > 
> > We've been very short on upstream macOS code reviewers so if people
> > interested in that host platform are able to chip in by
> > reviewing each others' code that helps a lot.

Which reminds me of the automated Xcode project discussion for QEMU. I still 
think if there was a simple way to work on QEMU with Xcode there were plenty 
of macOS reviewers and contributors, and I think it can be done with Meson.

Best regards,
Christian Schoenebeck




^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-21 13:03       ` Akihiko Odaki
@ 2022-01-28 14:29         ` Vladislav Yaroshchuk
  2022-01-28 23:00           ` Akihiko Odaki
  0 siblings, 1 reply; 35+ messages in thread
From: Vladislav Yaroshchuk @ 2022-01-28 14:29 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	Christian Schoenebeck, phillip.ennen, qemu-devel,
	Cameron Esfahani, Markus Armbruster, Roman Bolshakov,
	Alexander Graf, Phillip Tennen, Howard Spoelstra,
	Roman Bolshakov, Alessio Dionisi, Eric Blake,
	Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 28049 bytes --]

пт, 21 янв. 2022 г. в 16:03, Akihiko Odaki <akihiko.odaki@gmail.com>:

> On Fri, Jan 21, 2022 at 9:19 PM Vladislav Yaroshchuk
> <yaroshchuk2000@gmail.com> wrote:
> >
> >
> > чт, 20 янв. 2022 г. в 11:32, Roman Bolshakov <roman@roolebo.dev>:
> >>
> >> On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
> >> > Create separate netdevs for each vmnet operating mode:
> >> > - vmnet-host
> >> > - vmnet-shared
> >> > - vmnet-bridged
> >> >
> >>
> >> Sure I'm late to the party but what if we add only one backend - vmnet
> >> with default mode set to shared and all parameters are added there?
> >>
> >> The CLI would look more reasonable for the most typical use case:
> >>  -netdev vmnet,id=if1 -device virtio-net,netdev=if1
> >>
> >> That would remove duplication of options in QAPI schema (e.g. isolated
> >> is available in all backends now, altough I'm not sure if it makes sense
> >> for bridged mode):
> >>
> >>  -netdev vmnet,id=if1,isolated=yes
> >>
> >> start-address, end-address and subnet-mask are also used by both shared
> >> and host modes.
> >>
> >> Bridged netdev would lool like:
> >>
> >>  -netdev vmnet,id=if1,mode=bridged,ifname=en1
> >>
> >> Checksum offloading also seems to be available for all backends from
> >> Monterey.
> >>
> >> The approach might simplify integration of the changes to libvirt and
> >> discovery of upcoming vmnet features via qapi.
> >>
> >
> > I can rewrite this if it sounds more suitable to use
> > single `vmnet` netdev instead of three different ones.
> > We can discuss this with Markus as a QAPI reviewer.
> > Markus, what is your opinion about single netdev?
> >
> > P.S. Seems we have enough time for discussion:
> > I started fixing memory leaks found by Akihiko and
> > met a strange deadlock on QEMU shutdown on
> > `qemu_mutex_lock_iothread()` during careful
> > interface destruction with added semaphore.
> > Need to go deeper to understand what's the
> > problem, it will take some time.
> >
> > Mentioned part of Akihiko's review:
> >
> https://patchew.org/QEMU/20220113172219.66372-1-yaroshchuk2000@gmail.com/20220113172219.66372-4-yaroshchuk2000@gmail.com/
>
>
> Actually I thought it would be tricky to implement.

You mean single netdev type?

Actually I thought it would be tricky to implement. A deadlock will
> occur in a simple implementation if vmnet_send is already queued but
> not executed yet when destructing:
> - vmnet_send tries to lock the iothread and waits for the destructor to
> unlock.
> - vmnet_stop_interface waits for vmnet_send finishing.
>
>
Sounds like that's what happens actually.
With added semaphore:
--- a/net/vmnet-common.m
+++ b/net/vmnet-common.m
@@ -320,13 +320,14 @@ void vmnet_cleanup_common(NetClientState *nc)
         "org.qemu.vmnet.destroy",
         DISPATCH_QUEUE_SERIAL
     );
-
+    dispatch_semaphore_t if_destroy_sem = dispatch_semaphore_create(0);
     vmnet_stop_interface(
         s->vmnet_if,
         if_destroy_q,
         ^(vmnet_return_t status) {
+            dispatch_semaphore_signal(if_destroy_sem);
         });
-
+    dispatch_semaphore_wait(if_destroy_sem, DISPATCH_TIME_FOREVER);
     for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
         g_free(s->iov_buf[i].iov_base);
     }
-- 

I see this thread dump on deadlock:

(lldb) bt all
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff2037ebb2 libsystem_kernel.dylib`__semwait_signal +
10
    frame #1: 0x00007fff202fec1a libsystem_c.dylib`nanosleep + 196
    frame #2: 0x00007fff212c4bb8 Foundation`+[NSThread
sleepForTimeInterval:] + 170
    frame #3: 0x0000000101ebce3a
qemu-system-x86_64`-[QemuCocoaAppController
applicationWillTerminate:](self=0x00007fa9f91a1de0,
_cmd="applicationWillTerminate:",
aNotification=@"NSApplicationWillTerminateNotification") at cocoa.m:1202:5
    frame #4: 0x00007fff204a00cd
CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    frame #5: 0x00007fff2053bb1c
CoreFoundation`___CFXRegistrationPost_block_invoke + 49
    frame #6: 0x00007fff2053ba9a CoreFoundation`_CFXRegistrationPost + 454
    frame #7: 0x00007fff2047134e CoreFoundation`_CFXNotificationPost + 736
    frame #8: 0x00007fff211e1bb8 Foundation`-[NSNotificationCenter
postNotificationName:object:userInfo:] + 59
    frame #9: 0x00007fff22f585b3 AppKit`-[NSApplication terminate:] + 1377
    frame #10: 0x0000000101ebcf1f
qemu-system-x86_64`-[QemuCocoaAppController
windowShouldClose:](self=0x00007fa9f91a1de0, _cmd="windowShouldClose:",
sender=0x00007fa9f91a7810) at cocoa.m:1231:5
    frame #11: 0x00007fff230417c9 AppKit`__19-[NSWindow
__close]_block_invoke + 153
    frame #12: 0x00007fff23041723 AppKit`-[NSWindow __close] + 284
    frame #13: 0x00007fff22ed12bb AppKit`-[NSApplication(NSResponder)
sendAction:to:from:] + 288
    frame #14: 0x00007fff22ed115f AppKit`-[NSControl sendAction:to:] + 86
    frame #15: 0x00007fff22ed1091 AppKit`__26-[NSCell
_sendActionFrom:]_block_invoke + 131
    frame #16: 0x00007fff22ed0f98 AppKit`-[NSCell _sendActionFrom:] + 171
    frame #17: 0x00007fff22ed0ede AppKit`-[NSButtonCell _sendActionFrom:] +
96
    frame #18: 0x00007fff22ecdfc7 AppKit`NSControlTrackMouse + 1820
    frame #19: 0x00007fff22ecd883 AppKit`-[NSCell
trackMouse:inRect:ofView:untilMouseUp:] + 130
    frame #20: 0x00007fff22ecd74a AppKit`-[NSButtonCell
trackMouse:inRect:ofView:untilMouseUp:] + 697
    frame #21: 0x00007fff22ecca72 AppKit`-[NSControl mouseDown:] + 722
    frame #22: 0x00007fff22ecae5e AppKit`-[NSWindow(NSEventRouting)
_handleMouseDownEvent:isDelayedEvent:] + 4961
    frame #23: 0x00007fff22e3a648 AppKit`-[NSWindow(NSEventRouting)
_reallySendEvent:isDelayedEvent:] + 2594
    frame #24: 0x00007fff22e39a06 AppKit`-[NSWindow(NSEventRouting)
sendEvent:] + 347
    frame #25: 0x00007fff22e37e14 AppKit`-[NSApplication(NSEvent)
sendEvent:] + 352
    frame #26: 0x0000000101ebec29 qemu-system-x86_64`-[QemuApplication
sendEvent:](self=0x00007fa9f90374e0, _cmd="sendEvent:",
event=0x00007fa9f6ef1920) at cocoa.m:1582:9
    frame #27: 0x00007fff23110be1 AppKit`-[NSApplication _handleEvent:] + 65
    frame #28: 0x00007fff22ca0c8e AppKit`-[NSApplication run] + 623
    frame #29: 0x0000000101ebef45 qemu-system-x86_64`main(argc=3,
argv=0x00007ffeedd71a20) at cocoa.m:1947:5
    frame #30: 0x00007fff203ccf3d libdyld.dylib`start + 1
  thread #2
    frame #0: 0x00007fff2037ecde libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff203b1e49 libsystem_pthread.dylib`_pthread_cond_wait
+ 1298
    frame #2: 0x00000001026b7837
qemu-system-x86_64`qemu_futex_wait(ev=0x0000000102e88eb8, val=4294967295)
at qemu-thread-posix.c:386:9
    frame #3: 0x00000001026b77b0
qemu-system-x86_64`qemu_event_wait(ev=0x0000000102e88eb8) at
qemu-thread-posix.c:481:9
    frame #4: 0x00000001026c56be
qemu-system-x86_64`call_rcu_thread(opaque=0x0000000000000000) at
rcu.c:261:21
    frame #5: 0x00000001026b7b76
qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f9105320) at
qemu-thread-posix.c:556:9
    frame #6: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start +
224
    frame #7: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
  thread #3
    frame #0: 0x00007fff2037c2f6 libsystem_kernel.dylib`semaphore_wait_trap
+ 10
    frame #1: 0x00007fff20207c9b libdispatch.dylib`_dispatch_sema4_wait + 16
    frame #2: 0x00007fff2020816d
libdispatch.dylib`_dispatch_semaphore_wait_slow + 98
    frame #3: 0x0000000101f6ac1b
qemu-system-x86_64`vmnet_cleanup_common(nc=0x00007fa9f7019400) at
vmnet-common.m:330:5
    frame #4: 0x0000000101f5c6cd
qemu-system-x86_64`qemu_cleanup_net_client(nc=0x00007fa9f7019400) at
net.c:361:9
    frame #5: 0x0000000101f5c4cf
qemu-system-x86_64`qemu_del_net_client(nc=0x00007fa9f7019400) at
net.c:417:13
    frame #6: 0x0000000101f5e751 qemu-system-x86_64`net_cleanup at
net.c:1447:13
    frame #7: 0x000000010228f548 qemu-system-x86_64`qemu_cleanup at
runstate.c:820:5
    frame #8: 0x0000000101e9950d qemu-system-x86_64`qemu_main(argc=3,
argv=0x00007ffeedd71a20, envp=0x00007ffeedd71a40) at main.c:51:5
    frame #9: 0x0000000101ebefb4
qemu-system-x86_64`call_qemu_main(opaque=0x0000000000000000) at
cocoa.m:1897:14
    frame #10: 0x00000001026b7b76
qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f9105320) at
qemu-thread-posix.c:556:9
    frame #11: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start +
224
    frame #12: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
  thread #4
    frame #0: 0x00007fff20384e22 libsystem_kernel.dylib`__sigwait + 10
    frame #1: 0x00007fff203b1fff libsystem_pthread.dylib`sigwait + 29
    frame #2: 0x00000001026b3541
qemu-system-x86_64`sigwait_compat(opaque=0x00007fa9f6d0a3f0) at
compatfd.c:36:15
    frame #3: 0x00000001026b7b76
qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f6d09ec0) at
qemu-thread-posix.c:556:9
    frame #4: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start +
224
    frame #5: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
  thread #7
    frame #0: 0x00007fff2037e4ca libsystem_kernel.dylib`__psynch_mutexwait
+ 10
    frame #1: 0x00007fff203af2ab
libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 76
    frame #2: 0x00007fff203ad192
libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 204
    frame #3: 0x00007fff203b1ee1 libsystem_pthread.dylib`_pthread_cond_wait
+ 1450
    frame #4: 0x00000001026b6d92
qemu-system-x86_64`qemu_cond_wait_impl(cond=0x00007fa9f6c2edf0,
mutex=0x0000000102e758f0, file="../softmmu/cpus.c", line=423) at
qemu-thread-posix.c:195:11
    frame #5: 0x000000010227c716
qemu-system-x86_64`qemu_wait_io_event(cpu=0x00007fa9f949a000) at
cpus.c:423:9
    frame #6: 0x000000010239c94e
qemu-system-x86_64`mttcg_cpu_thread_fn(arg=0x00007fa9f949a000) at
tcg-accel-ops-mttcg.c:123:9
    frame #7: 0x00000001026b7b76
qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f6c2f5e0) at
qemu-thread-posix.c:556:9
    frame #8: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start +
224
    frame #9: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
  thread #8
    frame #0: 0x00007fff2037d95e libsystem_kernel.dylib`__workq_kernreturn
+ 10
    frame #1: 0x00007fff203ae4c1 libsystem_pthread.dylib`_pthread_wqthread
+ 414
    frame #2: 0x00007fff203ad42f libsystem_pthread.dylib`start_wqthread + 15
  thread #9, queue = 'org.qemu.vmnet.if_queue'
    frame #0: 0x00007fff2037e4ca libsystem_kernel.dylib`__psynch_mutexwait
+ 10
    frame #1: 0x00007fff203af2ab
libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 76
    frame #2: 0x00007fff203ad192
libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 204
    frame #3: 0x00000001026b67ea
qemu-system-x86_64`qemu_mutex_lock_impl(mutex=0x0000000102e758f0,
file="../net/vmnet-common.m", line=91) at qemu-thread-posix.c:80:11
    frame #4: 0x000000010227c9d2
qemu-system-x86_64`qemu_mutex_lock_iothread_impl(file="../net/vmnet-common.m",
line=91) at cpus.c:497:5
    frame #5: 0x0000000101f6ae9e
qemu-system-x86_64`vmnet_send(nc=0x00007fa9f7019400,
event_id=VMNET_INTERFACE_PACKETS_AVAILABLE, event=0x00007fa9f6d3b860) at
vmnet-common.m:91:5
    frame #6: 0x0000000101f6acf3
qemu-system-x86_64`__vmnet_register_event_callback_block_invoke(.block_descriptor=0x00007fa9f9034240,
event_id=VMNET_INTERFACE_PACKETS_AVAILABLE, event=0x00007fa9f6d3b860) at
vmnet-common.m:121:15
    frame #7: 0x00007fff6f385a3d
vmnet`__vmnet_interface_set_event_callback_block_invoke_3 + 195
    frame #8: 0x00007fff20207806 libdispatch.dylib`_dispatch_client_callout
+ 8
    frame #9: 0x00007fff2020a1b0
libdispatch.dylib`_dispatch_continuation_pop + 423
    frame #10: 0x00007fff2021a564 libdispatch.dylib`_dispatch_source_invoke
+ 2061
    frame #11: 0x00007fff2020d493
libdispatch.dylib`_dispatch_lane_serial_drain + 263
    frame #12: 0x00007fff2020e0ad libdispatch.dylib`_dispatch_lane_invoke +
366
    frame #13: 0x00007fff20217c0d
libdispatch.dylib`_dispatch_workloop_worker_thread + 811
    frame #14: 0x00007fff203ae45d libsystem_pthread.dylib`_pthread_wqthread
+ 314
    frame #15: 0x00007fff203ad42f libsystem_pthread.dylib`start_wqthread +
15
  thread #11, name = 'com.apple.NSEventThread'
    frame #0: 0x00007fff2037c2ba libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x00007fff2037c62c libsystem_kernel.dylib`mach_msg + 60
    frame #2: 0x00007fff204aab2f CoreFoundation`__CFRunLoopServiceMachPort
+ 316
    frame #3: 0x00007fff204a920f CoreFoundation`__CFRunLoopRun + 1328
    frame #4: 0x00007fff204a861c CoreFoundation`CFRunLoopRunSpecific + 563
    frame #5: 0x00007fff22e3623a AppKit`_NSEventThread + 124
    frame #6: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start +
224
    frame #7: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15

Though I doubt it is the cause of your deadlock. This deadlock would
> not happen frequently since vmnet_send will not be queued if the
> device is not used.
>
>
Having two-three connected nics causes deadlock almost every
time. With only one nic it happens one time out of two or three.

An interesting thing is that using qemu_send_packet() instead
of qemu_send_packet_async() fixes the problem. Hope to
start investigating this next week.

Regards,
> Akihiko Odaki
>
> >
> >
> >> Thanks,
> >> Roman
> >>
> >> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> >> > ---
> >> >  net/clients.h       |  11 ++++
> >> >  net/meson.build     |   7 +++
> >> >  net/net.c           |  10 ++++
> >> >  net/vmnet-bridged.m |  25 +++++++++
> >> >  net/vmnet-common.m  |  20 +++++++
> >> >  net/vmnet-host.c    |  24 ++++++++
> >> >  net/vmnet-shared.c  |  25 +++++++++
> >> >  net/vmnet_int.h     |  25 +++++++++
> >> >  qapi/net.json       | 133
> +++++++++++++++++++++++++++++++++++++++++++-
> >> >  9 files changed, 278 insertions(+), 2 deletions(-)
> >> >  create mode 100644 net/vmnet-bridged.m
> >> >  create mode 100644 net/vmnet-common.m
> >> >  create mode 100644 net/vmnet-host.c
> >> >  create mode 100644 net/vmnet-shared.c
> >> >  create mode 100644 net/vmnet_int.h
> >> >
> >> > diff --git a/net/net.c b/net/net.c
> >> > index f0d14dbfc1..1dbb64b935 100644
> >> > --- a/net/net.c
> >> > +++ b/net/net.c
> >> > @@ -1021,6 +1021,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 */
> >> >  };
> >> >
> >> >
> >> > @@ -1106,6 +1111,11 @@ void show_netdevs(void)
> >> >  #endif
> >> >  #ifdef CONFIG_VHOST_VDPA
> >> >          "vhost-vdpa",
> >> > +#endif
> >> > +#ifdef CONFIG_VMNET
> >> > +        "vmnet-host",
> >> > +        "vmnet-shared",
> >> > +        "vmnet-bridged",
> >> >  #endif
> >> >      };
> >> >
> >> > diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
> >> > new file mode 100644
> >> > index 0000000000..4e42a90391
> >> > --- /dev/null
> >> > +++ b/net/vmnet-bridged.m
> >> > @@ -0,0 +1,25 @@
> >> > +/*
> >> > + * vmnet-bridged.m
> >> > + *
> >> > + * 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 "qapi/qapi-types-net.h"
> >> > +#include "vmnet_int.h"
> >> > +#include "clients.h"
> >> > +#include "qemu/error-report.h"
> >> > +#include "qapi/error.h"
> >> > +
> >> > +#include <vmnet/vmnet.h>
> >> > +
> >> > +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
> >> > +                           NetClientState *peer, Error **errp)
> >> > +{
> >> > +  error_setg(errp, "vmnet-bridged is not implemented yet");
> >> > +  return -1;
> >> > +}
> >> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> >> > new file mode 100644
> >> > index 0000000000..532d152840
> >> > --- /dev/null
> >> > +++ b/net/vmnet-common.m
> >> > @@ -0,0 +1,20 @@
> >> > +/*
> >> > + * vmnet-common.m - network client wrapper for Apple vmnet.framework
> >> > + *
> >> > + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> >> > + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
> >> > +#include "vmnet_int.h"
> >> > +#include "clients.h"
> >> > +#include "qemu/error-report.h"
> >> > +#include "qapi/error.h"
> >> > +
> >> > +#include <vmnet/vmnet.h>
> >> > +
> >> > diff --git a/net/vmnet-host.c b/net/vmnet-host.c
> >> > new file mode 100644
> >> > index 0000000000..4a5ef99dc7
> >> > --- /dev/null
> >> > +++ b/net/vmnet-host.c
> >> > @@ -0,0 +1,24 @@
> >> > +/*
> >> > + * vmnet-host.c
> >> > + *
> >> > + * 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 "qapi/qapi-types-net.h"
> >> > +#include "vmnet_int.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-host is not implemented yet");
> >> > +  return -1;
> >> > +}
> >> > diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
> >> > new file mode 100644
> >> > index 0000000000..f8c4a4f3b8
> >> > --- /dev/null
> >> > +++ b/net/vmnet-shared.c
> >> > @@ -0,0 +1,25 @@
> >> > +/*
> >> > + * vmnet-shared.c
> >> > + *
> >> > + * 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 "qapi/qapi-types-net.h"
> >> > +#include "vmnet_int.h"
> >> > +#include "clients.h"
> >> > +#include "qemu/error-report.h"
> >> > +#include "qapi/error.h"
> >> > +
> >> > +#include <vmnet/vmnet.h>
> >> > +
> >> > +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
> >> > +                          NetClientState *peer, Error **errp)
> >> > +{
> >> > +  error_setg(errp, "vmnet-shared is not implemented yet");
> >> > +  return -1;
> >> > +}
> >> > diff --git a/net/vmnet_int.h b/net/vmnet_int.h
> >> > new file mode 100644
> >> > index 0000000000..c5982259a4
> >> > --- /dev/null
> >> > +++ b/net/vmnet_int.h
> >> > @@ -0,0 +1,25 @@
> >> > +/*
> >> > + * vmnet_int.h
> >> > + *
> >> > + * 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.
> >> > + *
> >> > + */
> >> > +#ifndef VMNET_INT_H
> >> > +#define VMNET_INT_H
> >> > +
> >> > +#include "qemu/osdep.h"
> >> > +#include "vmnet_int.h"
> >> > +#include "clients.h"
> >> > +
> >> > +#include <vmnet/vmnet.h>
> >> > +
> >> > +typedef struct VmnetCommonState {
> >> > +  NetClientState nc;
> >> > +
> >> > +} VmnetCommonState;
> >> > +
> >> > +
> >> > +#endif /* VMNET_INT_H */
> >> > diff --git a/qapi/net.json b/qapi/net.json
> >> > index 7fab2e7cd8..b922e2e34f 100644
> >> > --- a/qapi/net.json
> >> > +++ b/qapi/net.json
> >> > @@ -452,6 +452,120 @@
> >> >      '*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 host.
> >> > +#
> >> > +# @start-address: The starting IPv4 address to use for the interface.
> >> > +#                 Must be in the private IP range (RFC 1918). Must be
> >> > +#                 specified along with @end-address and @subnet-mask.
> >> > +#                 This address is used as the gateway address. The
> >> > +#                 subsequent address up to and including end-address
> are
> >> > +#                 placed in the DHCP pool.
> >> > +#
> >> > +# @end-address: 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 @start-address and
> >> > +#               @subnet-mask.
> >> > +#
> >> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> >> > +#               be specified along with @start-address and
> @subnet-mask.
> >> > +#
> >> > +# @isolated: Enable isolation for this interface. Interface isolation
> >> > +#            ensures that vmnet interface is not able to communicate
> >> > +#            with any other vmnet interfaces. Only communication with
> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
> >> > +#
> >> > +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
> >> > +#            network vmnet interface should be added to. If
> >> > +#            set, no DHCP service is provided for this interface and
> >> > +#            network communication is allowed only with other
> interfaces
> >> > +#            added to this network identified by the UUID. Available
> >> > +#            since macOS Big Sur 11.0.
> >> > +#
> >> > +# Since: 7.0
> >> > +##
> >> > +{ 'struct': 'NetdevVmnetHostOptions',
> >> > +  'data': {
> >> > +    '*start-address': 'str',
> >> > +    '*end-address':   'str',
> >> > +    '*subnet-mask':   'str',
> >> > +    '*isolated':      'bool',
> >> > +    '*net-uuid':      '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 communicate with the host and with
> >> > +# other shared mode interfaces on the same subnet. If no DHCP
> >> > +# settings, subnet mask and IPv6 prefix specified, the interface can
> >> > +# communicate with any of other interfaces in shared mode.
> >> > +#
> >> > +# @start-address: The starting IPv4 address to use for the interface.
> >> > +#                 Must be in the private IP range (RFC 1918). Must be
> >> > +#                 specified along with @end-address and @subnet-mask.
> >> > +#                 This address is used as the gateway address. The
> >> > +#                 subsequent address up to and including end-address
> are
> >> > +#                 placed in the DHCP pool.
> >> > +#
> >> > +# @end-address: 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 @start-address and
> @subnet-mask.
> >> > +#
> >> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
> >> > +#                be specified along with @start-address and
> @subnet-mask.
> >> > +#
> >> > +# @isolated: Enable isolation for this interface. Interface isolation
> >> > +#            ensures that vmnet interface is not able to communicate
> >> > +#            with any other vmnet interfaces. Only communication with
> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
> >> > +#
> >> > +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
> >> > +#                unique local address i.e. start with fd00::/8 and
> have
> >> > +#                length of 64.
> >> > +#
> >> > +# Since: 7.0
> >> > +##
> >> > +{ 'struct': 'NetdevVmnetSharedOptions',
> >> > +  'data': {
> >> > +    '*start-address': 'str',
> >> > +    '*end-address':   'str',
> >> > +    '*subnet-mask':   'str',
> >> > +    '*isolated':      'bool',
> >> > +    '*nat66-prefix':  '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.
> >> > +#
> >> > +# @isolated: Enable isolation for this interface. Interface isolation
> >> > +#            ensures that vmnet interface is not able to communicate
> >> > +#            with any other vmnet interfaces. Only communication with
> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
> >> > +#
> >> > +# Since: 7.0
> >> > +##
> >> > +{ 'struct': 'NetdevVmnetBridgedOptions',
> >> > +  'data': {
> >> > +    'ifname':     'str',
> >> > +    '*isolated':  'bool' },
> >> > +  'if': 'CONFIG_VMNET' }
> >> > +
> >> >  ##
> >> >  # @NetClientDriver:
> >> >  #
> >> > @@ -460,10 +574,16 @@
> >> >  # Since: 2.7
> >> >  #
> >> >  #        @vhost-vdpa since 5.1
> >> > +#        @vmnet-host since 7.0
> >> > +#        @vmnet-shared since 7.0
> >> > +#        @vmnet-bridged since 7.0
> >> >  ##
> >> >  { '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 +597,9 @@
> >> >  # Since: 1.2
> >> >  #
> >> >  #        'l2tpv3' - since 2.1
> >> > +#        'vmnet-host' - since 7.0
> >> > +#        'vmnet-shared' - since 7.0
> >> > +#        'vmnet-bridged' - since 7.0
> >> >  ##
> >> >  { 'union': 'Netdev',
> >> >    'base': { 'id': 'str', 'type': 'NetClientDriver' },
> >> > @@ -492,7 +615,13 @@
> >> >      'hubport':  'NetdevHubPortOptions',
> >> >      'netmap':   'NetdevNetmapOptions',
> >> >      'vhost-user': 'NetdevVhostUserOptions',
> >> > -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> >> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
> >> > +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
> >> > +                    'if': 'CONFIG_VMNET' },
> >> > +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
> >> > +                      'if': 'CONFIG_VMNET' },
> >> > +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
> >> > +                       'if': 'CONFIG_VMNET' } } }
> >> >
> >> >  ##
> >> >  # @RxState:
> >> > --
> >> > 2.23.0
> >> >
> >
> >
> >
> > --
> > Best Regards,
> >
> > Vladislav Yaroshchuk
>


-- 
Best Regards,

Vladislav Yaroshchuk

[-- Attachment #2: Type: text/html, Size: 36627 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-28 14:29         ` Vladislav Yaroshchuk
@ 2022-01-28 23:00           ` Akihiko Odaki
  0 siblings, 0 replies; 35+ messages in thread
From: Akihiko Odaki @ 2022-01-28 23:00 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: Peter Maydell, Gerd Hoffmann, Alex Bennée, Jason Wang,
	Christian Schoenebeck, phillip.ennen, qemu-devel,
	Cameron Esfahani, Markus Armbruster, Roman Bolshakov,
	Alexander Graf, Phillip Tennen, Howard Spoelstra,
	Roman Bolshakov, Alessio Dionisi, Eric Blake,
	Philippe Mathieu-Daudé

On Fri, Jan 28, 2022 at 11:30 PM Vladislav Yaroshchuk
<yaroshchuk2000@gmail.com> wrote:
>
>
>
> пт, 21 янв. 2022 г. в 16:03, Akihiko Odaki <akihiko.odaki@gmail.com>:
>>
>> On Fri, Jan 21, 2022 at 9:19 PM Vladislav Yaroshchuk
>> <yaroshchuk2000@gmail.com> wrote:
>> >
>> >
>> > чт, 20 янв. 2022 г. в 11:32, Roman Bolshakov <roman@roolebo.dev>:
>> >>
>> >> On Thu, Jan 13, 2022 at 08:22:14PM +0300, Vladislav Yaroshchuk wrote:
>> >> > Create separate netdevs for each vmnet operating mode:
>> >> > - vmnet-host
>> >> > - vmnet-shared
>> >> > - vmnet-bridged
>> >> >
>> >>
>> >> Sure I'm late to the party but what if we add only one backend - vmnet
>> >> with default mode set to shared and all parameters are added there?
>> >>
>> >> The CLI would look more reasonable for the most typical use case:
>> >>  -netdev vmnet,id=if1 -device virtio-net,netdev=if1
>> >>
>> >> That would remove duplication of options in QAPI schema (e.g. isolated
>> >> is available in all backends now, altough I'm not sure if it makes sense
>> >> for bridged mode):
>> >>
>> >>  -netdev vmnet,id=if1,isolated=yes
>> >>
>> >> start-address, end-address and subnet-mask are also used by both shared
>> >> and host modes.
>> >>
>> >> Bridged netdev would lool like:
>> >>
>> >>  -netdev vmnet,id=if1,mode=bridged,ifname=en1
>> >>
>> >> Checksum offloading also seems to be available for all backends from
>> >> Monterey.
>> >>
>> >> The approach might simplify integration of the changes to libvirt and
>> >> discovery of upcoming vmnet features via qapi.
>> >>
>> >
>> > I can rewrite this if it sounds more suitable to use
>> > single `vmnet` netdev instead of three different ones.
>> > We can discuss this with Markus as a QAPI reviewer.
>> > Markus, what is your opinion about single netdev?
>> >
>> > P.S. Seems we have enough time for discussion:
>> > I started fixing memory leaks found by Akihiko and
>> > met a strange deadlock on QEMU shutdown on
>> > `qemu_mutex_lock_iothread()` during careful
>> > interface destruction with added semaphore.
>> > Need to go deeper to understand what's the
>> > problem, it will take some time.
>> >
>> > Mentioned part of Akihiko's review:
>> > https://patchew.org/QEMU/20220113172219.66372-1-yaroshchuk2000@gmail.com/20220113172219.66372-4-yaroshchuk2000@gmail.com/
>>
>
> > Actually I thought it would be tricky to implement.
>
> You mean single netdev type?

I meant the semaphore causing the deadlock, but I also think
implementing the single netdev type would have a difficulty because it
would need a redundant encapsulation of the option type as Phillip
Tennen's original patch series did.

>
>> Actually I thought it would be tricky to implement. A deadlock will
>> occur in a simple implementation if vmnet_send is already queued but
>> not executed yet when destructing:
>> - vmnet_send tries to lock the iothread and waits for the destructor to unlock.
>> - vmnet_stop_interface waits for vmnet_send finishing.
>>
>
> Sounds like that's what happens actually.
> With added semaphore:
> --- a/net/vmnet-common.m
> +++ b/net/vmnet-common.m
> @@ -320,13 +320,14 @@ void vmnet_cleanup_common(NetClientState *nc)
>          "org.qemu.vmnet.destroy",
>          DISPATCH_QUEUE_SERIAL
>      );
> -
> +    dispatch_semaphore_t if_destroy_sem = dispatch_semaphore_create(0);
>      vmnet_stop_interface(
>          s->vmnet_if,
>          if_destroy_q,
>          ^(vmnet_return_t status) {
> +            dispatch_semaphore_signal(if_destroy_sem);
>          });
> -
> +    dispatch_semaphore_wait(if_destroy_sem, DISPATCH_TIME_FOREVER);
>      for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
>          g_free(s->iov_buf[i].iov_base);
>      }
> --
>
> I see this thread dump on deadlock:
>
> (lldb) bt all
> * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
>   * frame #0: 0x00007fff2037ebb2 libsystem_kernel.dylib`__semwait_signal + 10
>     frame #1: 0x00007fff202fec1a libsystem_c.dylib`nanosleep + 196
>     frame #2: 0x00007fff212c4bb8 Foundation`+[NSThread sleepForTimeInterval:] + 170
>     frame #3: 0x0000000101ebce3a qemu-system-x86_64`-[QemuCocoaAppController applicationWillTerminate:](self=0x00007fa9f91a1de0, _cmd="applicationWillTerminate:", aNotification=@"NSApplicationWillTerminateNotification") at cocoa.m:1202:5
>     frame #4: 0x00007fff204a00cd CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
>     frame #5: 0x00007fff2053bb1c CoreFoundation`___CFXRegistrationPost_block_invoke + 49
>     frame #6: 0x00007fff2053ba9a CoreFoundation`_CFXRegistrationPost + 454
>     frame #7: 0x00007fff2047134e CoreFoundation`_CFXNotificationPost + 736
>     frame #8: 0x00007fff211e1bb8 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 59
>     frame #9: 0x00007fff22f585b3 AppKit`-[NSApplication terminate:] + 1377
>     frame #10: 0x0000000101ebcf1f qemu-system-x86_64`-[QemuCocoaAppController windowShouldClose:](self=0x00007fa9f91a1de0, _cmd="windowShouldClose:", sender=0x00007fa9f91a7810) at cocoa.m:1231:5
>     frame #11: 0x00007fff230417c9 AppKit`__19-[NSWindow __close]_block_invoke + 153
>     frame #12: 0x00007fff23041723 AppKit`-[NSWindow __close] + 284
>     frame #13: 0x00007fff22ed12bb AppKit`-[NSApplication(NSResponder) sendAction:to:from:] + 288
>     frame #14: 0x00007fff22ed115f AppKit`-[NSControl sendAction:to:] + 86
>     frame #15: 0x00007fff22ed1091 AppKit`__26-[NSCell _sendActionFrom:]_block_invoke + 131
>     frame #16: 0x00007fff22ed0f98 AppKit`-[NSCell _sendActionFrom:] + 171
>     frame #17: 0x00007fff22ed0ede AppKit`-[NSButtonCell _sendActionFrom:] + 96
>     frame #18: 0x00007fff22ecdfc7 AppKit`NSControlTrackMouse + 1820
>     frame #19: 0x00007fff22ecd883 AppKit`-[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 130
>     frame #20: 0x00007fff22ecd74a AppKit`-[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 697
>     frame #21: 0x00007fff22ecca72 AppKit`-[NSControl mouseDown:] + 722
>     frame #22: 0x00007fff22ecae5e AppKit`-[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 4961
>     frame #23: 0x00007fff22e3a648 AppKit`-[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 2594
>     frame #24: 0x00007fff22e39a06 AppKit`-[NSWindow(NSEventRouting) sendEvent:] + 347
>     frame #25: 0x00007fff22e37e14 AppKit`-[NSApplication(NSEvent) sendEvent:] + 352
>     frame #26: 0x0000000101ebec29 qemu-system-x86_64`-[QemuApplication sendEvent:](self=0x00007fa9f90374e0, _cmd="sendEvent:", event=0x00007fa9f6ef1920) at cocoa.m:1582:9
>     frame #27: 0x00007fff23110be1 AppKit`-[NSApplication _handleEvent:] + 65
>     frame #28: 0x00007fff22ca0c8e AppKit`-[NSApplication run] + 623
>     frame #29: 0x0000000101ebef45 qemu-system-x86_64`main(argc=3, argv=0x00007ffeedd71a20) at cocoa.m:1947:5
>     frame #30: 0x00007fff203ccf3d libdyld.dylib`start + 1
>   thread #2
>     frame #0: 0x00007fff2037ecde libsystem_kernel.dylib`__psynch_cvwait + 10
>     frame #1: 0x00007fff203b1e49 libsystem_pthread.dylib`_pthread_cond_wait + 1298
>     frame #2: 0x00000001026b7837 qemu-system-x86_64`qemu_futex_wait(ev=0x0000000102e88eb8, val=4294967295) at qemu-thread-posix.c:386:9
>     frame #3: 0x00000001026b77b0 qemu-system-x86_64`qemu_event_wait(ev=0x0000000102e88eb8) at qemu-thread-posix.c:481:9
>     frame #4: 0x00000001026c56be qemu-system-x86_64`call_rcu_thread(opaque=0x0000000000000000) at rcu.c:261:21
>     frame #5: 0x00000001026b7b76 qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f9105320) at qemu-thread-posix.c:556:9
>     frame #6: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start + 224
>     frame #7: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
>   thread #3
>     frame #0: 0x00007fff2037c2f6 libsystem_kernel.dylib`semaphore_wait_trap + 10
>     frame #1: 0x00007fff20207c9b libdispatch.dylib`_dispatch_sema4_wait + 16
>     frame #2: 0x00007fff2020816d libdispatch.dylib`_dispatch_semaphore_wait_slow + 98
>     frame #3: 0x0000000101f6ac1b qemu-system-x86_64`vmnet_cleanup_common(nc=0x00007fa9f7019400) at vmnet-common.m:330:5
>     frame #4: 0x0000000101f5c6cd qemu-system-x86_64`qemu_cleanup_net_client(nc=0x00007fa9f7019400) at net.c:361:9
>     frame #5: 0x0000000101f5c4cf qemu-system-x86_64`qemu_del_net_client(nc=0x00007fa9f7019400) at net.c:417:13
>     frame #6: 0x0000000101f5e751 qemu-system-x86_64`net_cleanup at net.c:1447:13
>     frame #7: 0x000000010228f548 qemu-system-x86_64`qemu_cleanup at runstate.c:820:5
>     frame #8: 0x0000000101e9950d qemu-system-x86_64`qemu_main(argc=3, argv=0x00007ffeedd71a20, envp=0x00007ffeedd71a40) at main.c:51:5
>     frame #9: 0x0000000101ebefb4 qemu-system-x86_64`call_qemu_main(opaque=0x0000000000000000) at cocoa.m:1897:14
>     frame #10: 0x00000001026b7b76 qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f9105320) at qemu-thread-posix.c:556:9
>     frame #11: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start + 224
>     frame #12: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
>   thread #4
>     frame #0: 0x00007fff20384e22 libsystem_kernel.dylib`__sigwait + 10
>     frame #1: 0x00007fff203b1fff libsystem_pthread.dylib`sigwait + 29
>     frame #2: 0x00000001026b3541 qemu-system-x86_64`sigwait_compat(opaque=0x00007fa9f6d0a3f0) at compatfd.c:36:15
>     frame #3: 0x00000001026b7b76 qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f6d09ec0) at qemu-thread-posix.c:556:9
>     frame #4: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start + 224
>     frame #5: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
>   thread #7
>     frame #0: 0x00007fff2037e4ca libsystem_kernel.dylib`__psynch_mutexwait + 10
>     frame #1: 0x00007fff203af2ab libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 76
>     frame #2: 0x00007fff203ad192 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 204
>     frame #3: 0x00007fff203b1ee1 libsystem_pthread.dylib`_pthread_cond_wait + 1450
>     frame #4: 0x00000001026b6d92 qemu-system-x86_64`qemu_cond_wait_impl(cond=0x00007fa9f6c2edf0, mutex=0x0000000102e758f0, file="../softmmu/cpus.c", line=423) at qemu-thread-posix.c:195:11
>     frame #5: 0x000000010227c716 qemu-system-x86_64`qemu_wait_io_event(cpu=0x00007fa9f949a000) at cpus.c:423:9
>     frame #6: 0x000000010239c94e qemu-system-x86_64`mttcg_cpu_thread_fn(arg=0x00007fa9f949a000) at tcg-accel-ops-mttcg.c:123:9
>     frame #7: 0x00000001026b7b76 qemu-system-x86_64`qemu_thread_start(args=0x00007fa9f6c2f5e0) at qemu-thread-posix.c:556:9
>     frame #8: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start + 224
>     frame #9: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
>   thread #8
>     frame #0: 0x00007fff2037d95e libsystem_kernel.dylib`__workq_kernreturn + 10
>     frame #1: 0x00007fff203ae4c1 libsystem_pthread.dylib`_pthread_wqthread + 414
>     frame #2: 0x00007fff203ad42f libsystem_pthread.dylib`start_wqthread + 15
>   thread #9, queue = 'org.qemu.vmnet.if_queue'
>     frame #0: 0x00007fff2037e4ca libsystem_kernel.dylib`__psynch_mutexwait + 10
>     frame #1: 0x00007fff203af2ab libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 76
>     frame #2: 0x00007fff203ad192 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 204
>     frame #3: 0x00000001026b67ea qemu-system-x86_64`qemu_mutex_lock_impl(mutex=0x0000000102e758f0, file="../net/vmnet-common.m", line=91) at qemu-thread-posix.c:80:11
>     frame #4: 0x000000010227c9d2 qemu-system-x86_64`qemu_mutex_lock_iothread_impl(file="../net/vmnet-common.m", line=91) at cpus.c:497:5
>     frame #5: 0x0000000101f6ae9e qemu-system-x86_64`vmnet_send(nc=0x00007fa9f7019400, event_id=VMNET_INTERFACE_PACKETS_AVAILABLE, event=0x00007fa9f6d3b860) at vmnet-common.m:91:5
>     frame #6: 0x0000000101f6acf3 qemu-system-x86_64`__vmnet_register_event_callback_block_invoke(.block_descriptor=0x00007fa9f9034240, event_id=VMNET_INTERFACE_PACKETS_AVAILABLE, event=0x00007fa9f6d3b860) at vmnet-common.m:121:15
>     frame #7: 0x00007fff6f385a3d vmnet`__vmnet_interface_set_event_callback_block_invoke_3 + 195
>     frame #8: 0x00007fff20207806 libdispatch.dylib`_dispatch_client_callout + 8
>     frame #9: 0x00007fff2020a1b0 libdispatch.dylib`_dispatch_continuation_pop + 423
>     frame #10: 0x00007fff2021a564 libdispatch.dylib`_dispatch_source_invoke + 2061
>     frame #11: 0x00007fff2020d493 libdispatch.dylib`_dispatch_lane_serial_drain + 263
>     frame #12: 0x00007fff2020e0ad libdispatch.dylib`_dispatch_lane_invoke + 366
>     frame #13: 0x00007fff20217c0d libdispatch.dylib`_dispatch_workloop_worker_thread + 811
>     frame #14: 0x00007fff203ae45d libsystem_pthread.dylib`_pthread_wqthread + 314
>     frame #15: 0x00007fff203ad42f libsystem_pthread.dylib`start_wqthread + 15
>   thread #11, name = 'com.apple.NSEventThread'
>     frame #0: 0x00007fff2037c2ba libsystem_kernel.dylib`mach_msg_trap + 10
>     frame #1: 0x00007fff2037c62c libsystem_kernel.dylib`mach_msg + 60
>     frame #2: 0x00007fff204aab2f CoreFoundation`__CFRunLoopServiceMachPort + 316
>     frame #3: 0x00007fff204a920f CoreFoundation`__CFRunLoopRun + 1328
>     frame #4: 0x00007fff204a861c CoreFoundation`CFRunLoopRunSpecific + 563
>     frame #5: 0x00007fff22e3623a AppKit`_NSEventThread + 124
>     frame #6: 0x00007fff203b18fc libsystem_pthread.dylib`_pthread_start + 224
>     frame #7: 0x00007fff203ad443 libsystem_pthread.dylib`thread_start + 15
>
>> Though I doubt it is the cause of your deadlock. This deadlock would
>> not happen frequently since vmnet_send will not be queued if the
>> device is not used.
>>
>
> Having two-three connected nics causes deadlock almost every
> time. With only one nic it happens one time out of two or three.
>
> An interesting thing is that using qemu_send_packet() instead
> of qemu_send_packet_async() fixes the problem. Hope to
> start investigating this next week.

A proper fix is to add a flag to tell if it is being destroyed and
code to check it and then lock iothread in a critical section.

Looking at qemu_send_packet_async, I found some other problems.
send_enabled is accessed by both a dispatch queue thread and an
iothread but not protected for multi-thread use.
Another problem is that VMNET_INTERFACE_PACKETS_AVAILABLE is silently
ignored when send_enabled is not set. It should call vmnet_read after
setting send_enabled.
Finally, vmnet_send clamps pkt_cnt, but the remaining available
packets should also be read.

Regards,
Akihiko Odaki

>
>> Regards,
>> Akihiko Odaki
>>
>> >
>> >
>> >> Thanks,
>> >> Roman
>> >>
>> >> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
>> >> > ---
>> >> >  net/clients.h       |  11 ++++
>> >> >  net/meson.build     |   7 +++
>> >> >  net/net.c           |  10 ++++
>> >> >  net/vmnet-bridged.m |  25 +++++++++
>> >> >  net/vmnet-common.m  |  20 +++++++
>> >> >  net/vmnet-host.c    |  24 ++++++++
>> >> >  net/vmnet-shared.c  |  25 +++++++++
>> >> >  net/vmnet_int.h     |  25 +++++++++
>> >> >  qapi/net.json       | 133 +++++++++++++++++++++++++++++++++++++++++++-
>> >> >  9 files changed, 278 insertions(+), 2 deletions(-)
>> >> >  create mode 100644 net/vmnet-bridged.m
>> >> >  create mode 100644 net/vmnet-common.m
>> >> >  create mode 100644 net/vmnet-host.c
>> >> >  create mode 100644 net/vmnet-shared.c
>> >> >  create mode 100644 net/vmnet_int.h
>> >> >
>> >> > diff --git a/net/net.c b/net/net.c
>> >> > index f0d14dbfc1..1dbb64b935 100644
>> >> > --- a/net/net.c
>> >> > +++ b/net/net.c
>> >> > @@ -1021,6 +1021,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 */
>> >> >  };
>> >> >
>> >> >
>> >> > @@ -1106,6 +1111,11 @@ void show_netdevs(void)
>> >> >  #endif
>> >> >  #ifdef CONFIG_VHOST_VDPA
>> >> >          "vhost-vdpa",
>> >> > +#endif
>> >> > +#ifdef CONFIG_VMNET
>> >> > +        "vmnet-host",
>> >> > +        "vmnet-shared",
>> >> > +        "vmnet-bridged",
>> >> >  #endif
>> >> >      };
>> >> >
>> >> > diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
>> >> > new file mode 100644
>> >> > index 0000000000..4e42a90391
>> >> > --- /dev/null
>> >> > +++ b/net/vmnet-bridged.m
>> >> > @@ -0,0 +1,25 @@
>> >> > +/*
>> >> > + * vmnet-bridged.m
>> >> > + *
>> >> > + * 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 "qapi/qapi-types-net.h"
>> >> > +#include "vmnet_int.h"
>> >> > +#include "clients.h"
>> >> > +#include "qemu/error-report.h"
>> >> > +#include "qapi/error.h"
>> >> > +
>> >> > +#include <vmnet/vmnet.h>
>> >> > +
>> >> > +int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
>> >> > +                           NetClientState *peer, Error **errp)
>> >> > +{
>> >> > +  error_setg(errp, "vmnet-bridged is not implemented yet");
>> >> > +  return -1;
>> >> > +}
>> >> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
>> >> > new file mode 100644
>> >> > index 0000000000..532d152840
>> >> > --- /dev/null
>> >> > +++ b/net/vmnet-common.m
>> >> > @@ -0,0 +1,20 @@
>> >> > +/*
>> >> > + * vmnet-common.m - network client wrapper for Apple vmnet.framework
>> >> > + *
>> >> > + * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
>> >> > + * Copyright(c) 2021 Phillip Tennen <phillip@axleos.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 "qapi/qapi-types-net.h"
>> >> > +#include "vmnet_int.h"
>> >> > +#include "clients.h"
>> >> > +#include "qemu/error-report.h"
>> >> > +#include "qapi/error.h"
>> >> > +
>> >> > +#include <vmnet/vmnet.h>
>> >> > +
>> >> > diff --git a/net/vmnet-host.c b/net/vmnet-host.c
>> >> > new file mode 100644
>> >> > index 0000000000..4a5ef99dc7
>> >> > --- /dev/null
>> >> > +++ b/net/vmnet-host.c
>> >> > @@ -0,0 +1,24 @@
>> >> > +/*
>> >> > + * vmnet-host.c
>> >> > + *
>> >> > + * 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 "qapi/qapi-types-net.h"
>> >> > +#include "vmnet_int.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-host is not implemented yet");
>> >> > +  return -1;
>> >> > +}
>> >> > diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
>> >> > new file mode 100644
>> >> > index 0000000000..f8c4a4f3b8
>> >> > --- /dev/null
>> >> > +++ b/net/vmnet-shared.c
>> >> > @@ -0,0 +1,25 @@
>> >> > +/*
>> >> > + * vmnet-shared.c
>> >> > + *
>> >> > + * 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 "qapi/qapi-types-net.h"
>> >> > +#include "vmnet_int.h"
>> >> > +#include "clients.h"
>> >> > +#include "qemu/error-report.h"
>> >> > +#include "qapi/error.h"
>> >> > +
>> >> > +#include <vmnet/vmnet.h>
>> >> > +
>> >> > +int net_init_vmnet_shared(const Netdev *netdev, const char *name,
>> >> > +                          NetClientState *peer, Error **errp)
>> >> > +{
>> >> > +  error_setg(errp, "vmnet-shared is not implemented yet");
>> >> > +  return -1;
>> >> > +}
>> >> > diff --git a/net/vmnet_int.h b/net/vmnet_int.h
>> >> > new file mode 100644
>> >> > index 0000000000..c5982259a4
>> >> > --- /dev/null
>> >> > +++ b/net/vmnet_int.h
>> >> > @@ -0,0 +1,25 @@
>> >> > +/*
>> >> > + * vmnet_int.h
>> >> > + *
>> >> > + * 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.
>> >> > + *
>> >> > + */
>> >> > +#ifndef VMNET_INT_H
>> >> > +#define VMNET_INT_H
>> >> > +
>> >> > +#include "qemu/osdep.h"
>> >> > +#include "vmnet_int.h"
>> >> > +#include "clients.h"
>> >> > +
>> >> > +#include <vmnet/vmnet.h>
>> >> > +
>> >> > +typedef struct VmnetCommonState {
>> >> > +  NetClientState nc;
>> >> > +
>> >> > +} VmnetCommonState;
>> >> > +
>> >> > +
>> >> > +#endif /* VMNET_INT_H */
>> >> > diff --git a/qapi/net.json b/qapi/net.json
>> >> > index 7fab2e7cd8..b922e2e34f 100644
>> >> > --- a/qapi/net.json
>> >> > +++ b/qapi/net.json
>> >> > @@ -452,6 +452,120 @@
>> >> >      '*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 host.
>> >> > +#
>> >> > +# @start-address: The starting IPv4 address to use for the interface.
>> >> > +#                 Must be in the private IP range (RFC 1918). Must be
>> >> > +#                 specified along with @end-address and @subnet-mask.
>> >> > +#                 This address is used as the gateway address. The
>> >> > +#                 subsequent address up to and including end-address are
>> >> > +#                 placed in the DHCP pool.
>> >> > +#
>> >> > +# @end-address: 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 @start-address and
>> >> > +#               @subnet-mask.
>> >> > +#
>> >> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
>> >> > +#               be specified along with @start-address and @subnet-mask.
>> >> > +#
>> >> > +# @isolated: Enable isolation for this interface. Interface isolation
>> >> > +#            ensures that vmnet interface is not able to communicate
>> >> > +#            with any other vmnet interfaces. Only communication with
>> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
>> >> > +#
>> >> > +# @net-uuid: The identifier (UUID) to uniquely identify the isolated
>> >> > +#            network vmnet interface should be added to. If
>> >> > +#            set, no DHCP service is provided for this interface and
>> >> > +#            network communication is allowed only with other interfaces
>> >> > +#            added to this network identified by the UUID. Available
>> >> > +#            since macOS Big Sur 11.0.
>> >> > +#
>> >> > +# Since: 7.0
>> >> > +##
>> >> > +{ 'struct': 'NetdevVmnetHostOptions',
>> >> > +  'data': {
>> >> > +    '*start-address': 'str',
>> >> > +    '*end-address':   'str',
>> >> > +    '*subnet-mask':   'str',
>> >> > +    '*isolated':      'bool',
>> >> > +    '*net-uuid':      '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 communicate with the host and with
>> >> > +# other shared mode interfaces on the same subnet. If no DHCP
>> >> > +# settings, subnet mask and IPv6 prefix specified, the interface can
>> >> > +# communicate with any of other interfaces in shared mode.
>> >> > +#
>> >> > +# @start-address: The starting IPv4 address to use for the interface.
>> >> > +#                 Must be in the private IP range (RFC 1918). Must be
>> >> > +#                 specified along with @end-address and @subnet-mask.
>> >> > +#                 This address is used as the gateway address. The
>> >> > +#                 subsequent address up to and including end-address are
>> >> > +#                 placed in the DHCP pool.
>> >> > +#
>> >> > +# @end-address: 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 @start-address and @subnet-mask.
>> >> > +#
>> >> > +# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
>> >> > +#                be specified along with @start-address and @subnet-mask.
>> >> > +#
>> >> > +# @isolated: Enable isolation for this interface. Interface isolation
>> >> > +#            ensures that vmnet interface is not able to communicate
>> >> > +#            with any other vmnet interfaces. Only communication with
>> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
>> >> > +#
>> >> > +# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
>> >> > +#                unique local address i.e. start with fd00::/8 and have
>> >> > +#                length of 64.
>> >> > +#
>> >> > +# Since: 7.0
>> >> > +##
>> >> > +{ 'struct': 'NetdevVmnetSharedOptions',
>> >> > +  'data': {
>> >> > +    '*start-address': 'str',
>> >> > +    '*end-address':   'str',
>> >> > +    '*subnet-mask':   'str',
>> >> > +    '*isolated':      'bool',
>> >> > +    '*nat66-prefix':  '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.
>> >> > +#
>> >> > +# @isolated: Enable isolation for this interface. Interface isolation
>> >> > +#            ensures that vmnet interface is not able to communicate
>> >> > +#            with any other vmnet interfaces. Only communication with
>> >> > +#            host is allowed. Available since macOS Big Sur 11.0.
>> >> > +#
>> >> > +# Since: 7.0
>> >> > +##
>> >> > +{ 'struct': 'NetdevVmnetBridgedOptions',
>> >> > +  'data': {
>> >> > +    'ifname':     'str',
>> >> > +    '*isolated':  'bool' },
>> >> > +  'if': 'CONFIG_VMNET' }
>> >> > +
>> >> >  ##
>> >> >  # @NetClientDriver:
>> >> >  #
>> >> > @@ -460,10 +574,16 @@
>> >> >  # Since: 2.7
>> >> >  #
>> >> >  #        @vhost-vdpa since 5.1
>> >> > +#        @vmnet-host since 7.0
>> >> > +#        @vmnet-shared since 7.0
>> >> > +#        @vmnet-bridged since 7.0
>> >> >  ##
>> >> >  { '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 +597,9 @@
>> >> >  # Since: 1.2
>> >> >  #
>> >> >  #        'l2tpv3' - since 2.1
>> >> > +#        'vmnet-host' - since 7.0
>> >> > +#        'vmnet-shared' - since 7.0
>> >> > +#        'vmnet-bridged' - since 7.0
>> >> >  ##
>> >> >  { 'union': 'Netdev',
>> >> >    'base': { 'id': 'str', 'type': 'NetClientDriver' },
>> >> > @@ -492,7 +615,13 @@
>> >> >      'hubport':  'NetdevHubPortOptions',
>> >> >      'netmap':   'NetdevNetmapOptions',
>> >> >      'vhost-user': 'NetdevVhostUserOptions',
>> >> > -    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
>> >> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions',
>> >> > +    'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
>> >> > +                    'if': 'CONFIG_VMNET' },
>> >> > +    'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
>> >> > +                      'if': 'CONFIG_VMNET' },
>> >> > +    'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
>> >> > +                       'if': 'CONFIG_VMNET' } } }
>> >> >
>> >> >  ##
>> >> >  # @RxState:
>> >> > --
>> >> > 2.23.0
>> >> >
>> >
>> >
>> >
>> > --
>> > Best Regards,
>> >
>> > Vladislav Yaroshchuk
>
>
>
> --
> Best Regards,
>
> Vladislav Yaroshchuk


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net
  2022-01-25  4:14             ` Akihiko Odaki
  2022-01-25 10:32               ` Peter Maydell
@ 2022-01-29 21:03               ` Roman Bolshakov
  1 sibling, 0 replies; 35+ messages in thread
From: Roman Bolshakov @ 2022-01-29 21:03 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Peter Maydell, Philippe Mathieu-Daudé,
	Vladislav Yaroshchuk, phillip.ennen, Jason Wang,
	Christian Schoenebeck, qemu Developers, Cameron Esfahani,
	Markus Armbruster, Roman Bolshakov, Alexander Graf,
	Gerd Hoffmann, Howard Spoelstra, Alessio Dionisi,
	Alex Bennée, Eric Blake, Phillip Tennen

On Tue, Jan 25, 2022 at 01:14:27PM +0900, Akihiko Odaki wrote:
> On Tue, Jan 25, 2022 at 8:00 AM Roman Bolshakov <roman@roolebo.dev> wrote:
> >
> > On Mon, Jan 24, 2022 at 08:14:31PM +0000, Peter Maydell wrote:
> > > On Mon, 24 Jan 2022 at 17:49, Roman Bolshakov <roman@roolebo.dev> wrote:
> > > > I'm not sure why blocks are Objective-C specific. All the data I have
> > > > shows the opposite [3][4][5]. They're just extensively used in Apple APIs.
> > >
> > > This is true, but for the purposes of our build machinery it is
> > > simpler to have three types of source files that it deals
> > > with (C, C++, ObjC) rather than four (C, C++, ObjC, C-that-uses-blocks).
> > > So unless there's a clear benefit from adding the extra category
> > > I think we should do the simple thing and keep these files named
> > > with a ".m" extension.
> > >
> >
> > Fine by me as long as majority finds it's simpler :) Perhaps it's just a
> > matter of personal preference.
> >
> > I've used to the fact that platform-specific code uses platform-specific
> > extensions or some sort of weird "GCC attributes". Therefore C with an
> > extension is easier to reason for me than Objective-C with ARC and other
> > kinds of implicit behaviour without an actual Objective-C code.
> >
> 
> Being technically pedantic, actually this vmnet implementation uses
> Objective-C and there is a file with .c which uses blocks.
> If a file is named .m, dispatch_retain(o) will be redefined as [o
> retain], and effectively makes it Objective-C code. Therefore, vmnet
> involves Objective-C as long as its files are named .m. It will be C
> with blocks if they are named .c.
> Speaking of use of blocks, actually audio/coreaudio.c involves blocks
> in header files; Core Audio has functions which accept blocks.
> 

Right, dispatch_retain()/dispatch_release() is just one example of the
implicit behaviour I'm talking about.

> I'm neutral about the decision.

> I think QEMU should avoid using Objective-C code except for
> interactions with Apple's APIs, and .c is superior in terms of that as
> it would prevent accidental introduction of Objective-C code.

That was exactly my point :)

> On the other hand, naming them .m will allow the
> introduction of Automatic Reference Counting to manage dispatch queue
> objects.

As of now ARC doesn't work automatically for .m files in QEMU. It
happens because QEMU doesn't enable it via -fobjc-arc.

If you try to enable it, Cocoa UI won't compile at all because of many
errors like this one and similar ones:

../ui/cocoa.m:1186:12: error: ARC forbids explicit message send of
'dealloc'
    [super dealloc];
         ~~~~~ ^

> In fact, I have found a few memory leaks in vmnet in the last
> review and ui/cocoa.m has a suspicious construction of the object
> management (Particularly it has asynchronous dispatches wrapped with
> NSAutoreleasePool, which does not make sense).

> Introduction of Automatic Reference Counting would greatly help
> addressing those issues, but that would require significant rewriting
> of ui/cocoa.m.

Agreed.

Thanks,
Roman

P.S. I still think that given the mentioned facts and implicitness
introduced by Objective-C it would be more natural to have C code in
macOS-related device backends like vmnet and coreaudio unless
Objective-C is essential and required (like in UI code).

> Personally I'm concerned with ui/cocoa.m and do want to do that
> rewriting, but I'm being busy so it would not happen anytime soon.
> 
> Regards,
> Akihiko Odaki


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2022-01-29 21:06 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-13 17:22 [PATCH v13 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
2022-01-13 17:22 ` [PATCH v13 1/7] net/vmnet: add vmnet dependency and customizable option Vladislav Yaroshchuk
2022-01-20  7:14   ` Roman Bolshakov
2022-01-21 11:58     ` Vladislav Yaroshchuk
2022-01-13 17:22 ` [PATCH v13 2/7] net/vmnet: add vmnet backends to qapi/net Vladislav Yaroshchuk
2022-01-14  8:43   ` Akihiko Odaki
2022-01-15 13:00     ` Vladislav Yaroshchuk
2022-01-18 15:00   ` Markus Armbruster
2022-01-18 16:16     ` Vladislav Yaroshchuk
2022-01-18 16:26       ` Markus Armbruster
2022-01-18 16:46         ` Vladislav Yaroshchuk
2022-01-20  8:32   ` Roman Bolshakov
2022-01-21 12:19     ` Vladislav Yaroshchuk
2022-01-21 13:03       ` Akihiko Odaki
2022-01-28 14:29         ` Vladislav Yaroshchuk
2022-01-28 23:00           ` Akihiko Odaki
2022-01-24  9:56   ` Roman Bolshakov
2022-01-24 11:27     ` Christian Schoenebeck
2022-01-24 17:49       ` Roman Bolshakov
2022-01-24 20:00         ` Christian Schoenebeck
2022-01-24 20:14         ` Peter Maydell
2022-01-24 23:00           ` Roman Bolshakov
2022-01-25  4:14             ` Akihiko Odaki
2022-01-25 10:32               ` Peter Maydell
2022-01-25 11:08                 ` Akihiko Odaki
2022-01-25 17:30                   ` Christian Schoenebeck
2022-01-29 21:03               ` Roman Bolshakov
2022-01-13 17:22 ` [PATCH v13 3/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
2022-01-14  8:43   ` Akihiko Odaki
2022-01-13 17:22 ` [PATCH v13 4/7] net/vmnet: implement host mode (vmnet-host) Vladislav Yaroshchuk
2022-01-13 17:22 ` [PATCH v13 5/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
2022-01-14  8:43   ` Akihiko Odaki
2022-01-13 17:22 ` [PATCH v13 6/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
2022-01-14  8:43   ` Akihiko Odaki
2022-01-13 17:22 ` [PATCH v13 7/7] net/vmnet: update MAINTAINERS list Vladislav Yaroshchuk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.