vconn: Properly line up description for "tcp:" and "ssl:" usage.
[sliver-openvswitch.git] / lib / vconn.c
index caa1bcc..9271f4f 100644 (file)
@@ -138,10 +138,10 @@ vconn_usage(bool active, bool passive, bool bootstrap OVS_UNUSED)
     printf("\n");
     if (active) {
         printf("Active OpenFlow connection methods:\n");
-        printf("  tcp:IP[:PORT]         "
+        printf("  tcp:IP[:PORT]           "
                "PORT (default: %d) at remote IP\n", OFP_TCP_PORT);
 #ifdef HAVE_OPENSSL
-        printf("  ssl:IP[:PORT]         "
+        printf("  ssl:IP[:PORT]           "
                "SSL PORT (default: %d) at remote IP\n", OFP_SSL_PORT);
 #endif
         printf("  unix:FILE               Unix domain socket named FILE\n");
@@ -262,6 +262,12 @@ error:
 void
 vconn_run(struct vconn *vconn)
 {
+    if (vconn->state == VCS_CONNECTING ||
+        vconn->state == VCS_SEND_HELLO ||
+        vconn->state == VCS_RECV_HELLO) {
+        vconn_connect(vconn);
+    }
+
     if (vconn->class->run) {
         (vconn->class->run)(vconn);
     }
@@ -272,6 +278,12 @@ vconn_run(struct vconn *vconn)
 void
 vconn_run_wait(struct vconn *vconn)
 {
+    if (vconn->state == VCS_CONNECTING ||
+        vconn->state == VCS_SEND_HELLO ||
+        vconn->state == VCS_RECV_HELLO) {
+        vconn_connect_wait(vconn);
+    }
+
     if (vconn->class->run_wait) {
         (vconn->class->run_wait)(vconn);
     }
@@ -288,13 +300,7 @@ vconn_open_block(const char *name, enum ofp_version min_version,
 
     error = vconn_open(name, min_version, &vconn, DSCP_DEFAULT);
     if (!error) {
-        while ((error = vconn_connect(vconn)) == EAGAIN) {
-            vconn_run(vconn);
-            vconn_run_wait(vconn);
-            vconn_connect_wait(vconn);
-            poll_block();
-        }
-        assert(error != EINPROGRESS);
+        error = vconn_connect_block(vconn);
     }
 
     if (error) {
@@ -362,10 +368,10 @@ vconn_get_local_port(const struct vconn *vconn)
  *
  * A vconn that has successfully connected (that is, vconn_connect() or
  * vconn_send() or vconn_recv() has returned 0) always negotiated a version. */
-enum ofp_version
+int
 vconn_get_version(const struct vconn *vconn)
 {
-    return vconn->version;
+    return vconn->version ? vconn->version : -1;
 }
 
 static void
@@ -467,9 +473,8 @@ vcs_send_error(struct vconn *vconn)
 
     snprintf(s, sizeof s, "We support versions 0x%02x to 0x%02x inclusive but "
              "you support no later than version 0x%02"PRIx8".",
-             vconn->min_version, OFP10_VERSION, vconn->version);
-    b = ofperr_encode_hello(OFPERR_OFPHFC_INCOMPATIBLE,
-                            ofperr_domain_from_version(vconn->version), s);
+             vconn->min_version, OFP12_VERSION, vconn->version);
+    b = ofperr_encode_hello(OFPERR_OFPHFC_INCOMPATIBLE, vconn->version, s);
     retval = do_send(vconn, b);
     if (retval) {
         ofpbuf_delete(b);
@@ -622,6 +627,24 @@ do_send(struct vconn *vconn, struct ofpbuf *msg)
     return retval;
 }
 
+/* Same as vconn_connect(), except that it waits until the connection on
+ * 'vconn' completes or fails.  Thus, it will never return EAGAIN. */
+int
+vconn_connect_block(struct vconn *vconn)
+{
+    int error;
+
+    while ((error = vconn_connect(vconn)) == EAGAIN) {
+        vconn_run(vconn);
+        vconn_run_wait(vconn);
+        vconn_connect_wait(vconn);
+        poll_block();
+    }
+    assert(error != EINPROGRESS);
+
+    return error;
+}
+
 /* Same as vconn_send, except that it waits until 'msg' can be transmitted. */
 int
 vconn_send_block(struct vconn *vconn, struct ofpbuf *msg)
@@ -744,7 +767,7 @@ vconn_transact_noreply(struct vconn *vconn, struct ofpbuf *request,
     }
 
     /* Send barrier. */
-    barrier = ofputil_encode_barrier_request();
+    barrier = ofputil_encode_barrier_request(vconn_get_version(vconn));
     barrier_xid = ((struct ofp_header *) barrier->data)->xid;
     error = vconn_send_block(vconn, barrier);
     if (error) {