|
|
5544c1b |
From 17df2130cd8be0cd6892b86103947746f95efc2c Mon Sep 17 00:00:00 2001
|
|
|
5544c1b |
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
|
5544c1b |
Date: Mon, 20 Aug 2012 13:35:23 +0100
|
|
|
5544c1b |
Subject: [PATCH] net: do not report queued packets as sent
|
|
|
5544c1b |
|
|
|
5544c1b |
Net send functions have a return value where 0 means the packet has not
|
|
|
5544c1b |
been sent and will be queued. A non-zero value means the packet was
|
|
|
5544c1b |
sent or an error caused the packet to be dropped.
|
|
|
5544c1b |
|
|
|
5544c1b |
This patch fixes two instances where packets are queued but we return
|
|
|
5544c1b |
their size. This causes callers to believe the packets were sent. When
|
|
|
5544c1b |
the caller uses the async send interface this creates a real problem
|
|
|
5544c1b |
because the callback will be invoked for a packet that the caller
|
|
|
5544c1b |
believed to be already sent. This bug can cause double-frees in the
|
|
|
5544c1b |
caller.
|
|
|
5544c1b |
|
|
|
5544c1b |
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
|
5544c1b |
(cherry picked from commit 06b5f36d052b540a59b52150582d65674199b2ce)
|
|
|
5544c1b |
|
|
|
5544c1b |
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
|
5544c1b |
---
|
|
|
5544c1b |
net/queue.c | 35 ++++++++++++++++-------------------
|
|
|
5544c1b |
1 file changed, 16 insertions(+), 19 deletions(-)
|
|
|
5544c1b |
|
|
|
5544c1b |
diff --git a/net/queue.c b/net/queue.c
|
|
|
5544c1b |
index 6e64091..254f280 100644
|
|
|
5544c1b |
--- a/net/queue.c
|
|
|
5544c1b |
+++ b/net/queue.c
|
|
|
5544c1b |
@@ -83,12 +83,12 @@ void qemu_del_net_queue(NetQueue *queue)
|
|
|
5544c1b |
g_free(queue);
|
|
|
5544c1b |
}
|
|
|
5544c1b |
|
|
|
5544c1b |
-static ssize_t qemu_net_queue_append(NetQueue *queue,
|
|
|
5544c1b |
- NetClientState *sender,
|
|
|
5544c1b |
- unsigned flags,
|
|
|
5544c1b |
- const uint8_t *buf,
|
|
|
5544c1b |
- size_t size,
|
|
|
5544c1b |
- NetPacketSent *sent_cb)
|
|
|
5544c1b |
+static void qemu_net_queue_append(NetQueue *queue,
|
|
|
5544c1b |
+ NetClientState *sender,
|
|
|
5544c1b |
+ unsigned flags,
|
|
|
5544c1b |
+ const uint8_t *buf,
|
|
|
5544c1b |
+ size_t size,
|
|
|
5544c1b |
+ NetPacketSent *sent_cb)
|
|
|
5544c1b |
{
|
|
|
5544c1b |
NetPacket *packet;
|
|
|
5544c1b |
|
|
|
5544c1b |
@@ -100,16 +100,14 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
|
|
|
5544c1b |
memcpy(packet->data, buf, size);
|
|
|
5544c1b |
|
|
|
5544c1b |
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
|
|
|
5544c1b |
-
|
|
|
5544c1b |
- return size;
|
|
|
5544c1b |
}
|
|
|
5544c1b |
|
|
|
5544c1b |
-static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
|
|
|
5544c1b |
- NetClientState *sender,
|
|
|
5544c1b |
- unsigned flags,
|
|
|
5544c1b |
- const struct iovec *iov,
|
|
|
5544c1b |
- int iovcnt,
|
|
|
5544c1b |
- NetPacketSent *sent_cb)
|
|
|
5544c1b |
+static void qemu_net_queue_append_iov(NetQueue *queue,
|
|
|
5544c1b |
+ NetClientState *sender,
|
|
|
5544c1b |
+ unsigned flags,
|
|
|
5544c1b |
+ const struct iovec *iov,
|
|
|
5544c1b |
+ int iovcnt,
|
|
|
5544c1b |
+ NetPacketSent *sent_cb)
|
|
|
5544c1b |
{
|
|
|
5544c1b |
NetPacket *packet;
|
|
|
5544c1b |
size_t max_len = 0;
|
|
|
5544c1b |
@@ -133,8 +131,6 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
|
|
|
5544c1b |
}
|
|
|
5544c1b |
|
|
|
5544c1b |
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
|
|
|
5544c1b |
-
|
|
|
5544c1b |
- return packet->size;
|
|
|
5544c1b |
}
|
|
|
5544c1b |
|
|
|
5544c1b |
static ssize_t qemu_net_queue_deliver(NetQueue *queue,
|
|
|
5544c1b |
@@ -177,7 +173,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
|
|
|
5544c1b |
ssize_t ret;
|
|
|
5544c1b |
|
|
|
5544c1b |
if (queue->delivering || !qemu_can_send_packet(sender)) {
|
|
|
5544c1b |
- return qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
|
|
|
5544c1b |
+ qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
|
|
|
5544c1b |
+ return 0;
|
|
|
5544c1b |
}
|
|
|
5544c1b |
|
|
|
5544c1b |
ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
|
|
|
5544c1b |
@@ -201,8 +198,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
|
|
|
5544c1b |
ssize_t ret;
|
|
|
5544c1b |
|
|
|
5544c1b |
if (queue->delivering || !qemu_can_send_packet(sender)) {
|
|
|
5544c1b |
- return qemu_net_queue_append_iov(queue, sender, flags,
|
|
|
5544c1b |
- iov, iovcnt, sent_cb);
|
|
|
5544c1b |
+ qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb);
|
|
|
5544c1b |
+ return 0;
|
|
|
5544c1b |
}
|
|
|
5544c1b |
|
|
|
5544c1b |
ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
|
|
|
5544c1b |
--
|
|
|
f375e62 |
1.8.0.2
|
|
|
5544c1b |
|