]> git.proxmox.com Git - qemu.git/commitdiff
net: add an API for 'raw' packets
authorMark McLoughlin <markmc@redhat.com>
Thu, 22 Oct 2009 16:43:41 +0000 (17:43 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Tue, 27 Oct 2009 17:29:01 +0000 (12:29 -0500)
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>
net-queue.h
net.c
net.h

index 343760e9d47b1ed5a2ef9f968edfc7b6e55da817..a31958e3c6899113e03186ba5145c893ef598e80 100644 (file)
@@ -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,
diff --git a/net.c b/net.c
index fefed6c0c6a63aeaf163f67385d2bc2d3a4fe42e..d950029a2df37ebe64ada00833c20e31605e735c 100644 (file)
--- 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 {
diff --git a/net.h b/net.h
index 707870880730d55da5d6f489a15eb3fd5092ab88..489266ba791478c7cc7f53939997e5d82ddfc8b7 100644 (file)
--- a/net.h
+++ b/net.h
@@ -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);