diff options
author | Mark McLoughlin <markmc@redhat.com> | 2009-10-22 17:43:41 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-10-27 12:29:01 -0500 |
commit | ca77d175912f7d0b2296e8e3a803a0763c00bc0b (patch) | |
tree | d1b7908cee9de4ee213179b7b027aba610f6fd6e | |
parent | c0b8e49c695ac11e3ef543db9ea2d8a1f62ccfce (diff) |
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 <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | net-queue.h | 1 | ||||
-rw-r--r-- | net.c | 37 | ||||
-rw-r--r-- | net.h | 2 |
3 files changed, 32 insertions, 8 deletions
diff --git a/net-queue.h b/net-queue.h index 343760e9d4..a31958e3c6 100644 --- a/net-queue.h +++ b/net-queue.h @@ -44,6 +44,7 @@ typedef ssize_t (NetPacketDeliverIOV) (VLANClientState *sender, void *opaque); #define QEMU_NET_PACKET_FLAG_NONE 0 +#define QEMU_NET_PACKET_FLAG_RAW (1<<0) NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver, NetPacketDeliverIOV *deliver_iov, @@ -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 { @@ -45,6 +45,7 @@ typedef void (LinkStatusChanged)(VLANClientState *); struct VLANClientState { net_client_type type; NetReceive *receive; + NetReceive *receive_raw; NetReceiveIOV *receive_iov; /* Packets may still be sent if this returns zero. It's used to rate-limit the slirp code. */ @@ -89,6 +90,7 @@ ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov, int iovcnt, NetPacketSent *sent_cb); void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size); +ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size); ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf, int size, NetPacketSent *sent_cb); void qemu_purge_queued_packets(VLANClientState *vc); |