netdev: Extend rx_recv to pass multiple packets.
[sliver-openvswitch.git] / lib / netdev-dummy.c
index 0f93363..ecd7317 100644 (file)
@@ -21,6 +21,7 @@
 #include <errno.h>
 
 #include "connectivity.h"
+#include "dpif-netdev.h"
 #include "flow.h"
 #include "list.h"
 #include "netdev-provider.h"
@@ -198,6 +199,7 @@ dummy_packet_stream_run(struct netdev_dummy *dev, struct dummy_packet_stream *s)
 
         txbuf = ofpbuf_from_list(list_front(&s->txq));
         retval = stream_send(s->stream, txbuf->data, txbuf->size);
+
         if (retval > 0) {
             ofpbuf_pull(txbuf, retval);
             if (!txbuf->size) {
@@ -229,6 +231,7 @@ dummy_packet_stream_run(struct netdev_dummy *dev, struct dummy_packet_stream *s)
 
         ofpbuf_prealloc_tailroom(&s->rxbuf, n);
         retval = stream_recv(s->stream, ofpbuf_tail(&s->rxbuf), n);
+
         if (retval > 0) {
             s->rxbuf.size += retval;
             if (retval == n && s->rxbuf.size > 2) {
@@ -367,25 +370,27 @@ dummy_packet_conn_set_config(struct dummy_packet_conn *conn,
         reconnect_set_name(reconnect, stream);
         reconnect_set_passive(reconnect, false, time_msec());
         reconnect_enable(reconnect, time_msec());
-        reconnect_set_backoff(reconnect, 1000, INT_MAX);
+        reconnect_set_backoff(reconnect, 100, INT_MAX);
+        reconnect_set_probe_interval(reconnect, 0);
         conn->u.rconn.reconnect = reconnect;
+        conn->type = ACTIVE;
 
         error = stream_open(stream, &active_stream, DSCP_DEFAULT);
         conn->u.rconn.rstream = dummy_packet_stream_create(active_stream);
 
         switch (error) {
         case 0:
-            reconnect_connected(conn->u.rconn.reconnect, time_msec());
-            conn->type = ACTIVE;
+            reconnect_connected(reconnect, time_msec());
             break;
 
         case EAGAIN:
-            reconnect_connecting(conn->u.rconn.reconnect, time_msec());
+            reconnect_connecting(reconnect, time_msec());
             break;
 
         default:
-            reconnect_connecting(conn->u.rconn.reconnect, time_msec());
+            reconnect_connect_failed(reconnect, time_msec(), error);
             stream_close(active_stream);
+            conn->u.rconn.rstream->stream = NULL;
             break;
         }
     }
@@ -440,22 +445,29 @@ OVS_REQUIRES(dev->mutex)
     switch (reconnect_run(rconn->reconnect, time_msec())) {
     case RECONNECT_CONNECT:
         {
-            int err = stream_connect(rconn->rstream->stream);
+            int error;
+
+            if (rconn->rstream->stream) {
+                error = stream_connect(rconn->rstream->stream);
+            } else {
+                error = stream_open(reconnect_get_name(rconn->reconnect),
+                                    &rconn->rstream->stream, DSCP_DEFAULT);
+            }
 
-            switch (err) {
-            case 0: /* Connected. */
+            switch (error) {
+            case 0:
                 reconnect_connected(rconn->reconnect, time_msec());
-                dev->conn.type = ACTIVE;
                 break;
 
             case EAGAIN:
                 reconnect_connecting(rconn->reconnect, time_msec());
-                return;
+                break;
 
             default:
-                reconnect_connect_failed(rconn->reconnect, time_msec(), err);
+                reconnect_connect_failed(rconn->reconnect, time_msec(), error);
                 stream_close(rconn->rstream->stream);
-                return;
+                rconn->rstream->stream = NULL;
+                break;
             }
         }
         break;
@@ -474,6 +486,7 @@ OVS_REQUIRES(dev->mutex)
         if (err) {
             reconnect_disconnected(rconn->reconnect, time_msec(), err);
             stream_close(rconn->rstream->stream);
+            rconn->rstream->stream = NULL;
         }
     }
 }
@@ -510,7 +523,9 @@ dummy_packet_conn_wait(struct dummy_packet_conn *conn)
         }
         break;
     case ACTIVE:
-        dummy_packet_stream_wait(conn->u.rconn.rstream);
+        if (reconnect_is_connected(conn->u.rconn.reconnect)) {
+            dummy_packet_stream_wait(conn->u.rconn.rstream);
+        }
         break;
 
     case NONE:
@@ -536,8 +551,10 @@ dummy_packet_conn_send(struct dummy_packet_conn *conn,
         break;
 
     case ACTIVE:
-        dummy_packet_stream_send(conn->u.rconn.rstream, buffer, size);
-        dummy_packet_stream_wait(conn->u.rconn.rstream);
+        if (reconnect_is_connected(conn->u.rconn.reconnect)) {
+            dummy_packet_stream_send(conn->u.rconn.rstream, buffer, size);
+            dummy_packet_stream_wait(conn->u.rconn.rstream);
+        }
         break;
 
     case NONE:
@@ -739,12 +756,11 @@ netdev_dummy_rx_dealloc(struct netdev_rx *rx_)
 }
 
 static int
-netdev_dummy_rx_recv(struct netdev_rx *rx_, struct ofpbuf *buffer)
+netdev_dummy_rx_recv(struct netdev_rx *rx_, struct ofpbuf **arr, int *c)
 {
     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
     struct ofpbuf *packet;
-    int retval;
 
     ovs_mutex_lock(&netdev->mutex);
     if (!list_is_empty(&rx->recv_queue)) {
@@ -758,22 +774,15 @@ netdev_dummy_rx_recv(struct netdev_rx *rx_, struct ofpbuf *buffer)
     if (!packet) {
         return EAGAIN;
     }
+    ovs_mutex_lock(&netdev->mutex);
+    netdev->stats.rx_packets++;
+    netdev->stats.rx_bytes += packet->size;
+    ovs_mutex_unlock(&netdev->mutex);
 
-    if (packet->size <= ofpbuf_tailroom(buffer)) {
-        memcpy(buffer->data, packet->data, packet->size);
-        buffer->size += packet->size;
-        retval = 0;
-
-        ovs_mutex_lock(&netdev->mutex);
-        netdev->stats.rx_packets++;
-        netdev->stats.rx_bytes += packet->size;
-        ovs_mutex_unlock(&netdev->mutex);
-    } else {
-        retval = EMSGSIZE;
-    }
-    ofpbuf_delete(packet);
-
-    return retval;
+    dp_packet_pad(packet);
+    arr[0] = packet;
+    *c = 1;
+    return 0;
 }
 
 static void