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