[ovs-dev] [async-msgs 11/13] ovs-ofctl: New "ofctl/barrier" unixctl command.

Ben Pfaff blp at nicira.com
Thu Jan 26 23:53:49 UTC 2012


This will be useful in upcoming unit tests for ensuring that all
asynchronous messages due to previous actions have arrived.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 utilities/ovs-ofctl.8.in |    5 +++++
 utilities/ovs-ofctl.c    |   42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index afde46c..f8c1957 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1147,6 +1147,11 @@ Sends each \fIofmsg\fR, specified as a sequence of hex digits that
 express an OpenFlow message, on the OpenFlow connection.  This command
 is useful only when executing the \fBmonitor\fR command.
 .
+.IP "\fBofctl/barrier\fR"
+Sends an OpenFlow barrier request on the OpenFlow connection and waits
+for a reply.  This command is useful only for the \fBmonitor\fR
+command.
+.
 .SH EXAMPLES
 .
 The following examples assume that \fBovs\-vswitchd\fR has a bridge
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 4995354..17d367c 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -901,6 +901,37 @@ ofctl_send(struct unixctl_conn *conn, int argc,
     ds_destroy(&reply);
 }
 
+struct barrier_aux {
+    struct vconn *vconn;        /* OpenFlow connection for sending barrier. */
+    struct unixctl_conn *conn;  /* Connection waiting for barrier response. */
+};
+
+static void
+ofctl_barrier(struct unixctl_conn *conn, int argc OVS_UNUSED,
+              const char *argv[] OVS_UNUSED, void *aux_)
+{
+    struct barrier_aux *aux = aux_;
+    struct ofpbuf *msg;
+    int error;
+
+    if (aux->conn) {
+        unixctl_command_reply(conn, 501, "already waiting for barrier reply");
+        return;
+    }
+
+    msg = ofputil_encode_barrier_request();
+    fprintf(stderr, "send: ");
+    ofp_print(stderr, msg->data, msg->size, verbosity);
+
+    error = vconn_send_block(aux->vconn, msg);
+    if (error) {
+        ofpbuf_delete(msg);
+        unixctl_command_reply(conn, 501, strerror(error));
+    } else {
+        aux->conn = conn;
+    }
+}
+
 static void
 ofctl_set_output_file(struct unixctl_conn *conn, int argc OVS_UNUSED,
                       const char *argv[], void *aux OVS_UNUSED)
@@ -922,6 +953,7 @@ ofctl_set_output_file(struct unixctl_conn *conn, int argc OVS_UNUSED,
 static void
 monitor_vconn(struct vconn *vconn)
 {
+    struct barrier_aux barrier_aux = { vconn, NULL };
     struct unixctl_server *server;
     bool exiting = false;
     int error, fd;
@@ -956,6 +988,8 @@ monitor_vconn(struct vconn *vconn)
     unixctl_command_register("exit", "", 0, 0, ofctl_exit, &exiting);
     unixctl_command_register("ofctl/send", "OFMSG...", 1, INT_MAX,
                              ofctl_send, vconn);
+    unixctl_command_register("ofctl/barrier", "", 0, 0,
+                             ofctl_barrier, &barrier_aux);
     unixctl_command_register("ofctl/set-output-file", "FILE", 1, 1,
                              ofctl_set_output_file, NULL);
     daemonize_complete();
@@ -970,14 +1004,22 @@ monitor_vconn(struct vconn *vconn)
         unixctl_server_run(server);
 
         for (;;) {
+            uint8_t msg_type;
+
             retval = vconn_recv(vconn, &b);
             if (retval == EAGAIN) {
                 break;
             }
+            msg_type = ((const struct ofp_header *) b->data)->type;
 
             run(retval, "vconn_recv");
             ofp_print(stderr, b->data, b->size, verbosity + 2);
             ofpbuf_delete(b);
+
+            if (barrier_aux.conn && msg_type == OFPT_BARRIER_REPLY) {
+                unixctl_command_reply(barrier_aux.conn, 200, "");
+                barrier_aux.conn = NULL;
+            }
         }
 
         if (exiting) {
-- 
1.7.2.5




More information about the dev mailing list