aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2010-06-06 18:53:10 +0300
committerMichael S. Tsirkin <mst@redhat.com>2010-06-07 17:23:04 +0300
commit940cda94dc01e955b6008c47b782817a1ed3b201 (patch)
tree002a58c14358ef85e479f70ece46f0aedb229ac7
parent7f9744812291853425b614f68668f48d49882a1f (diff)
virtio-net: truncating packet
virtio net attempts to peek into virtio queue to determine that we have enough space for the complete packet to fit. However, it fails to account for space consumed by virtio net header when it does this, under stress this results in a failure with the message 'truncating packet'. redhat bz 591494. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/virtio-net.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 6a9d560a9b..06ba48103d 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -532,16 +532,17 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
if (!virtio_net_can_receive(&n->nic->nc))
return -1;
- if (!virtio_net_has_buffers(n, size))
+ /* hdr_len refers to the header we supply to the guest */
+ hdr_len = n->mergeable_rx_bufs ?
+ sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
+
+
+ if (!virtio_net_has_buffers(n, size + hdr_len))
return 0;
if (!receive_filter(n, buf, size))
return size;
- /* hdr_len refers to the header we supply to the guest */
- hdr_len = n->mergeable_rx_bufs ?
- sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
-
offset = i = 0;
while (offset < size) {
@@ -555,7 +556,9 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
virtqueue_pop(n->rx_vq, &elem) == 0) {
if (i == 0)
return -1;
- fprintf(stderr, "virtio-net truncating packet\n");
+ fprintf(stderr, "virtio-net truncating packet: "
+ "offset %zd, size %zd, hdr_len %zd\n",
+ offset, size, hdr_len);
exit(1);
}