qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH v2 2/8] qapi: net: introduce a way to bypass qemu_opts_parse_


From: Laurent Vivier
Subject: [RFC PATCH v2 2/8] qapi: net: introduce a way to bypass qemu_opts_parse_noisily()
Date: Thu, 12 May 2022 10:09:26 +0200

As qemu_opts_parse_noisily() flattens the QAPI structures ("type" field
of Netdev structure can collides with "type" field of SocketAddress),
we introduce a way to bypass qemu_opts_parse_noisily() and use directly
visit_type_Netdev() to parse the backend parameters.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 net/net.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/net/net.c b/net/net.c
index 58c05c200622..2aab7167316c 100644
--- a/net/net.c
+++ b/net/net.c
@@ -54,6 +54,7 @@
 #include "net/colo-compare.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
+#include "qapi/qobject-input-visitor.h"
 
 /* Net bridge is currently not supported for W32. */
 #if !defined(_WIN32)
@@ -63,6 +64,17 @@
 static VMChangeStateEntry *net_change_state_entry;
 static QTAILQ_HEAD(, NetClientState) net_clients;
 
+typedef struct NetdevQueueEntry {
+    bool is_netdev;
+    Netdev *nd;
+    Location loc;
+    QSIMPLEQ_ENTRY(NetdevQueueEntry) entry;
+} NetdevQueueEntry;
+
+typedef QSIMPLEQ_HEAD(, NetdevQueueEntry) NetdevQueue;
+
+static NetdevQueue nd_queue = QSIMPLEQ_HEAD_INITIALIZER(nd_queue);
+
 /***********************************************************/
 /* network device redirectors */
 
@@ -1559,6 +1571,19 @@ int net_init_clients(Error **errp)
 
     QTAILQ_INIT(&net_clients);
 
+    while (!QSIMPLEQ_EMPTY(&nd_queue)) {
+        NetdevQueueEntry *nd = QSIMPLEQ_FIRST(&nd_queue);
+
+        QSIMPLEQ_REMOVE_HEAD(&nd_queue, entry);
+        loc_push_restore(&nd->loc);
+        if (net_client_init1(nd->nd, nd->is_netdev, errp) < 0) {
+            return -1;
+        }
+        loc_pop(&nd->loc);
+        qapi_free_Netdev(nd->nd);
+        g_free(nd);
+    }
+
     if (qemu_opts_foreach(qemu_find_opts("netdev"),
                           net_init_netdev, NULL, errp)) {
         return -1;
@@ -1575,8 +1600,37 @@ int net_init_clients(Error **errp)
     return 0;
 }
 
+/*
+ * netdev_is_modern() returns true when the backend needs to bypass
+ * qemu_opts_parse_noisily()
+ */
+static bool netdev_is_modern(const char *optarg)
+{
+    return false;
+}
+
 int net_client_parse(QemuOptsList *opts_list, const char *optarg)
 {
+    if (netdev_is_modern(optarg)) {
+            /*
+             * We need to bypass qemu_opts_parse_noisily() to accept
+             * new style object like addr.type=inet in SocketAddress
+             */
+            Visitor *v;
+            NetdevQueueEntry *nd;
+
+            v = qobject_input_visitor_new_str(optarg, "type",
+                                              &error_fatal);
+            nd = g_new(NetdevQueueEntry, 1);
+            visit_type_Netdev(v, NULL, &nd->nd, &error_fatal);
+            visit_free(v);
+            loc_save(&nd->loc);
+            nd->is_netdev = strcmp(opts_list->name, "netdev") == 0;
+
+            QSIMPLEQ_INSERT_TAIL(&nd_queue, nd, entry);
+            return 0;
+    }
+
     if (!qemu_opts_parse_noisily(opts_list, optarg, true)) {
         return -1;
     }
-- 
2.35.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]