netdev: Send ofpbuf directly to netdev.
authorPravin <pshelar@nicira.com>
Thu, 20 Mar 2014 17:56:51 +0000 (10:56 -0700)
committerPravin B Shelar <pshelar@nicira.com>
Fri, 21 Mar 2014 18:48:28 +0000 (11:48 -0700)
DPDK netdev need to access ofpbuf while sending buffer. Following
patch changes netdev_send accordingly.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Thomas Graf <tgraf@redhat.com>
lib/dpif-netdev.c
lib/netdev-bsd.c
lib/netdev-dummy.c
lib/netdev-linux.c
lib/netdev-provider.h
lib/netdev.c
lib/netdev.h

index 254f8b8..f1bc10a 100644 (file)
@@ -1937,7 +1937,7 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
     case OVS_ACTION_ATTR_OUTPUT:
         p = dp_netdev_lookup_port(aux->dp, u32_to_odp(nl_attr_get_u32(a)));
         if (p) {
-            netdev_send(p->netdev, packet);
+            netdev_send(p->netdev, packet, may_steal);
         }
         break;
 
@@ -1951,6 +1951,10 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
                                        % aux->dp->n_handlers,
                                    DPIF_UC_ACTION, aux->key,
                                    userdata);
+
+        if (may_steal) {
+            ofpbuf_delete(packet);
+        }
         break;
     }
     case OVS_ACTION_ATTR_PUSH_VLAN:
@@ -1964,9 +1968,6 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
         OVS_NOT_REACHED();
     }
 
-    if (may_steal) {
-        ofpbuf_delete(packet);
-    }
 }
 
 static void
index cb99619..99a60f1 100644 (file)
@@ -683,10 +683,12 @@ netdev_bsd_rx_drain(struct netdev_rx *rx_)
  * system or a tap device.
  */
 static int
-netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
+netdev_bsd_send(struct netdev *netdev_, struct ofpbuf *pkt, bool may_steal)
 {
     struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
     const char *name = netdev_get_name(netdev_);
+    const void *data = pkt->data;
+    size_t size = pkt->size;
     int error;
 
     ovs_mutex_lock(&dev->mutex);
@@ -723,6 +725,10 @@ netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
     }
 
     ovs_mutex_unlock(&dev->mutex);
+    if (may_steal) {
+        ofpbuf_delete(pkt);
+    }
+
     return error;
 }
 
index ecd7317..a1d1b79 100644 (file)
@@ -818,9 +818,11 @@ netdev_dummy_rx_drain(struct netdev_rx *rx_)
 }
 
 static int
-netdev_dummy_send(struct netdev *netdev, const void *buffer, size_t size)
+netdev_dummy_send(struct netdev *netdev, struct ofpbuf *pkt, bool may_steal)
 {
     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
+    const void *buffer = pkt->data;
+    size_t size = pkt->size;
 
     if (size < ETH_HEADER_LEN) {
         return EMSGSIZE;
@@ -855,6 +857,9 @@ netdev_dummy_send(struct netdev *netdev, const void *buffer, size_t size)
     }
 
     ovs_mutex_unlock(&dev->mutex);
+    if (may_steal) {
+        ofpbuf_delete(pkt);
+    }
 
     return 0;
 }
index 2aa674a..5d7bfa1 100644 (file)
@@ -1054,8 +1054,11 @@ netdev_linux_rx_drain(struct netdev_rx *rx_)
  * The kernel maintains a packet transmission queue, so the caller is not
  * expected to do additional queuing of packets. */
 static int
-netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
+netdev_linux_send(struct netdev *netdev_, struct ofpbuf *pkt, bool may_steal)
 {
+    const void *data = pkt->data;
+    size_t size = pkt->size;
+
     for (;;) {
         ssize_t retval;
 
@@ -1106,6 +1109,10 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
             retval = write(netdev->tap_fd, data, size);
         }
 
+        if (may_steal) {
+            ofpbuf_delete(pkt);
+        }
+
         if (retval < 0) {
             /* The Linux AF_PACKET implementation never blocks waiting for room
              * for packets, instead returning ENOBUFS.  Translate this into
index 0711bb9..6a38e1f 100644 (file)
@@ -223,13 +223,13 @@ struct netdev_class {
     const struct netdev_tunnel_config *
         (*get_tunnel_config)(const struct netdev *netdev);
 
-    /* Sends the 'size'-byte packet in 'buffer' on 'netdev'.  Returns 0 if
-     * successful, otherwise a positive errno value.  Returns EAGAIN without
-     * blocking if the packet cannot be queued immediately.  Returns EMSGSIZE
-     * if a partial packet was transmitted or if the packet is too big or too
-     * small to transmit on the device.
+    /* Sends the buffer on 'netdev'.
+     * Returns 0 if successful, otherwise a positive errno value.  Returns
+     * EAGAIN without blocking if the packet cannot be queued immediately.
+     * Returns EMSGSIZE if a partial packet was transmitted or if the packet
+     * is too big or too small to transmit on the device.
      *
-     * The caller retains ownership of 'buffer' in all cases.
+     * To retain ownership of 'buffer' caller can set may_steal to false.
      *
      * The network device is expected to maintain a packet transmission queue,
      * so that the caller does not ordinarily have to do additional queuing of
@@ -241,7 +241,7 @@ struct netdev_class {
      * network device from being usefully used by the netdev-based "userspace
      * datapath".  It will also prevent the OVS implementation of bonding from
      * working properly over 'netdev'.) */
-    int (*send)(struct netdev *netdev, const void *buffer, size_t size);
+    int (*send)(struct netdev *netdev, struct ofpbuf *buffer, bool may_steal);
 
     /* Registers with the poll loop to wake up from the next call to
      * poll_block() when the packet transmission queue for 'netdev' has
index 0d7b69d..0d408bf 100644 (file)
@@ -599,7 +599,7 @@ netdev_rx_drain(struct netdev_rx *rx)
  * immediately.  Returns EMSGSIZE if a partial packet was transmitted or if
  * the packet is too big or too small to transmit on the device.
  *
- * The caller retains ownership of 'buffer' in all cases.
+ * To retain ownership of 'buffer' caller can set may_steal to false.
  *
  * The kernel maintains a packet transmission queue, so the caller is not
  * expected to do additional queuing of packets.
@@ -607,12 +607,12 @@ netdev_rx_drain(struct netdev_rx *rx)
  * Some network devices may not implement support for this function.  In such
  * cases this function will always return EOPNOTSUPP. */
 int
-netdev_send(struct netdev *netdev, const struct ofpbuf *buffer)
+netdev_send(struct netdev *netdev, struct ofpbuf *buffer, bool may_steal)
 {
     int error;
 
     error = (netdev->netdev_class->send
-             ? netdev->netdev_class->send(netdev, buffer->data, buffer->size)
+             ? netdev->netdev_class->send(netdev, buffer, may_steal)
              : EOPNOTSUPP);
     if (!error) {
         COVERAGE_INC(netdev_sent);
index a4dd99b..bbd717f 100644 (file)
@@ -166,7 +166,7 @@ void netdev_rx_wait(struct netdev_rx *);
 int netdev_rx_drain(struct netdev_rx *);
 
 /* Packet transmission. */
-int netdev_send(struct netdev *, const struct ofpbuf *);
+int netdev_send(struct netdev *, struct ofpbuf *, bool may_steal);
 void netdev_send_wait(struct netdev *);
 
 /* Hardware address. */