Add a QMP equivalent to hmp "info usernet", so we can disable HMP.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/net.json | 44 ++++++++++++++++++++++++++++++++++++++++++++
net/slirp.c | 34 ++++++++++++++++++++++++++++------
2 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/qapi/net.json b/qapi/net.json
index 118bd349651..dd56215fd15 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -1191,3 +1191,47 @@
##
{ 'event': 'NETDEV_VHOST_USER_DISCONNECTED',
'data': { 'netdev-id': 'str' } }
+
+##
+# @UsernetInfo:
+#
+# Information about a user-mode network stack (slirp).
+#
+# @hub-id: The hub id, if available.
+#
+# @hub-name: The name of the hub.
+#
+# @info: Network information from slirp.
+#
+# Since: 11.1
+##
+{ 'struct': 'UsernetInfo',
+ 'data': {
+ '*hub-id': 'int',
+ 'hub-name': 'str',
+ 'info': 'str' },
+ 'if': 'CONFIG_SLIRP' }
+
+##
+# @x-query-usernet:
+#
+# Query user-mode network stack connection states.
+#
+# Features:
+#
+# @unstable: This command is meant for debugging.
+#
+# Returns: list of user-mode network stack information.
+#
+# Since: 11.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "x-query-usernet" }
+# <- { "return": [ { "hub-id": 0, "hub-name": "vnet",
+# "info": "..." } ] }
+##
+{ 'command': 'x-query-usernet',
+ 'returns': ['UsernetInfo'],
+ 'if': 'CONFIG_SLIRP',
+ 'features': [ 'unstable' ] }
diff --git a/net/slirp.c b/net/slirp.c
index 04925f33187..d3ed5ec9cb8 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -43,6 +43,7 @@
#include "system/system.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-net.h"
#include "qobject/qdict.h"
#include "util.h"
#include "migration/register.h"
@@ -1199,18 +1200,39 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
return -1;
}
-void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+UsernetInfoList *qmp_x_query_usernet(Error **errp)
{
+ UsernetInfoList *head = NULL, **tail = &head;
SlirpState *s;
QTAILQ_FOREACH(s, &slirp_stacks, entry) {
+ UsernetInfo *ui = g_new0(UsernetInfo, 1);
int id;
- bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
- char *info = slirp_connection_info(s->slirp);
+
+ if (net_hub_id_for_client(&s->nc, &id) == 0) {
+ ui->has_hub_id = true;
+ ui->hub_id = id;
+ }
+ ui->hub_name = g_strdup(s->nc.name);
+ ui->info = slirp_connection_info(s->slirp);
+
+ QAPI_LIST_APPEND(tail, ui);
+ }
+
+ return head;
+}
+
+void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+{
+ g_autoptr(UsernetInfoList) list = NULL;
+ UsernetInfoList *entry;
+
+ list = qmp_x_query_usernet(&error_abort);
+ for (entry = list; entry; entry = entry->next) {
+ UsernetInfo *ui = entry->value;
monitor_printf(mon, "Hub %d (%s):\n%s",
- got_hub_id ? id : -1,
- s->nc.name, info);
- g_free(info);
+ ui->has_hub_id ? (int)ui->hub_id : -1,
+ ui->hub_name, ui->info);
}
}
--
2.54.0