From d32ad10a14d46dfe9304e3ed5858a11dcd5c71a0 Mon Sep 17 00:00:00 2001 From: Alexey Kirillov Date: Wed, 3 Mar 2021 12:59:06 +0300 Subject: qapi: net: Add query-netdev command The query-netdev command is used to get the configuration of the current network device backends (netdevs). This is the QMP analog of the HMP command "info network" but only for netdevs (i.e. excluding NIC and hubports). The query-netdev command returns an array of objects of the NetdevInfo type, which are an extension of Netdev type. It means that response can be used for netdev-add after small modification. This can be useful for recreate the same netdev configuration. Information about the network device is filled in when it is created or modified and is available through the NetClientState->stored_config. Signed-off-by: Alexey Kirillov Acked-by: Markus Armbruster Signed-off-by: Jason Wang --- net/tap-win32.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'net/tap-win32.c') diff --git a/net/tap-win32.c b/net/tap-win32.c index 2b5dcda36e..b60933bd1a 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_BACKEND_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); -- cgit 1.4.1 From 59b5437eb732d6b103a9bc279c3482c834d1eff9 Mon Sep 17 00:00:00 2001 From: Alexey Kirillov Date: Wed, 3 Mar 2021 12:59:08 +0300 Subject: net: Move NetClientState.info_str to dynamic allocations The info_str field of the NetClientState structure is static and has a size of 256 bytes. This amount is often unclaimed, and the field itself is used exclusively for HMP "info network". The patch translates info_str to dynamic memory allocation. This action is also allows us to painlessly discard usage of this field for backend devices. Signed-off-by: Alexey Kirillov Signed-off-by: Jason Wang --- hw/net/xen_nic.c | 5 ++--- include/net/net.h | 2 +- net/l2tpv3.c | 3 +-- net/net.c | 14 ++++++++------ net/slirp.c | 5 ++--- net/socket.c | 43 ++++++++++++++++++++++++------------------- net/tap-win32.c | 3 +-- net/tap.c | 13 +++++-------- net/vde.c | 3 +-- net/vhost-user.c | 3 +-- net/vhost-vdpa.c | 2 +- 11 files changed, 47 insertions(+), 49 deletions(-) (limited to 'net/tap-win32.c') diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 5c815b4f0c..8431808ea0 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -296,9 +296,8 @@ 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); + qemu_get_queue(netdev->nic)->info_str = g_strdup_printf( + "nic: xenbus vif macaddr=%s", netdev->mac); /* fill info */ xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1); diff --git a/include/net/net.h b/include/net/net.h index dc3679f41c..a02949f6db 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -94,7 +94,7 @@ struct NetClientState { NetQueue *incoming_queue; char *model; char *name; - char info_str[256]; + char *info_str; NetdevInfo *stored_config; unsigned receive_disabled : 1; NetClientDestructor *destructor; diff --git a/net/l2tpv3.c b/net/l2tpv3.c index 8aa0a3e1a0..96611cb4af 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -730,8 +730,7 @@ int net_init_l2tpv3(const Netdev *netdev, QAPI_CLONE_MEMBERS(NetdevL2TPv3Options, &nc->stored_config->u.l2tpv3, l2tpv3); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "l2tpv3: connected"); + s->nc.info_str = g_strdup_printf("l2tpv3: connected"); return 0; outerr: qemu_del_net_client(nc); diff --git a/net/net.c b/net/net.c index 9a2a6ab155..277da712eb 100644 --- a/net/net.c +++ b/net/net.c @@ -129,11 +129,12 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr) void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]) { - 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]); + g_free(nc->info_str); + nc->info_str = g_strdup_printf( + "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}; @@ -352,6 +353,7 @@ static void qemu_free_net_client(NetClientState *nc) } g_free(nc->name); g_free(nc->model); + g_free(nc->info_str); qapi_free_NetdevInfo(nc->stored_config); if (nc->destructor) { nc->destructor(nc); @@ -1226,7 +1228,7 @@ void print_net_client(Monitor *mon, NetClientState *nc) monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name, nc->queue_index, NetClientDriver_str(nc->info->type), - nc->info_str); + nc->info_str ? nc->info_str : ""); if (!QTAILQ_EMPTY(&nc->filters)) { monitor_printf(mon, "filters:\n"); } diff --git a/net/slirp.c b/net/slirp.c index 6ab348b943..bfa07e3432 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -664,9 +664,8 @@ 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"); + nc->info_str = g_strdup_printf("net=%s,restrict=%s", inet_ntoa(net), + restricted ? "on" : "off"); s = DO_UPCAST(SlirpState, nc, nc); diff --git a/net/socket.c b/net/socket.c index 1614523b82..98172347d7 100644 --- a/net/socket.c +++ b/net/socket.c @@ -180,7 +180,8 @@ 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)); + g_free(s->nc.info_str); + s->nc.info_str = g_new0(char, 1); return; } @@ -400,16 +401,16 @@ 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)); + nc->info_str = g_strdup_printf("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)); + nc->info_str = g_strdup_printf("socket: fd=%d %s", + fd, SocketAddressType_str(sa_type)); } return s; @@ -444,7 +445,7 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer, nc = qemu_new_net_client(&net_socket_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd); + nc->info_str = g_strdup_printf("socket: fd=%d", fd); s = DO_UPCAST(NetSocketState, nc, nc); @@ -528,9 +529,10 @@ 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)); + g_free(s->nc.info_str); + s->nc.info_str = g_strdup_printf("socket: connection from %s:%d", + inet_ntoa(saddr.sin_addr), + ntohs(saddr.sin_port)); } static int net_socket_listen_init(NetClientState *peer, @@ -645,9 +647,10 @@ 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)); + g_free(s->nc.info_str); + s->nc.info_str = g_strdup_printf("socket: connect to %s:%d", + inet_ntoa(saddr.sin_addr), + ntohs(saddr.sin_port)); return 0; } @@ -704,9 +707,10 @@ 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)); + g_free(s->nc.info_str); + s->nc.info_str = g_strdup_printf("socket: mcast=%s:%d", + inet_ntoa(saddr.sin_addr), + ntohs(saddr.sin_port)); return 0; } @@ -769,9 +773,10 @@ 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)); + g_free(s->nc.info_str); + s->nc.info_str = g_strdup_printf("socket: udp=%s:%d", + inet_ntoa(raddr.sin_addr), + ntohs(raddr.sin_port)); return 0; } diff --git a/net/tap-win32.c b/net/tap-win32.c index b60933bd1a..0888db8cce 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -787,8 +787,7 @@ static int tap_win32_init(NetClientState *peer, const char *model, stored->has_ifname = true; stored->ifname = g_strdup(ifname); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "tap: ifname=%s", ifname); + s->nc.info_str = g_strdup_printf("tap: ifname=%s", ifname); s->handle = handle; diff --git a/net/tap.c b/net/tap.c index 8041245ba7..f864f434b2 100644 --- a/net/tap.c +++ b/net/tap.c @@ -625,8 +625,7 @@ 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); + s->nc.info_str = g_strdup_printf("helper=%s,br=%s", helper, br); return 0; } @@ -714,7 +713,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, g_free(tmp_s); } - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd); + s->nc.info_str = g_strdup_printf("fd=%d", fd); } else if (tap->has_helper) { if (!stored->has_helper) { stored->has_helper = true; @@ -727,8 +726,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, g_strdup(DEFAULT_BRIDGE_INTERFACE); } - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s", - tap->helper); + s->nc.info_str = g_strdup_printf("helper=%s", tap->helper); } else { if (ifname && !stored->has_ifname) { stored->has_ifname = true; @@ -745,9 +743,8 @@ 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); + s->nc.info_str = g_strdup_printf("ifname=%s,script=%s,downscript=%s", + ifname, script, downscript); if (strcmp(downscript, "no") != 0) { snprintf(s->down_script, sizeof(s->down_script), "%s", downscript); diff --git a/net/vde.c b/net/vde.c index b0b8800571..67de6eb0c5 100644 --- a/net/vde.c +++ b/net/vde.c @@ -100,8 +100,7 @@ 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)); + nc->info_str = g_strdup_printf("sock=%s,fd=%d", sock, vde_datafd(vde)); s = DO_UPCAST(VDEState, nc, nc); diff --git a/net/vhost-user.c b/net/vhost-user.c index 5b7056be25..49c9a740c2 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -327,8 +327,7 @@ 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->info_str = g_strdup_printf("vhost-user%d to %s", i, chr->label); nc->queue_index = i; if (!nc0) { nc0 = nc; diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 8c27ea0142..423d71770d 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -200,7 +200,7 @@ static int net_vhost_vdpa_init(NetClientState *peer, const char *device, stored->has_queues = true; stored->queues = 1; /* TODO: change when support multiqueue */ - snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA); + nc->info_str = g_strdup_printf(TYPE_VHOST_VDPA); nc->queue_index = 0; s = DO_UPCAST(VhostVDPAState, nc, nc); vdpa_device_fd = qemu_open_old(vhostdev, O_RDWR); -- cgit 1.4.1 From f2e8319d456724c3d8514d943dc4607e2f08e88a Mon Sep 17 00:00:00 2001 From: Alexey Kirillov Date: Wed, 3 Mar 2021 12:59:10 +0300 Subject: net: Do not fill legacy info_str for backends As we use QAPI NetClientState->stored_config to store and get information about backend network devices, we can drop fill of legacy field info_str for them. We still use info_str field for NIC and hubports, so we can not completely remove it. Signed-off-by: Alexey Kirillov Signed-off-by: Jason Wang --- net/l2tpv3.c | 2 -- net/slirp.c | 3 --- net/socket.c | 28 ---------------------------- net/tap-win32.c | 2 -- net/tap.c | 9 --------- net/vde.c | 2 -- net/vhost-user.c | 1 - net/vhost-vdpa.c | 1 - 8 files changed, 48 deletions(-) (limited to 'net/tap-win32.c') diff --git a/net/l2tpv3.c b/net/l2tpv3.c index 96611cb4af..b7e1d84674 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -729,8 +729,6 @@ int net_init_l2tpv3(const Netdev *netdev, QAPI_CLONE_MEMBERS(NetdevL2TPv3Options, &nc->stored_config->u.l2tpv3, l2tpv3); - - s->nc.info_str = g_strdup_printf("l2tpv3: connected"); return 0; outerr: qemu_del_net_client(nc); diff --git a/net/slirp.c b/net/slirp.c index bfa07e3432..9454a673d6 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -664,9 +664,6 @@ static int net_slirp_init(NetClientState *peer, const char *model, stored->tftp_server_name = g_strdup(tftp_server_name); } - nc->info_str = g_strdup_printf("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 98172347d7..c0de10c0c0 100644 --- a/net/socket.c +++ b/net/socket.c @@ -180,8 +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; - g_free(s->nc.info_str); - s->nc.info_str = g_new0(char, 1); return; } @@ -401,16 +399,10 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, stored->mcast = g_strdup(mcast); s->dgram_dst = saddr; - nc->info_str = g_strdup_printf("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; } - - nc->info_str = g_strdup_printf("socket: fd=%d %s", - fd, SocketAddressType_str(sa_type)); } return s; @@ -445,8 +437,6 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer, nc = qemu_new_net_client(&net_socket_info, peer, model, name); - nc->info_str = g_strdup_printf("socket: fd=%d", fd); - s = DO_UPCAST(NetSocketState, nc, nc); s->fd = fd; @@ -528,11 +518,6 @@ static void net_socket_accept(void *opaque) stored->has_fd = true; stored->fd = g_strdup_printf("%d", fd); - - g_free(s->nc.info_str); - s->nc.info_str = g_strdup_printf("socket: connection from %s:%d", - inet_ntoa(saddr.sin_addr), - ntohs(saddr.sin_port)); } static int net_socket_listen_init(NetClientState *peer, @@ -647,10 +632,6 @@ static int net_socket_connect_init(NetClientState *peer, stored->has_connect = true; stored->connect = g_strdup(host_str); - g_free(s->nc.info_str); - s->nc.info_str = g_strdup_printf("socket: connect to %s:%d", - inet_ntoa(saddr.sin_addr), - ntohs(saddr.sin_port)); return 0; } @@ -707,12 +688,7 @@ static int net_socket_mcast_init(NetClientState *peer, stored->localaddr = g_strdup(localaddr_str); } - g_free(s->nc.info_str); - s->nc.info_str = g_strdup_printf("socket: mcast=%s:%d", - inet_ntoa(saddr.sin_addr), - ntohs(saddr.sin_port)); return 0; - } static int net_socket_udp_init(NetClientState *peer, @@ -773,10 +749,6 @@ static int net_socket_udp_init(NetClientState *peer, stored->has_udp = true; stored->udp = g_strdup(rhost); - g_free(s->nc.info_str); - s->nc.info_str = g_strdup_printf("socket: udp=%s:%d", - inet_ntoa(raddr.sin_addr), - ntohs(raddr.sin_port)); return 0; } diff --git a/net/tap-win32.c b/net/tap-win32.c index 0888db8cce..21e451107b 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -787,8 +787,6 @@ static int tap_win32_init(NetClientState *peer, const char *model, stored->has_ifname = true; stored->ifname = g_strdup(ifname); - s->nc.info_str = g_strdup_printf("tap: ifname=%s", ifname); - s->handle = handle; qemu_add_wait_object(s->handle->tap_semaphore, tap_win32_send, s); diff --git a/net/tap.c b/net/tap.c index f864f434b2..12a08d54fe 100644 --- a/net/tap.c +++ b/net/tap.c @@ -625,8 +625,6 @@ int net_init_bridge(const Netdev *netdev, const char *name, stored->helper = g_strdup(helper); } - s->nc.info_str = g_strdup_printf("helper=%s,br=%s", helper, br); - return 0; } @@ -712,8 +710,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); } - - s->nc.info_str = g_strdup_printf("fd=%d", fd); } else if (tap->has_helper) { if (!stored->has_helper) { stored->has_helper = true; @@ -725,8 +721,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); } - - s->nc.info_str = g_strdup_printf("helper=%s", tap->helper); } else { if (ifname && !stored->has_ifname) { stored->has_ifname = true; @@ -743,9 +737,6 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, stored->downscript = g_strdup(downscript); } - s->nc.info_str = g_strdup_printf("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 67de6eb0c5..64bdb937ca 100644 --- a/net/vde.c +++ b/net/vde.c @@ -100,8 +100,6 @@ static int net_vde_init(NetClientState *peer, const char *model, nc = qemu_new_net_client(&net_vde_info, peer, model, name); - nc->info_str = g_strdup_printf("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 49c9a740c2..e443c4b2b5 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -327,7 +327,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); - nc->info_str = g_strdup_printf("vhost-user%d to %s", i, chr->label); nc->queue_index = i; if (!nc0) { nc0 = nc; diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 423d71770d..5a28bbcd7b 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -200,7 +200,6 @@ static int net_vhost_vdpa_init(NetClientState *peer, const char *device, stored->has_queues = true; stored->queues = 1; /* TODO: change when support multiqueue */ - nc->info_str = g_strdup_printf(TYPE_VHOST_VDPA); nc->queue_index = 0; s = DO_UPCAST(VhostVDPAState, nc, nc); vdpa_device_fd = qemu_open_old(vhostdev, O_RDWR); -- cgit 1.4.1