diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2010-09-08 14:26:14 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2010-09-08 14:26:14 -0500 |
commit | dccbe6fbab47c9a2589f436e0592933b47cbe40b (patch) | |
tree | e5a851b48a3801dd28282eb17533975cade7ac23 /net | |
parent | 630c26893d6dc7713c0fcfc3c09d6bfe536a6ce3 (diff) | |
parent | a697a334b3c4d3250e6420f5d38550ea10eb5319 (diff) | |
download | qemu-dccbe6fbab47c9a2589f436e0592933b47cbe40b.zip qemu-dccbe6fbab47c9a2589f436e0592933b47cbe40b.tar.gz qemu-dccbe6fbab47c9a2589f436e0592933b47cbe40b.tar.bz2 |
Merge remote branch 'mst/for_anthony' into staging
Diffstat (limited to 'net')
-rw-r--r-- | net/tap-aix.c | 9 | ||||
-rw-r--r-- | net/tap-bsd.c | 9 | ||||
-rw-r--r-- | net/tap-linux.c | 29 | ||||
-rw-r--r-- | net/tap-linux.h | 8 | ||||
-rw-r--r-- | net/tap-solaris.c | 9 | ||||
-rw-r--r-- | net/tap-win32.c | 9 | ||||
-rw-r--r-- | net/tap.c | 49 | ||||
-rw-r--r-- | net/tap.h | 4 |
8 files changed, 112 insertions, 14 deletions
diff --git a/net/tap-aix.c b/net/tap-aix.c index 4bc9f2f..e19aaba 100644 --- a/net/tap-aix.c +++ b/net/tap-aix.c @@ -46,6 +46,15 @@ int tap_probe_has_ufo(int fd) return 0; } +int tap_probe_vnet_hdr_len(int fd, int len) +{ + return 0; +} + +void tap_fd_set_vnet_hdr_len(int fd, int len) +{ +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 3773d5d..3513075 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -116,6 +116,15 @@ int tap_probe_has_ufo(int fd) return 0; } +int tap_probe_vnet_hdr_len(int fd, int len) +{ + return 0; +} + +void tap_fd_set_vnet_hdr_len(int fd, int len) +{ +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-linux.c b/net/tap-linux.c index c92983c..f7aa904 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -129,6 +129,35 @@ int tap_probe_has_ufo(int fd) return 1; } +/* Verify that we can assign given length */ +int tap_probe_vnet_hdr_len(int fd, int len) +{ + int orig; + if (ioctl(fd, TUNGETVNETHDRSZ, &orig) == -1) { + return 0; + } + if (ioctl(fd, TUNSETVNETHDRSZ, &len) == -1) { + return 0; + } + /* Restore original length: we can't handle failure. */ + if (ioctl(fd, TUNSETVNETHDRSZ, &orig) == -1) { + fprintf(stderr, "TUNGETVNETHDRSZ ioctl() failed: %s. Exiting.\n", + strerror(errno)); + assert(0); + return -errno; + } + return 1; +} + +void tap_fd_set_vnet_hdr_len(int fd, int len) +{ + if (ioctl(fd, TUNSETVNETHDRSZ, &len) == -1) { + fprintf(stderr, "TUNSETVNETHDRSZ ioctl() failed: %s. Exiting.\n", + strerror(errno)); + assert(0); + } +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-linux.h b/net/tap-linux.h index 9f94358..659e981 100644 --- a/net/tap-linux.h +++ b/net/tap-linux.h @@ -27,6 +27,8 @@ #define TUNSETOFFLOAD _IOW('T', 208, unsigned int) #define TUNGETIFF _IOR('T', 210, unsigned int) #define TUNSETSNDBUF _IOW('T', 212, int) +#define TUNGETVNETHDRSZ _IOR('T', 215, int) +#define TUNSETVNETHDRSZ _IOW('T', 216, int) #endif @@ -52,4 +54,10 @@ struct virtio_net_hdr uint16_t csum_offset; }; +struct virtio_net_hdr_mrg_rxbuf +{ + struct virtio_net_hdr hdr; + uint16_t num_buffers; /* Number of merged rx buffers */ +}; + #endif /* QEMU_TAP_H */ diff --git a/net/tap-solaris.c b/net/tap-solaris.c index 4ac61d2..c216d28 100644 --- a/net/tap-solaris.c +++ b/net/tap-solaris.c @@ -212,6 +212,15 @@ int tap_probe_has_ufo(int fd) return 0; } +int tap_probe_vnet_hdr_len(int fd, int len) +{ + return 0; +} + +void tap_fd_set_vnet_hdr_len(int fd, int len) +{ +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-win32.c b/net/tap-win32.c index 74348da..9fe4fcd 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -728,6 +728,15 @@ int tap_has_vnet_hdr(VLANClientState *vc) return 0; } +int tap_probe_vnet_hdr_len(int fd, int len) +{ + return 0; +} + +void tap_fd_set_vnet_hdr_len(int fd, int len) +{ +} + void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr) { } @@ -57,10 +57,10 @@ typedef struct TAPState { uint8_t buf[TAP_BUFSIZE]; unsigned int read_poll : 1; unsigned int write_poll : 1; - unsigned int has_vnet_hdr : 1; unsigned int using_vnet_hdr : 1; unsigned int has_ufo: 1; VHostNetState *vhost_net; + unsigned host_vnet_hdr_len; } TAPState; static int launch_script(const char *setup_script, const char *ifname, int fd); @@ -121,11 +121,11 @@ static ssize_t tap_receive_iov(VLANClientState *nc, const struct iovec *iov, TAPState *s = DO_UPCAST(TAPState, nc, nc); const struct iovec *iovp = iov; struct iovec iov_copy[iovcnt + 1]; - struct virtio_net_hdr hdr = { 0, }; + struct virtio_net_hdr_mrg_rxbuf hdr = { }; - if (s->has_vnet_hdr && !s->using_vnet_hdr) { + if (s->host_vnet_hdr_len && !s->using_vnet_hdr) { iov_copy[0].iov_base = &hdr; - iov_copy[0].iov_len = sizeof(hdr); + iov_copy[0].iov_len = s->host_vnet_hdr_len; memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov)); iovp = iov_copy; iovcnt++; @@ -139,11 +139,11 @@ static ssize_t tap_receive_raw(VLANClientState *nc, const uint8_t *buf, size_t s TAPState *s = DO_UPCAST(TAPState, nc, nc); struct iovec iov[2]; int iovcnt = 0; - struct virtio_net_hdr hdr = { 0, }; + struct virtio_net_hdr_mrg_rxbuf hdr = { }; - if (s->has_vnet_hdr) { + if (s->host_vnet_hdr_len) { iov[iovcnt].iov_base = &hdr; - iov[iovcnt].iov_len = sizeof(hdr); + iov[iovcnt].iov_len = s->host_vnet_hdr_len; iovcnt++; } @@ -159,7 +159,7 @@ static ssize_t tap_receive(VLANClientState *nc, const uint8_t *buf, size_t size) TAPState *s = DO_UPCAST(TAPState, nc, nc); struct iovec iov[1]; - if (s->has_vnet_hdr && !s->using_vnet_hdr) { + if (s->host_vnet_hdr_len && !s->using_vnet_hdr) { return tap_receive_raw(nc, buf, size); } @@ -202,9 +202,9 @@ static void tap_send(void *opaque) break; } - if (s->has_vnet_hdr && !s->using_vnet_hdr) { - buf += sizeof(struct virtio_net_hdr); - size -= sizeof(struct virtio_net_hdr); + if (s->host_vnet_hdr_len && !s->using_vnet_hdr) { + buf += s->host_vnet_hdr_len; + size -= s->host_vnet_hdr_len; } size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed); @@ -229,7 +229,28 @@ int tap_has_vnet_hdr(VLANClientState *nc) assert(nc->info->type == NET_CLIENT_TYPE_TAP); - return s->has_vnet_hdr; + return !!s->host_vnet_hdr_len; +} + +int tap_has_vnet_hdr_len(VLANClientState *nc, int len) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + assert(nc->info->type == NET_CLIENT_TYPE_TAP); + + return tap_probe_vnet_hdr_len(s->fd, len); +} + +void tap_set_vnet_hdr_len(VLANClientState *nc, int len) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + assert(nc->info->type == NET_CLIENT_TYPE_TAP); + assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) || + len == sizeof(struct virtio_net_hdr)); + + tap_fd_set_vnet_hdr_len(s->fd, len); + s->host_vnet_hdr_len = len; } void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr) @@ -239,7 +260,7 @@ void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr) using_vnet_hdr = using_vnet_hdr != 0; assert(nc->info->type == NET_CLIENT_TYPE_TAP); - assert(s->has_vnet_hdr == using_vnet_hdr); + assert(!!s->host_vnet_hdr_len == using_vnet_hdr); s->using_vnet_hdr = using_vnet_hdr; } @@ -310,7 +331,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, s = DO_UPCAST(TAPState, nc, nc); s->fd = fd; - s->has_vnet_hdr = vnet_hdr != 0; + s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0; s->using_vnet_hdr = 0; s->has_ufo = tap_probe_has_ufo(s->fd); tap_set_offload(&s->nc, 0, 0, 0, 0, 0); @@ -40,13 +40,17 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen); int tap_has_ufo(VLANClientState *vc); int tap_has_vnet_hdr(VLANClientState *vc); +int tap_has_vnet_hdr_len(VLANClientState *vc, int len); void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr); void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn, int ufo); +void tap_set_vnet_hdr_len(VLANClientState *vc, int len); int tap_set_sndbuf(int fd, QemuOpts *opts); int tap_probe_vnet_hdr(int fd); +int tap_probe_vnet_hdr_len(int fd, int len); int tap_probe_has_ufo(int fd); void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo); +void tap_fd_set_vnet_hdr_len(int fd, int len); int tap_get_fd(VLANClientState *vc); |