ofproto: Do not update stats on fake bond interface.
[cascardo/ovs.git] / lib / netdev-dummy.c
index b087ed1..ca04812 100644 (file)
@@ -29,6 +29,7 @@
 #include "odp-util.h"
 #include "ofp-print.h"
 #include "ofpbuf.h"
+#include "packet-dpif.h"
 #include "packets.h"
 #include "pcap-file.h"
 #include "poll-loop.h"
@@ -624,11 +625,11 @@ netdev_dummy_alloc(void)
 static int
 netdev_dummy_construct(struct netdev *netdev_)
 {
-    static atomic_uint next_n = ATOMIC_VAR_INIT(0xaa550000);
+    static atomic_count next_n = ATOMIC_COUNT_INIT(0xaa550000);
     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
     unsigned int n;
 
-    atomic_add(&next_n, 1, &n);
+    n = atomic_count_inc(&next_n);
 
     ovs_mutex_init(&netdev->mutex);
     ovs_mutex_lock(&netdev->mutex);
@@ -779,7 +780,8 @@ netdev_dummy_rxq_dealloc(struct netdev_rxq *rxq_)
 }
 
 static int
-netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct ofpbuf **arr, int *c)
+netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct dpif_packet **arr,
+                      int *c)
 {
     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
@@ -803,7 +805,11 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct ofpbuf **arr, int *c)
     ovs_mutex_unlock(&netdev->mutex);
 
     dp_packet_pad(packet);
-    arr[0] = packet;
+
+    /* This performs a (sometimes unnecessary) copy */
+    arr[0] = dpif_packet_clone_from_ofpbuf(packet);
+    dpif_packet_set_dp_hash(arr[0], 0);
+    ofpbuf_delete(packet);
     *c = 1;
     return 0;
 }
@@ -841,50 +847,61 @@ netdev_dummy_rxq_drain(struct netdev_rxq *rxq_)
 }
 
 static int
-netdev_dummy_send(struct netdev *netdev, struct ofpbuf *pkt, bool may_steal)
+netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED,
+                  struct dpif_packet **pkts, int cnt, bool may_steal)
 {
     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
-    const void *buffer = ofpbuf_data(pkt);
-    size_t size = ofpbuf_size(pkt);
+    int error = 0;
+    int i;
 
-    if (size < ETH_HEADER_LEN) {
-        return EMSGSIZE;
-    } else {
-        const struct eth_header *eth = buffer;
-        int max_size;
+    for (i = 0; i < cnt; i++) {
+        const void *buffer = ofpbuf_data(&pkts[i]->ofpbuf);
+        size_t size = ofpbuf_size(&pkts[i]->ofpbuf);
 
-        ovs_mutex_lock(&dev->mutex);
-        max_size = dev->mtu + ETH_HEADER_LEN;
-        ovs_mutex_unlock(&dev->mutex);
+        if (size < ETH_HEADER_LEN) {
+            error = EMSGSIZE;
+            break;
+        } else {
+            const struct eth_header *eth = buffer;
+            int max_size;
 
-        if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
-            max_size += VLAN_HEADER_LEN;
-        }
-        if (size > max_size) {
-            return EMSGSIZE;
+            ovs_mutex_lock(&dev->mutex);
+            max_size = dev->mtu + ETH_HEADER_LEN;
+            ovs_mutex_unlock(&dev->mutex);
+
+            if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
+                max_size += VLAN_HEADER_LEN;
+            }
+            if (size > max_size) {
+                error = EMSGSIZE;
+                break;
+            }
         }
-    }
 
-    ovs_mutex_lock(&dev->mutex);
-    dev->stats.tx_packets++;
-    dev->stats.tx_bytes += size;
+        ovs_mutex_lock(&dev->mutex);
+        dev->stats.tx_packets++;
+        dev->stats.tx_bytes += size;
 
-    dummy_packet_conn_send(&dev->conn, buffer, size);
+        dummy_packet_conn_send(&dev->conn, buffer, size);
 
-    if (dev->tx_pcap) {
-        struct ofpbuf packet;
+        if (dev->tx_pcap) {
+            struct ofpbuf packet;
 
-        ofpbuf_use_const(&packet, buffer, size);
-        ovs_pcap_write(dev->tx_pcap, &packet);
-        fflush(dev->tx_pcap);
+            ofpbuf_use_const(&packet, buffer, size);
+            ovs_pcap_write(dev->tx_pcap, &packet);
+            fflush(dev->tx_pcap);
+        }
+
+        ovs_mutex_unlock(&dev->mutex);
     }
 
-    ovs_mutex_unlock(&dev->mutex);
     if (may_steal) {
-        ofpbuf_delete(pkt);
+        for (i = 0; i < cnt; i++) {
+            dpif_packet_delete(pkts[i]);
+        }
     }
 
-    return 0;
+    return error;
 }
 
 static int
@@ -952,18 +969,6 @@ netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
     return 0;
 }
 
-static int
-netdev_dummy_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
-{
-    struct netdev_dummy *dev = netdev_dummy_cast(netdev);
-
-    ovs_mutex_lock(&dev->mutex);
-    dev->stats = *stats;
-    ovs_mutex_unlock(&dev->mutex);
-
-    return 0;
-}
-
 static int
 netdev_dummy_get_ifindex(const struct netdev *netdev)
 {
@@ -1027,6 +1032,7 @@ static const struct netdev_class dummy_class = {
     netdev_dummy_get_config,
     netdev_dummy_set_config,
     NULL,                       /* get_tunnel_config */
+    NULL,                       /* get_numa_id */
 
     netdev_dummy_send,          /* send */
     NULL,                       /* send_wait */
@@ -1040,7 +1046,6 @@ static const struct netdev_class dummy_class = {
     NULL,                       /* get_carrier_resets */
     NULL,                       /* get_miimon */
     netdev_dummy_get_stats,
-    netdev_dummy_set_stats,
 
     NULL,                       /* get_features */
     NULL,                       /* set_advertisements */
@@ -1311,7 +1316,7 @@ netdev_dummy_conn_state(struct unixctl_conn *conn, int argc,
 void
 netdev_dummy_register(bool override)
 {
-    unixctl_command_register("netdev-dummy/receive", "NAME PACKET|FLOW...",
+    unixctl_command_register("netdev-dummy/receive", "name packet|flow...",
                              2, INT_MAX, netdev_dummy_receive, NULL);
     unixctl_command_register("netdev-dummy/set-admin-state",
                              "[netdev] up|down", 1, 2,