From ca77d175912f7d0b2296e8e3a803a0763c00bc0b Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Thu, 22 Oct 2009 17:43:41 +0100 Subject: net: add an API for 'raw' packets In the case where a NIC and backend agree on a packet header format, this API allows injecting packets which lack the agreed upon header. We need this for sending our gratuitous ARP. Signed-off-by: Mark McLoughlin Signed-off-by: Anthony Liguori --- net.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'net.c') diff --git a/net.c b/net.c index fefed6c0c6..d950029a2d 100644 --- a/net.c +++ b/net.c @@ -478,7 +478,10 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender, return size; } - return vc->receive(vc, data, size); + if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) + return vc->receive_raw(vc, data, size); + else + return vc->receive(vc, data, size); } static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, @@ -503,7 +506,10 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, continue; } - len = vc->receive(vc, buf, size); + if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) + len = vc->receive_raw(vc, buf, size); + else + len = vc->receive(vc, buf, size); ret = (ret >= 0) ? ret : len; } @@ -541,9 +547,10 @@ void qemu_flush_queued_packets(VLANClientState *vc) qemu_net_queue_flush(queue); } -ssize_t qemu_send_packet_async(VLANClientState *sender, - const uint8_t *buf, int size, - NetPacketSent *sent_cb) +static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender, + unsigned flags, + const uint8_t *buf, int size, + NetPacketSent *sent_cb) { NetQueue *queue; @@ -562,9 +569,15 @@ ssize_t qemu_send_packet_async(VLANClientState *sender, queue = sender->vlan->send_queue; } - return qemu_net_queue_send(queue, sender, - QEMU_NET_PACKET_FLAG_NONE, - buf, size, sent_cb); + return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb); +} + +ssize_t qemu_send_packet_async(VLANClientState *sender, + const uint8_t *buf, int size, + NetPacketSent *sent_cb) +{ + return qemu_send_packet_async_with_flags(sender, QEMU_NET_PACKET_FLAG_NONE, + buf, size, sent_cb); } void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) @@ -572,6 +585,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) qemu_send_packet_async(vc, buf, size, NULL); } +ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size) +{ + return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW, + buf, size, NULL); +} + static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, int iovcnt) { @@ -641,6 +660,8 @@ static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender, continue; } + assert(!(flags & QEMU_NET_PACKET_FLAG_RAW)); + if (vc->receive_iov) { len = vc->receive_iov(vc, iov, iovcnt); } else { -- cgit v1.2.3