aboutsummaryrefslogtreecommitdiffstats
path: root/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'net.c')
-rw-r--r--net.c138
1 files changed, 23 insertions, 115 deletions
diff --git a/net.c b/net.c
index 5d78f04e0..2c7b2ef1a 100644
--- a/net.c
+++ b/net.c
@@ -422,15 +422,16 @@ int qemu_can_send_packet(VLANClientState *sender)
return 0;
}
-static int
-qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
+static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
+ const uint8_t *buf,
+ size_t size,
+ void *opaque)
{
+ VLANState *vlan = opaque;
VLANClientState *vc;
int ret = -1;
- sender->vlan->delivering = 1;
-
- QTAILQ_FOREACH(vc, &sender->vlan->clients, next) {
+ QTAILQ_FOREACH(vc, &vlan->clients, next) {
ssize_t len;
if (vc == sender) {
@@ -447,24 +448,15 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
ret = (ret >= 0) ? ret : len;
}
- sender->vlan->delivering = 0;
-
return ret;
}
void qemu_purge_queued_packets(VLANClientState *vc)
{
- VLANPacket *packet, *next;
-
if (!vc->vlan)
return;
- QTAILQ_FOREACH_SAFE(packet, &vc->vlan->send_queue, entry, next) {
- if (packet->sender == vc) {
- QTAILQ_REMOVE(&vc->vlan->send_queue, packet, entry);
- qemu_free(packet);
- }
- }
+ qemu_net_queue_purge(vc->vlan->send_queue, vc);
}
void qemu_flush_queued_packets(VLANClientState *vc)
@@ -472,47 +464,13 @@ void qemu_flush_queued_packets(VLANClientState *vc)
if (!vc->vlan)
return;
- while (!QTAILQ_EMPTY(&vc->vlan->send_queue)) {
- VLANPacket *packet;
- int ret;
-
- packet = QTAILQ_FIRST(&vc->vlan->send_queue);
- QTAILQ_REMOVE(&vc->vlan->send_queue, packet, entry);
-
- ret = qemu_deliver_packet(packet->sender, packet->data, packet->size);
- if (ret == 0 && packet->sent_cb != NULL) {
- QTAILQ_INSERT_HEAD(&vc->vlan->send_queue, packet, entry);
- break;
- }
-
- if (packet->sent_cb)
- packet->sent_cb(packet->sender, ret);
-
- qemu_free(packet);
- }
-}
-
-static void qemu_enqueue_packet(VLANClientState *sender,
- const uint8_t *buf, int size,
- NetPacketSent *sent_cb)
-{
- VLANPacket *packet;
-
- packet = qemu_malloc(sizeof(VLANPacket) + size);
- packet->sender = sender;
- packet->size = size;
- packet->sent_cb = sent_cb;
- memcpy(packet->data, buf, size);
-
- QTAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry);
+ qemu_net_queue_flush(vc->vlan->send_queue);
}
ssize_t qemu_send_packet_async(VLANClientState *sender,
const uint8_t *buf, int size,
NetPacketSent *sent_cb)
{
- int ret;
-
if (sender->link_down || !sender->vlan) {
return size;
}
@@ -522,20 +480,8 @@ ssize_t qemu_send_packet_async(VLANClientState *sender,
hex_dump(stdout, buf, size);
#endif
- if (sender->vlan->delivering) {
- qemu_enqueue_packet(sender, buf, size, NULL);
- return size;
- }
-
- ret = qemu_deliver_packet(sender, buf, size);
- if (ret == 0 && sent_cb != NULL) {
- qemu_enqueue_packet(sender, buf, size, sent_cb);
- return 0;
- }
-
- qemu_flush_queued_packets(sender);
-
- return ret;
+ return qemu_net_queue_send(sender->vlan->send_queue,
+ sender, buf, size, sent_cb);
}
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
@@ -571,15 +517,16 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
return offset;
}
-static int qemu_deliver_packet_iov(VLANClientState *sender,
- const struct iovec *iov, int iovcnt)
+static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
+ const struct iovec *iov,
+ int iovcnt,
+ void *opaque)
{
+ VLANState *vlan = opaque;
VLANClientState *vc;
- int ret = -1;
-
- sender->vlan->delivering = 1;
+ ssize_t ret = -1;
- QTAILQ_FOREACH(vc, &sender->vlan->clients, next) {
+ QTAILQ_FOREACH(vc, &vlan->clients, next) {
ssize_t len;
if (vc == sender) {
@@ -600,61 +547,19 @@ static int qemu_deliver_packet_iov(VLANClientState *sender,
ret = (ret >= 0) ? ret : len;
}
- sender->vlan->delivering = 0;
-
return ret;
}
-static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
- const struct iovec *iov, int iovcnt,
- NetPacketSent *sent_cb)
-{
- VLANPacket *packet;
- size_t max_len = 0;
- int i;
-
- max_len = calc_iov_length(iov, iovcnt);
-
- packet = qemu_malloc(sizeof(VLANPacket) + max_len);
- packet->sender = sender;
- packet->sent_cb = sent_cb;
- packet->size = 0;
-
- for (i = 0; i < iovcnt; i++) {
- size_t len = iov[i].iov_len;
-
- memcpy(packet->data + packet->size, iov[i].iov_base, len);
- packet->size += len;
- }
-
- QTAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry);
-
- return packet->size;
-}
-
ssize_t qemu_sendv_packet_async(VLANClientState *sender,
const struct iovec *iov, int iovcnt,
NetPacketSent *sent_cb)
{
- int ret;
-
if (sender->link_down || !sender->vlan) {
return calc_iov_length(iov, iovcnt);
}
- if (sender->vlan->delivering) {
- return qemu_enqueue_packet_iov(sender, iov, iovcnt, NULL);
- }
-
- ret = qemu_deliver_packet_iov(sender, iov, iovcnt);
- if (ret == 0 && sent_cb != NULL) {
- qemu_enqueue_packet_iov(sender, iov, iovcnt, sent_cb);
- return 0;
- }
-
- qemu_flush_queued_packets(sender);
-
- return ret;
+ return qemu_net_queue_send_iov(sender->vlan->send_queue,
+ sender, iov, iovcnt, sent_cb);
}
ssize_t
@@ -2348,7 +2253,10 @@ VLANState *qemu_find_vlan(int id, int allocate)
vlan = qemu_mallocz(sizeof(VLANState));
vlan->id = id;
QTAILQ_INIT(&vlan->clients);
- QTAILQ_INIT(&vlan->send_queue);
+
+ vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet,
+ qemu_vlan_deliver_packet_iov,
+ vlan);
QTAILQ_INSERT_TAIL(&vlans, vlan, next);