mirror of
https://github.com/xemu-project/xemu.git
synced 2025-04-02 11:11:48 -04:00
Convert all the multi-line uses of fprintf(stderr, "warning:"..."\n"... to use warn_report() instead. This helps standardise on a single method of printing warnings to the user. All of the warnings were changed using these commands: find ./* -type f -exec sed -i \ 'N; {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + find ./* -type f -exec sed -i \ 'N;N; {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + find ./* -type f -exec sed -i \ 'N;N;N; {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + find ./* -type f -exec sed -i \ 'N;N;N;N {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + find ./* -type f -exec sed -i \ 'N;N;N;N;N {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + find ./* -type f -exec sed -i \ 'N;N;N;N;N;N {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + find ./* -type f -exec sed -i \ 'N;N;N;N;N;N;N; {s|fprintf(.*".*warning[,:] \(.*\)\\n"\(.*\));|warn_report("\1"\2);|Ig}' \ {} + Indentation fixed up manually afterwards. Some of the lines were manually edited to reduce the line length to below 80 charecters. Some of the lines with newlines in the middle of the string were also manually edit to avoid checkpatch errrors. The #include lines were manually updated to allow the code to compile. Several of the warning messages can be improved after this patch, to keep this patch mechanical this has been moved into a later patch. Signed-off-by: Alistair Francis <alistair.francis@xilinx.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Kevin Wolf <kwolf@redhat.com> Cc: Max Reitz <mreitz@redhat.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Peter Maydell <peter.maydell@linaro.org> Cc: Stefano Stabellini <sstabellini@kernel.org> Cc: Anthony Perard <anthony.perard@citrix.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Eduardo Habkost <ehabkost@redhat.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Cc: Yongbok Kim <yongbok.kim@imgtec.com> Cc: Cornelia Huck <cohuck@redhat.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Alexander Graf <agraf@suse.de> Cc: Jason Wang <jasowang@redhat.com> Cc: David Gibson <david@gibson.dropbear.id.au> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <5def63849ca8f551630c6f2b45bcb1c482f765a6.1505158760.git.alistair.francis@xilinx.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
355 lines
8.2 KiB
C
355 lines
8.2 KiB
C
/*
|
|
* Hub net client
|
|
*
|
|
* Copyright IBM, Corp. 2012
|
|
*
|
|
* Authors:
|
|
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
* Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
|
* See the COPYING.LIB file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "monitor/monitor.h"
|
|
#include "net/net.h"
|
|
#include "clients.h"
|
|
#include "hub.h"
|
|
#include "qemu/iov.h"
|
|
#include "qemu/error-report.h"
|
|
|
|
/*
|
|
* A hub broadcasts incoming packets to all its ports except the source port.
|
|
* Hubs can be used to provide independent network segments, also confusingly
|
|
* named the QEMU 'vlan' feature.
|
|
*/
|
|
|
|
typedef struct NetHub NetHub;
|
|
|
|
typedef struct NetHubPort {
|
|
NetClientState nc;
|
|
QLIST_ENTRY(NetHubPort) next;
|
|
NetHub *hub;
|
|
int id;
|
|
} NetHubPort;
|
|
|
|
struct NetHub {
|
|
int id;
|
|
QLIST_ENTRY(NetHub) next;
|
|
int num_ports;
|
|
QLIST_HEAD(, NetHubPort) ports;
|
|
};
|
|
|
|
static QLIST_HEAD(, NetHub) hubs = QLIST_HEAD_INITIALIZER(&hubs);
|
|
|
|
static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
|
|
const uint8_t *buf, size_t len)
|
|
{
|
|
NetHubPort *port;
|
|
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
if (port == source_port) {
|
|
continue;
|
|
}
|
|
|
|
qemu_send_packet(&port->nc, buf, len);
|
|
}
|
|
return len;
|
|
}
|
|
|
|
static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
|
|
const struct iovec *iov, int iovcnt)
|
|
{
|
|
NetHubPort *port;
|
|
ssize_t len = iov_size(iov, iovcnt);
|
|
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
if (port == source_port) {
|
|
continue;
|
|
}
|
|
|
|
qemu_sendv_packet(&port->nc, iov, iovcnt);
|
|
}
|
|
return len;
|
|
}
|
|
|
|
static NetHub *net_hub_new(int id)
|
|
{
|
|
NetHub *hub;
|
|
|
|
hub = g_malloc(sizeof(*hub));
|
|
hub->id = id;
|
|
hub->num_ports = 0;
|
|
QLIST_INIT(&hub->ports);
|
|
|
|
QLIST_INSERT_HEAD(&hubs, hub, next);
|
|
|
|
return hub;
|
|
}
|
|
|
|
static int net_hub_port_can_receive(NetClientState *nc)
|
|
{
|
|
NetHubPort *port;
|
|
NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
|
|
NetHub *hub = src_port->hub;
|
|
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
if (port == src_port) {
|
|
continue;
|
|
}
|
|
|
|
if (qemu_can_send_packet(&port->nc)) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static ssize_t net_hub_port_receive(NetClientState *nc,
|
|
const uint8_t *buf, size_t len)
|
|
{
|
|
NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
|
|
|
|
return net_hub_receive(port->hub, port, buf, len);
|
|
}
|
|
|
|
static ssize_t net_hub_port_receive_iov(NetClientState *nc,
|
|
const struct iovec *iov, int iovcnt)
|
|
{
|
|
NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
|
|
|
|
return net_hub_receive_iov(port->hub, port, iov, iovcnt);
|
|
}
|
|
|
|
static void net_hub_port_cleanup(NetClientState *nc)
|
|
{
|
|
NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
|
|
|
|
QLIST_REMOVE(port, next);
|
|
}
|
|
|
|
static NetClientInfo net_hub_port_info = {
|
|
.type = NET_CLIENT_DRIVER_HUBPORT,
|
|
.size = sizeof(NetHubPort),
|
|
.can_receive = net_hub_port_can_receive,
|
|
.receive = net_hub_port_receive,
|
|
.receive_iov = net_hub_port_receive_iov,
|
|
.cleanup = net_hub_port_cleanup,
|
|
};
|
|
|
|
static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
|
|
{
|
|
NetClientState *nc;
|
|
NetHubPort *port;
|
|
int id = hub->num_ports++;
|
|
char default_name[128];
|
|
|
|
if (!name) {
|
|
snprintf(default_name, sizeof(default_name),
|
|
"hub%dport%d", hub->id, id);
|
|
name = default_name;
|
|
}
|
|
|
|
nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
|
|
port = DO_UPCAST(NetHubPort, nc, nc);
|
|
port->id = id;
|
|
port->hub = hub;
|
|
|
|
QLIST_INSERT_HEAD(&hub->ports, port, next);
|
|
|
|
return port;
|
|
}
|
|
|
|
/**
|
|
* Create a port on a given hub
|
|
* @name: Net client name or NULL for default name.
|
|
*
|
|
* If there is no existing hub with the given id then a new hub is created.
|
|
*/
|
|
NetClientState *net_hub_add_port(int hub_id, const char *name)
|
|
{
|
|
NetHub *hub;
|
|
NetHubPort *port;
|
|
|
|
QLIST_FOREACH(hub, &hubs, next) {
|
|
if (hub->id == hub_id) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!hub) {
|
|
hub = net_hub_new(hub_id);
|
|
}
|
|
|
|
port = net_hub_port_new(hub, name);
|
|
return &port->nc;
|
|
}
|
|
|
|
/**
|
|
* Find a specific client on a hub
|
|
*/
|
|
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name)
|
|
{
|
|
NetHub *hub;
|
|
NetHubPort *port;
|
|
NetClientState *peer;
|
|
|
|
QLIST_FOREACH(hub, &hubs, next) {
|
|
if (hub->id == hub_id) {
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
peer = port->nc.peer;
|
|
|
|
if (peer && strcmp(peer->name, name) == 0) {
|
|
return peer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Find a available port on a hub; otherwise create one new port
|
|
*/
|
|
NetClientState *net_hub_port_find(int hub_id)
|
|
{
|
|
NetHub *hub;
|
|
NetHubPort *port;
|
|
NetClientState *nc;
|
|
|
|
QLIST_FOREACH(hub, &hubs, next) {
|
|
if (hub->id == hub_id) {
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
nc = port->nc.peer;
|
|
if (!nc) {
|
|
return &(port->nc);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
nc = net_hub_add_port(hub_id, NULL);
|
|
return nc;
|
|
}
|
|
|
|
/**
|
|
* Print hub configuration
|
|
*/
|
|
void net_hub_info(Monitor *mon)
|
|
{
|
|
NetHub *hub;
|
|
NetHubPort *port;
|
|
|
|
QLIST_FOREACH(hub, &hubs, next) {
|
|
monitor_printf(mon, "hub %d\n", hub->id);
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
monitor_printf(mon, " \\ %s", port->nc.name);
|
|
if (port->nc.peer) {
|
|
monitor_printf(mon, ": ");
|
|
print_net_client(mon, port->nc.peer);
|
|
} else {
|
|
monitor_printf(mon, "\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the hub id that a client is connected to
|
|
*
|
|
* @id: Pointer for hub id output, may be NULL
|
|
*/
|
|
int net_hub_id_for_client(NetClientState *nc, int *id)
|
|
{
|
|
NetHubPort *port;
|
|
|
|
if (nc->info->type == NET_CLIENT_DRIVER_HUBPORT) {
|
|
port = DO_UPCAST(NetHubPort, nc, nc);
|
|
} else if (nc->peer != NULL && nc->peer->info->type ==
|
|
NET_CLIENT_DRIVER_HUBPORT) {
|
|
port = DO_UPCAST(NetHubPort, nc, nc->peer);
|
|
} else {
|
|
return -ENOENT;
|
|
}
|
|
|
|
if (id) {
|
|
*id = port->hub->id;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int net_init_hubport(const Netdev *netdev, const char *name,
|
|
NetClientState *peer, Error **errp)
|
|
{
|
|
const NetdevHubPortOptions *hubport;
|
|
|
|
assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
|
|
assert(!peer);
|
|
hubport = &netdev->u.hubport;
|
|
|
|
net_hub_add_port(hubport->hubid, name);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Warn if hub configurations are likely wrong
|
|
*/
|
|
void net_hub_check_clients(void)
|
|
{
|
|
NetHub *hub;
|
|
NetHubPort *port;
|
|
NetClientState *peer;
|
|
|
|
QLIST_FOREACH(hub, &hubs, next) {
|
|
int has_nic = 0, has_host_dev = 0;
|
|
|
|
QLIST_FOREACH(port, &hub->ports, next) {
|
|
peer = port->nc.peer;
|
|
if (!peer) {
|
|
warn_report("hub port %s has no peer",
|
|
port->nc.name);
|
|
continue;
|
|
}
|
|
|
|
switch (peer->info->type) {
|
|
case NET_CLIENT_DRIVER_NIC:
|
|
has_nic = 1;
|
|
break;
|
|
case NET_CLIENT_DRIVER_USER:
|
|
case NET_CLIENT_DRIVER_TAP:
|
|
case NET_CLIENT_DRIVER_SOCKET:
|
|
case NET_CLIENT_DRIVER_VDE:
|
|
case NET_CLIENT_DRIVER_VHOST_USER:
|
|
has_host_dev = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (has_host_dev && !has_nic) {
|
|
warn_report("vlan %d with no nics", hub->id);
|
|
}
|
|
if (has_nic && !has_host_dev) {
|
|
warn_report("vlan %d is not connected to host network",
|
|
hub->id);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool net_hub_flush(NetClientState *nc)
|
|
{
|
|
NetHubPort *port;
|
|
NetHubPort *source_port = DO_UPCAST(NetHubPort, nc, nc);
|
|
int ret = 0;
|
|
|
|
QLIST_FOREACH(port, &source_port->hub->ports, next) {
|
|
if (port != source_port) {
|
|
ret += qemu_net_queue_flush(port->nc.incoming_queue);
|
|
}
|
|
}
|
|
return ret ? true : false;
|
|
}
|