xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH v2 0/4] Introducing QMP query-netdevs command
@ 2020-03-04 13:06 Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 1/4] qapi: net: Add " Alexey Kirillov
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-04 13:06 UTC (permalink / raw)
  To: Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Laurent Vivier, Jiri Pirko, yc-core, Stefan Weil,
	Alistair Francis, Beniamino Galvani, qemu-arm, Peter Chubb,
	Cédric Le Goater, xen-devel, Giuseppe Lettieri, Luigi Rizzo,
	Richard Henderson, Andrew Jeffery, Michael Walle, qemu-ppc,
	Aleksandar Markovic, Alexey Kirillov, Paolo Bonzini

This patch series introduces a new QMP command "query-netdevs" to get
information about currently attached network devices.
Also, since the "info_str" field of "NetClientState" is now deprecated,
it has been completely removed.
The HMP command "info network" now also uses the new QMP command inside.

Usage example:

-> { "execute": "query-netdevs" }
<- { "return": [
         {
             "peer": "netdev0",
             "netdev": "netdev0",
             "perm-mac": "52:54:00:12:34:56"
             "model": "virtio-net-pci",
             "macaddr": "52:54:00:12:34:56",
             "queues-count": 1,
             "type": "nic",
             "id": "net0"
         },
         {
             "peer": "net0",
             "ipv6": true,
             "ipv4": true,
             "host": "10.0.2.2",
             "queues-count": 1,
             "ipv6-dns": "fec0::3",
             "ipv6-prefix": "fec0::",
             "net": "10.0.2.0/255.255.255.0",
             "ipv6-host": "fec0::2",
             "type": "user",
             "dns": "10.0.2.3",
             "hostfwd": [
                 {
                     "str": "tcp::20004-:22"
                 }
             ],
             "ipv6-prefixlen": 64,
             "id": "netdev0",
             "restrict": false
         }
     ]
   }

v2->v1:
- Rewrite HMP "info network" to get information from results of QMP command.
- Remove obsolete field "info_str" from "NetClientState".

Alexey Kirillov (4):
  qapi: net: Add query-netdevs command
  tests: Add tests for query-netdevs command
  hmp: Use QMP query-netdevs in hmp_info_network
  net: Remove field info_str of NetClientState

 hw/net/allwinner_emac.c          |   2 +-
 hw/net/dp8393x.c                 |   2 +-
 hw/net/e1000.c                   |   4 +-
 hw/net/e1000e.c                  |   2 +-
 hw/net/e1000e_core.c             |   2 +-
 hw/net/e1000x_common.c           |   2 +-
 hw/net/eepro100.c                |   5 +-
 hw/net/etraxfs_eth.c             |   2 +-
 hw/net/fsl_etsec/etsec.c         |   2 +-
 hw/net/ftgmac100.c               |   2 +-
 hw/net/i82596.c                  |   6 +-
 hw/net/imx_fec.c                 |   2 +-
 hw/net/lan9118.c                 |   4 +-
 hw/net/mcf_fec.c                 |   2 +-
 hw/net/milkymist-minimac2.c      |   2 +-
 hw/net/mipsnet.c                 |   2 +-
 hw/net/ne2000-isa.c              |   2 +-
 hw/net/ne2000-pci.c              |   2 +-
 hw/net/pcnet.c                   |   2 +-
 hw/net/rocker/rocker_fp.c        |   4 +-
 hw/net/rtl8139.c                 |   6 +-
 hw/net/smc91c111.c               |   2 +-
 hw/net/spapr_llan.c              |   6 +-
 hw/net/stellaris_enet.c          |   2 +-
 hw/net/sungem.c                  |   4 +-
 hw/net/sunhme.c                  |   2 +-
 hw/net/tulip.c                   |   2 +-
 hw/net/virtio-net.c              |   8 +-
 hw/net/vmxnet3.c                 |   4 +-
 hw/net/xen_nic.c                 |   4 -
 hw/net/xgmac.c                   |   2 +-
 hw/net/xilinx_axienet.c          |   2 +-
 hw/net/xilinx_ethlite.c          |   2 +-
 hw/usb/dev-network.c             |   2 +-
 include/net/net.h                |   7 +-
 net/clients.h                    |   1 +
 net/hub.c                        |  12 +-
 net/hub.h                        |   2 +-
 net/l2tpv3.c                     |  20 ++-
 net/net.c                        | 272 +++++++++++++++++++++++++++++--
 net/netmap.c                     |  13 ++
 net/slirp.c                      | 128 ++++++++++++++-
 net/socket.c                     |  93 ++++++++---
 net/tap-win32.c                  |   9 +
 net/tap.c                        | 107 ++++++++++--
 net/vde.c                        |  40 ++++-
 net/vhost-user.c                 |  20 ++-
 qapi/net.json                    |  89 ++++++++++
 tests/qtest/Makefile.include     |   2 +
 tests/qtest/test-query-netdevs.c | 120 ++++++++++++++
 50 files changed, 917 insertions(+), 119 deletions(-)
 create mode 100644 tests/qtest/test-query-netdevs.c

-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH v2 1/4] qapi: net: Add query-netdevs command
  2020-03-04 13:06 [Xen-devel] [PATCH v2 0/4] Introducing QMP query-netdevs command Alexey Kirillov
@ 2020-03-04 13:06 ` Alexey Kirillov
  2020-03-04 15:57   ` Laurent Vivier
  2020-03-05 12:02   ` Markus Armbruster
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 2/4] tests: Add tests for " Alexey Kirillov
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-04 13:06 UTC (permalink / raw)
  To: Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Laurent Vivier, Jiri Pirko, yc-core, Stefan Weil,
	Alistair Francis, Beniamino Galvani, qemu-arm, Peter Chubb,
	Cédric Le Goater, xen-devel, Giuseppe Lettieri, Luigi Rizzo,
	Richard Henderson, Andrew Jeffery, Michael Walle, qemu-ppc,
	Aleksandar Markovic, Alexey Kirillov, Paolo Bonzini

Add a qmp command that provides information about currently attached
network devices and their configuration.

Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
---
 include/net/net.h |   1 +
 net/hub.c         |   8 +++
 net/l2tpv3.c      |  19 +++++++
 net/net.c         |  91 +++++++++++++++++++++++++++++++++
 net/netmap.c      |  13 +++++
 net/slirp.c       | 126 ++++++++++++++++++++++++++++++++++++++++++++++
 net/socket.c      |  71 ++++++++++++++++++++++++++
 net/tap-win32.c   |   9 ++++
 net/tap.c         | 103 +++++++++++++++++++++++++++++++++++--
 net/vde.c         |  26 ++++++++++
 net/vhost-user.c  |  18 +++++--
 qapi/net.json     |  89 ++++++++++++++++++++++++++++++++
 12 files changed, 566 insertions(+), 8 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index e175ba9677..2c8956c0b3 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -92,6 +92,7 @@ struct NetClientState {
     char *model;
     char *name;
     char info_str[256];
+    NetdevInfo *stored_config;
     unsigned receive_disabled : 1;
     NetClientDestructor *destructor;
     unsigned int queue_index;
diff --git a/net/hub.c b/net/hub.c
index 5795a678ed..37995b5517 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -148,6 +148,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
     NetHubPort *port;
     int id = hub->num_ports++;
     char default_name[128];
+    NetdevHubPortOptions *stored;
 
     if (!name) {
         snprintf(default_name, sizeof(default_name),
@@ -160,6 +161,13 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
     port->id = id;
     port->hub = hub;
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_HUBPORT;
+    stored = &nc->stored_config->u.hubport;
+
+    stored->hubid = hub->id;
+
     QLIST_INSERT_HEAD(&hub->ports, port, next);
 
     return port;
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 55fea17c0f..f4e45e7b28 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -535,6 +535,7 @@ int net_init_l2tpv3(const Netdev *netdev,
     struct addrinfo hints;
     struct addrinfo *result = NULL;
     char *srcport, *dstport;
+    NetdevL2TPv3Options *stored;
 
     nc = qemu_new_net_client(&net_l2tpv3_info, peer, "l2tpv3", name);
 
@@ -726,6 +727,24 @@ int net_init_l2tpv3(const Netdev *netdev,
 
     l2tpv3_read_poll(s, true);
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_L2TPV3;
+    stored = &nc->stored_config->u.l2tpv3;
+
+    memcpy(stored, l2tpv3, sizeof(NetdevL2TPv3Options));
+
+    stored->src = g_strdup(l2tpv3->src);
+    stored->dst = g_strdup(l2tpv3->dst);
+
+    if (l2tpv3->has_srcport) {
+        stored->srcport = g_strdup(l2tpv3->srcport);
+    }
+
+    if (l2tpv3->has_dstport) {
+        stored->dstport = g_strdup(l2tpv3->dstport);
+    }
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "l2tpv3: connected");
     return 0;
diff --git a/net/net.c b/net/net.c
index 9e93c3f8a1..01e0548295 100644
--- a/net/net.c
+++ b/net/net.c
@@ -54,6 +54,7 @@
 #include "sysemu/sysemu.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
+#include "qapi/clone-visitor.h"
 
 /* Net bridge is currently not supported for W32. */
 #if !defined(_WIN32)
@@ -128,6 +129,12 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr)
 
 void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 {
+    g_assert(nc->stored_config);
+
+    g_free(nc->stored_config->u.nic.macaddr);
+    nc->stored_config->u.nic.macaddr = g_strdup_printf(MAC_FMT,
+                                                       MAC_ARG(macaddr));
+
     snprintf(nc->info_str, sizeof(nc->info_str),
              "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
              nc->model,
@@ -283,6 +290,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
     NetClientState **peers = conf->peers.ncs;
     NICState *nic;
     int i, queues = MAX(1, conf->peers.queues);
+    NetLegacyNicOptions *stored;
 
     assert(info->type == NET_CLIENT_DRIVER_NIC);
     assert(info->size >= sizeof(NICState));
@@ -298,6 +306,27 @@ NICState *qemu_new_nic(NetClientInfo *info,
         nic->ncs[i].queue_index = i;
     }
 
+    /* Store startup parameters */
+    nic->ncs[0].stored_config = g_new0(NetdevInfo, 1);
+    nic->ncs[0].stored_config->type = NET_CLIENT_DRIVER_NIC;
+    stored = &nic->ncs[0].stored_config->u.nic;
+
+    /* Read-only in runtime */
+    nic->ncs[0].stored_config->has_perm_mac = true;
+    nic->ncs[0].stored_config->perm_mac = g_strdup_printf(MAC_FMT,
+        MAC_ARG(conf->macaddr.a));
+
+    if (peers[0]) {
+        stored->has_netdev = true;
+        stored->netdev = g_strdup(peers[0]->name);
+    }
+
+    stored->has_macaddr = true;
+    stored->macaddr = g_strdup_printf(MAC_FMT, MAC_ARG(conf->macaddr.a));
+
+    stored->has_model = true;
+    stored->model = g_strdup(model);
+
     return nic;
 }
 
@@ -344,6 +373,7 @@ static void qemu_free_net_client(NetClientState *nc)
     }
     g_free(nc->name);
     g_free(nc->model);
+    qapi_free_NetdevInfo(nc->stored_config);
     if (nc->destructor) {
         nc->destructor(nc);
     }
@@ -1320,6 +1350,67 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
     return filter_list;
 }
 
+NetdevInfoList *qmp_query_netdevs(Error **errp)
+{
+    NetdevInfoList *list = NULL;
+    NetClientState *nc;
+
+    QTAILQ_FOREACH(nc, &net_clients, next) {
+        /* Only look at netdevs, not for each queue */
+        if (nc->stored_config) {
+            NetdevInfoList *node = g_new0(NetdevInfoList, 1);
+
+            node->value = QAPI_CLONE(NetdevInfo, nc->stored_config);
+            g_free(node->value->id); /* Need to dealloc default empty id */
+            node->value->id = g_strdup(nc->name);
+
+            if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
+                NICState *state = qemu_get_nic(nc);
+                assert(state);
+
+                /* NIC have explicit number of queues */
+                assert(state->conf);
+                node->value->queues_count = state->conf->peers.queues;
+            } else {
+                /* Not a NIC, but can have queues */
+                NetClientState *nc_iterable;
+
+                QTAILQ_FOREACH(nc_iterable, &net_clients, next) {
+                    if (strcmp(nc_iterable->name, nc->name) == 0) {
+                        node->value->queues_count++;
+                    }
+                }
+            }
+
+            node->value->has_peer = nc->peer != NULL;
+            if (node->value->has_peer) {
+                node->value->peer = g_strdup(nc->peer->name);
+            }
+
+            node->value->has_hub =
+                net_hub_id_for_client(nc, (int *)&node->value->hub) == 0;
+
+            /*
+             * Copy the current hubport peer id to connected netdev id,
+             * because it could have been changed at runtime
+             */
+            if (nc->info->type == NET_CLIENT_DRIVER_HUBPORT) {
+                if (node->value->has_peer) {
+                    g_free(node->value->u.hubport.netdev);
+
+                    node->value->u.hubport.has_netdev = true;
+                    node->value->u.hubport.netdev = g_strdup(nc->peer->name);
+                }
+            }
+
+            node->next = list;
+            list = node;
+        }
+    }
+
+    return list;
+}
+
 void hmp_info_network(Monitor *mon, const QDict *qdict)
 {
     NetClientState *nc, *peer;
diff --git a/net/netmap.c b/net/netmap.c
index 350f097f91..71feacb92c 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -411,6 +411,7 @@ int net_init_netmap(const Netdev *netdev,
     NetClientState *nc;
     Error *err = NULL;
     NetmapState *s;
+    NetdevNetmapOptions *stored;
 
     nmd = netmap_open(netmap_opts, &err);
     if (err) {
@@ -427,6 +428,18 @@ int net_init_netmap(const Netdev *netdev,
     pstrcpy(s->ifname, sizeof(s->ifname), netmap_opts->ifname);
     netmap_read_poll(s, true); /* Initially only poll for reads. */
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_NETMAP;
+    stored = &nc->stored_config->u.netmap;
+
+    stored->ifname = g_strdup(netmap_opts->ifname);
+
+    if (netmap_opts->has_devname) {
+        stored->has_devname = true;
+        stored->devname = g_strdup(netmap_opts->devname);
+    }
+
     return 0;
 }
 
diff --git a/net/slirp.c b/net/slirp.c
index c4334ee876..fb5b87ebed 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -346,6 +346,14 @@ static SaveVMHandlers savevm_slirp_state = {
     .load_state = net_slirp_state_load,
 };
 
+#define APPEND_STRINGLIST(tail, new_val) \
+    do { \
+        *(tail) = g_new0(StringList, 1); \
+        (*(tail))->value = g_new0(String, 1); \
+        (*(tail))->value->str = g_strdup((new_val)); \
+        (tail) = &((*(tail))->next); \
+    } while (0)
+
 static int net_slirp_init(NetClientState *peer, const char *model,
                           const char *name, int restricted,
                           bool ipv4, const char *vnetwork, const char *vhost,
@@ -378,6 +386,9 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     int shift;
     char *end;
     struct slirp_config_str *config;
+    NetdevUserOptions *stored;
+    StringList **stored_hostfwd;
+    StringList **stored_guestfwd;
 
     if (!ipv4 && (vnetwork || vhost || vnameserver)) {
         error_setg(errp, "IPv4 disabled but netmask/host/dns provided");
@@ -553,6 +564,112 @@ static int net_slirp_init(NetClientState *peer, const char *model,
 
     nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_USER;
+    stored = &nc->stored_config->u.user;
+
+    if (vhostname) {
+        stored->has_hostname = true;
+        stored->hostname = g_strdup(vhostname);
+    }
+
+    stored->has_q_restrict = true;
+    stored->q_restrict = restricted;
+
+    stored->has_ipv4 = true;
+    stored->ipv4 = ipv4;
+
+    stored->has_ipv6 = true;
+    stored->ipv6 = ipv6;
+
+    if (ipv4) {
+        uint8_t *net_bytes = (uint8_t *)&net;
+        uint8_t *mask_bytes = (uint8_t *)&mask;
+
+        stored->has_net = true;
+        stored->net = g_strdup_printf("%d.%d.%d.%d/%d.%d.%d.%d",
+                                      net_bytes[0], net_bytes[1],
+                                      net_bytes[2], net_bytes[3],
+                                      mask_bytes[0], mask_bytes[1],
+                                      mask_bytes[2], mask_bytes[3]);
+
+        stored->has_host = true;
+        stored->host = g_strdup(inet_ntoa(host));
+    }
+
+    if (tftp_export) {
+        stored->has_tftp = true;
+        stored->tftp = g_strdup(tftp_export);
+    }
+
+    if (bootfile) {
+        stored->has_bootfile = true;
+        stored->bootfile = g_strdup(bootfile);
+    }
+
+    if (vdhcp_start) {
+        stored->has_dhcpstart = true;
+        stored->dhcpstart = g_strdup(vdhcp_start);
+    }
+
+    if (ipv4) {
+        stored->has_dns = true;
+        stored->dns = g_strdup(inet_ntoa(dns));
+    }
+
+    if (dnssearch) {
+        stored->has_dnssearch = true;
+        StringList **stored_list = &stored->dnssearch;
+
+        for (int i = 0; dnssearch[i]; i++) {
+            APPEND_STRINGLIST(stored_list, dnssearch[i]);
+        }
+    }
+
+    if (vdomainname) {
+        stored->has_domainname = true;
+        stored->domainname = g_strdup(vdomainname);
+    }
+
+    if (ipv6) {
+        char addrstr[INET6_ADDRSTRLEN];
+        const char *res;
+
+        stored->has_ipv6_prefix = true;
+        stored->ipv6_prefix = g_strdup(vprefix6);
+
+        stored->has_ipv6_prefixlen = true;
+        stored->ipv6_prefixlen = vprefix6_len;
+
+        res = inet_ntop(AF_INET6, &ip6_host,
+                        addrstr, sizeof(addrstr));
+
+        stored->has_ipv6_host = true;
+        stored->ipv6_host = g_strdup(res);
+
+        res = inet_ntop(AF_INET6, &ip6_dns,
+                        addrstr, sizeof(addrstr));
+
+        stored->has_ipv6_dns = true;
+        stored->ipv6_dns = g_strdup(res);
+    }
+
+    if (smb_export) {
+        stored->has_smb = true;
+        stored->smb = g_strdup(smb_export);
+    }
+
+    if (vsmbserver) {
+        stored->has_smbserver = true;
+        stored->smbserver = g_strdup(vsmbserver);
+    }
+
+    if (tftp_server_name) {
+        stored->has_tftp_server_name = true;
+        stored->tftp_server_name = g_strdup(tftp_server_name);
+    }
+
     snprintf(nc->info_str, sizeof(nc->info_str),
              "net=%s,restrict=%s", inet_ntoa(net),
              restricted ? "on" : "off");
@@ -582,14 +699,23 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     s->poll_notifier.notify = net_slirp_poll_notify;
     main_loop_poll_add_notifier(&s->poll_notifier);
 
+    stored_hostfwd = &stored->hostfwd;
+    stored_guestfwd = &stored->guestfwd;
+
     for (config = slirp_configs; config; config = config->next) {
         if (config->flags & SLIRP_CFG_HOSTFWD) {
             if (slirp_hostfwd(s, config->str, errp) < 0) {
                 goto error;
+            } else {
+                stored->has_hostfwd = true;
+                APPEND_STRINGLIST(stored_hostfwd, config->str);
             }
         } else {
             if (slirp_guestfwd(s, config->str, errp) < 0) {
                 goto error;
+            } else {
+                stored->has_guestfwd = true;
+                APPEND_STRINGLIST(stored_guestfwd, config->str);
             }
         }
     }
diff --git a/net/socket.c b/net/socket.c
index c92354049b..2d2d5419ca 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -342,6 +342,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
     NetSocketState *s;
     SocketAddress *sa;
     SocketAddressType sa_type;
+    NetdevSocketOptions *stored;
 
     sa = socket_local_address(fd, errp);
     if (!sa) {
@@ -385,8 +386,19 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
     net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
     net_socket_read_poll(s, true);
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_SOCKET;
+    stored = &nc->stored_config->u.socket;
+
+    stored->has_fd = true;
+    stored->fd = g_strdup_printf("%d", fd);
+
     /* mcast: save bound address as dst */
     if (is_connected && mcast != NULL) {
+        stored->has_mcast = true;
+        stored->mcast = g_strdup(mcast);
+
         s->dgram_dst = saddr;
         snprintf(nc->info_str, sizeof(nc->info_str),
                  "socket: fd=%d (cloned mcast=%s:%d)",
@@ -428,6 +440,7 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
 {
     NetClientState *nc;
     NetSocketState *s;
+    NetdevSocketOptions *stored;
 
     nc = qemu_new_net_client(&net_socket_info, peer, model, name);
 
@@ -447,6 +460,15 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
     } else {
         qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
     }
+
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_SOCKET;
+    stored = &nc->stored_config->u.socket;
+
+    stored->has_fd = true;
+    stored->fd = g_strdup_printf("%d", fd);
+
     return s;
 }
 
@@ -483,6 +505,7 @@ static void net_socket_accept(void *opaque)
     struct sockaddr_in saddr;
     socklen_t len;
     int fd;
+    NetdevSocketOptions *stored;
 
     for(;;) {
         len = sizeof(saddr);
@@ -498,6 +521,13 @@ static void net_socket_accept(void *opaque)
     s->fd = fd;
     s->nc.link_down = false;
     net_socket_connect(s);
+
+    /* Store additional startup parameters (extend net_socket_listen_init) */
+    stored = &s->nc.stored_config->u.socket;
+
+    stored->has_fd = true;
+    stored->fd = g_strdup_printf("%d", fd);
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "socket: connection from %s:%d",
              inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
@@ -513,6 +543,7 @@ static int net_socket_listen_init(NetClientState *peer,
     NetSocketState *s;
     struct sockaddr_in saddr;
     int fd, ret;
+    NetdevSocketOptions *stored;
 
     if (parse_host_port(&saddr, host_str, errp) < 0) {
         return -1;
@@ -549,6 +580,15 @@ static int net_socket_listen_init(NetClientState *peer,
     net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
 
     qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_SOCKET;
+    stored = &nc->stored_config->u.socket;
+
+    stored->has_listen = true;
+    stored->listen = g_strdup(host_str);
+
     return 0;
 }
 
@@ -561,6 +601,7 @@ static int net_socket_connect_init(NetClientState *peer,
     NetSocketState *s;
     int fd, connected, ret;
     struct sockaddr_in saddr;
+    NetdevSocketOptions *stored;
 
     if (parse_host_port(&saddr, host_str, errp) < 0) {
         return -1;
@@ -598,6 +639,12 @@ static int net_socket_connect_init(NetClientState *peer,
         return -1;
     }
 
+    /* Store additional startup parameters (extend net_socket_fd_init) */
+    stored = &s->nc.stored_config->u.socket;
+
+    stored->has_connect = true;
+    stored->connect = g_strdup(host_str);
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "socket: connect to %s:%d",
              inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
@@ -615,6 +662,7 @@ static int net_socket_mcast_init(NetClientState *peer,
     int fd;
     struct sockaddr_in saddr;
     struct in_addr localaddr, *param_localaddr;
+    NetdevSocketOptions *stored;
 
     if (parse_host_port(&saddr, host_str, errp) < 0) {
         return -1;
@@ -643,6 +691,19 @@ static int net_socket_mcast_init(NetClientState *peer,
 
     s->dgram_dst = saddr;
 
+    /* Store additional startup parameters (extend net_socket_fd_init) */
+    stored = &s->nc.stored_config->u.socket;
+
+    if (!stored->has_mcast) {
+        stored->has_mcast = true;
+        stored->mcast = g_strdup(host_str);
+    }
+
+    if (localaddr_str) {
+        stored->has_localaddr = true;
+        stored->localaddr = g_strdup(localaddr_str);
+    }
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "socket: mcast=%s:%d",
              inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
@@ -660,6 +721,7 @@ static int net_socket_udp_init(NetClientState *peer,
     NetSocketState *s;
     int fd, ret;
     struct sockaddr_in laddr, raddr;
+    NetdevSocketOptions *stored;
 
     if (parse_host_port(&laddr, lhost, errp) < 0) {
         return -1;
@@ -698,6 +760,15 @@ static int net_socket_udp_init(NetClientState *peer,
 
     s->dgram_dst = raddr;
 
+    /* Store additional startup parameters (extend net_socket_fd_init) */
+    stored = &s->nc.stored_config->u.socket;
+
+    stored->has_localaddr = true;
+    stored->localaddr = g_strdup(lhost);
+
+    stored->has_udp = true;
+    stored->udp = g_strdup(rhost);
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "socket: udp=%s:%d",
              inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 2b5dcda36e..20ba0b1dc8 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -768,6 +768,7 @@ static int tap_win32_init(NetClientState *peer, const char *model,
     NetClientState *nc;
     TAPState *s;
     tap_win32_overlapped_t *handle;
+    NetdevTapOptions *stored;
 
     if (tap_win32_open(&handle, ifname) < 0) {
         printf("tap: Could not open '%s'\n", ifname);
@@ -778,6 +779,14 @@ static int tap_win32_init(NetClientState *peer, const char *model,
 
     s = DO_UPCAST(TAPState, nc, nc);
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_TAP;
+    stored = &nc->stored_config->u.tap;
+
+    stored->has_ifname = true;
+    stored->ifname = g_strdup(ifname);
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "tap: ifname=%s", ifname);
 
diff --git a/net/tap.c b/net/tap.c
index 6207f61f84..f40f378c2a 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -584,6 +584,7 @@ int net_init_bridge(const Netdev *netdev, const char *name,
     const char *helper, *br;
     TAPState *s;
     int fd, vnet_hdr;
+    NetdevBridgeOptions *stored;
 
     assert(netdev->type == NET_CLIENT_DRIVER_BRIDGE);
     bridge = &netdev->u.bridge;
@@ -600,6 +601,21 @@ int net_init_bridge(const Netdev *netdev, const char *name,
     vnet_hdr = tap_probe_vnet_hdr(fd);
     s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
 
+    /* Store startup parameters */
+    s->nc.stored_config = g_new0(NetdevInfo, 1);
+    s->nc.stored_config->type = NET_CLIENT_DRIVER_BRIDGE;
+    stored = &s->nc.stored_config->u.bridge;
+
+    if (br) {
+        stored->has_br = true;
+        stored->br = g_strdup(br);
+    }
+
+    if (helper) {
+        stored->has_helper = true;
+        stored->helper = g_strdup(helper);
+    }
+
     snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper,
              br);
 
@@ -647,11 +663,13 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
                              const char *model, const char *name,
                              const char *ifname, const char *script,
                              const char *downscript, const char *vhostfdname,
-                             int vnet_hdr, int fd, Error **errp)
+                             int vnet_hdr, int fd, NetdevInfo **common_stored,
+                             Error **errp)
 {
     Error *err = NULL;
     TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
     int vhostfd;
+    NetdevTapOptions *stored;
 
     tap_set_sndbuf(s->fd, tap, &err);
     if (err) {
@@ -659,12 +677,65 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
         return;
     }
 
+    /* Store startup parameters */
+    if (!*common_stored) {
+        *common_stored = g_new0(NetdevInfo, 1);
+        (*common_stored)->type = NET_CLIENT_DRIVER_TAP;
+        s->nc.stored_config = *common_stored;
+    }
+    stored = &(*common_stored)->u.tap;
+
+    if (tap->has_sndbuf && !stored->has_sndbuf) {
+        stored->has_sndbuf = true;
+        stored->sndbuf = tap->sndbuf;
+    }
+
+    if (vnet_hdr && !stored->has_vnet_hdr) {
+        stored->has_vnet_hdr = true;
+        stored->vnet_hdr = true;
+    }
+
     if (tap->has_fd || tap->has_fds) {
+        if (!stored->has_fds) {
+            stored->has_fds = true;
+            stored->fds = g_strdup_printf("%d", fd);
+        } else {
+            char *tmp_s = stored->fds;
+            stored->fds = g_strdup_printf("%s:%d", stored->fds, fd);
+            g_free(tmp_s);
+        }
+
         snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);
     } else if (tap->has_helper) {
+        if (!stored->has_helper) {
+            stored->has_helper = true;
+            stored->helper = g_strdup(tap->helper);
+        }
+
+        if (!stored->has_br) {
+            stored->has_br = true;
+            stored->br = tap->has_br ? g_strdup(tap->br) :
+                                    g_strdup(DEFAULT_BRIDGE_INTERFACE);
+        }
+
         snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s",
                  tap->helper);
     } else {
+        if (ifname && !stored->has_ifname) {
+            stored->has_ifname = true;
+            stored->ifname = g_strdup(ifname);
+        }
+
+        if (script && !stored->has_script) {
+            stored->has_script = true;
+            stored->script = g_strdup(script);
+        }
+
+        if (downscript && !stored->has_downscript) {
+            stored->has_downscript = true;
+            stored->downscript = g_strdup(downscript);
+        }
+
         snprintf(s->nc.info_str, sizeof(s->nc.info_str),
                  "ifname=%s,script=%s,downscript=%s", ifname, script,
                  downscript);
@@ -680,9 +751,20 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
         vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
         VhostNetOptions options;
 
+        stored->has_vhost = true;
+        stored->vhost = true;
+
+        if (tap->has_vhostforce && tap->vhostforce) {
+            stored->has_vhostforce = true;
+            stored->vhostforce = true;
+        }
+
         options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
         options.net_backend = &s->nc;
         if (tap->has_poll_us) {
+            stored->has_poll_us = true;
+            stored->poll_us = tap->poll_us;
+
             options.busyloop_timeout = tap->poll_us;
         } else {
             options.busyloop_timeout = 0;
@@ -715,6 +797,15 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
         }
         options.opaque = (void *)(uintptr_t)vhostfd;
 
+        if (!stored->has_vhostfds) {
+            stored->has_vhostfds = true;
+            stored->vhostfds = g_strdup_printf("%d", vhostfd);
+        } else {
+            char *tmp_s = stored->vhostfds;
+            stored->vhostfds = g_strdup_printf("%s:%d", stored->fds, vhostfd);
+            g_free(tmp_s);
+        }
+
         s->vhost_net = vhost_net_init(&options);
         if (!s->vhost_net) {
             if (tap->has_vhostforce && tap->vhostforce) {
@@ -766,6 +857,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
     Error *err = NULL;
     const char *vhostfdname;
     char ifname[128];
+    NetdevInfo *common_stored = NULL; /* will store configuration */
 
     assert(netdev->type == NET_CLIENT_DRIVER_TAP);
     tap = &netdev->u.tap;
@@ -801,7 +893,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
 
         net_init_tap_one(tap, peer, "tap", name, NULL,
                          script, downscript,
-                         vhostfdname, vnet_hdr, fd, &err);
+                         vhostfdname, vnet_hdr, fd, &common_stored, &err);
         if (err) {
             error_propagate(errp, err);
             return -1;
@@ -857,7 +949,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
             net_init_tap_one(tap, peer, "tap", name, ifname,
                              script, downscript,
                              tap->has_vhostfds ? vhost_fds[i] : NULL,
-                             vnet_hdr, fd, &err);
+                             vnet_hdr, fd, &common_stored, &err);
             if (err) {
                 error_propagate(errp, err);
                 ret = -1;
@@ -896,7 +988,7 @@ free_fail:
 
         net_init_tap_one(tap, peer, "bridge", name, ifname,
                          script, downscript, vhostfdname,
-                         vnet_hdr, fd, &err);
+                         vnet_hdr, fd, &common_stored, &err);
         if (err) {
             error_propagate(errp, err);
             close(fd);
@@ -935,7 +1027,8 @@ free_fail:
             net_init_tap_one(tap, peer, "tap", name, ifname,
                              i >= 1 ? "no" : script,
                              i >= 1 ? "no" : downscript,
-                             vhostfdname, vnet_hdr, fd, &err);
+                             vhostfdname, vnet_hdr, fd,
+                             &common_stored, &err);
             if (err) {
                 error_propagate(errp, err);
                 close(fd);
diff --git a/net/vde.c b/net/vde.c
index 99189cccb6..c0ab2bb65c 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -84,6 +84,7 @@ static int net_vde_init(NetClientState *peer, const char *model,
     VDECONN *vde;
     char *init_group = (char *)group;
     char *init_sock = (char *)sock;
+    NetdevVdeOptions *stored;
 
     struct vde_open_args args = {
         .port = port,
@@ -108,6 +109,31 @@ static int net_vde_init(NetClientState *peer, const char *model,
 
     qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
 
+    /* Store startup parameters */
+    nc->stored_config = g_new0(NetdevInfo, 1);
+    nc->stored_config->type = NET_CLIENT_DRIVER_VDE;
+    stored = &nc->stored_config->u.vde;
+
+    if (sock) {
+        stored->has_sock = true;
+        stored->sock = g_strdup(sock);
+    }
+
+    if (port) {
+        stored->has_port = true;
+        stored->port = port;
+    }
+
+    if (group) {
+        stored->has_group = true;
+        stored->group = g_strdup(group);
+    }
+
+    if (mode) {
+        stored->has_mode = true;
+        stored->mode = mode;
+    }
+
     return 0;
 }
 
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 17532daaf3..aa2dc53179 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -307,14 +307,15 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event)
 }
 
 static int net_vhost_user_init(NetClientState *peer, const char *device,
-                               const char *name, Chardev *chr,
-                               int queues)
+                               const char *name, const char *chardev,
+                               Chardev *chr, int queues)
 {
     Error *err = NULL;
     NetClientState *nc, *nc0 = NULL;
     NetVhostUserState *s = NULL;
     VhostUserState *user;
     int i;
+    NetdevVhostUserOptions *stored;
 
     assert(name);
     assert(queues > 0);
@@ -351,6 +352,16 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
 
     assert(s->vhost_net);
 
+    /* Store startup parameters */
+    nc0->stored_config = g_new0(NetdevInfo, 1);
+    nc0->stored_config->type = NET_CLIENT_DRIVER_VHOST_USER;
+    stored = &nc0->stored_config->u.vhost_user;
+
+    stored->chardev = g_strdup(chardev);
+
+    stored->has_queues = true;
+    stored->queues = queues;
+
     return 0;
 
 err:
@@ -442,5 +453,6 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
         return -1;
     }
 
-    return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
+    return net_vhost_user_init(peer, "vhost_user", name,
+                               vhost_user_opts->chardev, chr, queues);
 }
diff --git a/qapi/net.json b/qapi/net.json
index 1cb9a7d782..4f329a1de0 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -750,3 +750,92 @@
 ##
 { 'event': 'FAILOVER_NEGOTIATED',
   'data': {'device-id': 'str'} }
+
+##
+# @NetdevInfo:
+#
+# Configuration of a network device.
+#
+# @id: Device identifier.
+#
+# @type: Specify the driver used for interpreting remaining arguments.
+#
+# @peer: Connected network device.
+#
+# @queues-count: Number of queues.
+#
+# @hub: hubid of hub, if connected to.
+#
+# @perm-mac: Original MAC address.
+#
+# Since: 5.0
+##
+{ 'union': 'NetdevInfo',
+  'base': { 'id': 'str',
+            'type': 'NetClientDriver',
+            '*peer': 'str',
+            'queues-count': 'int',
+            '*hub': 'int',
+            '*perm-mac': 'str' },
+  'discriminator': 'type',
+  'data': {
+      'nic':        'NetLegacyNicOptions',
+      'user':       'NetdevUserOptions',
+      'tap':        'NetdevTapOptions',
+      'l2tpv3':     'NetdevL2TPv3Options',
+      'socket':     'NetdevSocketOptions',
+      'vde':        'NetdevVdeOptions',
+      'bridge':     'NetdevBridgeOptions',
+      'hubport':    'NetdevHubPortOptions',
+      'netmap':     'NetdevNetmapOptions',
+      'vhost-user': 'NetdevVhostUserOptions' } }
+
+##
+# @query-netdevs:
+#
+# Get a list of @NetdevInfo for all virtual network devices.
+#
+# Returns: a list of @NetdevInfo describing each virtual network device.
+#
+# Since: 5.0
+#
+# Example:
+#
+# -> { "execute": "query-netdevs" }
+# <- { "return": [
+#          {
+#              "peer": "netdev0",
+#              "netdev": "netdev0",
+#              "perm-mac": "52:54:00:12:34:56"
+#              "model": "virtio-net-pci",
+#              "macaddr": "52:54:00:12:34:56",
+#              "queues-count": 1,
+#              "type": "nic",
+#              "id": "net0"
+#          },
+#          {
+#              "peer": "net0",
+#              "ipv6": true,
+#              "ipv4": true,
+#              "host": "10.0.2.2",
+#              "queues-count": 1,
+#              "ipv6-dns": "fec0::3",
+#              "ipv6-prefix": "fec0::",
+#              "net": "10.0.2.0/255.255.255.0",
+#              "ipv6-host": "fec0::2",
+#              "type": "user",
+#              "dns": "10.0.2.3",
+#              "hostfwd": [
+#                  {
+#                      "str": "tcp::20004-:22"
+#                  }
+#              ],
+#              "ipv6-prefixlen": 64,
+#              "id": "netdev0",
+#              "restrict": false
+#          }
+#      ]
+#    }
+#
+##
+{ 'command': 'query-netdevs', 'returns': ['NetdevInfo'] }
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH v2 2/4] tests: Add tests for query-netdevs command
  2020-03-04 13:06 [Xen-devel] [PATCH v2 0/4] Introducing QMP query-netdevs command Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 1/4] qapi: net: Add " Alexey Kirillov
@ 2020-03-04 13:06 ` Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 3/4] hmp: Use QMP query-netdevs in hmp_info_network Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 4/4] net: Remove field info_str of NetClientState Alexey Kirillov
  3 siblings, 0 replies; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-04 13:06 UTC (permalink / raw)
  To: Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Laurent Vivier, Jiri Pirko, yc-core, Stefan Weil,
	Alistair Francis, Beniamino Galvani, qemu-arm, Peter Chubb,
	Cédric Le Goater, xen-devel, Giuseppe Lettieri, Luigi Rizzo,
	Richard Henderson, Andrew Jeffery, Michael Walle, qemu-ppc,
	Aleksandar Markovic, Alexey Kirillov, Paolo Bonzini

Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
---
 tests/qtest/Makefile.include     |   2 +
 tests/qtest/test-query-netdevs.c | 120 +++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 tests/qtest/test-query-netdevs.c

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index e769c1ad70..6924843ef9 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -9,6 +9,7 @@ check-qtest-generic-y += qmp-cmd-test
 check-qtest-generic-y += qom-test
 check-qtest-generic-$(CONFIG_MODULES) += modules-test
 check-qtest-generic-y += test-hmp
+check-qtest-generic-$(CONFIG_SLIRP) += test-query-netdevs
 
 check-qtest-pci-$(CONFIG_RTL8139_PCI) += rtl8139-test
 check-qtest-pci-$(CONFIG_VGA) += display-vga-test
@@ -303,6 +304,7 @@ tests/qtest/tpm-crb-test$(EXESUF): tests/qtest/tpm-crb-test.o tests/qtest/tpm-em
 tests/qtest/tpm-tis-swtpm-test$(EXESUF): tests/qtest/tpm-tis-swtpm-test.o tests/qtest/tpm-emu.o \
 	tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
 tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o tests/qtest/tpm-emu.o $(test-io-obj-y)
+tests/qtest/test-query-netdevs$(EXESUF): tests/qtest/test-query-netdevs.o
 
 # QTest rules
 
diff --git a/tests/qtest/test-query-netdevs.c b/tests/qtest/test-query-netdevs.c
new file mode 100644
index 0000000000..e077358a50
--- /dev/null
+++ b/tests/qtest/test-query-netdevs.c
@@ -0,0 +1,120 @@
+/*
+ * QTest testcase for the query-netdevs
+ *
+ * Copyright Yandex N.V., 2019
+ *
+ * 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 "libqtest.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlist.h"
+
+/*
+ * Events can get in the way of responses we are actually waiting for.
+ */
+GCC_FMT_ATTR(2, 3)
+static QObject *wait_command(QTestState *who, const char *command, ...)
+{
+    va_list ap;
+    QDict *response;
+    QObject *result;
+
+    va_start(ap, command);
+    qtest_qmp_vsend(who, command, ap);
+    va_end(ap);
+
+    response = qtest_qmp_receive(who);
+
+    result = qdict_get(response, "return");
+    g_assert(result);
+    qobject_ref(result);
+    qobject_unref(response);
+
+    return result;
+}
+
+static void qmp_query_netdevs_no_error(QTestState *qts,
+                                       size_t netdevs_count)
+{
+    QObject *resp;
+    QList *netdevs;
+
+    resp = wait_command(qts, "{'execute': 'query-netdevs'}");
+
+    netdevs = qobject_to(QList, resp);
+    g_assert(netdevs);
+    g_assert(qlist_size(netdevs) == netdevs_count);
+
+    qobject_unref(resp);
+}
+
+static void test_query_netdevs(void)
+{
+    const char *arch = qtest_get_arch();
+    size_t correction = 0;
+    QObject *resp;
+    QTestState *state;
+
+    /* Archs which still have a netdev despite of -nodefaults */
+    if (g_str_equal(arch, "cris") ||
+        g_str_equal(arch, "microblaze") ||
+        g_str_equal(arch, "microblazeel") ||
+        g_str_equal(arch, "sparc")) {
+        correction = 1;
+    }
+
+    if (g_str_equal(arch, "arm") ||
+        g_str_equal(arch, "aarch64")) {
+        state = qtest_init(
+            "-nodefaults "
+            "-M virt "
+            "-netdev user,id=slirp0");
+    } else if (g_str_equal(arch, "tricore")) {
+        state = qtest_init(
+            "-nodefaults "
+            "-M tricore_testboard "
+            "-netdev user,id=slirp0");
+    } else {
+        state = qtest_init(
+            "-nodefaults "
+            "-netdev user,id=slirp0");
+    }
+    g_assert(state);
+
+    qmp_query_netdevs_no_error(state, 1 + correction);
+
+    resp = wait_command(state,
+        "{'execute': 'netdev_add', 'arguments': {"
+        " 'id': 'slirp1',"
+        " 'type': 'user'}}");
+    qobject_unref(resp);
+
+    qmp_query_netdevs_no_error(state, 2 + correction);
+
+    resp = wait_command(state,
+        "{'execute': 'netdev_del', 'arguments': {"
+        " 'id': 'slirp1'}}");
+    qobject_unref(resp);
+
+    qmp_query_netdevs_no_error(state, 1 + correction);
+
+    qtest_quit(state);
+}
+
+int main(int argc, char **argv)
+{
+    int ret = 0;
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/net/qapi/query_netdevs",
+        test_query_netdevs);
+
+    ret = g_test_run();
+
+    return ret;
+}
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH v2 3/4] hmp: Use QMP query-netdevs in hmp_info_network
  2020-03-04 13:06 [Xen-devel] [PATCH v2 0/4] Introducing QMP query-netdevs command Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 1/4] qapi: net: Add " Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 2/4] tests: Add tests for " Alexey Kirillov
@ 2020-03-04 13:06 ` Alexey Kirillov
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 4/4] net: Remove field info_str of NetClientState Alexey Kirillov
  3 siblings, 0 replies; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-04 13:06 UTC (permalink / raw)
  To: Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Laurent Vivier, Jiri Pirko, yc-core, Stefan Weil,
	Alistair Francis, Beniamino Galvani, qemu-arm, Peter Chubb,
	Cédric Le Goater, xen-devel, Giuseppe Lettieri, Luigi Rizzo,
	Richard Henderson, Andrew Jeffery, Michael Walle, qemu-ppc,
	Aleksandar Markovic, Alexey Kirillov, Paolo Bonzini

Replace legacy field info_str of NetClientState with
result of QMP command query-netdevs.

Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
---
 include/net/net.h |   3 +-
 net/clients.h     |   1 +
 net/hub.c         |   4 +-
 net/hub.h         |   2 +-
 net/net.c         | 175 ++++++++++++++++++++++++++++++++++++++++++++--
 net/vde.c         |  10 +++
 6 files changed, 186 insertions(+), 9 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 2c8956c0b3..9df4680937 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -171,7 +171,8 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
                         const char *default_model);
 
-void print_net_client(Monitor *mon, NetClientState *nc);
+void print_net_client(Monitor *mon, NetClientState *nc,
+                      NetdevInfoList *ni_list);
 void hmp_info_network(Monitor *mon, const QDict *qdict);
 void net_socket_rs_init(SocketReadState *rs,
                         SocketReadStateFinalize *finalize,
diff --git a/net/clients.h b/net/clients.h
index a6ef267e19..f439933522 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -51,6 +51,7 @@ int net_init_l2tpv3(const Netdev *netdev, const char *name,
 #ifdef CONFIG_VDE
 int net_init_vde(const Netdev *netdev, const char *name,
                  NetClientState *peer, Error **errp);
+int net_vde_get_fd(const NetClientState *nc);
 #endif
 
 #ifdef CONFIG_NETMAP
diff --git a/net/hub.c b/net/hub.c
index 37995b5517..cce970b59d 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -252,7 +252,7 @@ NetClientState *net_hub_port_find(int hub_id)
 /**
  * Print hub configuration
  */
-void net_hub_info(Monitor *mon)
+void net_hub_info(Monitor *mon, NetdevInfoList *ni_list)
 {
     NetHub *hub;
     NetHubPort *port;
@@ -263,7 +263,7 @@ void net_hub_info(Monitor *mon)
             monitor_printf(mon, " \\ %s", port->nc.name);
             if (port->nc.peer) {
                 monitor_printf(mon, ": ");
-                print_net_client(mon, port->nc.peer);
+                print_net_client(mon, port->nc.peer, ni_list);
             } else {
                 monitor_printf(mon, "\n");
             }
diff --git a/net/hub.h b/net/hub.h
index 66d3322fac..424658a4a2 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -19,7 +19,7 @@
 NetClientState *net_hub_add_port(int hub_id, const char *name,
                                  NetClientState *hubpeer);
 NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
-void net_hub_info(Monitor *mon);
+void net_hub_info(Monitor *mon, NetdevInfoList *ninfo);
 void net_hub_check_clients(void);
 bool net_hub_flush(NetClientState *nc);
 
diff --git a/net/net.c b/net/net.c
index 01e0548295..1a8153dbf7 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1271,14 +1271,176 @@ static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
     monitor_printf(mon, "\n");
 }
 
-void print_net_client(Monitor *mon, NetClientState *nc)
+static NetdevInfo *get_netdev_info(NetdevInfoList *ni_list, char *name)
+{
+    NetdevInfo *ni;
+
+    while (ni_list) {
+        ni = ni_list->value;
+        if (g_str_equal(ni->id, name)) {
+            return ni;
+        }
+        ni_list = ni_list->next;
+    }
+
+    return NULL;
+}
+
+static char *generate_info_str(NetdevInfo *ni, NetClientState *nc)
+{
+    char *info_str;
+
+    if (!ni) {
+        return g_malloc0(1);
+    }
+
+    switch (ni->type) {
+        case NET_CLIENT_DRIVER_NIC: {
+            info_str = g_strdup_printf("model=%s,macaddr=%s",
+                                       ni->u.nic.model,
+                                       ni->u.nic.macaddr);
+            break;
+        }
+#ifdef CONFIG_SLIRP
+        case NET_CLIENT_DRIVER_USER: {
+            size_t len = strchr(ni->u.user.net, '/') - ni->u.user.net;
+            char *net = g_strndup(ni->u.user.net, len);
+
+            info_str = g_strdup_printf("net=%s,restrict=%s",
+                                       net,
+                                       ni->u.user.q_restrict ? "on" : "off");
+            g_free(net);
+            break;
+        }
+#endif /* CONFIG_SLIRP */
+        case NET_CLIENT_DRIVER_TAP: {
+#ifndef _WIN32
+            if (ni->u.tap.has_fds) {
+                char **fds = g_strsplit(ni->u.tap.fds, ":", -1);
+
+                info_str = g_strdup_printf("fd=%s", fds[nc->queue_index]);
+                g_strfreev(fds);
+            } else if (ni->u.tap.has_helper) {
+                info_str = g_strdup_printf("helper=%s", ni->u.tap.helper);
+            } else {
+                info_str = g_strdup_printf("ifname=%s,script=%s,downscript=%s",
+                    ni->u.tap.ifname,
+                    nc->queue_index == 0 ? ni->u.tap.script : "no",
+                    nc->queue_index == 0 ? ni->u.tap.downscript : "no");
+            }
+#else
+            info_str = g_strdup_printf("tap: ifname=%s", ni->u.tap.ifname);
+#endif /* _WIN32 */
+            break;
+        }
+#ifdef CONFIG_L2TPV3
+        case NET_CLIENT_DRIVER_L2TPV3: {
+            info_str = g_strdup_printf("l2tpv3: connected");
+            break;
+        }
+#endif /* CONFIG_L2TPV3 */
+        case NET_CLIENT_DRIVER_SOCKET: {
+            if (ni->u.socket.has_listen) {
+                if (ni->u.socket.has_fd) {
+                    info_str = g_strdup_printf("socket: connection from %s",
+                                               ni->u.socket.listen);
+                } else {
+                    info_str = g_strdup_printf("socket: wait from %s",
+                                               ni->u.socket.listen);
+                }
+            } else if (ni->u.socket.has_connect && ni->u.socket.has_fd) {
+                info_str = g_strdup_printf("socket: connect to %s",
+                                           ni->u.socket.connect);
+            } else if (ni->u.socket.has_mcast && ni->u.socket.has_fd) {
+                info_str = g_strdup_printf("socket: mcast=%s",
+                                           ni->u.socket.mcast);
+            } else if (ni->u.socket.has_udp && ni->u.socket.has_fd) {
+                info_str = g_strdup_printf("socket: udp=%s", ni->u.socket.udp);
+            } else {
+                g_assert(ni->u.socket.has_fd);
+                int so_type = -1;
+                int optlen = sizeof(so_type);
+                int fd = atoi(ni->u.socket.fd);
+
+                getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
+                           (socklen_t *)&optlen);
+                if (so_type == SOCK_STREAM) {
+                    info_str = g_strdup_printf("socket: fd=%s",
+                                               ni->u.socket.fd);
+                } else {
+                    if (ni->u.socket.has_mcast) {
+                        /*
+                         * This branch is unreachable, according to how it is in
+                         * net/socket.c at this moment
+                         */
+                        info_str = g_strdup_printf("socket: fd=%s "
+                                                   "(cloned mcast=%s)",
+                                                   ni->u.socket.fd,
+                                                   ni->u.socket.mcast);
+                    } else {
+                        SocketAddress *sa = socket_local_address(fd, NULL);
+
+                        info_str = g_strdup_printf("socket: fd=%s %s",
+                            ni->u.socket.fd,
+                            SocketAddressType_str(sa->type));
+                        qapi_free_SocketAddress(sa);
+                    }
+                }
+            }
+            break;
+        }
+#ifdef CONFIG_VDE
+        case NET_CLIENT_DRIVER_VDE: {
+            info_str = g_strdup_printf("sock=%s,fd=%d",
+                                       ni->u.vde.sock,
+                                       net_vde_get_fd(nc));
+            break;
+        }
+#endif /* CONFIG_VDE */
+#ifdef CONFIG_NET_BRIDGE
+        case NET_CLIENT_DRIVER_BRIDGE: {
+            info_str = g_strdup_printf("helper=%s,br=%s",
+                                       ni->u.bridge.helper,
+                                       ni->u.bridge.br);
+            break;
+        }
+#endif /* CONFIG_NET_BRIDGE */
+#ifdef CONFIG_NETMAP
+        case NET_CLIENT_DRIVER_NETMAP: {
+            info_str = g_strdup_printf("netmap: ifname=%s",
+                                       ni->u.netmap.ifname);
+            break;
+        }
+#endif /* CONFIG_NETMAP */
+#ifdef CONFIG_VHOST_NET_USER
+        case NET_CLIENT_DRIVER_VHOST_USER: {
+            info_str = g_strdup_printf("vhost-user%d to %s",
+                                       nc->queue_index,
+                                       ni->u.vhost_user.chardev);
+            break;
+        }
+#endif /* CONFIG_VHOST_NET_USER */
+        default: {
+            info_str = g_malloc0(1);
+            break;
+        }
+    }
+
+    return info_str;
+}
+
+void print_net_client(Monitor *mon, NetClientState *nc, NetdevInfoList *ni_list)
 {
     NetFilterState *nf;
+    NetdevInfo *ni = get_netdev_info(ni_list, nc->name);
+    char *info_str = generate_info_str(ni, nc);
 
     monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name,
                    nc->queue_index,
                    NetClientDriver_str(nc->info->type),
-                   nc->info_str);
+                   info_str);
+    g_free(info_str);
+
     if (!QTAILQ_EMPTY(&nc->filters)) {
         monitor_printf(mon, "filters:\n");
     }
@@ -1415,8 +1577,9 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
 {
     NetClientState *nc, *peer;
     NetClientDriver type;
+    NetdevInfoList *ni_list = qmp_query_netdevs(NULL);
 
-    net_hub_info(mon);
+    net_hub_info(mon, ni_list);
 
     QTAILQ_FOREACH(nc, &net_clients, next) {
         peer = nc->peer;
@@ -1428,13 +1591,15 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
         }
 
         if (!peer || type == NET_CLIENT_DRIVER_NIC) {
-            print_net_client(mon, nc);
+            print_net_client(mon, nc, ni_list);
         } /* else it's a netdev connected to a NIC, printed with the NIC */
         if (peer && type == NET_CLIENT_DRIVER_NIC) {
             monitor_printf(mon, " \\ ");
-            print_net_client(mon, peer);
+            print_net_client(mon, peer, ni_list);
         }
     }
+
+    qapi_free_NetdevInfoList(ni_list);
 }
 
 void colo_notify_filters_event(int event, Error **errp)
diff --git a/net/vde.c b/net/vde.c
index c0ab2bb65c..c4edf5cba1 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -153,3 +153,13 @@ int net_init_vde(const Netdev *netdev, const char *name,
 
     return 0;
 }
+
+int net_vde_get_fd(const NetClientState *nc)
+{
+    VDEState *s;
+    assert(nc->info->type == NET_CLIENT_DRIVER_VDE);
+
+    s = DO_UPCAST(VDEState, nc, nc);
+
+    return vde_datafd(s->vde);
+}
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH v2 4/4] net: Remove field info_str of NetClientState
  2020-03-04 13:06 [Xen-devel] [PATCH v2 0/4] Introducing QMP query-netdevs command Alexey Kirillov
                   ` (2 preceding siblings ...)
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 3/4] hmp: Use QMP query-netdevs in hmp_info_network Alexey Kirillov
@ 2020-03-04 13:06 ` Alexey Kirillov
  2020-03-04 15:41   ` Laurent Vivier
  3 siblings, 1 reply; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-04 13:06 UTC (permalink / raw)
  To: Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Laurent Vivier, Jiri Pirko, yc-core, Stefan Weil,
	Alistair Francis, Beniamino Galvani, qemu-arm, Peter Chubb,
	Cédric Le Goater, xen-devel, Giuseppe Lettieri, Luigi Rizzo,
	Richard Henderson, Andrew Jeffery, Michael Walle, qemu-ppc,
	Aleksandar Markovic, Alexey Kirillov, Paolo Bonzini

Completely remove the info_str field of struct NetClientState because
it is no longer required due to the addition of the QMP query-netdevs command.

Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
---
 hw/net/allwinner_emac.c     |  2 +-
 hw/net/dp8393x.c            |  2 +-
 hw/net/e1000.c              |  4 ++--
 hw/net/e1000e.c             |  2 +-
 hw/net/e1000e_core.c        |  2 +-
 hw/net/e1000x_common.c      |  2 +-
 hw/net/eepro100.c           |  5 +++--
 hw/net/etraxfs_eth.c        |  2 +-
 hw/net/fsl_etsec/etsec.c    |  2 +-
 hw/net/ftgmac100.c          |  2 +-
 hw/net/i82596.c             |  6 +++---
 hw/net/imx_fec.c            |  2 +-
 hw/net/lan9118.c            |  4 ++--
 hw/net/mcf_fec.c            |  2 +-
 hw/net/milkymist-minimac2.c |  2 +-
 hw/net/mipsnet.c            |  2 +-
 hw/net/ne2000-isa.c         |  2 +-
 hw/net/ne2000-pci.c         |  2 +-
 hw/net/pcnet.c              |  2 +-
 hw/net/rocker/rocker_fp.c   |  4 ++--
 hw/net/rtl8139.c            |  6 +++---
 hw/net/smc91c111.c          |  2 +-
 hw/net/spapr_llan.c         |  6 +++---
 hw/net/stellaris_enet.c     |  2 +-
 hw/net/sungem.c             |  4 ++--
 hw/net/sunhme.c             |  2 +-
 hw/net/tulip.c              |  2 +-
 hw/net/virtio-net.c         |  8 ++++----
 hw/net/vmxnet3.c            |  4 ++--
 hw/net/xen_nic.c            |  4 ----
 hw/net/xgmac.c              |  2 +-
 hw/net/xilinx_axienet.c     |  2 +-
 hw/net/xilinx_ethlite.c     |  2 +-
 hw/usb/dev-network.c        |  2 +-
 include/net/net.h           |  3 +--
 net/l2tpv3.c                |  3 ---
 net/net.c                   |  8 +-------
 net/slirp.c                 |  4 ----
 net/socket.c                | 24 ------------------------
 net/tap.c                   | 12 ------------
 net/vde.c                   |  4 ----
 net/vhost-user.c            |  2 --
 42 files changed, 51 insertions(+), 110 deletions(-)

diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index e9bbff8710..6abbdbfd4b 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -454,7 +454,7 @@ static void aw_emac_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_aw_emac_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     fifo8_create(&s->rx_fifo, RX_FIFO_SIZE);
     fifo8_create(&s->tx_fifo[0], TX_FIFO_SIZE);
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 8a3504d962..a6f95b097b 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -982,7 +982,7 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_dp83932_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
 
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 0b833d5a15..5ae52e37ea 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1095,7 +1095,7 @@ mac_writereg(E1000State *s, int index, uint32_t val)
     if (index == RA + 1) {
         macaddr[0] = cpu_to_le32(s->mac_reg[RA]);
         macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);
-        qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t *)macaddr);
+        qemu_update_nic_macaddr(qemu_get_queue(s->nic), (uint8_t *)macaddr);
     }
 }
 
@@ -1711,7 +1711,7 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
     d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
                           object_get_typename(OBJECT(d)), dev->id, d);
 
-    qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
+    qemu_update_nic_macaddr(qemu_get_queue(d->nic), macaddr);
 
     d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
     d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index a91dbdca3c..763661227d 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -333,7 +333,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr)
     trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
     memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
 
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), macaddr);
 
     /* Setup virtio headers */
     if (s->disable_vnet) {
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 94ea34dca5..358e90b40d 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -2731,7 +2731,7 @@ e1000e_mac_setmacaddr(E1000ECore *core, int index, uint32_t val)
 
     macaddr[0] = cpu_to_le32(core->mac[RA]);
     macaddr[1] = cpu_to_le32(core->mac[RA + 1]);
-    qemu_format_nic_info_str(qemu_get_queue(core->owner_nic),
+    qemu_update_nic_macaddr(qemu_get_queue(core->owner_nic),
         (uint8_t *) macaddr);
 
     trace_e1000e_mac_set_sw(MAC_ARG(macaddr));
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
index 717f9df1c9..ad66dd3d55 100644
--- a/hw/net/e1000x_common.c
+++ b/hw/net/e1000x_common.c
@@ -145,7 +145,7 @@ void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
             (i < 2) ? mac_addr[i + 4] << (8 * i) : 0;
     }
 
-    qemu_format_nic_info_str(qemu_get_queue(nic), mac_addr);
+    qemu_update_nic_macaddr(qemu_get_queue(nic), mac_addr);
     trace_e1000x_mac_indicate(MAC_ARG(mac_addr));
 }
 
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index f6474f0e68..31cb5c007f 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1867,8 +1867,9 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
     s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
                           object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
 
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-    TRACE(OTHER, logout("%s\n", qemu_get_queue(s->nic)->info_str));
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    TRACE(OTHER, logout("macaddr=%s\n",
+                        qemu_get_queue(s->nic)->stored_config->u.nic.macaddr));
 
     qemu_register_reset(nic_reset, s);
 
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index 27fd069b96..dccdcb9e67 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -620,7 +620,7 @@ static void etraxfs_eth_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
                           object_get_typename(OBJECT(s)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     s->phy.read = tdk_read;
     s->phy.write = tdk_write;
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index 475f3c887a..1de9c2fff3 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -390,7 +390,7 @@ static void etsec_realize(DeviceState *dev, Error **errp)
 
     etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
                               object_get_typename(OBJECT(dev)), dev->id, etsec);
-    qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
 
     etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_DEFAULT);
     ptimer_transaction_begin(etsec->ptimer);
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index 2f92b65d4e..14286cac81 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -1037,7 +1037,7 @@ static void ftgmac100_realize(DeviceState *dev, Error **errp)
     s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
                           object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
                           s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static const VMStateDescription vmstate_ftgmac100 = {
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
index fe9f2390a9..3d62720920 100644
--- a/hw/net/i82596.c
+++ b/hw/net/i82596.c
@@ -174,8 +174,8 @@ static void set_individual_address(I82596State *s, uint32_t addr)
     m = s->conf.macaddr.a;
     address_space_read(&address_space_memory, addr + 8,
                        MEMTXATTRS_UNSPECIFIED, m, ETH_ALEN);
-    qemu_format_nic_info_str(nc, m);
-    trace_i82596_new_mac(nc->info_str);
+    qemu_update_nic_macaddr(nc, m);
+    trace_i82596_new_mac(nc->stored_config->u.nic.macaddr);
 }
 
 static void set_multicast_list(I82596State *s, uint32_t addr)
@@ -723,7 +723,7 @@ void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info)
     }
     s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)),
                 dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     if (USE_TIMER) {
         s->flush_queue_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6a124a154a..e8047ec42e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1323,7 +1323,7 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
                           object_get_typename(OBJECT(dev)),
                           DEVICE(dev)->id, s);
 
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static Property imx_eth_properties[] = {
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index da7e0bb0e8..0c1bc0f0eb 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -353,7 +353,7 @@ static void lan9118_update(lan9118_state *s)
 
 static void lan9118_mac_changed(lan9118_state *s)
 {
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static void lan9118_reload_eeprom(lan9118_state *s)
@@ -1343,7 +1343,7 @@ static void lan9118_realize(DeviceState *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_lan9118_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
     s->eeprom[0] = 0xa5;
     for (i = 0; i < 6; i++) {
         s->eeprom[i + 1] = s->conf.macaddr.a[i];
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index 9327ac8a30..5690a48829 100644
--- a/hw/net/mcf_fec.c
+++ b/hw/net/mcf_fec.c
@@ -641,7 +641,7 @@ static void mcf_fec_realize(DeviceState *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static void mcf_fec_instance_init(Object *obj)
diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c
index 1ba01754ee..1852ec124e 100644
--- a/hw/net/milkymist-minimac2.c
+++ b/hw/net/milkymist-minimac2.c
@@ -485,7 +485,7 @@ static void milkymist_minimac2_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
index 0c578c430c..ca2649d4d2 100644
--- a/hw/net/mipsnet.c
+++ b/hw/net/mipsnet.c
@@ -255,7 +255,7 @@ static void mipsnet_realize(DeviceState *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static void mipsnet_sysbus_reset(DeviceState *dev)
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index e744eff153..f4d7791271 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -74,7 +74,7 @@ static void isa_ne2000_realizefn(DeviceState *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->c.macaddr.a);
 }
 
 static Property ne2000_isa_properties[] = {
diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c
index e11d67bf75..e8690f47e2 100644
--- a/hw/net/ne2000-pci.c
+++ b/hw/net/ne2000-pci.c
@@ -72,7 +72,7 @@ static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
     s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
                           object_get_typename(OBJECT(pci_dev)),
                           pci_dev->qdev.id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->c.macaddr.a);
 }
 
 static void pci_ne2000_exit(PCIDevice *pci_dev)
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index f3f18d8598..ecb1fcb332 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1719,7 +1719,7 @@ void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     /* Initialize the PROM */
 
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 4aa7da79b8..ddb2191949 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -240,8 +240,8 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
 
     port->nic = qemu_new_nic(&fp_port_info, &port->conf,
                              sw_name, NULL, port);
-    qemu_format_nic_info_str(qemu_get_queue(port->nic),
-                             port->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(port->nic),
+                            port->conf.macaddr.a);
 
     fp_port_reset(port);
 
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index ae4739bc09..a3f42ea567 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -1227,7 +1227,7 @@ static void rtl8139_reset(DeviceState *d)
 
     /* restore MAC address */
     memcpy(s->phys, s->conf.macaddr.a, 6);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->phys);
 
     /* reset interrupt mask */
     s->IntrStatus = 0;
@@ -2676,7 +2676,7 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
             break;
         case MAC0+5:
             s->phys[addr - MAC0] = val;
-            qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
+            qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->phys);
             break;
         case MAC0+6 ... MAC0+7:
             /* reserved */
@@ -3398,7 +3398,7 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf,
                           object_get_typename(OBJECT(dev)), d->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     s->cplus_txbuffer = NULL;
     s->cplus_txbuffer_len = 0;
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index e9eb6f6c05..f23746dc33 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -782,7 +782,7 @@ static void smc91c111_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
     /* ??? Save/restore.  */
 }
 
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 80f5a1dd37..26b11a21a9 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -314,7 +314,7 @@ static void spapr_vlan_reset(SpaprVioDevice *sdev)
 
     memcpy(&dev->nicconf.macaddr.a, &dev->perm_mac.a,
            sizeof(dev->nicconf.macaddr.a));
-    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
 }
 
 static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
@@ -327,7 +327,7 @@ static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
 
     dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
                             object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
-    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
 
     dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,
                                   dev);
@@ -775,7 +775,7 @@ static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
         macaddr >>= 8;
     }
 
-    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
 
     return H_SUCCESS;
 }
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index cb6e2509ea..aec99bc214 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -493,7 +493,7 @@ static void stellaris_enet_realize(DeviceState *dev, Error **errp)
 
     s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static Property stellaris_enet_properties[] = {
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
index 89da51f7f6..b3f49b23ae 100644
--- a/hw/net/sungem.c
+++ b/hw/net/sungem.c
@@ -1361,8 +1361,8 @@ static void sungem_realize(PCIDevice *pci_dev, Error **errp)
     s->nic = qemu_new_nic(&net_sungem_info, &s->conf,
                           object_get_typename(OBJECT(dev)),
                           dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic),
-                             s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic),
+                            s->conf.macaddr.a);
 }
 
 static void sungem_reset(DeviceState *dev)
diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index 8863601f6c..2ff2ef1162 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -892,7 +892,7 @@ static void sunhme_realize(PCIDevice *pci_dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_sunhme_info, &s->conf,
                           object_get_typename(OBJECT(d)), d->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static void sunhme_instance_init(Object *obj)
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index cfac2719d3..36ff10c593 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -964,7 +964,7 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
     s->nic = qemu_new_nic(&net_tulip_info, &s->c,
                           object_get_typename(OBJECT(pci_dev)),
                           pci_dev->qdev.id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->c.macaddr.a);
 }
 
 static void pci_tulip_exit(PCIDevice *pci_dev)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3627bb1717..ea1992bc84 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -152,7 +152,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
         !virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1) &&
         memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
-        qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
+        qemu_update_nic_macaddr(qemu_get_queue(n->nic), n->mac);
     }
 }
 
@@ -521,7 +521,7 @@ static void virtio_net_reset(VirtIODevice *vdev)
     n->mac_table.uni_overflow = 0;
     memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
     memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac));
-    qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
+    qemu_update_nic_macaddr(qemu_get_queue(n->nic), n->mac);
     memset(n->vlans, 0, MAX_VLAN >> 3);
 
     /* Flush any async TX */
@@ -1009,7 +1009,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
         }
         s = iov_to_buf(iov, iov_cnt, 0, &n->mac, sizeof(n->mac));
         assert(s == sizeof(n->mac));
-        qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
+        qemu_update_nic_macaddr(qemu_get_queue(n->nic), n->mac);
         rxfilter_notify(nc);
 
         return VIRTIO_NET_OK;
@@ -3056,7 +3056,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
         n->host_hdr_len = 0;
     }
 
-    qemu_format_nic_info_str(qemu_get_queue(n->nic), n->nic_conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(n->nic), n->nic_conf.macaddr.a);
 
     n->vqs[0].tx_waiting = 0;
     n->tx_burst = n->net_conf.txburst;
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 6d91cd8309..3c337739d0 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -366,7 +366,7 @@ static void vmxnet3_set_variable_mac(VMXNET3State *s, uint32_t h, uint32_t l)
 
     VMW_CFPRN("Variable MAC: " MAC_FMT, MAC_ARG(s->conf.macaddr.a));
 
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static uint64_t vmxnet3_get_mac_low(MACAddr *addr)
@@ -2069,7 +2069,7 @@ static void vmxnet3_net_init(VMXNET3State *s)
         qemu_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1);
     }
 
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static void
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 00a7fdf843..19476fc08c 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -296,10 +296,6 @@ static int net_init(struct XenLegacyDevice *xendev)
     netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
                                "xen", NULL, netdev);
 
-    snprintf(qemu_get_queue(netdev->nic)->info_str,
-             sizeof(qemu_get_queue(netdev->nic)->info_str),
-             "nic: xenbus vif macaddr=%s", netdev->mac);
-
     /* fill info */
     xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1);
     xenstore_write_be_int(&netdev->xendev, "feature-rx-flip", 0);
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index 574dd47b41..f882026930 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -393,7 +393,7 @@ static void xgmac_enet_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) |
                                    s->conf.macaddr.a[4];
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 704788811a..73cc3f2aa8 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -975,7 +975,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
     tdk_init(&s->TEMAC.phy);
     mdio_attach(&s->TEMAC.mdio_bus, &s->TEMAC.phy, s->c_phyaddr);
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index cf07e698b3..37692f15e1 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -235,7 +235,7 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
                           object_get_typename(OBJECT(dev)), dev->id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
 static void xilinx_ethlite_init(Object *obj)
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 9a78ad928b..52e8e6989a 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1362,7 +1362,7 @@ static void usb_net_realize(USBDevice *dev, Error **errp)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
                           object_get_typename(OBJECT(s)), s->dev.qdev.id, s);
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+    qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
     snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
              "%02x%02x%02x%02x%02x%02x",
              0x40,
diff --git a/include/net/net.h b/include/net/net.h
index 9df4680937..b4ca9112aa 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -91,7 +91,6 @@ struct NetClientState {
     NetQueue *incoming_queue;
     char *model;
     char *name;
-    char info_str[256];
     NetdevInfo *stored_config;
     unsigned receive_disabled : 1;
     NetClientDestructor *destructor;
@@ -155,7 +154,7 @@ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
 void qemu_purge_queued_packets(NetClientState *nc);
 void qemu_flush_queued_packets(NetClientState *nc);
 void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge);
-void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]);
+void qemu_update_nic_macaddr(NetClientState *nc, uint8_t macaddr[6]);
 bool qemu_has_ufo(NetClientState *nc);
 bool qemu_has_vnet_hdr(NetClientState *nc);
 bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index f4e45e7b28..8dccdd625e 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -744,9 +744,6 @@ int net_init_l2tpv3(const Netdev *netdev,
     if (l2tpv3->has_dstport) {
         stored->dstport = g_strdup(l2tpv3->dstport);
     }
-
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-             "l2tpv3: connected");
     return 0;
 outerr:
     qemu_del_net_client(nc);
diff --git a/net/net.c b/net/net.c
index 1a8153dbf7..88755e5c1c 100644
--- a/net/net.c
+++ b/net/net.c
@@ -127,19 +127,13 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr)
                            macaddr[3], macaddr[4], macaddr[5]);
 }
 
-void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
+void qemu_update_nic_macaddr(NetClientState *nc, uint8_t macaddr[6])
 {
     g_assert(nc->stored_config);
 
     g_free(nc->stored_config->u.nic.macaddr);
     nc->stored_config->u.nic.macaddr = g_strdup_printf(MAC_FMT,
                                                        MAC_ARG(macaddr));
-
-    snprintf(nc->info_str, sizeof(nc->info_str),
-             "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
-             nc->model,
-             macaddr[0], macaddr[1], macaddr[2],
-             macaddr[3], macaddr[4], macaddr[5]);
 }
 
 static int mac_table[256] = {0};
diff --git a/net/slirp.c b/net/slirp.c
index fb5b87ebed..24a8877ddc 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -670,10 +670,6 @@ static int net_slirp_init(NetClientState *peer, const char *model,
         stored->tftp_server_name = g_strdup(tftp_server_name);
     }
 
-    snprintf(nc->info_str, sizeof(nc->info_str),
-             "net=%s,restrict=%s", inet_ntoa(net),
-             restricted ? "on" : "off");
-
     s = DO_UPCAST(SlirpState, nc, nc);
 
     s->slirp = slirp_init(restricted, ipv4, net, mask, host,
diff --git a/net/socket.c b/net/socket.c
index 2d2d5419ca..1f8801970c 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -180,7 +180,6 @@ static void net_socket_send(void *opaque)
         s->fd = -1;
         net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
         s->nc.link_down = true;
-        memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 
         return;
     }
@@ -400,16 +399,10 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
         stored->mcast = g_strdup(mcast);
 
         s->dgram_dst = saddr;
-        snprintf(nc->info_str, sizeof(nc->info_str),
-                 "socket: fd=%d (cloned mcast=%s:%d)",
-                 fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
     } else {
         if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) {
             s->dgram_dst.sin_family = AF_UNIX;
         }
-
-        snprintf(nc->info_str, sizeof(nc->info_str),
-                 "socket: fd=%d %s", fd, SocketAddressType_str(sa_type));
     }
 
     return s;
@@ -443,9 +436,6 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
     NetdevSocketOptions *stored;
 
     nc = qemu_new_net_client(&net_socket_info, peer, model, name);
-
-    snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);
-
     s = DO_UPCAST(NetSocketState, nc, nc);
 
     s->fd = fd;
@@ -527,10 +517,6 @@ static void net_socket_accept(void *opaque)
 
     stored->has_fd = true;
     stored->fd = g_strdup_printf("%d", fd);
-
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-             "socket: connection from %s:%d",
-             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 }
 
 static int net_socket_listen_init(NetClientState *peer,
@@ -645,9 +631,6 @@ static int net_socket_connect_init(NetClientState *peer,
     stored->has_connect = true;
     stored->connect = g_strdup(host_str);
 
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-             "socket: connect to %s:%d",
-             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
     return 0;
 }
 
@@ -704,11 +687,7 @@ static int net_socket_mcast_init(NetClientState *peer,
         stored->localaddr = g_strdup(localaddr_str);
     }
 
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-             "socket: mcast=%s:%d",
-             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
     return 0;
-
 }
 
 static int net_socket_udp_init(NetClientState *peer,
@@ -769,9 +748,6 @@ static int net_socket_udp_init(NetClientState *peer,
     stored->has_udp = true;
     stored->udp = g_strdup(rhost);
 
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-             "socket: udp=%s:%d",
-             inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
     return 0;
 }
 
diff --git a/net/tap.c b/net/tap.c
index f40f378c2a..bd5cb6f5cd 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -616,9 +616,6 @@ int net_init_bridge(const Netdev *netdev, const char *name,
         stored->helper = g_strdup(helper);
     }
 
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper,
-             br);
-
     return 0;
 }
 
@@ -704,8 +701,6 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
             stored->fds = g_strdup_printf("%s:%d", stored->fds, fd);
             g_free(tmp_s);
         }
-
-        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);
     } else if (tap->has_helper) {
         if (!stored->has_helper) {
             stored->has_helper = true;
@@ -717,9 +712,6 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
             stored->br = tap->has_br ? g_strdup(tap->br) :
                                     g_strdup(DEFAULT_BRIDGE_INTERFACE);
         }
-
-        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s",
-                 tap->helper);
     } else {
         if (ifname && !stored->has_ifname) {
             stored->has_ifname = true;
@@ -736,10 +728,6 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
             stored->downscript = g_strdup(downscript);
         }
 
-        snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-                 "ifname=%s,script=%s,downscript=%s", ifname, script,
-                 downscript);
-
         if (strcmp(downscript, "no") != 0) {
             snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);
             snprintf(s->down_script_arg, sizeof(s->down_script_arg),
diff --git a/net/vde.c b/net/vde.c
index c4edf5cba1..cdd27eddd7 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -99,10 +99,6 @@ static int net_vde_init(NetClientState *peer, const char *model,
     }
 
     nc = qemu_new_net_client(&net_vde_info, peer, model, name);
-
-    snprintf(nc->info_str, sizeof(nc->info_str), "sock=%s,fd=%d",
-             sock, vde_datafd(vde));
-
     s = DO_UPCAST(VDEState, nc, nc);
 
     s->vde = vde;
diff --git a/net/vhost-user.c b/net/vhost-user.c
index aa2dc53179..dcc60f9c34 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -323,8 +323,6 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
     user = g_new0(struct VhostUserState, 1);
     for (i = 0; i < queues; i++) {
         nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
-        snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
-                 i, chr->label);
         nc->queue_index = i;
         if (!nc0) {
             nc0 = nc;
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH v2 4/4] net: Remove field info_str of NetClientState
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 4/4] net: Remove field info_str of NetClientState Alexey Kirillov
@ 2020-03-04 15:41   ` Laurent Vivier
  0 siblings, 0 replies; 11+ messages in thread
From: Laurent Vivier @ 2020-03-04 15:41 UTC (permalink / raw)
  To: Alexey Kirillov, Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Jiri Pirko, yc-core, Stefan Weil, Alistair Francis,
	Beniamino Galvani, qemu-arm, Peter Chubb, Cédric Le Goater,
	xen-devel, Giuseppe Lettieri, Luigi Rizzo, Richard Henderson,
	Andrew Jeffery, Michael Walle, qemu-ppc, Aleksandar Markovic,
	Paolo Bonzini

On 04/03/2020 14:06, Alexey Kirillov wrote:
> Completely remove the info_str field of struct NetClientState because
> it is no longer required due to the addition of the QMP query-netdevs command.
> 
> Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
> ---
>  hw/net/allwinner_emac.c     |  2 +-
>  hw/net/dp8393x.c            |  2 +-
>  hw/net/e1000.c              |  4 ++--
>  hw/net/e1000e.c             |  2 +-
>  hw/net/e1000e_core.c        |  2 +-
>  hw/net/e1000x_common.c      |  2 +-
>  hw/net/eepro100.c           |  5 +++--
>  hw/net/etraxfs_eth.c        |  2 +-
>  hw/net/fsl_etsec/etsec.c    |  2 +-
>  hw/net/ftgmac100.c          |  2 +-
>  hw/net/i82596.c             |  6 +++---
>  hw/net/imx_fec.c            |  2 +-
>  hw/net/lan9118.c            |  4 ++--
>  hw/net/mcf_fec.c            |  2 +-
>  hw/net/milkymist-minimac2.c |  2 +-
>  hw/net/mipsnet.c            |  2 +-
>  hw/net/ne2000-isa.c         |  2 +-
>  hw/net/ne2000-pci.c         |  2 +-
>  hw/net/pcnet.c              |  2 +-
>  hw/net/rocker/rocker_fp.c   |  4 ++--
>  hw/net/rtl8139.c            |  6 +++---
>  hw/net/smc91c111.c          |  2 +-
>  hw/net/spapr_llan.c         |  6 +++---
>  hw/net/stellaris_enet.c     |  2 +-
>  hw/net/sungem.c             |  4 ++--
>  hw/net/sunhme.c             |  2 +-
>  hw/net/tulip.c              |  2 +-
>  hw/net/virtio-net.c         |  8 ++++----
>  hw/net/vmxnet3.c            |  4 ++--
>  hw/net/xen_nic.c            |  4 ----
>  hw/net/xgmac.c              |  2 +-
>  hw/net/xilinx_axienet.c     |  2 +-
>  hw/net/xilinx_ethlite.c     |  2 +-
>  hw/usb/dev-network.c        |  2 +-
>  include/net/net.h           |  3 +--
>  net/l2tpv3.c                |  3 ---
>  net/net.c                   |  8 +-------
>  net/slirp.c                 |  4 ----
>  net/socket.c                | 24 ------------------------
>  net/tap.c                   | 12 ------------
>  net/vde.c                   |  4 ----
>  net/vhost-user.c            |  2 --
>  42 files changed, 51 insertions(+), 110 deletions(-)
> 

Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>




_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH v2 1/4] qapi: net: Add query-netdevs command
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 1/4] qapi: net: Add " Alexey Kirillov
@ 2020-03-04 15:57   ` Laurent Vivier
  2020-03-05 14:25     ` Alexey Kirillov
  2020-03-05 12:02   ` Markus Armbruster
  1 sibling, 1 reply; 11+ messages in thread
From: Laurent Vivier @ 2020-03-04 15:57 UTC (permalink / raw)
  To: Alexey Kirillov, Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Jiri Pirko, yc-core, Stefan Weil, Alistair Francis,
	Beniamino Galvani, qemu-arm, Peter Chubb, Cédric Le Goater,
	xen-devel, Giuseppe Lettieri, Luigi Rizzo, Richard Henderson,
	Andrew Jeffery, Michael Walle, qemu-ppc, Aleksandar Markovic,
	Paolo Bonzini

On 04/03/2020 14:06, Alexey Kirillov wrote:
> Add a qmp command that provides information about currently attached
> network devices and their configuration.
> 
> Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
> ---
>  include/net/net.h |   1 +
>  net/hub.c         |   8 +++
>  net/l2tpv3.c      |  19 +++++++
>  net/net.c         |  91 +++++++++++++++++++++++++++++++++
>  net/netmap.c      |  13 +++++
>  net/slirp.c       | 126 ++++++++++++++++++++++++++++++++++++++++++++++
>  net/socket.c      |  71 ++++++++++++++++++++++++++
>  net/tap-win32.c   |   9 ++++
>  net/tap.c         | 103 +++++++++++++++++++++++++++++++++++--
>  net/vde.c         |  26 ++++++++++
>  net/vhost-user.c  |  18 +++++--
>  qapi/net.json     |  89 ++++++++++++++++++++++++++++++++
>  12 files changed, 566 insertions(+), 8 deletions(-)
> 
...
> diff --git a/net/net.c b/net/net.c
> index 9e93c3f8a1..01e0548295 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -54,6 +54,7 @@
>  #include "sysemu/sysemu.h"
>  #include "net/filter.h"
>  #include "qapi/string-output-visitor.h"
> +#include "qapi/clone-visitor.h"
>  
>  /* Net bridge is currently not supported for W32. */
>  #if !defined(_WIN32)
> @@ -128,6 +129,12 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr)
>  
>  void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
>  {
> +    g_assert(nc->stored_config);
> +
> +    g_free(nc->stored_config->u.nic.macaddr);
> +    nc->stored_config->u.nic.macaddr = g_strdup_printf(MAC_FMT,
> +                                                       MAC_ARG(macaddr));
> +

Why do you use this rather than the qemu_mac_strdup_printf() function
defined above?

qemu_mac_strdup_printf():
  890ee6abb385 ("net: add MAC address string printer")

MAC_FMT/MAC_ARG:
  6d1d4939a647 ("net: Add macros for MAC address tracing")

MAC_FMT/MAC_ARG seems to be reserved for tracing.

Thanks,
Laurent


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH v2 1/4] qapi: net: Add query-netdevs command
  2020-03-04 13:06 ` [Xen-devel] [PATCH v2 1/4] qapi: net: Add " Alexey Kirillov
  2020-03-04 15:57   ` Laurent Vivier
@ 2020-03-05 12:02   ` Markus Armbruster
  2020-03-05 14:26     ` Alexey Kirillov
  1 sibling, 1 reply; 11+ messages in thread
From: Markus Armbruster @ 2020-03-05 12:02 UTC (permalink / raw)
  To: Alexey Kirillov
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Eric Blake,
	Paul Durrant, Joel Stanley, Anthony Perard, Samuel Thibault,
	Aleksandar Rikalo, Richard Henderson, Laurent Vivier, Jiri Pirko,
	Aleksandar Markovic, Stefan Weil, Alistair Francis,
	Beniamino Galvani, qemu-arm, Peter Chubb, Cédric Le Goater,
	xen-devel, Giuseppe Lettieri, Luigi Rizzo, David Gibson,
	Thomas Huth, Andrew Jeffery, Michael Walle, qemu-ppc, yc-core,
	Paolo Bonzini

Alexey Kirillov <lekiravi@yandex-team.ru> writes:

> Add a qmp command that provides information about currently attached
> network devices and their configuration.

Closes a gap in QMP; appreciated!

> Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
[...]
> diff --git a/qapi/net.json b/qapi/net.json
> index 1cb9a7d782..4f329a1de0 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -750,3 +750,92 @@
>  ##
>  { 'event': 'FAILOVER_NEGOTIATED',
>    'data': {'device-id': 'str'} }
> +
> +##
> +# @NetdevInfo:
> +#
> +# Configuration of a network device.
> +#
> +# @id: Device identifier.
> +#
> +# @type: Specify the driver used for interpreting remaining arguments.
> +#
> +# @peer: Connected network device.

@peer is optional.  I assume its present when the device is connected
(frontend to backend or vice versa).  Correct?

> +#
> +# @queues-count: Number of queues.

We use plain @queues elsewhere in the schema.

> +#
> +# @hub: hubid of hub, if connected to.

How @hub is related to @peer is not quite obvious to me.  Can you give
an example where @hub is present?

> +#
> +# @perm-mac: Original MAC address.

What does "perm-" mean?

It's optional.  When exactly is it present?

> +#
> +# Since: 5.0
> +##
> +{ 'union': 'NetdevInfo',
> +  'base': { 'id': 'str',
> +            'type': 'NetClientDriver',
> +            '*peer': 'str',
> +            'queues-count': 'int',
> +            '*hub': 'int',
> +            '*perm-mac': 'str' },
> +  'discriminator': 'type',
> +  'data': {
> +      'nic':        'NetLegacyNicOptions',
> +      'user':       'NetdevUserOptions',
> +      'tap':        'NetdevTapOptions',
> +      'l2tpv3':     'NetdevL2TPv3Options',
> +      'socket':     'NetdevSocketOptions',
> +      'vde':        'NetdevVdeOptions',
> +      'bridge':     'NetdevBridgeOptions',
> +      'hubport':    'NetdevHubPortOptions',
> +      'netmap':     'NetdevNetmapOptions',
> +      'vhost-user': 'NetdevVhostUserOptions' } }

This is a copy of union 'Netdev' with a few additional common members
(@peer, @queues-count, @hub, @perm-mac).  I can't see how to avoid the
duplication without adding nesting on the wire.

> +
> +##
> +# @query-netdevs:
> +#
> +# Get a list of @NetdevInfo for all virtual network devices.
> +#
> +# Returns: a list of @NetdevInfo describing each virtual network device.
> +#
> +# Since: 5.0
> +#
> +# Example:
> +#
> +# -> { "execute": "query-netdevs" }
> +# <- { "return": [
> +#          {
> +#              "peer": "netdev0",
> +#              "netdev": "netdev0",
> +#              "perm-mac": "52:54:00:12:34:56"
> +#              "model": "virtio-net-pci",
> +#              "macaddr": "52:54:00:12:34:56",
> +#              "queues-count": 1,
> +#              "type": "nic",
> +#              "id": "net0"
> +#          },
> +#          {
> +#              "peer": "net0",
> +#              "ipv6": true,
> +#              "ipv4": true,
> +#              "host": "10.0.2.2",
> +#              "queues-count": 1,
> +#              "ipv6-dns": "fec0::3",
> +#              "ipv6-prefix": "fec0::",
> +#              "net": "10.0.2.0/255.255.255.0",
> +#              "ipv6-host": "fec0::2",
> +#              "type": "user",
> +#              "dns": "10.0.2.3",
> +#              "hostfwd": [
> +#                  {
> +#                      "str": "tcp::20004-:22"
> +#                  }
> +#              ],
> +#              "ipv6-prefixlen": 64,
> +#              "id": "netdev0",
> +#              "restrict": false
> +#          }
> +#      ]
> +#    }
> +#
> +##
> +{ 'command': 'query-netdevs', 'returns': ['NetdevInfo'] }

Like HMP "info network" and -net, this mixes frontends ("type": "nic")
and backends.  Unlike query-chardev and query-block.  Hmm.

A long time ago, all we had was -net: "-net nic" for configuring
frontends, "-net none" for suppressing a default frontend + backend, and
"-net anything-else" for configuring backends.  "info network" showed
the stuff set up with -net.

In v0.12, we got -device for configuring frontends, and -netdev for
backends.  -netdev is like -net less "none", "nic", and the hub
weirdness.  "info network" was extended to also show all this.

In v2.12, we got -nic, replacing -net nic.

Unless I'm missing something, -net is just for backward compatibility
now.

What's the use case for query-networks reporting frontends?


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH v2 1/4] qapi: net: Add query-netdevs command
  2020-03-04 15:57   ` Laurent Vivier
@ 2020-03-05 14:25     ` Alexey Kirillov
  0 siblings, 0 replies; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-05 14:25 UTC (permalink / raw)
  To: Laurent Vivier, Eric Blake, Thomas Huth, Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Paul Durrant,
	Joel Stanley, Anthony Perard, Samuel Thibault, Aleksandar Rikalo,
	David Gibson, Jiri Pirko, yc-core, Stefan Weil, Alistair Francis,
	Beniamino Galvani, qemu-arm, Peter Chubb, Cédric Le Goater,
	xen-devel, Giuseppe Lettieri, Luigi Rizzo, Richard Henderson,
	Andrew Jeffery, Michael Walle, qemu-ppc, Aleksandar Markovic,
	Paolo Bonzini



04.03.2020, 18:57, "Laurent Vivier" <lvivier@redhat.com>:
> On 04/03/2020 14:06, Alexey Kirillov wrote:
>>  Add a qmp command that provides information about currently attached
>>  network devices and their configuration.
>>
>>  Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
>>  ---
>>   include/net/net.h | 1 +
>>   net/hub.c | 8 +++
>>   net/l2tpv3.c | 19 +++++++
>>   net/net.c | 91 +++++++++++++++++++++++++++++++++
>>   net/netmap.c | 13 +++++
>>   net/slirp.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++
>>   net/socket.c | 71 ++++++++++++++++++++++++++
>>   net/tap-win32.c | 9 ++++
>>   net/tap.c | 103 +++++++++++++++++++++++++++++++++++--
>>   net/vde.c | 26 ++++++++++
>>   net/vhost-user.c | 18 +++++--
>>   qapi/net.json | 89 ++++++++++++++++++++++++++++++++
>>   12 files changed, 566 insertions(+), 8 deletions(-)
>
> ...
>>  diff --git a/net/net.c b/net/net.c
>>  index 9e93c3f8a1..01e0548295 100644
>>  --- a/net/net.c
>>  +++ b/net/net.c
>>  @@ -54,6 +54,7 @@
>>   #include "sysemu/sysemu.h"
>>   #include "net/filter.h"
>>   #include "qapi/string-output-visitor.h"
>>  +#include "qapi/clone-visitor.h"
>>
>>   /* Net bridge is currently not supported for W32. */
>>   #if !defined(_WIN32)
>>  @@ -128,6 +129,12 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr)
>>
>>   void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
>>   {
>>  + g_assert(nc->stored_config);
>>  +
>>  + g_free(nc->stored_config->u.nic.macaddr);
>>  + nc->stored_config->u.nic.macaddr = g_strdup_printf(MAC_FMT,
>>  + MAC_ARG(macaddr));
>>  +
>
> Why do you use this rather than the qemu_mac_strdup_printf() function
> defined above?
>
> qemu_mac_strdup_printf():
>   890ee6abb385 ("net: add MAC address string printer")
>
> MAC_FMT/MAC_ARG:
>   6d1d4939a647 ("net: Add macros for MAC address tracing")
>
> MAC_FMT/MAC_ARG seems to be reserved for tracing.
>
> Thanks,
> Laurent

Somehow, I managed not to notice this feature.
Thank you for pointing this out, I will definitely fix this place.

-- 
Alexey Kirillov
Yandex.Cloud


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH v2 1/4] qapi: net: Add query-netdevs command
  2020-03-05 12:02   ` Markus Armbruster
@ 2020-03-05 14:26     ` Alexey Kirillov
  2020-06-23  9:59       ` Alexey Kirillov
  0 siblings, 1 reply; 11+ messages in thread
From: Alexey Kirillov @ 2020-03-05 14:26 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Eric Blake,
	Paul Durrant, Joel Stanley, Anthony Perard, Samuel Thibault,
	Aleksandar Rikalo, Richard Henderson, Laurent Vivier, Jiri Pirko,
	Aleksandar Markovic, Stefan Weil, Alistair Francis,
	Beniamino Galvani, qemu-arm, Peter Chubb, Cédric Le Goater,
	xen-devel, Giuseppe Lettieri, Luigi Rizzo, David Gibson,
	Thomas Huth, Andrew Jeffery, Michael Walle, qemu-ppc, yc-core,
	Paolo Bonzini



05.03.2020, 15:03, "Markus Armbruster" <armbru@redhat.com>:
> Alexey Kirillov <lekiravi@yandex-team.ru> writes:
>
>>  Add a qmp command that provides information about currently attached
>>  network devices and their configuration.
>
> Closes a gap in QMP; appreciated!
>
>>  Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
>
> [...]
>>  diff --git a/qapi/net.json b/qapi/net.json
>>  index 1cb9a7d782..4f329a1de0 100644
>>  --- a/qapi/net.json
>>  +++ b/qapi/net.json
>>  @@ -750,3 +750,92 @@
>>   ##
>>   { 'event': 'FAILOVER_NEGOTIATED',
>>     'data': {'device-id': 'str'} }
>>  +
>>  +##
>>  +# @NetdevInfo:
>>  +#
>>  +# Configuration of a network device.
>>  +#
>>  +# @id: Device identifier.
>>  +#
>>  +# @type: Specify the driver used for interpreting remaining arguments.
>>  +#
>>  +# @peer: Connected network device.
>
> @peer is optional. I assume its present when the device is connected
> (frontend to backend or vice versa). Correct?
>

Yes, this field stores connected frontend/backend device @id.

>>  +#
>>  +# @queues-count: Number of queues.
>
> We use plain @queues elsewhere in the schema.
>

It can conflict with fields inside Netdev*Options, isn't it?

>>  +#
>>  +# @hub: hubid of hub, if connected to.
>
> How @hub is related to @peer is not quite obvious to me. Can you give
> an example where @hub is present?
>

NetdevHubPortOptions has an option @hubid. @hub gives that id, if
netdev is connected to the hub via hubport. As example:

HMP:

hub 0
 \ hub0port1: socket.0: index=0,type=socket,
 \ hub0port0: virtio-net-pci.0: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:56

QMP:

[
  {
    "peer": "hub0port0",
    "netdev": "hub0port0",
    "hub": 0,
    "model": "virtio-net-pci",
    "macaddr": "52:54:00:12:34:56",
    "type": "nic",
    "queues-count": 1,
    "id": "virtio-net-pci.0"
  },
  {
    "peer": "hub0port1",
    "listen": "127.0.0.1:90",
    "hub": 0,
    "type": "socket",
    "queues-count": 1,
    "id": "socket.0"
  },
  {
    "peer": "socket.0",
    "netdev": "socket.0",
    "hub": 0,
    "hubid": 0,
    "type": "hubport",
    "queues-count": 1,
    "id": "hub0port1"
  },
  {
    "peer": "virtio-net-pci.0",
    "netdev": "virtio-net-pci.0",
    "hub": 0,
    "hubid": 0,
    "type": "hubport",
    "queues-count": 1,
    "id": "hub0port0"
  }
]

>>  +#
>>  +# @perm-mac: Original MAC address.
>
> What does "perm-" mean?
>
> It's optional. When exactly is it present?
>

@perm-mac is the permanent (original) MAC address. It only used
for nic, because most of nic realizations can change MAC at
runtime and/or reset it to default (permanent) value.

>>  +#
>>  +# Since: 5.0
>>  +##
>>  +{ 'union': 'NetdevInfo',
>>  + 'base': { 'id': 'str',
>>  + 'type': 'NetClientDriver',
>>  + '*peer': 'str',
>>  + 'queues-count': 'int',
>>  + '*hub': 'int',
>>  + '*perm-mac': 'str' },
>>  + 'discriminator': 'type',
>>  + 'data': {
>>  + 'nic': 'NetLegacyNicOptions',
>>  + 'user': 'NetdevUserOptions',
>>  + 'tap': 'NetdevTapOptions',
>>  + 'l2tpv3': 'NetdevL2TPv3Options',
>>  + 'socket': 'NetdevSocketOptions',
>>  + 'vde': 'NetdevVdeOptions',
>>  + 'bridge': 'NetdevBridgeOptions',
>>  + 'hubport': 'NetdevHubPortOptions',
>>  + 'netmap': 'NetdevNetmapOptions',
>>  + 'vhost-user': 'NetdevVhostUserOptions' } }
>
> This is a copy of union 'Netdev' with a few additional common members
> (@peer, @queues-count, @hub, @perm-mac). I can't see how to avoid the
> duplication without adding nesting on the wire.
>
>>  +
>>  +##
>>  +# @query-netdevs:
>>  +#
>>  +# Get a list of @NetdevInfo for all virtual network devices.
>>  +#
>>  +# Returns: a list of @NetdevInfo describing each virtual network device.
>>  +#
>>  +# Since: 5.0
>>  +#
>>  +# Example:
>>  +#
>>  +# -> { "execute": "query-netdevs" }
>>  +# <- { "return": [
>>  +# {
>>  +# "peer": "netdev0",
>>  +# "netdev": "netdev0",
>>  +# "perm-mac": "52:54:00:12:34:56"
>>  +# "model": "virtio-net-pci",
>>  +# "macaddr": "52:54:00:12:34:56",
>>  +# "queues-count": 1,
>>  +# "type": "nic",
>>  +# "id": "net0"
>>  +# },
>>  +# {
>>  +# "peer": "net0",
>>  +# "ipv6": true,
>>  +# "ipv4": true,
>>  +# "host": "10.0.2.2",
>>  +# "queues-count": 1,
>>  +# "ipv6-dns": "fec0::3",
>>  +# "ipv6-prefix": "fec0::",
>>  +# "net": "10.0.2.0/255.255.255.0",
>>  +# "ipv6-host": "fec0::2",
>>  +# "type": "user",
>>  +# "dns": "10.0.2.3",
>>  +# "hostfwd": [
>>  +# {
>>  +# "str": "tcp::20004-:22"
>>  +# }
>>  +# ],
>>  +# "ipv6-prefixlen": 64,
>>  +# "id": "netdev0",
>>  +# "restrict": false
>>  +# }
>>  +# ]
>>  +# }
>>  +#
>>  +##
>>  +{ 'command': 'query-netdevs', 'returns': ['NetdevInfo'] }
>
> Like HMP "info network" and -net, this mixes frontends ("type": "nic")
> and backends. Unlike query-chardev and query-block. Hmm.
>
> A long time ago, all we had was -net: "-net nic" for configuring
> frontends, "-net none" for suppressing a default frontend + backend, and
> "-net anything-else" for configuring backends. "info network" showed
> the stuff set up with -net.
>
> In v0.12, we got -device for configuring frontends, and -netdev for
> backends. -netdev is like -net less "none", "nic", and the hub
> weirdness. "info network" was extended to also show all this.
>
> In v2.12, we got -nic, replacing -net nic.
>
> Unless I'm missing something, -net is just for backward compatibility
> now.
>
> What's the use case for query-networks reporting frontends?

In my vision, new QMP command is the replacement for old
HMP command. It must provide information about all
network devices, mainly for recreate similar net topology.
Currently, there are no differrence between fronted and
backend devices in context of my command, because
all of them use the same interface in NetClientState.

>

-- 
Alexey Kirillov
Yandex.Cloud


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH v2 1/4] qapi: net: Add query-netdevs command
  2020-03-05 14:26     ` Alexey Kirillov
@ 2020-06-23  9:59       ` Alexey Kirillov
  0 siblings, 0 replies; 11+ messages in thread
From: Alexey Kirillov @ 2020-06-23  9:59 UTC (permalink / raw)
  To: Markus Armbruster, Thomas Huth
  Cc: Peter Maydell, Dmitry Fleytman, Michael S. Tsirkin, Jason Wang,
	qemu-devel, Vincenzo Maffione, Gerd Hoffmann, Edgar E. Iglesias,
	Sven Schnelle, Rob Herring, Stefano Stabellini, Eric Blake,
	Paul Durrant, Joel Stanley, Anthony Perard, Samuel Thibault,
	Aleksandar Rikalo, Richard Henderson, Laurent Vivier, Jiri Pirko,
	Aleksandar Markovic, Stefan Weil, Alistair Francis,
	Beniamino Galvani, qemu-arm, Peter Chubb, Cédric Le Goater,
	xen-devel, Giuseppe Lettieri, Luigi Rizzo, David Gibson,
	Andrew Jeffery, Michael Walle, qemu-ppc, yc-core, Paolo Bonzini

ping

Sorry, I lost a point in discussion.

As I wrote early, main reason for mix frontend and backend devices is for
easy recreation of current state of network. As we have common structure
for all netdevs (`struct NetClientState`), I think, that it'll be good
idea to iterate using `net_clients`.
There is no such trouble to split `query-netdevs` by two, for example,
`query-front-netdevs` and `query-back-netdevs`, but in my opinion it'll
break consistancy in getting links between netdevs.

05.03.2020, 17:26, "Alexey Kirillov" <lekiravi@yandex-team.ru>:
> 05.03.2020, 15:03, "Markus Armbruster" <armbru@redhat.com>:
>>  Alexey Kirillov <lekiravi@yandex-team.ru> writes:
>>
>>>   Add a qmp command that provides information about currently attached
>>>   network devices and their configuration.
>>
>>  Closes a gap in QMP; appreciated!
>>
>>>   Signed-off-by: Alexey Kirillov <lekiravi@yandex-team.ru>
>>
>>  [...]
>>>   diff --git a/qapi/net.json b/qapi/net.json
>>>   index 1cb9a7d782..4f329a1de0 100644
>>>   --- a/qapi/net.json
>>>   +++ b/qapi/net.json
>>>   @@ -750,3 +750,92 @@
>>>    ##
>>>    { 'event': 'FAILOVER_NEGOTIATED',
>>>      'data': {'device-id': 'str'} }
>>>   +
>>>   +##
>>>   +# @NetdevInfo:
>>>   +#
>>>   +# Configuration of a network device.
>>>   +#
>>>   +# @id: Device identifier.
>>>   +#
>>>   +# @type: Specify the driver used for interpreting remaining arguments.
>>>   +#
>>>   +# @peer: Connected network device.
>>
>>  @peer is optional. I assume its present when the device is connected
>>  (frontend to backend or vice versa). Correct?
>
> Yes, this field stores connected frontend/backend device @id.
>
>>>   +#
>>>   +# @queues-count: Number of queues.
>>
>>  We use plain @queues elsewhere in the schema.
>
> It can conflict with fields inside Netdev*Options, isn't it?
>
>>>   +#
>>>   +# @hub: hubid of hub, if connected to.
>>
>>  How @hub is related to @peer is not quite obvious to me. Can you give
>>  an example where @hub is present?
>
> NetdevHubPortOptions has an option @hubid. @hub gives that id, if
> netdev is connected to the hub via hubport. As example:
>
> HMP:
>
> hub 0
>  \ hub0port1: socket.0: index=0,type=socket,
>  \ hub0port0: virtio-net-pci.0: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:56
>
> QMP:
>
> [
>   {
>     "peer": "hub0port0",
>     "netdev": "hub0port0",
>     "hub": 0,
>     "model": "virtio-net-pci",
>     "macaddr": "52:54:00:12:34:56",
>     "type": "nic",
>     "queues-count": 1,
>     "id": "virtio-net-pci.0"
>   },
>   {
>     "peer": "hub0port1",
>     "listen": "127.0.0.1:90",
>     "hub": 0,
>     "type": "socket",
>     "queues-count": 1,
>     "id": "socket.0"
>   },
>   {
>     "peer": "socket.0",
>     "netdev": "socket.0",
>     "hub": 0,
>     "hubid": 0,
>     "type": "hubport",
>     "queues-count": 1,
>     "id": "hub0port1"
>   },
>   {
>     "peer": "virtio-net-pci.0",
>     "netdev": "virtio-net-pci.0",
>     "hub": 0,
>     "hubid": 0,
>     "type": "hubport",
>     "queues-count": 1,
>     "id": "hub0port0"
>   }
> ]
>
>>>   +#
>>>   +# @perm-mac: Original MAC address.
>>
>>  What does "perm-" mean?
>>
>>  It's optional. When exactly is it present?
>
> @perm-mac is the permanent (original) MAC address. It only used
> for nic, because most of nic realizations can change MAC at
> runtime and/or reset it to default (permanent) value.
>
>>>   +#
>>>   +# Since: 5.0
>>>   +##
>>>   +{ 'union': 'NetdevInfo',
>>>   + 'base': { 'id': 'str',
>>>   + 'type': 'NetClientDriver',
>>>   + '*peer': 'str',
>>>   + 'queues-count': 'int',
>>>   + '*hub': 'int',
>>>   + '*perm-mac': 'str' },
>>>   + 'discriminator': 'type',
>>>   + 'data': {
>>>   + 'nic': 'NetLegacyNicOptions',
>>>   + 'user': 'NetdevUserOptions',
>>>   + 'tap': 'NetdevTapOptions',
>>>   + 'l2tpv3': 'NetdevL2TPv3Options',
>>>   + 'socket': 'NetdevSocketOptions',
>>>   + 'vde': 'NetdevVdeOptions',
>>>   + 'bridge': 'NetdevBridgeOptions',
>>>   + 'hubport': 'NetdevHubPortOptions',
>>>   + 'netmap': 'NetdevNetmapOptions',
>>>   + 'vhost-user': 'NetdevVhostUserOptions' } }
>>
>>  This is a copy of union 'Netdev' with a few additional common members
>>  (@peer, @queues-count, @hub, @perm-mac). I can't see how to avoid the
>>  duplication without adding nesting on the wire.
>>
>>>   +
>>>   +##
>>>   +# @query-netdevs:
>>>   +#
>>>   +# Get a list of @NetdevInfo for all virtual network devices.
>>>   +#
>>>   +# Returns: a list of @NetdevInfo describing each virtual network device.
>>>   +#
>>>   +# Since: 5.0
>>>   +#
>>>   +# Example:
>>>   +#
>>>   +# -> { "execute": "query-netdevs" }
>>>   +# <- { "return": [
>>>   +# {
>>>   +# "peer": "netdev0",
>>>   +# "netdev": "netdev0",
>>>   +# "perm-mac": "52:54:00:12:34:56"
>>>   +# "model": "virtio-net-pci",
>>>   +# "macaddr": "52:54:00:12:34:56",
>>>   +# "queues-count": 1,
>>>   +# "type": "nic",
>>>   +# "id": "net0"
>>>   +# },
>>>   +# {
>>>   +# "peer": "net0",
>>>   +# "ipv6": true,
>>>   +# "ipv4": true,
>>>   +# "host": "10.0.2.2",
>>>   +# "queues-count": 1,
>>>   +# "ipv6-dns": "fec0::3",
>>>   +# "ipv6-prefix": "fec0::",
>>>   +# "net": "10.0.2.0/255.255.255.0",
>>>   +# "ipv6-host": "fec0::2",
>>>   +# "type": "user",
>>>   +# "dns": "10.0.2.3",
>>>   +# "hostfwd": [
>>>   +# {
>>>   +# "str": "tcp::20004-:22"
>>>   +# }
>>>   +# ],
>>>   +# "ipv6-prefixlen": 64,
>>>   +# "id": "netdev0",
>>>   +# "restrict": false
>>>   +# }
>>>   +# ]
>>>   +# }
>>>   +#
>>>   +##
>>>   +{ 'command': 'query-netdevs', 'returns': ['NetdevInfo'] }
>>
>>  Like HMP "info network" and -net, this mixes frontends ("type": "nic")
>>  and backends. Unlike query-chardev and query-block. Hmm.
>>
>>  A long time ago, all we had was -net: "-net nic" for configuring
>>  frontends, "-net none" for suppressing a default frontend + backend, and
>>  "-net anything-else" for configuring backends. "info network" showed
>>  the stuff set up with -net.
>>
>>  In v0.12, we got -device for configuring frontends, and -netdev for
>>  backends. -netdev is like -net less "none", "nic", and the hub
>>  weirdness. "info network" was extended to also show all this.
>>
>>  In v2.12, we got -nic, replacing -net nic.
>>
>>  Unless I'm missing something, -net is just for backward compatibility
>>  now.
>>
>>  What's the use case for query-networks reporting frontends?
>
> In my vision, new QMP command is the replacement for old
> HMP command. It must provide information about all
> network devices, mainly for recreate similar net topology.
> Currently, there are no differrence between fronted and
> backend devices in context of my command, because
> all of them use the same interface in NetClientState.
>
>>
>
> --
> Alexey Kirillov
> Yandex.Cloud

-- 
Alexey Kirillov
Yandex.Cloud




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

end of thread, other threads:[~2020-06-23 10:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-04 13:06 [Xen-devel] [PATCH v2 0/4] Introducing QMP query-netdevs command Alexey Kirillov
2020-03-04 13:06 ` [Xen-devel] [PATCH v2 1/4] qapi: net: Add " Alexey Kirillov
2020-03-04 15:57   ` Laurent Vivier
2020-03-05 14:25     ` Alexey Kirillov
2020-03-05 12:02   ` Markus Armbruster
2020-03-05 14:26     ` Alexey Kirillov
2020-06-23  9:59       ` Alexey Kirillov
2020-03-04 13:06 ` [Xen-devel] [PATCH v2 2/4] tests: Add tests for " Alexey Kirillov
2020-03-04 13:06 ` [Xen-devel] [PATCH v2 3/4] hmp: Use QMP query-netdevs in hmp_info_network Alexey Kirillov
2020-03-04 13:06 ` [Xen-devel] [PATCH v2 4/4] net: Remove field info_str of NetClientState Alexey Kirillov
2020-03-04 15:41   ` Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).