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 /net.c | |
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>
Diffstat (limited to 'net.c')
-rw-r--r-- | net.c | 37 |
1 files changed, 29 insertions, 8 deletions
@@ -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 { |