57 |
57 |
uint8_t buf[TAP_BUFSIZE];
|
58 |
58 |
unsigned int read_poll : 1;
|
59 |
59 |
unsigned int write_poll : 1;
|
60 |
|
unsigned int has_vnet_hdr : 1;
|
61 |
60 |
unsigned int using_vnet_hdr : 1;
|
62 |
61 |
unsigned int has_ufo: 1;
|
63 |
62 |
VHostNetState *vhost_net;
|
|
63 |
unsigned host_vnet_hdr_len;
|
64 |
64 |
} TAPState;
|
65 |
65 |
|
66 |
66 |
static int launch_script(const char *setup_script, const char *ifname, int fd);
|
... | ... | |
121 |
121 |
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
122 |
122 |
const struct iovec *iovp = iov;
|
123 |
123 |
struct iovec iov_copy[iovcnt + 1];
|
124 |
|
struct virtio_net_hdr hdr = { 0, };
|
|
124 |
struct virtio_net_hdr_mrg_rxbuf hdr = { };
|
125 |
125 |
|
126 |
|
if (s->has_vnet_hdr && !s->using_vnet_hdr) {
|
|
126 |
if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
|
127 |
127 |
iov_copy[0].iov_base = &hdr;
|
128 |
|
iov_copy[0].iov_len = sizeof(hdr);
|
|
128 |
iov_copy[0].iov_len = s->host_vnet_hdr_len;
|
129 |
129 |
memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
|
130 |
130 |
iovp = iov_copy;
|
131 |
131 |
iovcnt++;
|
... | ... | |
139 |
139 |
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
140 |
140 |
struct iovec iov[2];
|
141 |
141 |
int iovcnt = 0;
|
142 |
|
struct virtio_net_hdr hdr = { 0, };
|
|
142 |
struct virtio_net_hdr_mrg_rxbuf hdr = { };
|
143 |
143 |
|
144 |
|
if (s->has_vnet_hdr) {
|
|
144 |
if (s->host_vnet_hdr_len) {
|
145 |
145 |
iov[iovcnt].iov_base = &hdr;
|
146 |
|
iov[iovcnt].iov_len = sizeof(hdr);
|
|
146 |
iov[iovcnt].iov_len = s->host_vnet_hdr_len;
|
147 |
147 |
iovcnt++;
|
148 |
148 |
}
|
149 |
149 |
|
... | ... | |
159 |
159 |
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
160 |
160 |
struct iovec iov[1];
|
161 |
161 |
|
162 |
|
if (s->has_vnet_hdr && !s->using_vnet_hdr) {
|
|
162 |
if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
|
163 |
163 |
return tap_receive_raw(nc, buf, size);
|
164 |
164 |
}
|
165 |
165 |
|
... | ... | |
202 |
202 |
break;
|
203 |
203 |
}
|
204 |
204 |
|
205 |
|
if (s->has_vnet_hdr && !s->using_vnet_hdr) {
|
206 |
|
buf += sizeof(struct virtio_net_hdr);
|
207 |
|
size -= sizeof(struct virtio_net_hdr);
|
|
205 |
if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
|
|
206 |
buf += s->host_vnet_hdr_len;
|
|
207 |
size -= s->host_vnet_hdr_len;
|
208 |
208 |
}
|
209 |
209 |
|
210 |
210 |
size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
|
... | ... | |
229 |
229 |
|
230 |
230 |
assert(nc->info->type == NET_CLIENT_TYPE_TAP);
|
231 |
231 |
|
232 |
|
return s->has_vnet_hdr;
|
|
232 |
return !!s->host_vnet_hdr_len;
|
233 |
233 |
}
|
234 |
234 |
|
235 |
235 |
void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr)
|
... | ... | |
239 |
239 |
using_vnet_hdr = using_vnet_hdr != 0;
|
240 |
240 |
|
241 |
241 |
assert(nc->info->type == NET_CLIENT_TYPE_TAP);
|
242 |
|
assert(s->has_vnet_hdr == using_vnet_hdr);
|
|
242 |
assert(!!s->host_vnet_hdr_len == using_vnet_hdr);
|
243 |
243 |
|
244 |
244 |
s->using_vnet_hdr = using_vnet_hdr;
|
245 |
245 |
}
|
... | ... | |
310 |
310 |
s = DO_UPCAST(TAPState, nc, nc);
|
311 |
311 |
|
312 |
312 |
s->fd = fd;
|
313 |
|
s->has_vnet_hdr = vnet_hdr != 0;
|
|
313 |
s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
|
314 |
314 |
s->using_vnet_hdr = 0;
|
315 |
315 |
s->has_ufo = tap_probe_has_ufo(s->fd);
|
316 |
316 |
tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
|