Revision e35e23f6
b/hw/virtio-net.c | ||
---|---|---|
41 | 41 |
int32_t tx_burst; |
42 | 42 |
int tx_waiting; |
43 | 43 |
uint32_t has_vnet_hdr; |
44 |
size_t host_hdr_len; |
|
45 |
size_t guest_hdr_len; |
|
44 | 46 |
uint8_t has_ufo; |
45 | 47 |
struct { |
46 | 48 |
VirtQueueElement elem; |
... | ... | |
231 | 233 |
|
232 | 234 |
if (peer_has_vnet_hdr(n)) { |
233 | 235 |
tap_using_vnet_hdr(n->nic->nc.peer, 1); |
236 |
n->host_hdr_len = sizeof(struct virtio_net_hdr); |
|
234 | 237 |
} else { |
235 | 238 |
features &= ~(0x1 << VIRTIO_NET_F_CSUM); |
236 | 239 |
features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4); |
... | ... | |
278 | 281 |
VirtIONet *n = to_virtio_net(vdev); |
279 | 282 |
|
280 | 283 |
n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)); |
284 |
n->guest_hdr_len = n->mergeable_rx_bufs ? |
|
285 |
sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); |
|
281 | 286 |
|
282 | 287 |
if (n->has_vnet_hdr) { |
283 | 288 |
tap_set_offload(n->nic->nc.peer, |
... | ... | |
593 | 598 |
{ |
594 | 599 |
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque; |
595 | 600 |
struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL; |
596 |
size_t guest_hdr_len, offset, i, host_hdr_len;
|
|
601 |
size_t offset, i;
|
|
597 | 602 |
|
598 | 603 |
if (!virtio_net_can_receive(&n->nic->nc)) |
599 | 604 |
return -1; |
600 | 605 |
|
601 | 606 |
/* hdr_len refers to the header we supply to the guest */ |
602 |
guest_hdr_len = n->mergeable_rx_bufs ? |
|
603 |
sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); |
|
604 |
|
|
605 |
|
|
606 |
host_hdr_len = n->has_vnet_hdr ? sizeof(struct virtio_net_hdr) : 0; |
|
607 |
if (!virtio_net_has_buffers(n, size + guest_hdr_len - host_hdr_len)) |
|
607 |
if (!virtio_net_has_buffers(n, size + n->guest_hdr_len - n->host_hdr_len)) |
|
608 | 608 |
return 0; |
609 | 609 |
|
610 | 610 |
if (!receive_filter(n, buf, size)) |
... | ... | |
626 | 626 |
"i %zd mergeable %d offset %zd, size %zd, " |
627 | 627 |
"guest hdr len %zd, host hdr len %zd guest features 0x%x", |
628 | 628 |
i, n->mergeable_rx_bufs, offset, size, |
629 |
guest_hdr_len, host_hdr_len, n->vdev.guest_features);
|
|
629 |
n->guest_hdr_len, n->host_hdr_len, n->vdev.guest_features);
|
|
630 | 630 |
exit(1); |
631 | 631 |
} |
632 | 632 |
|
... | ... | |
635 | 635 |
exit(1); |
636 | 636 |
} |
637 | 637 |
|
638 |
if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != guest_hdr_len) { |
|
638 |
if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != n->guest_hdr_len) {
|
|
639 | 639 |
error_report("virtio-net header not in first element"); |
640 | 640 |
exit(1); |
641 | 641 |
} |
... | ... | |
647 | 647 |
mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base; |
648 | 648 |
|
649 | 649 |
offset += receive_header(n, sg, elem.in_num, |
650 |
buf + offset, size - offset, guest_hdr_len); |
|
651 |
total += guest_hdr_len; |
|
650 |
buf + offset, size - offset, |
|
651 |
n->guest_hdr_len); |
|
652 |
total += n->guest_hdr_len; |
|
652 | 653 |
} |
653 | 654 |
|
654 | 655 |
/* copy in packet. ugh */ |
... | ... | |
665 | 666 |
"i %zd mergeable %d offset %zd, size %zd, " |
666 | 667 |
"guest hdr len %zd, host hdr len %zd", |
667 | 668 |
i, n->mergeable_rx_bufs, |
668 |
offset, size, guest_hdr_len, host_hdr_len);
|
|
669 |
offset, size, n->guest_hdr_len, n->host_hdr_len);
|
|
669 | 670 |
#endif |
670 | 671 |
return size; |
671 | 672 |
} |
... | ... | |
900 | 901 |
qemu_get_buffer(f, n->mac, ETH_ALEN); |
901 | 902 |
n->tx_waiting = qemu_get_be32(f); |
902 | 903 |
n->mergeable_rx_bufs = qemu_get_be32(f); |
904 |
n->guest_hdr_len = n->mergeable_rx_bufs ? |
|
905 |
sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); |
|
903 | 906 |
|
904 | 907 |
if (version_id >= 3) |
905 | 908 |
n->status = qemu_get_be16(f); |
... | ... | |
940 | 943 |
|
941 | 944 |
if (n->has_vnet_hdr) { |
942 | 945 |
tap_using_vnet_hdr(n->nic->nc.peer, 1); |
946 |
n->host_hdr_len = sizeof(struct virtio_net_hdr); |
|
943 | 947 |
tap_set_offload(n->nic->nc.peer, |
944 | 948 |
(n->vdev.guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1, |
945 | 949 |
(n->vdev.guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1, |
... | ... | |
1044 | 1048 |
n->tx_waiting = 0; |
1045 | 1049 |
n->tx_burst = net->txburst; |
1046 | 1050 |
n->mergeable_rx_bufs = 0; |
1051 |
n->guest_hdr_len = sizeof(struct virtio_net_hdr); |
|
1047 | 1052 |
n->promisc = 1; /* for compatibility */ |
1048 | 1053 |
|
1049 | 1054 |
n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN); |
Also available in: Unified diff