*
*/
+#include "qemu/osdep.h"
+#include "qapi/error.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.
+ * Hubs can be used to provide independent emulated network segments.
*/
typedef struct NetHub NetHub;
}
static NetClientInfo net_hub_port_info = {
- .type = NET_CLIENT_OPTIONS_KIND_HUBPORT,
+ .type = NET_CLIENT_DRIVER_HUBPORT,
.size = sizeof(NetHubPort),
.can_receive = net_hub_port_can_receive,
.receive = net_hub_port_receive,
.cleanup = net_hub_port_cleanup,
};
-static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
+static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
+ NetClientState *hubpeer)
{
NetClientState *nc;
NetHubPort *port;
name = default_name;
}
- nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
+ nc = qemu_new_net_client(&net_hub_port_info, hubpeer, "hub", name);
port = DO_UPCAST(NetHubPort, nc, nc);
port->id = id;
port->hub = hub;
/**
* Create a port on a given hub
+ * @hub_id: Number of the hub
* @name: Net client name or NULL for default name.
+ * @hubpeer: Peer to use (if "netdev=id" has been specified)
*
* 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)
+NetClientState *net_hub_add_port(int hub_id, const char *name,
+ NetClientState *hubpeer)
{
NetHub *hub;
NetHubPort *port;
hub = net_hub_new(hub_id);
}
- port = net_hub_port_new(hub, name);
+ port = net_hub_port_new(hub, name, hubpeer);
return &port->nc;
}
}
}
- nc = net_hub_add_port(hub_id, NULL);
+ nc = net_hub_add_port(hub_id, NULL, NULL);
return nc;
}
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, " \\ ");
+ monitor_printf(mon, ": ");
print_net_client(mon, port->nc.peer);
+ } else {
+ monitor_printf(mon, "\n");
}
}
}
{
NetHubPort *port;
- if (nc->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+ 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_OPTIONS_KIND_HUBPORT) {
+ NET_CLIENT_DRIVER_HUBPORT) {
port = DO_UPCAST(NetHubPort, nc, nc->peer);
} else {
return -ENOENT;
return 0;
}
-int net_init_hubport(const NetClientOptions *opts, const char *name,
- NetClientState *peer)
+int net_init_hubport(const Netdev *netdev, const char *name,
+ NetClientState *peer, Error **errp)
{
const NetdevHubPortOptions *hubport;
+ NetClientState *hubpeer = NULL;
- assert(opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT);
- hubport = opts->hubport;
+ assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
+ assert(!peer);
+ hubport = &netdev->u.hubport;
- /* Treat hub port like a backend, NIC must be the one to peer */
- if (peer) {
- return -EINVAL;
+ if (hubport->has_netdev) {
+ hubpeer = qemu_find_netdev(hubport->netdev);
+ if (!hubpeer) {
+ error_setg(errp, "netdev '%s' not found", hubport->netdev);
+ return -1;
+ }
}
- net_hub_add_port(hubport->hubid, name);
+ net_hub_add_port(hubport->hubid, name, hubpeer);
+
return 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);
+ warn_report("hub port %s has no peer", port->nc.name);
continue;
}
switch (peer->info->type) {
- case NET_CLIENT_OPTIONS_KIND_NIC:
+ case NET_CLIENT_DRIVER_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_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:
}
}
if (has_host_dev && !has_nic) {
- fprintf(stderr, "Warning: vlan %d with no nics\n", hub->id);
+ warn_report("hub %d with no nics", hub->id);
}
if (has_nic && !has_host_dev) {
- fprintf(stderr,
- "Warning: vlan %d is not connected to host network\n",
- hub->id);
+ warn_report("hub %d is not connected to host network", hub->id);
}
}
}