X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=net.c;h=e8ae13e2831dcd90f67a8499d313fd1d624181af;hb=55903f1d2d8abfa8d7610ab32a4046a1ed4fdbb8;hp=f88d38d52472108b482c6aaf605d98a92ae105e6;hpb=90d87a33c700e0634bc4343fa7a034f909662254;p=qemu.git diff --git a/net.c b/net.c index f88d38d52..e8ae13e28 100644 --- a/net.c +++ b/net.c @@ -21,17 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "net.h" - #include "config-host.h" -#include "net/tap.h" -#include "net/socket.h" -#include "net/dump.h" -#include "net/slirp.h" -#include "net/vde.h" +#include "net.h" +#include "net/clients.h" #include "net/hub.h" +#include "net/slirp.h" #include "net/util.h" + #include "monitor.h" #include "qemu-common.h" #include "qemu_socket.h" @@ -47,8 +44,7 @@ # define CONFIG_NET_BRIDGE #endif -static QTAILQ_HEAD(, VLANState) vlans; -static QTAILQ_HEAD(, VLANClientState) non_vlan_clients; +static QTAILQ_HEAD(, NetClientState) net_clients; int default_net = 1; @@ -133,11 +129,11 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str) return 0; } -void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]) +void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]) { - snprintf(vc->info_str, sizeof(vc->info_str), + snprintf(nc->info_str, sizeof(nc->info_str), "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x", - vc->model, + nc->model, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); } @@ -163,19 +159,19 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr) * Only net clients created with the legacy -net option need this. Naming is * mandatory for net clients created with -netdev. */ -static char *assign_name(VLANClientState *vc1, const char *model) +static char *assign_name(NetClientState *nc1, const char *model) { - VLANClientState *vc; + NetClientState *nc; char buf[256]; int id = 0; - QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - if (vc == vc1) { + QTAILQ_FOREACH(nc, &net_clients, next) { + if (nc == nc1) { continue; } /* For compatibility only bump id for net clients on a vlan */ - if (strcmp(vc->model, model) == 0 && - net_hub_id_for_client(vc, NULL) == 0) { + if (strcmp(nc->model, model) == 0 && + net_hub_id_for_client(nc, NULL) == 0) { id++; } } @@ -185,55 +181,35 @@ static char *assign_name(VLANClientState *vc1, const char *model) return g_strdup(buf); } -static ssize_t qemu_deliver_packet(VLANClientState *sender, - unsigned flags, - const uint8_t *data, - size_t size, - void *opaque); -static ssize_t qemu_deliver_packet_iov(VLANClientState *sender, - unsigned flags, - const struct iovec *iov, - int iovcnt, - void *opaque); - -VLANClientState *qemu_new_net_client(NetClientInfo *info, - VLANState *vlan, - VLANClientState *peer, - const char *model, - const char *name) +NetClientState *qemu_new_net_client(NetClientInfo *info, + NetClientState *peer, + const char *model, + const char *name) { - VLANClientState *vc; + NetClientState *nc; - assert(info->size >= sizeof(VLANClientState)); + assert(info->size >= sizeof(NetClientState)); - vc = g_malloc0(info->size); + nc = g_malloc0(info->size); - vc->info = info; - vc->model = g_strdup(model); + nc->info = info; + nc->model = g_strdup(model); if (name) { - vc->name = g_strdup(name); + nc->name = g_strdup(name); } else { - vc->name = assign_name(vc, model); + nc->name = assign_name(nc, model); } - if (vlan) { - assert(!peer); - vc->vlan = vlan; - QTAILQ_INSERT_TAIL(&vc->vlan->clients, vc, next); - } else { - if (peer) { - assert(!peer->peer); - vc->peer = peer; - peer->peer = vc; - } - QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next); - - vc->send_queue = qemu_new_net_queue(qemu_deliver_packet, - qemu_deliver_packet_iov, - vc); + if (peer) { + assert(!peer->peer); + nc->peer = peer; + peer->peer = nc; } + QTAILQ_INSERT_TAIL(&net_clients, nc, next); - return vc; + nc->send_queue = qemu_new_net_queue(nc); + + return nc; } NICState *qemu_new_nic(NetClientInfo *info, @@ -242,13 +218,13 @@ NICState *qemu_new_nic(NetClientInfo *info, const char *name, void *opaque) { - VLANClientState *nc; + NetClientState *nc; NICState *nic; assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC); assert(info->size >= sizeof(NICState)); - nc = qemu_new_net_client(info, conf->vlan, conf->peer, model, name); + nc = qemu_new_net_client(info, conf->peer, model, name); nic = DO_UPCAST(NICState, nc, nc); nic->conf = conf; @@ -257,224 +233,136 @@ NICState *qemu_new_nic(NetClientInfo *info, return nic; } -static void qemu_cleanup_vlan_client(VLANClientState *vc) +static void qemu_cleanup_net_client(NetClientState *nc) { - if (vc->vlan) { - QTAILQ_REMOVE(&vc->vlan->clients, vc, next); - } else { - QTAILQ_REMOVE(&non_vlan_clients, vc, next); - } + QTAILQ_REMOVE(&net_clients, nc, next); - if (vc->info->cleanup) { - vc->info->cleanup(vc); + if (nc->info->cleanup) { + nc->info->cleanup(nc); } } -static void qemu_free_vlan_client(VLANClientState *vc) +static void qemu_free_net_client(NetClientState *nc) { - if (!vc->vlan) { - if (vc->send_queue) { - qemu_del_net_queue(vc->send_queue); - } - if (vc->peer) { - vc->peer->peer = NULL; - } + if (nc->send_queue) { + qemu_del_net_queue(nc->send_queue); + } + if (nc->peer) { + nc->peer->peer = NULL; } - g_free(vc->name); - g_free(vc->model); - g_free(vc); + g_free(nc->name); + g_free(nc->model); + g_free(nc); } -void qemu_del_vlan_client(VLANClientState *vc) +void qemu_del_net_client(NetClientState *nc) { /* If there is a peer NIC, delete and cleanup client, but do not free. */ - if (!vc->vlan && vc->peer && vc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { - NICState *nic = DO_UPCAST(NICState, nc, vc->peer); + if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { + NICState *nic = DO_UPCAST(NICState, nc, nc->peer); if (nic->peer_deleted) { return; } nic->peer_deleted = true; /* Let NIC know peer is gone. */ - vc->peer->link_down = true; - if (vc->peer->info->link_status_changed) { - vc->peer->info->link_status_changed(vc->peer); + nc->peer->link_down = true; + if (nc->peer->info->link_status_changed) { + nc->peer->info->link_status_changed(nc->peer); } - qemu_cleanup_vlan_client(vc); + qemu_cleanup_net_client(nc); return; } /* If this is a peer NIC and peer has already been deleted, free it now. */ - if (!vc->vlan && vc->peer && vc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { - NICState *nic = DO_UPCAST(NICState, nc, vc); + if (nc->peer && nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { + NICState *nic = DO_UPCAST(NICState, nc, nc); if (nic->peer_deleted) { - qemu_free_vlan_client(vc->peer); + qemu_free_net_client(nc->peer); } } - qemu_cleanup_vlan_client(vc); - qemu_free_vlan_client(vc); + qemu_cleanup_net_client(nc); + qemu_free_net_client(nc); } void qemu_foreach_nic(qemu_nic_foreach func, void *opaque) { - VLANClientState *nc; - VLANState *vlan; + NetClientState *nc; - QTAILQ_FOREACH(nc, &non_vlan_clients, next) { + QTAILQ_FOREACH(nc, &net_clients, next) { if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { func(DO_UPCAST(NICState, nc, nc), opaque); } } - - QTAILQ_FOREACH(vlan, &vlans, next) { - QTAILQ_FOREACH(nc, &vlan->clients, next) { - if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { - func(DO_UPCAST(NICState, nc, nc), opaque); - } - } - } } -int qemu_can_send_packet(VLANClientState *sender) +int qemu_can_send_packet(NetClientState *sender) { - VLANState *vlan = sender->vlan; - VLANClientState *vc; - - if (sender->peer) { - if (sender->peer->receive_disabled) { - return 0; - } else if (sender->peer->info->can_receive && - !sender->peer->info->can_receive(sender->peer)) { - return 0; - } else { - return 1; - } - } - - if (!sender->vlan) { + if (!sender->peer) { return 1; } - QTAILQ_FOREACH(vc, &vlan->clients, next) { - if (vc == sender) { - continue; - } - - /* no can_receive() handler, they can always receive */ - if (vc->info->can_receive && !vc->info->can_receive(vc)) { - return 0; - } + 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; } -static ssize_t qemu_deliver_packet(VLANClientState *sender, - unsigned flags, - const uint8_t *data, - size_t size, - void *opaque) +ssize_t qemu_deliver_packet(NetClientState *sender, + unsigned flags, + const uint8_t *data, + size_t size, + void *opaque) { - VLANClientState *vc = opaque; + NetClientState *nc = opaque; ssize_t ret; - if (vc->link_down) { + if (nc->link_down) { return size; } - if (vc->receive_disabled) { + if (nc->receive_disabled) { return 0; } - if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) { - ret = vc->info->receive_raw(vc, data, size); + if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) { + ret = nc->info->receive_raw(nc, data, size); } else { - ret = vc->info->receive(vc, data, size); + ret = nc->info->receive(nc, data, size); } if (ret == 0) { - vc->receive_disabled = 1; + nc->receive_disabled = 1; }; return ret; } -static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, - unsigned flags, - const uint8_t *buf, - size_t size, - void *opaque) +void qemu_purge_queued_packets(NetClientState *nc) { - VLANState *vlan = opaque; - VLANClientState *vc; - ssize_t ret = -1; - - QTAILQ_FOREACH(vc, &vlan->clients, next) { - ssize_t len; - - if (vc == sender) { - continue; - } - - if (vc->link_down) { - ret = size; - continue; - } - - if (vc->receive_disabled) { - ret = 0; - continue; - } - - if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) { - len = vc->info->receive_raw(vc, buf, size); - } else { - len = vc->info->receive(vc, buf, size); - } - - if (len == 0) { - vc->receive_disabled = 1; - } - - ret = (ret >= 0) ? ret : len; - - } - - return ret; -} - -void qemu_purge_queued_packets(VLANClientState *vc) -{ - NetQueue *queue; - - if (!vc->peer && !vc->vlan) { + if (!nc->peer) { return; } - if (vc->peer) { - queue = vc->peer->send_queue; - } else { - queue = vc->vlan->send_queue; - } - - qemu_net_queue_purge(queue, vc); + qemu_net_queue_purge(nc->peer->send_queue, nc); } -void qemu_flush_queued_packets(VLANClientState *vc) +void qemu_flush_queued_packets(NetClientState *nc) { - NetQueue *queue; + nc->receive_disabled = 0; - vc->receive_disabled = 0; - - if (vc->vlan) { - queue = vc->vlan->send_queue; - } else { - queue = vc->send_queue; + if (qemu_net_queue_flush(nc->send_queue)) { + /* We emptied the queue successfully, signal to the IO thread to repoll + * the file descriptor (for tap, for example). + */ + qemu_notify_event(); } - - qemu_net_queue_flush(queue); } -static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender, +static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender, unsigned flags, const uint8_t *buf, int size, NetPacketSent *sent_cb) @@ -486,20 +374,16 @@ static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender, hex_dump(stdout, buf, size); #endif - if (sender->link_down || (!sender->peer && !sender->vlan)) { + if (sender->link_down || !sender->peer) { return size; } - if (sender->peer) { - queue = sender->peer->send_queue; - } else { - queue = sender->vlan->send_queue; - } + queue = sender->peer->send_queue; return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb); } -ssize_t qemu_send_packet_async(VLANClientState *sender, +ssize_t qemu_send_packet_async(NetClientState *sender, const uint8_t *buf, int size, NetPacketSent *sent_cb) { @@ -507,18 +391,18 @@ ssize_t qemu_send_packet_async(VLANClientState *sender, buf, size, sent_cb); } -void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) +void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size) { - qemu_send_packet_async(vc, buf, size, NULL); + qemu_send_packet_async(nc, buf, size, NULL); } -ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size) +ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size) { - return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW, + return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW, buf, size, NULL); } -static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, +static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov, int iovcnt) { uint8_t buffer[4096]; @@ -526,79 +410,50 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, offset = iov_to_buf(iov, iovcnt, 0, buffer, sizeof(buffer)); - return vc->info->receive(vc, buffer, offset); + return nc->info->receive(nc, buffer, offset); } -static ssize_t qemu_deliver_packet_iov(VLANClientState *sender, - unsigned flags, - const struct iovec *iov, - int iovcnt, - void *opaque) +ssize_t qemu_deliver_packet_iov(NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + void *opaque) { - VLANClientState *vc = opaque; + NetClientState *nc = opaque; + int ret; - if (vc->link_down) { + if (nc->link_down) { return iov_size(iov, iovcnt); } - if (vc->info->receive_iov) { - return vc->info->receive_iov(vc, iov, iovcnt); - } else { - return vc_sendv_compat(vc, iov, iovcnt); + if (nc->receive_disabled) { + return 0; } -} - -static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender, - unsigned flags, - const struct iovec *iov, - int iovcnt, - void *opaque) -{ - VLANState *vlan = opaque; - VLANClientState *vc; - ssize_t ret = -1; - - QTAILQ_FOREACH(vc, &vlan->clients, next) { - ssize_t len; - - if (vc == sender) { - continue; - } - - if (vc->link_down) { - ret = iov_size(iov, iovcnt); - continue; - } - assert(!(flags & QEMU_NET_PACKET_FLAG_RAW)); - - if (vc->info->receive_iov) { - len = vc->info->receive_iov(vc, iov, iovcnt); - } else { - len = vc_sendv_compat(vc, iov, iovcnt); - } + if (nc->info->receive_iov) { + ret = nc->info->receive_iov(nc, iov, iovcnt); + } else { + ret = nc_sendv_compat(nc, iov, iovcnt); + } - ret = (ret >= 0) ? ret : len; + if (ret == 0) { + nc->receive_disabled = 1; } return ret; } -ssize_t qemu_sendv_packet_async(VLANClientState *sender, +ssize_t qemu_sendv_packet_async(NetClientState *sender, const struct iovec *iov, int iovcnt, NetPacketSent *sent_cb) { NetQueue *queue; - if (sender->link_down || (!sender->peer && !sender->vlan)) { + if (sender->link_down || !sender->peer) { return iov_size(iov, iovcnt); } - if (sender->peer) { - queue = sender->peer->send_queue; - } else { - queue = sender->vlan->send_queue; - } + queue = sender->peer->send_queue; return qemu_net_queue_send_iov(queue, sender, QEMU_NET_PACKET_FLAG_NONE, @@ -606,48 +461,20 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender, } ssize_t -qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, int iovcnt) +qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt) { - return qemu_sendv_packet_async(vc, iov, iovcnt, NULL); -} - -/* find or alloc a new VLAN */ -VLANState *qemu_find_vlan(int id, int allocate) -{ - VLANState *vlan; - - QTAILQ_FOREACH(vlan, &vlans, next) { - if (vlan->id == id) { - return vlan; - } - } - - if (!allocate) { - return NULL; - } - - vlan = g_malloc0(sizeof(VLANState)); - vlan->id = id; - QTAILQ_INIT(&vlan->clients); - - vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet, - qemu_vlan_deliver_packet_iov, - vlan); - - QTAILQ_INSERT_TAIL(&vlans, vlan, next); - - return vlan; + return qemu_sendv_packet_async(nc, iov, iovcnt, NULL); } -VLANClientState *qemu_find_netdev(const char *id) +NetClientState *qemu_find_netdev(const char *id) { - VLANClientState *vc; + NetClientState *nc; - QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - if (vc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) + QTAILQ_FOREACH(nc, &net_clients, next) { + if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) continue; - if (!strcmp(vc->name, id)) { - return vc; + if (!strcmp(nc->name, id)) { + return nc; } } @@ -668,8 +495,9 @@ int qemu_show_nic_models(const char *arg, const char *const *models) { int i; - if (!arg || strcmp(arg, "?")) + if (!arg || !is_help_option(arg)) { return 0; + } fprintf(stderr, "qemu: Supported NIC models: "); for (i = 0 ; models[i]; i++) @@ -707,26 +535,8 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models, return -1; } -int net_handle_fd_param(Monitor *mon, const char *param) -{ - int fd; - - if (!qemu_isdigit(param[0]) && mon) { - - fd = monitor_get_fd(mon, param); - if (fd == -1) { - error_report("No file descriptor named %s found", param); - return -1; - } - } else { - fd = qemu_parse_fd(param); - } - - return fd; -} - static int net_init_nic(const NetClientOptions *opts, const char *name, - VLANClientState *peer) + NetClientState *peer) { int idx; NICInfo *nd; @@ -792,7 +602,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name, static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( const NetClientOptions *opts, const char *name, - VLANClientState *peer) = { + NetClientState *peer) = { [NET_CLIENT_OPTIONS_KIND_NIC] = net_init_nic, #ifdef CONFIG_SLIRP [NET_CLIENT_OPTIONS_KIND_USER] = net_init_slirp, @@ -852,7 +662,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp) } if (net_client_init_fun[opts->kind]) { - VLANClientState *peer = NULL; + NetClientState *peer = NULL; /* Do not add to a vlan if it's a -netdev or a nic with a netdev= * parameter. */ @@ -964,19 +774,19 @@ void net_host_device_add(Monitor *mon, const QDict *qdict) void net_host_device_remove(Monitor *mon, const QDict *qdict) { - VLANClientState *vc; + NetClientState *nc; int vlan_id = qdict_get_int(qdict, "vlan_id"); const char *device = qdict_get_str(qdict, "device"); - vc = net_hub_find_client_by_name(vlan_id, device); - if (!vc) { + nc = net_hub_find_client_by_name(vlan_id, device); + if (!nc) { return; } - if (!net_host_check_device(vc->model)) { + if (!net_host_check_device(nc->model)) { monitor_printf(mon, "invalid host network device %s\n", device); return; } - qemu_del_vlan_client(vc); + qemu_del_net_client(nc); } void netdev_add(QemuOpts *opts, Error **errp) @@ -1016,82 +826,76 @@ exit_err: void qmp_netdev_del(const char *id, Error **errp) { - VLANClientState *vc; + NetClientState *nc; + QemuOpts *opts; - vc = qemu_find_netdev(id); - if (!vc) { + nc = qemu_find_netdev(id); + if (!nc) { error_set(errp, QERR_DEVICE_NOT_FOUND, id); return; } - qemu_del_vlan_client(vc); - qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id)); + opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), id); + if (!opts) { + error_setg(errp, "Device '%s' is not a netdev", id); + return; + } + + qemu_del_net_client(nc); + qemu_opts_del(opts); } -static void print_net_client(Monitor *mon, VLANClientState *vc) +void print_net_client(Monitor *mon, NetClientState *nc) { - monitor_printf(mon, "%s: type=%s,%s\n", vc->name, - NetClientOptionsKind_lookup[vc->info->type], vc->info_str); + monitor_printf(mon, "%s: type=%s,%s\n", nc->name, + NetClientOptionsKind_lookup[nc->info->type], nc->info_str); } void do_info_network(Monitor *mon) { - VLANState *vlan; - VLANClientState *vc, *peer; + NetClientState *nc, *peer; NetClientOptionsKind type; - QTAILQ_FOREACH(vlan, &vlans, next) { - monitor_printf(mon, "VLAN %d devices:\n", vlan->id); + net_hub_info(mon); + + QTAILQ_FOREACH(nc, &net_clients, next) { + peer = nc->peer; + type = nc->info->type; - QTAILQ_FOREACH(vc, &vlan->clients, next) { - monitor_printf(mon, " "); - print_net_client(mon, vc); + /* Skip if already printed in hub info */ + if (net_hub_id_for_client(nc, NULL) == 0) { + continue; } - } - monitor_printf(mon, "Devices not on any VLAN:\n"); - QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - peer = vc->peer; - type = vc->info->type; + if (!peer || type == NET_CLIENT_OPTIONS_KIND_NIC) { - monitor_printf(mon, " "); - print_net_client(mon, vc); + print_net_client(mon, nc); } /* else it's a netdev connected to a NIC, printed with the NIC */ if (peer && type == NET_CLIENT_OPTIONS_KIND_NIC) { - monitor_printf(mon, " \\ "); + monitor_printf(mon, " \\ "); print_net_client(mon, peer); } } - net_hub_info(mon); } void qmp_set_link(const char *name, bool up, Error **errp) { - VLANState *vlan; - VLANClientState *vc = NULL; + NetClientState *nc = NULL; - QTAILQ_FOREACH(vlan, &vlans, next) { - QTAILQ_FOREACH(vc, &vlan->clients, next) { - if (strcmp(vc->name, name) == 0) { - goto done; - } - } - } - QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - if (!strcmp(vc->name, name)) { + QTAILQ_FOREACH(nc, &net_clients, next) { + if (!strcmp(nc->name, name)) { goto done; } } done: - - if (!vc) { + if (!nc) { error_set(errp, QERR_DEVICE_NOT_FOUND, name); return; } - vc->link_down = !up; + nc->link_down = !up; - if (vc->info->link_status_changed) { - vc->info->link_status_changed(vc); + if (nc->info->link_status_changed) { + nc->info->link_status_changed(nc); } /* Notify peer. Don't update peer link status: this makes it possible to @@ -1101,31 +905,23 @@ done: * Current behaviour is compatible with qemu vlans where there could be * multiple clients that can still communicate with each other in * disconnected mode. For now maintain this compatibility. */ - if (vc->peer && vc->peer->info->link_status_changed) { - vc->peer->info->link_status_changed(vc->peer); + if (nc->peer && nc->peer->info->link_status_changed) { + nc->peer->info->link_status_changed(nc->peer); } } void net_cleanup(void) { - VLANState *vlan; - VLANClientState *vc, *next_vc; - - QTAILQ_FOREACH(vlan, &vlans, next) { - QTAILQ_FOREACH_SAFE(vc, &vlan->clients, next, next_vc) { - qemu_del_vlan_client(vc); - } - } + NetClientState *nc, *next_vc; - QTAILQ_FOREACH_SAFE(vc, &non_vlan_clients, next, next_vc) { - qemu_del_vlan_client(vc); + QTAILQ_FOREACH_SAFE(nc, &net_clients, next, next_vc) { + qemu_del_net_client(nc); } } void net_check_clients(void) { - VLANState *vlan; - VLANClientState *vc; + NetClientState *nc; int i; /* Don't warn about the default network setup that you get if @@ -1140,35 +936,13 @@ void net_check_clients(void) return; } - QTAILQ_FOREACH(vlan, &vlans, next) { - int has_nic = 0, has_host_dev = 0; - - QTAILQ_FOREACH(vc, &vlan->clients, next) { - switch (vc->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: - has_host_dev = 1; - break; - default: ; - } - } - if (has_host_dev && !has_nic) - fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id); - if (has_nic && !has_host_dev) - fprintf(stderr, - "Warning: vlan %d is not connected to host network\n", - vlan->id); - } - QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - if (!vc->peer) { + net_hub_check_clients(); + + QTAILQ_FOREACH(nc, &net_clients, next) { + if (!nc->peer) { fprintf(stderr, "Warning: %s %s has no peer\n", - vc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ? "nic" : "netdev", - vc->name); + nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ? + "nic" : "netdev", nc->name); } } @@ -1228,8 +1002,7 @@ int net_init_clients(void) #endif } - QTAILQ_INIT(&vlans); - QTAILQ_INIT(&non_vlan_clients); + QTAILQ_INIT(&net_clients); if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1) return -1;