All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Add vmnet.framework based network backend
@ 2021-06-17 14:32 Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 1/7] net/vmnet: dependencies setup, initial preparations Vladislav Yaroshchuk
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

macOS provides networking API for VMs called vmnet.framework.
I tried to add it as a network backend. All three modes are supported:

-shared:
  allows the guest to comminicate with other guests in shared mode and
  also with external network (Internet) via NAT

-host:
  allows the guest to communicate with other guests in host mode

-bridged:
  bridges the guest with a physical network interface

Separate netdev for each vmnet mode was created because they use quite
different settings, especially since macOS 11.0 when vmnet.framework
gets a lot of updates.

Not sure that I use qemu_mutex_lock_iothread() and
qemu_mutex_unlock_iothread() in correct way while sending packet
from vmnet interface to QEMU. I'll be happy to receive
recomendations how to make this thing better if I done sth wrong.

Also vmnet.framework requires com.apple.vm.networking entitlement to
run without root priveledges. Ad-hoc signing does not fit there,
so I didn't touch anything related to signing. As a result we should
run qemu-system by a priviledged user:
`$ sudo qemu-system-x86_64 -nic vmnet-shared`
otherwise vmnet fails with 'general failure'.

But in any way it seems working now,
I tested it within qemu-system-x86-64 on macOS 10.15.7 host, with nic
models:
- e1000-82545em
- virtio-net-pci

and having such guests:
- macOS 10.15.7
- Ubuntu Bionic (server cloudimg) 

Vladislav Yaroshchuk (7):
  net/vmnet: dependencies setup, initial preparations
  net/vmnet: add new netdevs to qapi/net
  net/vmnet: create common netdev state structure
  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

 configure           |  31 +++++
 meson.build         |   5 +
 net/clients.h       |  11 ++
 net/meson.build     |   7 ++
 net/net.c           |  10 ++
 net/vmnet-bridged.m | 123 ++++++++++++++++++
 net/vmnet-common.m  | 294 ++++++++++++++++++++++++++++++++++++++++++++
 net/vmnet-host.c    |  93 ++++++++++++++
 net/vmnet-shared.c  |  94 ++++++++++++++
 net/vmnet_int.h     |  48 ++++++++
 qapi/net.json       |  99 ++++++++++++++-
 qemu-options.hx     |  17 +++
 12 files changed, 830 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

-- 
2.23.0



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

* [PATCH 1/7] net/vmnet: dependencies setup, initial preparations
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-08-06 21:13   ` Eric Blake
  2021-06-17 14:32 ` [PATCH 2/7] net/vmnet: add new netdevs to qapi/net Vladislav Yaroshchuk
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

Add 'vmnet' customizable option and 'vmnet.framework' probe into
configure;

Create source files for network client driver, update meson.build;

Add 'vmnet' into qapi::net::NetClientDriver options list.

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 configure       | 31 +++++++++++++++++++++++++++++++
 meson.build     |  5 +++++
 net/clients.h   |  4 ++++
 net/meson.build |  1 +
 net/net.c       |  6 ++++++
 net/vmnet.c     | 22 ++++++++++++++++++++++
 qapi/net.json   |  3 ++-
 7 files changed, 71 insertions(+), 1 deletion(-)
 create mode 100644 net/vmnet.c

diff --git a/configure b/configure
index 8dcb9965b2..cdc171988b 100755
--- a/configure
+++ b/configure
@@ -307,6 +307,7 @@ mpath="auto"
 vnc="enabled"
 sparse="auto"
 vde="$default_feature"
+vmnet="auto"
 vnc_sasl="auto"
 vnc_jpeg="auto"
 vnc_png="auto"
@@ -1059,6 +1060,10 @@ for opt do
   ;;
   --enable-vde) vde="yes"
   ;;
+  --disable-vmnet) vmnet="no"
+  ;;
+  --enable-vmnet) vmnet="yes"
+  ;;
   --disable-netmap) netmap="no"
   ;;
   --enable-netmap) netmap="yes"
@@ -1871,6 +1876,7 @@ disabled with --disable-FEATURE, default is enabled if available
   rdma            Enable RDMA-based migration
   pvrdma          Enable PVRDMA support
   vde             support for vde network
+  vmnet           vmnet.framework support (macOS)
   netmap          support for netmap network
   linux-aio       Linux AIO support
   linux-io-uring  Linux io_uring support
@@ -3157,6 +3163,28 @@ EOF
   fi
 fi
 
+##########################################
+# vmnet.framework probe
+if test "$vmnet" != "no" ; then
+  vmnet_flags="-framework vmnet"
+  cat > $TMPC << EOF
+#include <vmnet/vmnet.h>
+int main(void)
+{
+    (void) vmnet_allocate_mac_address_key;
+    return 0;
+}
+EOF
+  if compile_prog "" "$vmnet_flags" ; then
+    vmnet=yes
+  else
+    if test "$vmnet" = "yes" ; then
+      feature_not_found "vmnet" "'vmnet.framework' in unsupported in this build"
+    fi
+    vmnet=no
+  fi
+fi
+
 ##########################################
 # netmap support probe
 # Apart from looking for netmap headers, we make sure that the host API version
@@ -5559,6 +5587,9 @@ if test "$vde" = "yes" ; then
   echo "CONFIG_VDE=y" >> $config_host_mak
   echo "VDE_LIBS=$vde_libs" >> $config_host_mak
 fi
+if test "$vmnet" = "yes" ; then
+  echo "CONFIG_VMNET=y" >> $config_host_mak
+fi
 if test "$netmap" = "yes" ; then
   echo "CONFIG_NETMAP=y" >> $config_host_mak
 fi
diff --git a/meson.build b/meson.build
index a2311eda6e..df254522af 100644
--- a/meson.build
+++ b/meson.build
@@ -173,6 +173,7 @@ iokit = []
 emulator_link_args = []
 nvmm =not_found
 hvf = not_found
+vmnet = not_found
 if targetos == 'windows'
   socket = cc.find_library('ws2_32')
   winmm = cc.find_library('winmm')
@@ -184,6 +185,9 @@ if targetos == 'windows'
 elif targetos == 'darwin'
   coref = dependency('appleframeworks', modules: 'CoreFoundation')
   iokit = dependency('appleframeworks', modules: 'IOKit')
+  if config_host.has_key('CONFIG_VMNET')
+    vmnet = dependency('appleframeworks', modules: 'vmnet')
+  endif
 elif targetos == 'sunos'
   socket = [cc.find_library('socket'),
             cc.find_library('nsl'),
@@ -2522,6 +2526,7 @@ summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
+summary_info += {'vmnet support': vmnet.found()}
 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
 summary(summary_info, bool_yn: true, section: 'Configurable features')
 
diff --git a/net/clients.h b/net/clients.h
index 92f9b59aed..ac19843aab 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -63,4 +63,8 @@ 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(const Netdev *netdev, const char *name,
+                          NetClientState *peer, Error **errp);
+#endif
 #endif /* QEMU_NET_CLIENTS_H */
diff --git a/net/meson.build b/net/meson.build
index 1076b0a7ab..196cf321a2 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -38,4 +38,5 @@ softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files(tap_posix))
 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('tap-win32.c'))
 softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
 
+softmmu_ss.add(when: ['CONFIG_VMNET', vmnet], if_true: files('vmnet.c'))
 subdir('can')
diff --git a/net/net.c b/net/net.c
index 76bbb7c31b..645c52ef6e 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1001,6 +1001,9 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
 #ifdef CONFIG_L2TPV3
         [NET_CLIENT_DRIVER_L2TPV3]    = net_init_l2tpv3,
 #endif
+#ifdef CONFIG_VMNET
+        [NET_CLIENT_DRIVER_VMNET] = net_init_vmnet,
+#endif
 };
 
 
@@ -1086,6 +1089,9 @@ void show_netdevs(void)
 #endif
 #ifdef CONFIG_VHOST_VDPA
         "vhost-vdpa",
+#endif
+#ifdef CONFIG_VMNET
+        "vmnet",
 #endif
     };
 
diff --git a/net/vmnet.c b/net/vmnet.c
new file mode 100644
index 0000000000..f8b64e2a27
--- /dev/null
+++ b/net/vmnet.c
@@ -0,0 +1,22 @@
+/*
+ * vmnet.c - network client wrapper for Apple vmnet.framework
+ *
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+
+int net_init_vmnet(const Netdev *netdev, const char *name,
+                    NetClientState *peer, Error **errp) {
+  error_setg(errp, "vmnet is not implemented yet");
+  return -1;
+}
diff --git a/qapi/net.json b/qapi/net.json
index 7fab2e7cd8..c5de234e2c 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -460,10 +460,11 @@
 # Since: 2.7
 #
 #        @vhost-vdpa since 5.1
+#        @vmnet since 6.1
 ##
 { 'enum': 'NetClientDriver',
   'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
-            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
+            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa', 'vmnet' ] }
 
 ##
 # @Netdev:
-- 
2.23.0



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

* [PATCH 2/7] net/vmnet: add new netdevs to qapi/net
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 1/7] net/vmnet: dependencies setup, initial preparations Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-08-06 21:19   ` Eric Blake
  2021-06-17 14:32 ` [PATCH 3/7] net/vmnet: create common netdev state structure Vladislav Yaroshchuk
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

Created separate netdev per each vmnet operating mode
because they use quite different settings. Especially since
macOS 11.0 (vmnet.framework API gets lots of updates)

Three new netdevs are added:
- vmnet-host
- vmnet-shared
- vmnet-bridged

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/clients.h |  11 +++++-
 net/net.c     |  10 +++--
 net/vmnet.c   |  14 ++++++-
 qapi/net.json | 100 ++++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 126 insertions(+), 9 deletions(-)

diff --git a/net/clients.h b/net/clients.h
index ac19843aab..c9157789f2 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -64,7 +64,14 @@ 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(const Netdev *netdev, const char *name,
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
                           NetClientState *peer, Error **errp);
-#endif
+
+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/net.c b/net/net.c
index 645c52ef6e..87a6f96665 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1002,8 +1002,10 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
         [NET_CLIENT_DRIVER_L2TPV3]    = net_init_l2tpv3,
 #endif
 #ifdef CONFIG_VMNET
-        [NET_CLIENT_DRIVER_VMNET] = net_init_vmnet,
-#endif
+        [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 */
 };
 
 
@@ -1091,7 +1093,9 @@ void show_netdevs(void)
         "vhost-vdpa",
 #endif
 #ifdef CONFIG_VMNET
-        "vmnet",
+        "vmnet-host",
+        "vmnet-shared",
+        "vmnet-bridged",
 #endif
     };
 
diff --git a/net/vmnet.c b/net/vmnet.c
index f8b64e2a27..3f25afd7e8 100644
--- a/net/vmnet.c
+++ b/net/vmnet.c
@@ -15,7 +15,19 @@
 
 #include <vmnet/vmnet.h>
 
-int net_init_vmnet(const Netdev *netdev, const char *name,
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
+                    NetClientState *peer, Error **errp) {
+  error_setg(errp, "vmnet is not implemented yet");
+  return -1;
+}
+
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
+                    NetClientState *peer, Error **errp) {
+  error_setg(errp, "vmnet is not implemented yet");
+  return -1;
+}
+
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
                     NetClientState *peer, Error **errp) {
   error_setg(errp, "vmnet is not implemented yet");
   return -1;
diff --git a/qapi/net.json b/qapi/net.json
index c5de234e2c..a548d7a7f4 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -452,6 +452,89 @@
     '*vhostdev':     'str',
     '*queues':       'int' } }
 
+##
+# @NetdevVmnetHostOptions:
+#
+# vmnet (host mode) network backend.
+#
+# Allows the vmnet interface to communicate with
+# other vmnet interfaces that are in host mode and also with the native host.
+#
+# @dhcpstart: The starting IPv4 address to use for the interface. Must be in the
+#             private IP range (RFC 1918). Must be specified along
+#             with @dhcpend and @subnetmask.
+#             This address is used as the gateway address. The subsequent address
+#             up to and including dhcpend are  placed in the DHCP pool.
+#
+# @dhcpend: The DHCP IPv4 range end address to use for the interface. Must be in
+#           the private IP range (RFC 1918). Must be specified along
+#           with @dhcpstart and @subnetmask.
+#
+# @subnetmask: The IPv4 subnet mask to use on the interface. Must be specified
+#              along with @dhcpstart and @subnetmask.
+#
+#
+# Since: 6.1,
+##
+{ 'struct': 'NetdevVmnetHostOptions',
+  'data': {
+    '*dhcpstart':   'str',
+    '*dhcpend':     'str',
+    '*subnetmask':  'str'
+  },
+  'if': 'defined(CONFIG_VMNET)' }
+
+##
+# @NetdevVmnetSharedOptions:
+#
+# vmnet (shared mode) network backend.
+#
+# Allows traffic originating from the vmnet interface to reach the
+# Internet through a network address translator (NAT). The vmnet interface
+# can also communicate with the native host. By default, the vmnet interface
+# is able to communicate with other shared mode interfaces. If a subnet range
+# is specified, the vmnet interface can communicate with other shared mode
+# interfaces on the same subnet.
+#
+# @dhcpstart: The starting IPv4 address to use for the interface. Must be in the
+#             private IP range (RFC 1918). Must be specified along
+#             with @dhcpend and @subnetmask.
+#             This address is used as the gateway address. The subsequent address
+#             up to and including dhcpend are  placed in the DHCP pool.
+#
+# @dhcpend: The DHCP IPv4 range end address to use for the interface. Must be in
+#           the private IP range (RFC 1918). Must be specified along
+#           with @dhcpstart and @subnetmask.
+#
+# @subnetmask: The IPv4 subnet mask to use on the interface. Must be specified
+#              along with @dhcpstart and @subnetmask.
+#
+#
+# Since: 6.1,
+##
+{ 'struct': 'NetdevVmnetSharedOptions',
+  'data': {
+    '*dhcpstart':    'str',
+    '*dhcpend':      'str',
+    '*subnetmask':   'str'
+  },
+  'if': 'defined(CONFIG_VMNET)' }
+
+##
+# @NetdevVmnetBridgedOptions:
+#
+# vmnet (bridged mode) network backend.
+#
+# Bridges the vmnet interface with a physical network interface.
+#
+# @ifname: The name of the physical interface to be bridged.
+#
+# Since: 6.1
+##
+{ 'struct': 'NetdevVmnetBridgedOptions',
+  'data': { 'ifname': 'str' },
+  'if': 'defined(CONFIG_VMNET)' }
+
 ##
 # @NetClientDriver:
 #
@@ -460,11 +543,16 @@
 # Since: 2.7
 #
 #        @vhost-vdpa since 5.1
-#        @vmnet since 6.1
+#        @vmnet-host since 6.1
+#        @vmnet-shared since 6.1
+#        @vmnet-bridged since 6.1
 ##
 { 'enum': 'NetClientDriver',
   'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
-            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa', 'vmnet' ] }
+            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
+            { 'name': 'vmnet-host', 'if': 'defined(CONFIG_VMNET)' },
+            { 'name': 'vmnet-shared', 'if': 'defined(CONFIG_VMNET)' },
+            { 'name': 'vmnet-bridged', 'if': 'defined(CONFIG_VMNET)' }] }
 
 ##
 # @Netdev:
@@ -478,6 +566,9 @@
 # Since: 1.2
 #
 #        'l2tpv3' - since 2.1
+#        'vmnet-host' - since 6.1
+#        'vmnet-shared' - since 6.1
+#        'vmnet-bridged' - since 6.1
 ##
 { 'union': 'Netdev',
   'base': { 'id': 'str', 'type': 'NetClientDriver' },
@@ -493,7 +584,10 @@
     'hubport':  'NetdevHubPortOptions',
     'netmap':   'NetdevNetmapOptions',
     'vhost-user': 'NetdevVhostUserOptions',
-    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
+    'vhost-vdpa': 'NetdevVhostVDPAOptions',
+    'vmnet-host': 'NetdevVmnetHostOptions',
+    'vmnet-shared': 'NetdevVmnetSharedOptions',
+    'vmnet-bridged': 'NetdevVmnetBridgedOptions' } }
 
 ##
 # @RxState:
-- 
2.23.0



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

* [PATCH 3/7] net/vmnet: create common netdev state structure
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 1/7] net/vmnet: dependencies setup, initial preparations Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 2/7] net/vmnet: add new netdevs to qapi/net Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 4/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/meson.build     |  8 +++++++-
 net/vmnet-bridged.c | 25 +++++++++++++++++++++++++
 net/vmnet-common.c  | 20 ++++++++++++++++++++
 net/vmnet-host.c    | 24 ++++++++++++++++++++++++
 net/vmnet-shared.c  | 25 +++++++++++++++++++++++++
 net/vmnet.c         | 34 ----------------------------------
 net/vmnet_int.h     | 25 +++++++++++++++++++++++++
 7 files changed, 126 insertions(+), 35 deletions(-)
 create mode 100644 net/vmnet-bridged.c
 create mode 100644 net/vmnet-common.c
 create mode 100644 net/vmnet-host.c
 create mode 100644 net/vmnet-shared.c
 delete mode 100644 net/vmnet.c
 create mode 100644 net/vmnet_int.h

diff --git a/net/meson.build b/net/meson.build
index 196cf321a2..82eed63c8f 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -38,5 +38,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'))
 
-softmmu_ss.add(when: ['CONFIG_VMNET', vmnet], if_true: files('vmnet.c'))
+vmnet_files = files(
+  'vmnet-common.c',
+  'vmnet-bridged.c',
+  'vmnet-host.c',
+  'vmnet-shared.c'
+)
+softmmu_ss.add(when: ['CONFIG_VMNET', vmnet], if_true: vmnet_files)
 subdir('can')
diff --git a/net/vmnet-bridged.c b/net/vmnet-bridged.c
new file mode 100644
index 0000000000..9226c42353
--- /dev/null
+++ b/net/vmnet-bridged.c
@@ -0,0 +1,25 @@
+/*
+ * vmnet-bridged.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-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.c b/net/vmnet-common.c
new file mode 100644
index 0000000000..8ba31dc7b2
--- /dev/null
+++ b/net/vmnet-common.c
@@ -0,0 +1,20 @@
+/*
+ * vmnet.c - 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-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..1d3484b51e
--- /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-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..177b5a48ec
--- /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-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.c b/net/vmnet.c
deleted file mode 100644
index 3f25afd7e8..0000000000
--- a/net/vmnet.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * vmnet.c - network client wrapper for Apple vmnet.framework
- *
- * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "clients.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-
-#include <vmnet/vmnet.h>
-
-int net_init_vmnet_host(const Netdev *netdev, const char *name,
-                    NetClientState *peer, Error **errp) {
-  error_setg(errp, "vmnet is not implemented yet");
-  return -1;
-}
-
-int net_init_vmnet_shared(const Netdev *netdev, const char *name,
-                    NetClientState *peer, Error **errp) {
-  error_setg(errp, "vmnet is not implemented yet");
-  return -1;
-}
-
-int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
-                    NetClientState *peer, Error **errp) {
-  error_setg(errp, "vmnet is not implemented yet");
-  return -1;
-}
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 */
-- 
2.23.0



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

* [PATCH 4/7] net/vmnet: implement shared mode (vmnet-shared)
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (2 preceding siblings ...)
  2021-06-17 14:32 ` [PATCH 3/7] net/vmnet: create common netdev state structure Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 5/7] net/vmnet: implement host mode (vmnet-host) Vladislav Yaroshchuk
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

Still not implemented:
- port forwarding
- ipv6 prefix setting

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/meson.build    |   2 +-
 net/vmnet-common.c |  20 ---
 net/vmnet-common.m | 294 +++++++++++++++++++++++++++++++++++++++++++++
 net/vmnet-shared.c |  73 ++++++++++-
 net/vmnet_int.h    |  23 ++++
 5 files changed, 389 insertions(+), 23 deletions(-)
 delete mode 100644 net/vmnet-common.c
 create mode 100644 net/vmnet-common.m

diff --git a/net/meson.build b/net/meson.build
index 82eed63c8f..1df498ad99 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -39,7 +39,7 @@ 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.c',
+  'vmnet-common.m',
   'vmnet-bridged.c',
   'vmnet-host.c',
   'vmnet-shared.c'
diff --git a/net/vmnet-common.c b/net/vmnet-common.c
deleted file mode 100644
index 8ba31dc7b2..0000000000
--- a/net/vmnet-common.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * vmnet.c - 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-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-common.m b/net/vmnet-common.m
new file mode 100644
index 0000000000..c6e7df99e0
--- /dev/null
+++ b/net/vmnet-common.m
@@ -0,0 +1,294 @@
+/*
+ * vmnet.c - network backend based on vmnet.framework
+ *
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qapi-types-net.h"
+#include "vmnet_int.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+#include <dispatch/dispatch.h>
+
+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";
+    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);
+
+    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;
+          }
+
+          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,
+                   "interface creation error: %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 177b5a48ec..a9db0ad52b 100644
--- a/net/vmnet-shared.c
+++ b/net/vmnet-shared.c
@@ -17,9 +17,78 @@
 
 #include <vmnet/vmnet.h>
 
+typedef struct VmnetSharedState {
+  VmnetCommonState common;
+
+} VmnetSharedState;
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp);
+
+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;
+    xpc_object_t if_desc;
+
+    nc = qemu_new_net_client(&net_vmnet_shared_info,
+                             peer, "vmnet-shared", name);
+    if_desc = create_if_desc(netdev, errp);
+    return vmnet_if_create(nc, if_desc, errp, NULL);
+}
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
+{
+    const NetdevVmnetSharedOptions *options;
+    xpc_object_t if_desc;
+
+    if_desc = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(
+        if_desc,
+        vmnet_operation_mode_key,
+        VMNET_SHARED_MODE
+    );
+
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_allocate_mac_address_key,
+        false
+    );
+
+    options = &(netdev->u.vmnet_shared);
+
+    if (options->has_dhcpstart ||
+        options->has_dhcpend ||
+        options->has_subnetmask) {
+
+        if (options->has_dhcpstart &&
+            options->has_dhcpend &&
+            options->has_subnetmask) {
+
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_start_address_key,
+                                      options->dhcpstart);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_end_address_key,
+                                      options->dhcpend);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_subnet_mask_key,
+                                      options->subnetmask);
+        } else {
+            error_setg(
+                errp,
+                "'dhcpstart', 'dhcpend', 'subnetmask' "
+                "must be provided together"
+            );
+        }
+    }
+
+    return if_desc;
 }
+
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] 15+ messages in thread

* [PATCH 5/7] net/vmnet: implement host mode (vmnet-host)
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (3 preceding siblings ...)
  2021-06-17 14:32 ` [PATCH 4/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 6/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

Still not implemented:
- port forwarding

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

diff --git a/net/vmnet-host.c b/net/vmnet-host.c
index 1d3484b51e..77a2c20b48 100644
--- a/net/vmnet-host.c
+++ b/net/vmnet-host.c
@@ -17,8 +17,77 @@
 
 #include <vmnet/vmnet.h>
 
+typedef struct VmnetHostState {
+  VmnetCommonState common;
+
+} VmnetHostState;
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp);
+
+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, errp);
+    return vmnet_if_create(nc, if_desc, errp, NULL);
+}
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
+{
+    const NetdevVmnetHostOptions *options;
+    xpc_object_t if_desc;
+
+    if_desc = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(
+        if_desc,
+        vmnet_operation_mode_key,
+        VMNET_HOST_MODE
+    );
+
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_allocate_mac_address_key,
+        false
+    );
+
+    options = &(netdev->u.vmnet_host);
+
+    if (options->has_dhcpstart ||
+        options->has_dhcpend ||
+        options->has_subnetmask) {
+
+        if (options->has_dhcpstart &&
+            options->has_dhcpend &&
+            options->has_subnetmask) {
+
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_start_address_key,
+                                      options->dhcpstart);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_end_address_key,
+                                      options->dhcpend);
+            xpc_dictionary_set_string(if_desc,
+                                      vmnet_subnet_mask_key,
+                                      options->subnetmask);
+        } else {
+            error_setg(
+                errp,
+                "'dhcpstart', 'dhcpend', 'subnetmask' "
+                "must be provided together"
+            );
+        }
+    }
+
+    return if_desc;
 }
-- 
2.23.0



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

* [PATCH 6/7] net/vmnet: implement bridged mode (vmnet-bridged)
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (4 preceding siblings ...)
  2021-06-17 14:32 ` [PATCH 5/7] net/vmnet: implement host mode (vmnet-host) Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-06-17 14:32 ` [PATCH 7/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
---
 net/meson.build     |   2 +-
 net/vmnet-bridged.c |  25 ---------
 net/vmnet-bridged.m | 123 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 26 deletions(-)
 delete mode 100644 net/vmnet-bridged.c
 create mode 100644 net/vmnet-bridged.m

diff --git a/net/meson.build b/net/meson.build
index 1df498ad99..495419e964 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -40,7 +40,7 @@ softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
 
 vmnet_files = files(
   'vmnet-common.m',
-  'vmnet-bridged.c',
+  'vmnet-bridged.m',
   'vmnet-host.c',
   'vmnet-shared.c'
 )
diff --git a/net/vmnet-bridged.c b/net/vmnet-bridged.c
deleted file mode 100644
index 9226c42353..0000000000
--- a/net/vmnet-bridged.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * vmnet-bridged.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-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-bridged.m b/net/vmnet-bridged.m
new file mode 100644
index 0000000000..61a96ce11a
--- /dev/null
+++ b/net/vmnet-bridged.m
@@ -0,0 +1,123 @@
+/*
+ * vmnet-bridged.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-types-net.h"
+#include "vmnet_int.h"
+#include "clients.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+#include <vmnet/vmnet.h>
+
+typedef struct VmnetBridgedState {
+  VmnetCommonState common;
+
+} VmnetBridgedState;
+
+static NetClientInfo net_vmnet_bridged_info = {
+    .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
+    .size = sizeof(VmnetBridgedState),
+    .receive = vmnet_receive_common,
+    .cleanup = vmnet_cleanup_common,
+};
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp);
+
+static bool validate_ifname(const char *ifname);
+
+static const char *get_valid_ifnames(void);
+
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
+                           NetClientState *peer, Error **errp)
+{
+    NetClientState *nc;
+    xpc_object_t if_desc;
+
+    nc = qemu_new_net_client(&net_vmnet_bridged_info,
+                             peer, "vmnet-bridged", name);
+    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);
+}
+
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
+{
+    const NetdevVmnetBridgedOptions *options;
+    xpc_object_t if_desc;
+
+    if_desc = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(
+        if_desc,
+        vmnet_operation_mode_key,
+        VMNET_BRIDGED_MODE
+    );
+
+    xpc_dictionary_set_bool(
+        if_desc,
+        vmnet_allocate_mac_address_key,
+        false
+    );
+
+    options = &(netdev->u.vmnet_bridged);
+    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 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]";
+}
-- 
2.23.0



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

* [PATCH 7/7] net/vmnet: update qemu-options.hx
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (5 preceding siblings ...)
  2021-06-17 14:32 ` [PATCH 6/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
@ 2021-06-17 14:32 ` Vladislav Yaroshchuk
  2021-08-06 19:03 ` [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
  2021-08-12  6:00 ` Roman Bolshakov
  8 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-06-17 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, r.bolshakov, Vladislav Yaroshchuk

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

diff --git a/qemu-options.hx b/qemu-options.hx
index 14258784b3..631572f2d4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2582,6 +2582,17 @@ 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,[dhcpstart=addr,dhcpend=addr,subnetmask=mask]\n"
+    "                configure a vmnet network backend in host mode with ID 'str',\n"
+    "                configure its DHCP server and choose a subnet\n"
+    "-netdev vmnet-shared,id=str,[dhcpstart=addr,dhcpend=addr,subnetmask=mask]\n"
+    "                configure a vmnet network backend in shared mode with ID 'str',\n"
+    "                configure its DHCP server and choose a subnet\n"
+    "-netdev vmnet-bridged,id=str,ifname=name\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"
 #endif
     "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
     "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
@@ -2601,6 +2612,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"
@@ -2623,6 +2637,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] 15+ messages in thread

* Re: [PATCH 0/7] Add vmnet.framework based network backend
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (6 preceding siblings ...)
  2021-06-17 14:32 ` [PATCH 7/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
@ 2021-08-06 19:03 ` Vladislav Yaroshchuk
  2021-08-09  3:23   ` Jason Wang
  2021-08-12  6:00 ` Roman Bolshakov
  8 siblings, 1 reply; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-08-06 19:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, Roman Bolshakov

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

ping
https://patchew.org/QEMU/20210617143246.55336-1-yaroshchuk2000@gmail.com/

чт, 17 июн. 2021 г. в 17:33, Vladislav Yaroshchuk <yaroshchuk2000@gmail.com
>:

> macOS provides networking API for VMs called vmnet.framework.
> I tried to add it as a network backend. All three modes are supported:
>
> -shared:
>   allows the guest to comminicate with other guests in shared mode and
>   also with external network (Internet) via NAT
>
> -host:
>   allows the guest to communicate with other guests in host mode
>
> -bridged:
>   bridges the guest with a physical network interface
>
> Separate netdev for each vmnet mode was created because they use quite
> different settings, especially since macOS 11.0 when vmnet.framework
> gets a lot of updates.
>
> Not sure that I use qemu_mutex_lock_iothread() and
> qemu_mutex_unlock_iothread() in correct way while sending packet
> from vmnet interface to QEMU. I'll be happy to receive
> recomendations how to make this thing better if I done sth wrong.
>
> Also vmnet.framework requires com.apple.vm.networking entitlement to
> run without root priveledges. Ad-hoc signing does not fit there,
> so I didn't touch anything related to signing. As a result we should
> run qemu-system by a priviledged user:
> `$ sudo qemu-system-x86_64 -nic vmnet-shared`
> otherwise vmnet fails with 'general failure'.
>
> But in any way it seems working now,
> I tested it within qemu-system-x86-64 on macOS 10.15.7 host, with nic
> models:
> - e1000-82545em
> - virtio-net-pci
>
> and having such guests:
> - macOS 10.15.7
> - Ubuntu Bionic (server cloudimg)
>
> Vladislav Yaroshchuk (7):
>   net/vmnet: dependencies setup, initial preparations
>   net/vmnet: add new netdevs to qapi/net
>   net/vmnet: create common netdev state structure
>   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
>
>  configure           |  31 +++++
>  meson.build         |   5 +
>  net/clients.h       |  11 ++
>  net/meson.build     |   7 ++
>  net/net.c           |  10 ++
>  net/vmnet-bridged.m | 123 ++++++++++++++++++
>  net/vmnet-common.m  | 294 ++++++++++++++++++++++++++++++++++++++++++++
>  net/vmnet-host.c    |  93 ++++++++++++++
>  net/vmnet-shared.c  |  94 ++++++++++++++
>  net/vmnet_int.h     |  48 ++++++++
>  qapi/net.json       |  99 ++++++++++++++-
>  qemu-options.hx     |  17 +++
>  12 files changed, 830 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
>
> --
> 2.23.0
>
>

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

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

* Re: [PATCH 1/7] net/vmnet: dependencies setup, initial preparations
  2021-06-17 14:32 ` [PATCH 1/7] net/vmnet: dependencies setup, initial preparations Vladislav Yaroshchuk
@ 2021-08-06 21:13   ` Eric Blake
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Blake @ 2021-08-06 21:13 UTC (permalink / raw)
  To: Vladislav Yaroshchuk; +Cc: jasowang, r.bolshakov, qemu-devel

On Thu, Jun 17, 2021 at 05:32:40PM +0300, Vladislav Yaroshchuk wrote:
> Add 'vmnet' customizable option and 'vmnet.framework' probe into
> configure;

I'm sorry no one else has taken time to review this yet; thanks for
your ping.  I'm not the network maintainer, and I don't develop on
Mac, so I'm uncomfortable doing a full review myself, but I can at
least point out:

> 
> Create source files for network client driver, update meson.build;
> 
> Add 'vmnet' into qapi::net::NetClientDriver options list.
> 
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---

> +++ b/qapi/net.json
> @@ -460,10 +460,11 @@
>  # Since: 2.7
>  #
>  #        @vhost-vdpa since 5.1
> +#        @vmnet since 6.1

Sadly, since no one reviewed, it has missed the 6.1 boat, and you'll
have to respin this to call out 6.2 (no need to do that until you have
other review comments to address).

>  ##
>  { 'enum': 'NetClientDriver',
>    'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> -            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
> +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa', 'vmnet' ] }

Long line; please wrap to keep under 80 columns.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



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

* Re: [PATCH 2/7] net/vmnet: add new netdevs to qapi/net
  2021-06-17 14:32 ` [PATCH 2/7] net/vmnet: add new netdevs to qapi/net Vladislav Yaroshchuk
@ 2021-08-06 21:19   ` Eric Blake
  2021-08-17  9:28     ` Vladislav Yaroshchuk
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Blake @ 2021-08-06 21:19 UTC (permalink / raw)
  To: Vladislav Yaroshchuk; +Cc: jasowang, r.bolshakov, qemu-devel

On Thu, Jun 17, 2021 at 05:32:41PM +0300, Vladislav Yaroshchuk wrote:
> Created separate netdev per each vmnet operating mode
> because they use quite different settings. Especially since
> macOS 11.0 (vmnet.framework API gets lots of updates)
> 
> Three new netdevs are added:
> - vmnet-host
> - vmnet-shared
> - vmnet-bridged
> 
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---

> +++ b/qapi/net.json
> @@ -452,6 +452,89 @@
>      '*vhostdev':     'str',
>      '*queues':       'int' } }
>  
> +##
> +# @NetdevVmnetHostOptions:
> +#
> +# vmnet (host mode) network backend.
> +#
> +# Allows the vmnet interface to communicate with
> +# other vmnet interfaces that are in host mode and also with the native host.
> +#
> +# @dhcpstart: The starting IPv4 address to use for the interface. Must be in the
> +#             private IP range (RFC 1918). Must be specified along
> +#             with @dhcpend and @subnetmask.
> +#             This address is used as the gateway address. The subsequent address
> +#             up to and including dhcpend are  placed in the DHCP pool.
> +#
> +# @dhcpend: The DHCP IPv4 range end address to use for the interface. Must be in
> +#           the private IP range (RFC 1918). Must be specified along
> +#           with @dhcpstart and @subnetmask.
> +#
> +# @subnetmask: The IPv4 subnet mask to use on the interface. Must be specified
> +#              along with @dhcpstart and @subnetmask.
> +#
> +#
> +# Since: 6.1,
> +##

Same comments about 6.1 vs. 6.2 as before (I'll quit pointing it out).
Spurious trailing comma.

> +{ 'struct': 'NetdevVmnetHostOptions',
> +  'data': {
> +    '*dhcpstart':   'str',
> +    '*dhcpend':     'str',
> +    '*subnetmask':  'str'

Hmm. You listed all three as optional, but document that they must all
be specified together.  Why not just make them all required, and
simplify the documentation?

> +  },
> +  'if': 'defined(CONFIG_VMNET)' }
> +
> +##
> +# @NetdevVmnetSharedOptions:
> +#
> +# vmnet (shared mode) network backend.
> +#
> +# Allows traffic originating from the vmnet interface to reach the
> +# Internet through a network address translator (NAT). The vmnet interface
> +# can also communicate with the native host. By default, the vmnet interface
> +# is able to communicate with other shared mode interfaces. If a subnet range
> +# is specified, the vmnet interface can communicate with other shared mode
> +# interfaces on the same subnet.
> +#
> +# @dhcpstart: The starting IPv4 address to use for the interface. Must be in the
> +#             private IP range (RFC 1918). Must be specified along
> +#             with @dhcpend and @subnetmask.
> +#             This address is used as the gateway address. The subsequent address
> +#             up to and including dhcpend are  placed in the DHCP pool.

Spurious double space.

> +#
> +# @dhcpend: The DHCP IPv4 range end address to use for the interface. Must be in
> +#           the private IP range (RFC 1918). Must be specified along
> +#           with @dhcpstart and @subnetmask.
> +#
> +# @subnetmask: The IPv4 subnet mask to use on the interface. Must be specified
> +#              along with @dhcpstart and @subnetmask.
> +#
> +#
> +# Since: 6.1,
> +##
> +{ 'struct': 'NetdevVmnetSharedOptions',
> +  'data': {
> +    '*dhcpstart':    'str',
> +    '*dhcpend':      'str',
> +    '*subnetmask':   'str'
> +  },
> +  'if': 'defined(CONFIG_VMNET)' }
> +
> +##
> +# @NetdevVmnetBridgedOptions:
> +#
> +# vmnet (bridged mode) network backend.
> +#
> +# Bridges the vmnet interface with a physical network interface.
> +#
> +# @ifname: The name of the physical interface to be bridged.
> +#
> +# Since: 6.1
> +##
> +{ 'struct': 'NetdevVmnetBridgedOptions',
> +  'data': { 'ifname': 'str' },
> +  'if': 'defined(CONFIG_VMNET)' }
> +
>  ##
>  # @NetClientDriver:
>  #
> @@ -460,11 +543,16 @@
>  # Since: 2.7
>  #
>  #        @vhost-vdpa since 5.1
> -#        @vmnet since 6.1

Why are you dropping vmnet?  Especially since you just added it in the
previous patch?  That feels like needless churn.

> +#        @vmnet-host since 6.1
> +#        @vmnet-shared since 6.1
> +#        @vmnet-bridged since 6.1
>  ##
>  { 'enum': 'NetClientDriver',
>    'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> -            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa', 'vmnet' ] }
> +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
> +            { 'name': 'vmnet-host', 'if': 'defined(CONFIG_VMNET)' },
> +            { 'name': 'vmnet-shared', 'if': 'defined(CONFIG_VMNET)' },
> +            { 'name': 'vmnet-bridged', 'if': 'defined(CONFIG_VMNET)' }] }

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



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

* Re: [PATCH 0/7] Add vmnet.framework based network backend
  2021-08-06 19:03 ` [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
@ 2021-08-09  3:23   ` Jason Wang
  0 siblings, 0 replies; 15+ messages in thread
From: Jason Wang @ 2021-08-09  3:23 UTC (permalink / raw)
  To: Vladislav Yaroshchuk, qemu-devel; +Cc: Roman Bolshakov


在 2021/8/7 上午3:03, Vladislav Yaroshchuk 写道:
> ping
> https://patchew.org/QEMU/20210617143246.55336-1-yaroshchuk2000@gmail.com/ 
> <https://patchew.org/QEMU/20210617143246.55336-1-yaroshchuk2000@gmail.com/>


Will review this week.

Thanks


>
> чт, 17 июн. 2021 г. в 17:33, Vladislav Yaroshchuk 
> <yaroshchuk2000@gmail.com <mailto:yaroshchuk2000@gmail.com>>:
>
>     macOS provides networking API for VMs called vmnet.framework.
>     I tried to add it as a network backend. All three modes are supported:
>
>     -shared:
>       allows the guest to comminicate with other guests in shared mode and
>       also with external network (Internet) via NAT
>
>     -host:
>       allows the guest to communicate with other guests in host mode
>
>     -bridged:
>       bridges the guest with a physical network interface
>
>     Separate netdev for each vmnet mode was created because they use quite
>     different settings, especially since macOS 11.0 when vmnet.framework
>     gets a lot of updates.
>
>     Not sure that I use qemu_mutex_lock_iothread() and
>     qemu_mutex_unlock_iothread() in correct way while sending packet
>     from vmnet interface to QEMU. I'll be happy to receive
>     recomendations how to make this thing better if I done sth wrong.
>
>     Also vmnet.framework requires com.apple.vm.networking entitlement to
>     run without root priveledges. Ad-hoc signing does not fit there,
>     so I didn't touch anything related to signing. As a result we should
>     run qemu-system by a priviledged user:
>     `$ sudo qemu-system-x86_64 -nic vmnet-shared`
>     otherwise vmnet fails with 'general failure'.
>
>     But in any way it seems working now,
>     I tested it within qemu-system-x86-64 on macOS 10.15.7 host, with nic
>     models:
>     - e1000-82545em
>     - virtio-net-pci
>
>     and having such guests:
>     - macOS 10.15.7
>     - Ubuntu Bionic (server cloudimg)
>
>     Vladislav Yaroshchuk (7):
>       net/vmnet: dependencies setup, initial preparations
>       net/vmnet: add new netdevs to qapi/net
>       net/vmnet: create common netdev state structure
>       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
>
>      configure           |  31 +++++
>      meson.build         |   5 +
>      net/clients.h       |  11 ++
>      net/meson.build     |   7 ++
>      net/net.c           |  10 ++
>      net/vmnet-bridged.m | 123 ++++++++++++++++++
>      net/vmnet-common.m  | 294
>     ++++++++++++++++++++++++++++++++++++++++++++
>      net/vmnet-host.c    |  93 ++++++++++++++
>      net/vmnet-shared.c  |  94 ++++++++++++++
>      net/vmnet_int.h     |  48 ++++++++
>      qapi/net.json       |  99 ++++++++++++++-
>      qemu-options.hx     |  17 +++
>      12 files changed, 830 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
>
>     -- 
>     2.23.0
>



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

* Re: [PATCH 0/7] Add vmnet.framework based network backend
  2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
                   ` (7 preceding siblings ...)
  2021-08-06 19:03 ` [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
@ 2021-08-12  6:00 ` Roman Bolshakov
  2021-08-17  9:10   ` Vladislav Yaroshchuk
  8 siblings, 1 reply; 15+ messages in thread
From: Roman Bolshakov @ 2021-08-12  6:00 UTC (permalink / raw)
  To: Vladislav Yaroshchuk
  Cc: Thomas Huth, Stefan Hajnoczi, jasowang, qemu-devel,
	Cameron Esfahani, Markus Armbruster, Phillip Tennen,
	Howard Spoelstra, Alessio Dionisi

On Thu, Jun 17, 2021 at 05:32:39PM +0300, Vladislav Yaroshchuk wrote:
> macOS provides networking API for VMs called vmnet.framework.
> I tried to add it as a network backend. All three modes are supported:
> 
> -shared:
>   allows the guest to comminicate with other guests in shared mode and
>   also with external network (Internet) via NAT
> 
> -host:
>   allows the guest to communicate with other guests in host mode
> 
> -bridged:
>   bridges the guest with a physical network interface
> 
> Separate netdev for each vmnet mode was created because they use quite
> different settings, especially since macOS 11.0 when vmnet.framework
> gets a lot of updates.
> 
> Not sure that I use qemu_mutex_lock_iothread() and
> qemu_mutex_unlock_iothread() in correct way while sending packet
> from vmnet interface to QEMU. I'll be happy to receive
> recomendations how to make this thing better if I done sth wrong.
> 
> Also vmnet.framework requires com.apple.vm.networking entitlement to
> run without root priveledges. Ad-hoc signing does not fit there,
> so I didn't touch anything related to signing. As a result we should
> run qemu-system by a priviledged user:
> `$ sudo qemu-system-x86_64 -nic vmnet-shared`
> otherwise vmnet fails with 'general failure'.
> 
> But in any way it seems working now,
> I tested it within qemu-system-x86-64 on macOS 10.15.7 host, with nic
> models:
> - e1000-82545em
> - virtio-net-pci
> 
> and having such guests:
> - macOS 10.15.7
> - Ubuntu Bionic (server cloudimg) 
> 

Hi Vladislav,

I appreciate the efforts and I'm sorry I didn't look into it yet, lack
of time :(

To all: earlier this year another series was sent by Phillip Tennen to
add vmnet.framework and some comments were provided:
https://mail.gnu.org/archive/html/qemu-devel/2021-02/msg05874.html

I'm not sure how to proceed with arbitration which of the series is
preferred. FIFO or LIFO?

Regards,
Roman

> Vladislav Yaroshchuk (7):
>   net/vmnet: dependencies setup, initial preparations
>   net/vmnet: add new netdevs to qapi/net
>   net/vmnet: create common netdev state structure
>   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
> 
>  configure           |  31 +++++
>  meson.build         |   5 +
>  net/clients.h       |  11 ++
>  net/meson.build     |   7 ++
>  net/net.c           |  10 ++
>  net/vmnet-bridged.m | 123 ++++++++++++++++++
>  net/vmnet-common.m  | 294 ++++++++++++++++++++++++++++++++++++++++++++
>  net/vmnet-host.c    |  93 ++++++++++++++
>  net/vmnet-shared.c  |  94 ++++++++++++++
>  net/vmnet_int.h     |  48 ++++++++
>  qapi/net.json       |  99 ++++++++++++++-
>  qemu-options.hx     |  17 +++
>  12 files changed, 830 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
> 
> -- 
> 2.23.0
> 


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

* Re: [PATCH 0/7] Add vmnet.framework based network backend
  2021-08-12  6:00 ` Roman Bolshakov
@ 2021-08-17  9:10   ` Vladislav Yaroshchuk
  0 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-08-17  9:10 UTC (permalink / raw)
  To: Roman Bolshakov
  Cc: Thomas Huth, Stefan Hajnoczi, jasowang, qemu-devel,
	Cameron Esfahani, Markus Armbruster, Phillip Tennen,
	Howard Spoelstra, Alessio Dionisi

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

Hi Roman,

Sorry for the late reply. In my series of patches I partially reuse Phillip
Tennen's work that you have mentioned
https://mail.gnu.org/archive/html/qemu-devel/2021-02/msg05874.html. The
main idea and provided feature is the same, so please select the series on
your choice. I just can say that I'm ready to update/improve my patches
asap, make them ready to be merged. Can't say anything about Phillip, is he
ready too or not.

Regards,
Vladislav

чт, 12 авг. 2021 г. в 09:01, Roman Bolshakov <r.bolshakov@yadro.com>:

> On Thu, Jun 17, 2021 at 05:32:39PM +0300, Vladislav Yaroshchuk wrote:
> > macOS provides networking API for VMs called vmnet.framework.
> > I tried to add it as a network backend. All three modes are supported:
> >
> > -shared:
> >   allows the guest to comminicate with other guests in shared mode and
> >   also with external network (Internet) via NAT
> >
> > -host:
> >   allows the guest to communicate with other guests in host mode
> >
> > -bridged:
> >   bridges the guest with a physical network interface
> >
> > Separate netdev for each vmnet mode was created because they use quite
> > different settings, especially since macOS 11.0 when vmnet.framework
> > gets a lot of updates.
> >
> > Not sure that I use qemu_mutex_lock_iothread() and
> > qemu_mutex_unlock_iothread() in correct way while sending packet
> > from vmnet interface to QEMU. I'll be happy to receive
> > recomendations how to make this thing better if I done sth wrong.
> >
> > Also vmnet.framework requires com.apple.vm.networking entitlement to
> > run without root priveledges. Ad-hoc signing does not fit there,
> > so I didn't touch anything related to signing. As a result we should
> > run qemu-system by a priviledged user:
> > `$ sudo qemu-system-x86_64 -nic vmnet-shared`
> > otherwise vmnet fails with 'general failure'.
> >
> > But in any way it seems working now,
> > I tested it within qemu-system-x86-64 on macOS 10.15.7 host, with nic
> > models:
> > - e1000-82545em
> > - virtio-net-pci
> >
> > and having such guests:
> > - macOS 10.15.7
> > - Ubuntu Bionic (server cloudimg)
> >
>
> Hi Vladislav,
>
> I appreciate the efforts and I'm sorry I didn't look into it yet, lack
> of time :(
>
> To all: earlier this year another series was sent by Phillip Tennen to
> add vmnet.framework and some comments were provided:
> https://mail.gnu.org/archive/html/qemu-devel/2021-02/msg05874.html
>
> I'm not sure how to proceed with arbitration which of the series is
> preferred. FIFO or LIFO?
>
> Regards,
> Roman
>
> > Vladislav Yaroshchuk (7):
> >   net/vmnet: dependencies setup, initial preparations
> >   net/vmnet: add new netdevs to qapi/net
> >   net/vmnet: create common netdev state structure
> >   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
> >
> >  configure           |  31 +++++
> >  meson.build         |   5 +
> >  net/clients.h       |  11 ++
> >  net/meson.build     |   7 ++
> >  net/net.c           |  10 ++
> >  net/vmnet-bridged.m | 123 ++++++++++++++++++
> >  net/vmnet-common.m  | 294 ++++++++++++++++++++++++++++++++++++++++++++
> >  net/vmnet-host.c    |  93 ++++++++++++++
> >  net/vmnet-shared.c  |  94 ++++++++++++++
> >  net/vmnet_int.h     |  48 ++++++++
> >  qapi/net.json       |  99 ++++++++++++++-
> >  qemu-options.hx     |  17 +++
> >  12 files changed, 830 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
> >
> > --
> > 2.23.0
> >
>

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

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

* Re: [PATCH 2/7] net/vmnet: add new netdevs to qapi/net
  2021-08-06 21:19   ` Eric Blake
@ 2021-08-17  9:28     ` Vladislav Yaroshchuk
  0 siblings, 0 replies; 15+ messages in thread
From: Vladislav Yaroshchuk @ 2021-08-17  9:28 UTC (permalink / raw)
  To: Eric Blake; +Cc: jasowang, Roman Bolshakov, qemu-devel

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

Hi Eric,
Thank you for your review.

сб, 7 авг. 2021 г. в 00:19, Eric Blake <eblake@redhat.com>:

> On Thu, Jun 17, 2021 at 05:32:41PM +0300, Vladislav Yaroshchuk wrote:
> > Created separate netdev per each vmnet operating mode
> > because they use quite different settings. Especially since
> > macOS 11.0 (vmnet.framework API gets lots of updates)
> >
> > Three new netdevs are added:
> > - vmnet-host
> > - vmnet-shared
> > - vmnet-bridged
> >
> > Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> > ---
>
> > +++ b/qapi/net.json
> > @@ -452,6 +452,89 @@
> >      '*vhostdev':     'str',
> >      '*queues':       'int' } }
> >
> > +##
> > +# @NetdevVmnetHostOptions:
> > +#
> > +# vmnet (host mode) network backend.
> > +#
> > +# Allows the vmnet interface to communicate with
> > +# other vmnet interfaces that are in host mode and also with the native
> host.
> > +#
> > +# @dhcpstart: The starting IPv4 address to use for the interface. Must
> be in the
> > +#             private IP range (RFC 1918). Must be specified along
> > +#             with @dhcpend and @subnetmask.
> > +#             This address is used as the gateway address. The
> subsequent address
> > +#             up to and including dhcpend are  placed in the DHCP pool.
> > +#
> > +# @dhcpend: The DHCP IPv4 range end address to use for the interface.
> Must be in
> > +#           the private IP range (RFC 1918). Must be specified along
> > +#           with @dhcpstart and @subnetmask.
> > +#
> > +# @subnetmask: The IPv4 subnet mask to use on the interface. Must be
> specified
> > +#              along with @dhcpstart and @subnetmask.
> > +#
> > +#
> > +# Since: 6.1,
> > +##
>
> Same comments about 6.1 vs. 6.2 as before (I'll quit pointing it out).
> Spurious trailing comma.
>
> > +{ 'struct': 'NetdevVmnetHostOptions',
> > +  'data': {
> > +    '*dhcpstart':   'str',
> > +    '*dhcpend':     'str',
> > +    '*subnetmask':  'str'
>
> Hmm. You listed all three as optional, but document that they must all
> be specified together.  Why not just make them all required, and
> simplify the documentation?
>
> All three options can be not specified at all, or, if specified, must be
used all together. It's the user's choice to adjust DHCP settings or leave
it for vmnet.framework.
`-netdev vmnet-host` is correct and `-netdev
vmnet-host,dhcpstart="..",dhcpend="..",subnetmask=".."` is correct too. So
we can't make all the options required

> > +  },
> > +  'if': 'defined(CONFIG_VMNET)' }
> > +
> > +##
> > +# @NetdevVmnetSharedOptions:
> > +#
> > +# vmnet (shared mode) network backend.
> > +#
> > +# Allows traffic originating from the vmnet interface to reach the
> > +# Internet through a network address translator (NAT). The vmnet
> interface
> > +# can also communicate with the native host. By default, the vmnet
> interface
> > +# is able to communicate with other shared mode interfaces. If a subnet
> range
> > +# is specified, the vmnet interface can communicate with other shared
> mode
> > +# interfaces on the same subnet.
> > +#
> > +# @dhcpstart: The starting IPv4 address to use for the interface. Must
> be in the
> > +#             private IP range (RFC 1918). Must be specified along
> > +#             with @dhcpend and @subnetmask.
> > +#             This address is used as the gateway address. The
> subsequent address
> > +#             up to and including dhcpend are  placed in the DHCP pool.
>
> Spurious double space.
>
> > +#
> > +# @dhcpend: The DHCP IPv4 range end address to use for the interface.
> Must be in
> > +#           the private IP range (RFC 1918). Must be specified along
> > +#           with @dhcpstart and @subnetmask.
> > +#
> > +# @subnetmask: The IPv4 subnet mask to use on the interface. Must be
> specified
> > +#              along with @dhcpstart and @subnetmask.
> > +#
> > +#
> > +# Since: 6.1,
> > +##
> > +{ 'struct': 'NetdevVmnetSharedOptions',
> > +  'data': {
> > +    '*dhcpstart':    'str',
> > +    '*dhcpend':      'str',
> > +    '*subnetmask':   'str'
> > +  },
> > +  'if': 'defined(CONFIG_VMNET)' }
> > +
> > +##
> > +# @NetdevVmnetBridgedOptions:
> > +#
> > +# vmnet (bridged mode) network backend.
> > +#
> > +# Bridges the vmnet interface with a physical network interface.
> > +#
> > +# @ifname: The name of the physical interface to be bridged.
> > +#
> > +# Since: 6.1
> > +##
> > +{ 'struct': 'NetdevVmnetBridgedOptions',
> > +  'data': { 'ifname': 'str' },
> > +  'if': 'defined(CONFIG_VMNET)' }
> > +
> >  ##
> >  # @NetClientDriver:
> >  #
> > @@ -460,11 +543,16 @@
> >  # Since: 2.7
> >  #
> >  #        @vhost-vdpa since 5.1
> > -#        @vmnet since 6.1
>
> Why are you dropping vmnet?  Especially since you just added it in the
> previous patch?  That feels like needless churn.
>
> Yep, that was my mistake, on that stage I decided to create separate
backends for each vmnet operational mode. Will remove redundant change the
next series.

> +#        @vmnet-host since 6.1
> > +#        @vmnet-shared since 6.1
> > +#        @vmnet-bridged since 6.1
> >  ##
> >  { 'enum': 'NetClientDriver',
> >    'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> > -            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
> 'vmnet' ] }
> > +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
> > +            { 'name': 'vmnet-host', 'if': 'defined(CONFIG_VMNET)' },
> > +            { 'name': 'vmnet-shared', 'if': 'defined(CONFIG_VMNET)' },
> > +            { 'name': 'vmnet-bridged', 'if': 'defined(CONFIG_VMNET)' }]
> }
>
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3266
> Virtualization:  qemu.org | libvirt.org
>
>
Will fix all other issues asap, thank you!

Regards,
Vladislav

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

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

end of thread, other threads:[~2021-08-17  9:29 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-17 14:32 [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
2021-06-17 14:32 ` [PATCH 1/7] net/vmnet: dependencies setup, initial preparations Vladislav Yaroshchuk
2021-08-06 21:13   ` Eric Blake
2021-06-17 14:32 ` [PATCH 2/7] net/vmnet: add new netdevs to qapi/net Vladislav Yaroshchuk
2021-08-06 21:19   ` Eric Blake
2021-08-17  9:28     ` Vladislav Yaroshchuk
2021-06-17 14:32 ` [PATCH 3/7] net/vmnet: create common netdev state structure Vladislav Yaroshchuk
2021-06-17 14:32 ` [PATCH 4/7] net/vmnet: implement shared mode (vmnet-shared) Vladislav Yaroshchuk
2021-06-17 14:32 ` [PATCH 5/7] net/vmnet: implement host mode (vmnet-host) Vladislav Yaroshchuk
2021-06-17 14:32 ` [PATCH 6/7] net/vmnet: implement bridged mode (vmnet-bridged) Vladislav Yaroshchuk
2021-06-17 14:32 ` [PATCH 7/7] net/vmnet: update qemu-options.hx Vladislav Yaroshchuk
2021-08-06 19:03 ` [PATCH 0/7] Add vmnet.framework based network backend Vladislav Yaroshchuk
2021-08-09  3:23   ` Jason Wang
2021-08-12  6:00 ` Roman Bolshakov
2021-08-17  9:10   ` 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.