secchan: Purge buffered packets on startup.
authorBen Pfaff <blp@nicira.com>
Tue, 10 Mar 2009 17:41:30 +0000 (10:41 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 10 Mar 2009 21:00:35 +0000 (14:00 -0700)
This keeps packets that can be minutes old from getting forwarded.

datapath/datapath.c
include/openflow/datapath-protocol.h
lib/dpif.c
lib/dpif.h
secchan/ofproto.c

index 10a76786de0d6cf14e571b7cb4ae95aeb9c2a188..e222162fe96933ee1e0b3c7683ced16efaeb5814 100644 (file)
@@ -1131,6 +1131,8 @@ get_dp_stats(struct datapath *dp, struct odp_stats __user *statsp)
                stats.n_missed += s->n_missed;
                stats.n_lost += s->n_lost;
        }
+       stats.max_miss_queue = DP_MAX_QUEUE_LEN;
+       stats.max_action_queue = DP_MAX_QUEUE_LEN;
        return copy_to_user(statsp, &stats, sizeof stats);
 }
 
index ec3d72520dee4b8f5b8c254c727533c8af5f7dad..c65293cd8cd846956f8b48d16ba893de416ca7ee 100644 (file)
@@ -92,7 +92,11 @@ struct odp_stats {
     __u64 n_frags;               /* Number of dropped IP fragments. */
     __u64 n_hit;                 /* Number of flow table matches. */
     __u64 n_missed;              /* Number of flow table misses. */
-    __u64 n_lost;               /* Number of misses not sent to userspace. */
+    __u64 n_lost;                /* Number of misses not sent to userspace. */
+
+    /* Queues. */
+    __u16 max_miss_queue;       /* Max length of ODPL_MISS queue. */
+    __u16 max_action_queue;     /* Max length of ODPL_ACTION queue. */
 };
 
 /* Logical ports. */
index 9b89a9e2235f3af8c22f60bc03bcba63796232cf..c179fbda10ed00f1edd632baf03b841a61afa01d 100644 (file)
@@ -246,6 +246,29 @@ dpif_set_listen_mask(struct dpif *dpif, int listen_mask)
     return IOCTL(dpif, ODP_SET_LISTEN_MASK, &listen_mask);
 }
 
+int
+dpif_purge(struct dpif *dpif)
+{
+    struct odp_stats stats;
+    unsigned int i;
+    int error;
+
+    error = dpif_get_dp_stats(dpif, &stats);
+    if (error) {
+        return error;
+    }
+
+    for (i = 0; i < stats.max_miss_queue + stats.max_action_queue; i++) {
+        struct ofpbuf *buf;
+        error = dpif_recv(dpif, &buf);
+        if (error) {
+            return error == EAGAIN ? 0 : error;
+        }
+        ofpbuf_delete(buf);
+    }
+    return 0;
+}
+
 int
 dpif_port_add(struct dpif *dpif, const char *devname, uint16_t port_no)
 {
index f52b9acf6b24e04283dca1d39707f9aeb0301a69..070d28aa4d7c9e246f7154c972683772a0edb77e 100644 (file)
@@ -67,6 +67,7 @@ int dpif_set_drop_frags(struct dpif *, bool drop_frags);
 
 int dpif_get_listen_mask(const struct dpif *, int *listen_mask);
 int dpif_set_listen_mask(struct dpif *, int listen_mask);
+int dpif_purge(struct dpif *);
 
 int dpif_port_add(struct dpif *, const char *devname, uint16_t port_no);
 int dpif_port_del(struct dpif *, uint16_t port_no);
index bc99ea20394e11e86fbffdcea27932713d1257f0..36794ae6c7b0732e2d4fa1f28e6dd2947e7a2e9c 100644 (file)
@@ -223,6 +223,7 @@ ofproto_create(const char *datapath, const struct ofhooks *ofhooks, void *aux,
         return error;
     }
     dpif_flow_flush(&dpif);
+    dpif_purge(&dpif);
 
     /* Start monitoring datapath ports for status changes. */
     error = dpifmon_create(datapath, &dpifmon);