diff options
Diffstat (limited to 'qemu/net/hub.c')
-rw-r--r-- | qemu/net/hub.c | 355 |
1 files changed, 0 insertions, 355 deletions
diff --git a/qemu/net/hub.c b/qemu/net/hub.c deleted file mode 100644 index 6d90c6ee6..000000000 --- a/qemu/net/hub.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * 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" - -/* - * 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_OPTIONS_KIND_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_OPTIONS_KIND_HUBPORT) { - port = DO_UPCAST(NetHubPort, nc, nc); - } else if (nc->peer != NULL && nc->peer->info->type == - NET_CLIENT_OPTIONS_KIND_HUBPORT) { - port = DO_UPCAST(NetHubPort, nc, nc->peer); - } else { - return -ENOENT; - } - - if (id) { - *id = port->hub->id; - } - return 0; -} - -int net_init_hubport(const NetClientOptions *opts, const char *name, - NetClientState *peer, Error **errp) -{ - const NetdevHubPortOptions *hubport; - - assert(opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT); - assert(!peer); - hubport = opts->u.hubport.data; - - 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) { - fprintf(stderr, "Warning: hub port %s has no peer\n", - port->nc.name); - continue; - } - - switch (peer->info->type) { - case NET_CLIENT_OPTIONS_KIND_NIC: - has_nic = 1; - break; - case NET_CLIENT_OPTIONS_KIND_USER: - case NET_CLIENT_OPTIONS_KIND_TAP: - case NET_CLIENT_OPTIONS_KIND_SOCKET: - case NET_CLIENT_OPTIONS_KIND_VDE: - case NET_CLIENT_OPTIONS_KIND_VHOST_USER: - has_host_dev = 1; - break; - default: - break; - } - } - if (has_host_dev && !has_nic) { - fprintf(stderr, "Warning: vlan %d with no nics\n", hub->id); - } - if (has_nic && !has_host_dev) { - fprintf(stderr, - "Warning: vlan %d is not connected to host network\n", - 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; -} |