diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/clients.h (renamed from net/socket.h) | 28 | ||||
-rw-r--r-- | net/dump.c | 2 | ||||
-rw-r--r-- | net/dump.h | 33 | ||||
-rw-r--r-- | net/hub.c | 7 | ||||
-rw-r--r-- | net/hub.h | 2 | ||||
-rw-r--r-- | net/queue.c | 40 | ||||
-rw-r--r-- | net/queue.h | 2 | ||||
-rw-r--r-- | net/slirp.c | 38 | ||||
-rw-r--r-- | net/slirp.h | 3 | ||||
-rw-r--r-- | net/socket.c | 117 | ||||
-rw-r--r-- | net/tap-win32.c | 13 | ||||
-rw-r--r-- | net/tap.c | 14 | ||||
-rw-r--r-- | net/tap.h | 6 | ||||
-rw-r--r-- | net/vde.c | 3 | ||||
-rw-r--r-- | net/vde.h | 37 |
15 files changed, 207 insertions, 138 deletions
diff --git a/net/socket.h b/net/clients.h index 3f8a092..c58cc60 100644 --- a/net/socket.h +++ b/net/clients.h @@ -21,13 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef QEMU_NET_SOCKET_H -#define QEMU_NET_SOCKET_H +#ifndef QEMU_NET_CLIENTS_H +#define QEMU_NET_CLIENTS_H #include "net.h" #include "qapi-types.h" +int net_init_dump(const NetClientOptions *opts, const char *name, + NetClientState *peer); + +#ifdef CONFIG_SLIRP +int net_init_slirp(const NetClientOptions *opts, const char *name, + NetClientState *peer); +#endif + +int net_init_hubport(const NetClientOptions *opts, const char *name, + NetClientState *peer); + int net_init_socket(const NetClientOptions *opts, const char *name, NetClientState *peer); -#endif /* QEMU_NET_SOCKET_H */ +int net_init_tap(const NetClientOptions *opts, const char *name, + NetClientState *peer); + +int net_init_bridge(const NetClientOptions *opts, const char *name, + NetClientState *peer); + +#ifdef CONFIG_VDE +int net_init_vde(const NetClientOptions *opts, const char *name, + NetClientState *peer); +#endif + +#endif /* QEMU_NET_CLIENTS_H */ @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -#include "dump.h" +#include "clients.h" #include "qemu-common.h" #include "qemu-error.h" #include "qemu-log.h" diff --git a/net/dump.h b/net/dump.h deleted file mode 100644 index 33f152b..0000000 --- a/net/dump.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef QEMU_NET_DUMP_H -#define QEMU_NET_DUMP_H - -#include "net.h" -#include "qapi-types.h" - -int net_init_dump(const NetClientOptions *opts, const char *name, - NetClientState *peer); - -#endif /* QEMU_NET_DUMP_H */ @@ -14,6 +14,7 @@ #include "monitor.h" #include "net.h" +#include "clients.h" #include "hub.h" #include "iov.h" @@ -97,12 +98,12 @@ static int net_hub_port_can_receive(NetClientState *nc) continue; } - if (!qemu_can_send_packet(&port->nc)) { - return 0; + if (qemu_can_send_packet(&port->nc)) { + return 1; } } - return 1; + return 0; } static ssize_t net_hub_port_receive(NetClientState *nc, @@ -17,8 +17,6 @@ #include "qemu-common.h" -int net_init_hubport(const NetClientOptions *opts, const char *name, - NetClientState *peer); NetClientState *net_hub_add_port(int hub_id, const char *name); NetClientState *net_hub_find_client_by_name(int hub_id, const char *name); void net_hub_info(Monitor *mon); diff --git a/net/queue.c b/net/queue.c index e8030aa..254f280 100644 --- a/net/queue.c +++ b/net/queue.c @@ -83,12 +83,12 @@ void qemu_del_net_queue(NetQueue *queue) g_free(queue); } -static ssize_t qemu_net_queue_append(NetQueue *queue, - NetClientState *sender, - unsigned flags, - const uint8_t *buf, - size_t size, - NetPacketSent *sent_cb) +static void qemu_net_queue_append(NetQueue *queue, + NetClientState *sender, + unsigned flags, + const uint8_t *buf, + size_t size, + NetPacketSent *sent_cb) { NetPacket *packet; @@ -100,16 +100,14 @@ static ssize_t qemu_net_queue_append(NetQueue *queue, memcpy(packet->data, buf, size); QTAILQ_INSERT_TAIL(&queue->packets, packet, entry); - - return size; } -static ssize_t qemu_net_queue_append_iov(NetQueue *queue, - NetClientState *sender, - unsigned flags, - const struct iovec *iov, - int iovcnt, - NetPacketSent *sent_cb) +static void qemu_net_queue_append_iov(NetQueue *queue, + NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + NetPacketSent *sent_cb) { NetPacket *packet; size_t max_len = 0; @@ -133,8 +131,6 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue, } QTAILQ_INSERT_TAIL(&queue->packets, packet, entry); - - return packet->size; } static ssize_t qemu_net_queue_deliver(NetQueue *queue, @@ -177,7 +173,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue, ssize_t ret; if (queue->delivering || !qemu_can_send_packet(sender)) { - return qemu_net_queue_append(queue, sender, flags, data, size, sent_cb); + qemu_net_queue_append(queue, sender, flags, data, size, sent_cb); + return 0; } ret = qemu_net_queue_deliver(queue, sender, flags, data, size); @@ -201,8 +198,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue, ssize_t ret; if (queue->delivering || !qemu_can_send_packet(sender)) { - return qemu_net_queue_append_iov(queue, sender, flags, - iov, iovcnt, sent_cb); + qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb); + return 0; } ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt); @@ -228,7 +225,7 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from) } } -void qemu_net_queue_flush(NetQueue *queue) +bool qemu_net_queue_flush(NetQueue *queue) { while (!QTAILQ_EMPTY(&queue->packets)) { NetPacket *packet; @@ -244,7 +241,7 @@ void qemu_net_queue_flush(NetQueue *queue) packet->size); if (ret == 0) { QTAILQ_INSERT_HEAD(&queue->packets, packet, entry); - break; + return false; } if (packet->sent_cb) { @@ -253,4 +250,5 @@ void qemu_net_queue_flush(NetQueue *queue) g_free(packet); } + return true; } diff --git a/net/queue.h b/net/queue.h index 9d44a9b..fc02b33 100644 --- a/net/queue.h +++ b/net/queue.h @@ -53,6 +53,6 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue, NetPacketSent *sent_cb); void qemu_net_queue_purge(NetQueue *queue, NetClientState *from); -void qemu_net_queue_flush(NetQueue *queue); +bool qemu_net_queue_flush(NetQueue *queue); #endif /* QEMU_NET_QUEUE_H */ diff --git a/net/slirp.c b/net/slirp.c index 8db66ea..afb52c3 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -30,7 +30,8 @@ #include <sys/wait.h> #endif #include "net.h" -#include "net/hub.h" +#include "clients.h" +#include "hub.h" #include "monitor.h" #include "qemu_socket.h" #include "slirp/libslirp.h" @@ -135,7 +136,7 @@ static int net_slirp_init(NetClientState *peer, const char *model, const char *vhostname, const char *tftp_export, const char *bootfile, const char *vdhcp_start, const char *vnameserver, const char *smb_export, - const char *vsmbserver) + const char *vsmbserver, const char **dnssearch) { /* default settings according to historic slirp */ struct in_addr net = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */ @@ -241,7 +242,7 @@ static int net_slirp_init(NetClientState *peer, const char *model, s = DO_UPCAST(SlirpState, nc, nc); s->slirp = slirp_init(restricted, net, mask, host, vhostname, - tftp_export, bootfile, dhcp, dns, s); + tftp_export, bootfile, dhcp, dns, dnssearch, s); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); for (config = slirp_configs; config; config = config->next) { @@ -698,6 +699,31 @@ net_init_slirp_configs(const StringList *fwd, int flags) } } +static const char **slirp_dnssearch(const StringList *dnsname) +{ + const StringList *c = dnsname; + size_t i = 0, num_opts = 0; + const char **ret; + + while (c) { + num_opts++; + c = c->next; + } + + if (num_opts == 0) { + return NULL; + } + + ret = g_malloc((num_opts + 1) * sizeof(*ret)); + c = dnsname; + while (c) { + ret[i++] = c->value->str; + c = c->next; + } + ret[i] = NULL; + return ret; +} + int net_init_slirp(const NetClientOptions *opts, const char *name, NetClientState *peer) { @@ -705,6 +731,7 @@ int net_init_slirp(const NetClientOptions *opts, const char *name, char *vnet; int ret; const NetdevUserOptions *user; + const char **dnssearch; assert(opts->kind == NET_CLIENT_OPTIONS_KIND_USER); user = opts->user; @@ -713,6 +740,8 @@ int net_init_slirp(const NetClientOptions *opts, const char *name, user->has_ip ? g_strdup_printf("%s/24", user->ip) : NULL; + dnssearch = slirp_dnssearch(user->dnssearch); + /* all optional fields are initialized to "all bits zero" */ net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD); @@ -721,7 +750,7 @@ int net_init_slirp(const NetClientOptions *opts, const char *name, ret = net_slirp_init(peer, "user", name, user->q_restrict, vnet, user->host, user->hostname, user->tftp, user->bootfile, user->dhcpstart, user->dns, user->smb, - user->smbserver); + user->smbserver, dnssearch); while (slirp_configs) { config = slirp_configs; @@ -730,6 +759,7 @@ int net_init_slirp(const NetClientOptions *opts, const char *name, } g_free(vnet); + g_free(dnssearch); return ret; } diff --git a/net/slirp.h b/net/slirp.h index 5f685c4..2ca09b6 100644 --- a/net/slirp.h +++ b/net/slirp.h @@ -31,9 +31,6 @@ #ifdef CONFIG_SLIRP -int net_init_slirp(const NetClientOptions *opts, const char *name, - NetClientState *peer); - void net_slirp_hostfwd_add(Monitor *mon, const QDict *qdict); void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict); diff --git a/net/socket.c b/net/socket.c index c172c24..c01323d 100644 --- a/net/socket.c +++ b/net/socket.c @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "net/socket.h" - #include "config-host.h" #include "net.h" +#include "clients.h" #include "monitor.h" #include "qemu-char.h" #include "qemu-common.h" #include "qemu-error.h" #include "qemu-option.h" #include "qemu_socket.h" +#include "iov.h" typedef struct NetSocketState { NetClientState nc; @@ -40,29 +40,106 @@ typedef struct NetSocketState { int state; /* 0 = getting length, 1 = getting data */ unsigned int index; unsigned int packet_len; + unsigned int send_index; /* number of bytes sent (only SOCK_STREAM) */ uint8_t buf[4096]; struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */ + IOHandler *send_fn; /* differs between SOCK_STREAM/SOCK_DGRAM */ + bool read_poll; /* waiting to receive data? */ + bool write_poll; /* waiting to transmit data? */ } NetSocketState; static void net_socket_accept(void *opaque); +static void net_socket_writable(void *opaque); + +/* Only read packets from socket when peer can receive them */ +static int net_socket_can_send(void *opaque) +{ + NetSocketState *s = opaque; + + return qemu_can_send_packet(&s->nc); +} + +static void net_socket_update_fd_handler(NetSocketState *s) +{ + qemu_set_fd_handler2(s->fd, + s->read_poll ? net_socket_can_send : NULL, + s->read_poll ? s->send_fn : NULL, + s->write_poll ? net_socket_writable : NULL, + s); +} + +static void net_socket_read_poll(NetSocketState *s, bool enable) +{ + s->read_poll = enable; + net_socket_update_fd_handler(s); +} + +static void net_socket_write_poll(NetSocketState *s, bool enable) +{ + s->write_poll = enable; + net_socket_update_fd_handler(s); +} + +static void net_socket_writable(void *opaque) +{ + NetSocketState *s = opaque; + + net_socket_write_poll(s, false); + + qemu_flush_queued_packets(&s->nc); +} -/* XXX: we consider we can send the whole packet without blocking */ static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size) { NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); - uint32_t len; - len = htonl(size); - - send_all(s->fd, (const uint8_t *)&len, sizeof(len)); - return send_all(s->fd, buf, size); + uint32_t len = htonl(size); + struct iovec iov[] = { + { + .iov_base = &len, + .iov_len = sizeof(len), + }, { + .iov_base = (void *)buf, + .iov_len = size, + }, + }; + size_t remaining; + ssize_t ret; + + remaining = iov_size(iov, 2) - s->send_index; + ret = iov_send(s->fd, iov, 2, s->send_index, remaining); + + if (ret == -1 && errno == EAGAIN) { + ret = 0; /* handled further down */ + } + if (ret == -1) { + s->send_index = 0; + return -errno; + } + if (ret < (ssize_t)remaining) { + s->send_index += ret; + net_socket_write_poll(s, true); + return 0; + } + s->send_index = 0; + return size; } static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size) { NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); + ssize_t ret; + + do { + ret = qemu_sendto(s->fd, buf, size, 0, + (struct sockaddr *)&s->dgram_dst, + sizeof(s->dgram_dst)); + } while (ret == -1 && errno == EINTR); - return sendto(s->fd, (const void *)buf, size, 0, - (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst)); + if (ret == -1 && errno == EAGAIN) { + net_socket_write_poll(s, true); + return 0; + } + return ret; } static void net_socket_send(void *opaque) @@ -81,7 +158,8 @@ static void net_socket_send(void *opaque) } else if (size == 0) { /* end of connection */ eoc: - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + net_socket_read_poll(s, false); + net_socket_write_poll(s, false); if (s->listen_fd != -1) { qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s); } @@ -152,7 +230,8 @@ static void net_socket_send_dgram(void *opaque) return; if (size == 0) { /* end of connection */ - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + net_socket_read_poll(s, false); + net_socket_write_poll(s, false); return; } qemu_send_packet(&s->nc, s->buf, size); @@ -243,7 +322,8 @@ static void net_socket_cleanup(NetClientState *nc) { NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); if (s->fd != -1) { - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + net_socket_read_poll(s, false); + net_socket_write_poll(s, false); close(s->fd); s->fd = -1; } @@ -314,8 +394,8 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, s->fd = fd; s->listen_fd = -1; - - qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s); + s->send_fn = net_socket_send_dgram; + net_socket_read_poll(s, true); /* mcast: save bound address as dst */ if (is_connected) { @@ -332,7 +412,8 @@ err: static void net_socket_connect(void *opaque) { NetSocketState *s = opaque; - qemu_set_fd_handler(s->fd, net_socket_send, NULL, s); + s->send_fn = net_socket_send; + net_socket_read_poll(s, true); } static NetClientInfo net_socket_info = { @@ -629,7 +710,7 @@ int net_init_socket(const NetClientOptions *opts, const char *name, if (sock->has_fd) { int fd; - fd = net_handle_fd_param(cur_mon, sock->fd); + fd = monitor_handle_fd_param(cur_mon, sock->fd); if (fd == -1 || !net_socket_fd_init(peer, "socket", name, fd, 1)) { return -1; } @@ -666,7 +747,7 @@ int net_init_socket(const NetClientOptions *opts, const char *name, error_report("localaddr= is mandatory with udp="); return -1; } - if (net_socket_udp_init(peer, "udp", name, sock->udp, sock->localaddr) == + if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr) == -1) { return -1; } diff --git a/net/tap-win32.c b/net/tap-win32.c index c0ea954..8d2d32b 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -26,9 +26,10 @@ * distribution); if not, see <http://www.gnu.org/licenses/>. */ -#include "net/tap.h" +#include "tap.h" #include "qemu-common.h" +#include "clients.h" /* net_init_tap */ #include "net.h" #include "sysemu.h" #include "qemu-error.h" @@ -751,3 +752,13 @@ struct vhost_net *tap_get_vhost_net(NetClientState *nc) { return NULL; } + +int tap_has_vnet_hdr_len(NetClientState *nc, int len) +{ + return 0; +} + +void tap_set_vnet_hdr_len(NetClientState *nc, int len) +{ + assert(0); +} @@ -23,7 +23,7 @@ * THE SOFTWARE. */ -#include "net/tap.h" +#include "tap.h" #include "config-host.h" @@ -34,6 +34,7 @@ #include <net/if.h> #include "net.h" +#include "clients.h" #include "monitor.h" #include "sysemu.h" #include "qemu-char.h" @@ -340,6 +341,13 @@ static TAPState *net_tap_fd_init(NetClientState *peer, s->using_vnet_hdr = 0; s->has_ufo = tap_probe_has_ufo(s->fd); tap_set_offload(&s->nc, 0, 0, 0, 0, 0); + /* + * Make sure host header length is set correctly in tap: + * it might have been modified by another instance of qemu. + */ + if (tap_probe_vnet_hdr_len(s->fd, s->host_vnet_hdr_len)) { + tap_fd_set_vnet_hdr_len(s->fd, s->host_vnet_hdr_len); + } tap_read_poll(s, 1); s->vhost_net = NULL; return s; @@ -610,7 +618,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name, return -1; } - fd = net_handle_fd_param(cur_mon, tap->fd); + fd = monitor_handle_fd_param(cur_mon, tap->fd); if (fd == -1) { return -1; } @@ -686,7 +694,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name, int vhostfd; if (tap->has_vhostfd) { - vhostfd = net_handle_fd_param(cur_mon, tap->vhostfd); + vhostfd = monitor_handle_fd_param(cur_mon, tap->vhostfd); if (vhostfd == -1) { return -1; } @@ -32,9 +32,6 @@ #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" -int net_init_tap(const NetClientOptions *opts, const char *name, - NetClientState *peer); - int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required); ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen); @@ -58,7 +55,4 @@ int tap_get_fd(NetClientState *nc); struct vhost_net; struct vhost_net *tap_get_vhost_net(NetClientState *nc); -int net_init_bridge(const NetClientOptions *opts, const char *name, - NetClientState *peer); - #endif /* QEMU_NET_TAP_H */ @@ -21,13 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "net/vde.h" - #include "config-host.h" #include <libvdeplug.h> #include "net.h" +#include "clients.h" #include "qemu-char.h" #include "qemu-common.h" #include "qemu-option.h" diff --git a/net/vde.h b/net/vde.h deleted file mode 100644 index 6ce6698..0000000 --- a/net/vde.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef QEMU_NET_VDE_H -#define QEMU_NET_VDE_H - -#include "qemu-common.h" -#include "qapi-types.h" - -#ifdef CONFIG_VDE - -int net_init_vde(const NetClientOptions *opts, const char *name, - NetClientState *peer); - -#endif /* CONFIG_VDE */ - -#endif /* QEMU_NET_VDE_H */ |