aboutsummaryrefslogtreecommitdiff
path: root/net/net.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-03-16 10:53:47 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-03-16 10:53:47 +0000
commit6e31b3a5c34c6e5be7ef60773e607f189eaa15f3 (patch)
treed12963d6df1819264b349159e6ed49b41f9e3eb0 /net/net.c
parent2615a5e433aeb812c300d3a48e1a88e1303e2339 (diff)
parentf2e8319d456724c3d8514d943dc4607e2f08e88a (diff)
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Mon 15 Mar 2021 08:42:25 GMT # gpg: using RSA key EF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" [marginal] # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * remotes/jasowang/tags/net-pull-request: net: Do not fill legacy info_str for backends hmp: Use QAPI NetdevInfo in hmp_info_network net: Move NetClientState.info_str to dynamic allocations tests: Add tests for query-netdev command qapi: net: Add query-netdev command pvrdma: wean code off pvrdma_ring.h kernel header lan9118: switch to use qemu_receive_packet() for loopback cadence_gem: switch to use qemu_receive_packet() for loopback pcnet: switch to use qemu_receive_packet() for loopback rtl8139: switch to use qemu_receive_packet() for loopback tx_pkt: switch to use qemu_receive_packet_iov() for loopback sungem: switch to use qemu_receive_packet() for loopback msf2-mac: switch to use qemu_receive_packet() for loopback dp8393x: switch to use qemu_receive_packet() for loopback packet e1000: switch to use qemu_receive_packet() for loopback net: introduce qemu_receive_packet() e1000: fail early for evil descriptor net: validate that ids are well formed net: Fix build error when DEBUG_NET is on virtio-net: calculating proper msix vectors on init Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # hw/core/machine.c
Diffstat (limited to 'net/net.c')
-rw-r--r--net/net.c117
1 files changed, 103 insertions, 14 deletions
diff --git a/net/net.c b/net/net.c
index 9a2a4c99a5..725a4e1450 100644
--- a/net/net.c
+++ b/net/net.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu-common.h"
#include "net/net.h"
#include "clients.h"
@@ -35,7 +36,6 @@
#include "monitor/monitor.h"
#include "qemu/help_option.h"
#include "qapi/qapi-commands-net.h"
-#include "qapi/qapi-visit-net.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
@@ -55,6 +55,7 @@
#include "sysemu/sysemu.h"
#include "net/filter.h"
#include "qapi/string-output-visitor.h"
+#include "qapi/hmp-output-visitor.h"
/* Net bridge is currently not supported for W32. */
#if !defined(_WIN32)
@@ -129,11 +130,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 +354,8 @@ 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);
}
@@ -528,6 +532,17 @@ int qemu_set_vnet_be(NetClientState *nc, bool is_be)
#endif
}
+int qemu_can_receive_packet(NetClientState *nc)
+{
+ if (nc->receive_disabled) {
+ return 0;
+ } else if (nc->info->can_receive &&
+ !nc->info->can_receive(nc)) {
+ return 0;
+ }
+ return 1;
+}
+
int qemu_can_send_packet(NetClientState *sender)
{
int vm_running = runstate_is_running();
@@ -540,13 +555,7 @@ int qemu_can_send_packet(NetClientState *sender)
return 1;
}
- if (sender->peer->receive_disabled) {
- return 0;
- } else if (sender->peer->info->can_receive &&
- !sender->peer->info->can_receive(sender->peer)) {
- return 0;
- }
- return 1;
+ return qemu_can_receive_packet(sender->peer);
}
static ssize_t filter_receive_iov(NetClientState *nc,
@@ -679,6 +688,25 @@ ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
return qemu_send_packet_async(nc, buf, size, NULL);
}
+ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size)
+{
+ if (!qemu_can_receive_packet(nc)) {
+ return 0;
+ }
+
+ return qemu_net_queue_receive(nc->incoming_queue, buf, size);
+}
+
+ssize_t qemu_receive_packet_iov(NetClientState *nc, const struct iovec *iov,
+ int iovcnt)
+{
+ if (!qemu_can_receive_packet(nc)) {
+ return 0;
+ }
+
+ return qemu_net_queue_receive_iov(nc->incoming_queue, iov, iovcnt);
+}
+
ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
{
return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW,
@@ -1133,6 +1161,11 @@ void netdev_add(QemuOpts *opts, Error **errp)
void qmp_netdev_add(Netdev *netdev, Error **errp)
{
+ if (!id_wellformed(netdev->id)) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
+ return;
+ }
+
net_client_init1(netdev, true, errp);
}
@@ -1189,14 +1222,42 @@ static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
monitor_printf(mon, "\n");
}
+static char *generate_info_str(NetClientState *nc)
+{
+ NetdevInfo *ni = nc->stored_config;
+ char *ret_out = NULL;
+ Visitor *v;
+
+ /* Use legacy field info_str for NIC and hubports */
+ if ((nc->info->type == NET_CLIENT_DRIVER_NIC) ||
+ (nc->info->type == NET_CLIENT_DRIVER_HUBPORT)) {
+ return g_strdup(nc->info_str ? nc->info_str : "");
+ }
+
+ if (!ni) {
+ return g_malloc0(1);
+ }
+
+ v = hmp_output_visitor_new(&ret_out);
+ if (visit_type_NetdevInfo(v, "", &ni, NULL)) {
+ visit_complete(v, &ret_out);
+ }
+ visit_free(v);
+
+ return ret_out;
+}
+
void print_net_client(Monitor *mon, NetClientState *nc)
{
NetFilterState *nf;
+ char *info_str = generate_info_str(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");
}
@@ -1259,6 +1320,34 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
return filter_list;
}
+NetdevInfoList *qmp_query_netdev(Error **errp)
+{
+ NetdevInfoList *list = NULL;
+ NetClientState *nc;
+
+ QTAILQ_FOREACH(nc, &net_clients, next) {
+ /*
+ * Only look at netdevs (backend network devices), not for each queue
+ * or NIC / hubport
+ */
+ if (nc->stored_config) {
+ NetdevInfo *element = QAPI_CLONE(NetdevInfo, nc->stored_config);
+
+ g_free(element->id); /* Need to dealloc empty id after clone */
+ element->id = g_strdup(nc->name);
+
+ element->has_peer_id = nc->peer != NULL;
+ if (element->has_peer_id) {
+ element->peer_id = g_strdup(nc->peer->name);
+ }
+
+ QAPI_LIST_PREPEND(list, element);
+ }
+ }
+
+ return list;
+}
+
void hmp_info_network(Monitor *mon, const QDict *qdict)
{
NetClientState *nc, *peer;