[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