[ovs-dev] [PATCH 02/17] vconn: Allow passing a maximum Open Flow version

Simon Horman horms at verge.net.au
Thu Oct 4 02:41:17 UTC 2012


Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/rconn.c                |    3 ++-
 lib/vconn-provider.h       |    1 +
 lib/vconn.c                |   35 ++++++++++++++++++++---------------
 lib/vconn.h                |    9 +++++----
 ofproto/connmgr.c          |    6 ++++--
 tests/test-vconn.c         |   16 ++++++++--------
 utilities/ovs-controller.c |    6 ++++--
 utilities/ovs-ofctl.c      |    4 ++--
 8 files changed, 46 insertions(+), 34 deletions(-)

diff --git a/lib/rconn.c b/lib/rconn.c
index ddf578c..3db3c21 100644
--- a/lib/rconn.c
+++ b/lib/rconn.c
@@ -354,7 +354,8 @@ reconnect(struct rconn *rc)
         VLOG_INFO("%s: connecting...", rc->name);
     }
     rc->n_attempted_connections++;
-    retval = vconn_open(rc->target, OFP10_VERSION, &rc->vconn, rc->dscp);
+    retval = vconn_open(rc->target, OFP10_VERSION, OFP10_VERSION,
+                        &rc->vconn, rc->dscp);
     if (!retval) {
         rc->remote_ip = vconn_get_remote_ip(rc->vconn);
         rc->local_ip = vconn_get_local_ip(rc->vconn);
diff --git a/lib/vconn-provider.h b/lib/vconn-provider.h
index 54ec2e6..fa9e1ed 100644
--- a/lib/vconn-provider.h
+++ b/lib/vconn-provider.h
@@ -34,6 +34,7 @@ struct vconn {
     int state;
     int error;
     enum ofp_version min_version;
+    enum ofp_version max_version;
     enum ofp_version version;
     ovs_be32 remote_ip;
     ovs_be16 remote_port;
diff --git a/lib/vconn.c b/lib/vconn.c
index 9271f4f..4d052c0 100644
--- a/lib/vconn.c
+++ b/lib/vconn.c
@@ -215,14 +215,14 @@ vconn_verify_name(const char *name)
  *
  * The vconn will automatically negotiate an OpenFlow protocol version
  * acceptable to both peers on the connection.  The version negotiated will be
- * no lower than 'min_version' and no higher than OFP10_VERSION.
+ * no lower than 'min_version' and no higher than 'max_version'.
  *
  * Returns 0 if successful, otherwise a positive errno value.  If successful,
  * stores a pointer to the new connection in '*vconnp', otherwise a null
  * pointer.  */
 int
-vconn_open(const char *name, int min_version, struct vconn **vconnp,
-           uint8_t dscp)
+vconn_open(const char *name, enum ofp_version min_version,
+           enum ofp_version max_version, struct vconn **vconnp, uint8_t dscp)
 {
     struct vconn_class *class;
     struct vconn *vconn;
@@ -249,6 +249,7 @@ vconn_open(const char *name, int min_version, struct vconn **vconnp,
     /* Success. */
     assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
     vconn->min_version = min_version;
+    vconn->max_version = max_version;
     *vconnp = vconn;
     return 0;
 
@@ -291,14 +292,14 @@ vconn_run_wait(struct vconn *vconn)
 
 int
 vconn_open_block(const char *name, enum ofp_version min_version,
-                 struct vconn **vconnp)
+                 enum ofp_version max_version, struct vconn **vconnp)
 {
     struct vconn *vconn;
     int error;
 
     fatal_signal_run();
 
-    error = vconn_open(name, min_version, &vconn, DSCP_DEFAULT);
+    error = vconn_open(name, min_version, max_version, &vconn, DSCP_DEFAULT);
     if (!error) {
         error = vconn_connect_block(vconn);
     }
@@ -388,12 +389,12 @@ vcs_connecting(struct vconn *vconn)
 }
 
 static void
-vcs_send_hello(struct vconn *vconn)
+vcs_send_hello(struct vconn *vconn, enum ofp_version max_version)
 {
     struct ofpbuf *b;
     int retval;
 
-    b = ofpraw_alloc(OFPRAW_OFPT_HELLO, OFP10_VERSION, 0);
+    b = ofpraw_alloc(OFPRAW_OFPT_HELLO, max_version, 0);
     retval = do_send(vconn, b);
     if (!retval) {
         vconn->state = VCS_RECV_HELLO;
@@ -428,13 +429,13 @@ vcs_recv_hello(struct vconn *vconn)
                 ds_destroy(&msg);
             }
 
-            vconn->version = MIN(OFP10_VERSION, oh->version);
+            vconn->version = MIN(vconn->max_version, oh->version);
             if (vconn->version < vconn->min_version) {
                 VLOG_WARN_RL(&bad_ofmsg_rl,
                              "%s: version negotiation failed: we support "
                              "versions 0x%02x to 0x%02x inclusive but peer "
                              "supports no later than version 0x%02"PRIx8,
-                             vconn->name, vconn->min_version, OFP10_VERSION,
+                             vconn->name, vconn->min_version, vconn->max_version,
                              oh->version);
                 vconn->state = VCS_SEND_ERROR;
             } else {
@@ -442,7 +443,7 @@ vcs_recv_hello(struct vconn *vconn)
                          "(we support versions 0x%02x to 0x%02x inclusive, "
                          "peer no later than version 0x%02"PRIx8")",
                          vconn->name, vconn->version, vconn->min_version,
-                         OFP10_VERSION, oh->version);
+                         vconn->max_version, oh->version);
                 vconn->state = VCS_CONNECTED;
             }
             ofpbuf_delete(b);
@@ -473,7 +474,7 @@ 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, OFP12_VERSION, vconn->version);
+             vconn->min_version, vconn->max_version, vconn->version);
     b = ofperr_encode_hello(OFPERR_OFPHFC_INCOMPATIBLE, vconn->version, s);
     retval = do_send(vconn, b);
     if (retval) {
@@ -494,7 +495,8 @@ vconn_connect(struct vconn *vconn)
 {
     enum vconn_state last_state;
 
-    assert(vconn->min_version > 0);
+    assert(vconn->min_version > 0 &&
+           vconn->max_version >= vconn->min_version);
     do {
         last_state = vconn->state;
         switch (vconn->state) {
@@ -503,7 +505,7 @@ vconn_connect(struct vconn *vconn)
             break;
 
         case VCS_SEND_HELLO:
-            vcs_send_hello(vconn);
+            vcs_send_hello(vconn, vconn->max_version);
             break;
 
         case VCS_RECV_HELLO:
@@ -982,12 +984,13 @@ pvconn_close(struct pvconn *pvconn)
  *
  * The new vconn will automatically negotiate an OpenFlow protocol version
  * acceptable to both peers on the connection.  The version negotiated will be
- * no lower than 'min_version' and no higher than OFP10_VERSION.
+ * no lower than 'min_version' and no higher than 'max_version'.
  *
  * pvconn_accept() will not block waiting for a connection.  If no connection
  * is ready to be accepted, it returns EAGAIN immediately. */
 int
-pvconn_accept(struct pvconn *pvconn, int min_version, struct vconn **new_vconn)
+pvconn_accept(struct pvconn *pvconn, enum ofp_version min_version,
+              enum ofp_version max_version, struct vconn **new_vconn)
 {
     int retval = (pvconn->class->accept)(pvconn, new_vconn);
     if (retval) {
@@ -996,6 +999,7 @@ pvconn_accept(struct pvconn *pvconn, int min_version, struct vconn **new_vconn)
         assert((*new_vconn)->state != VCS_CONNECTING
                || (*new_vconn)->class->connect);
         (*new_vconn)->min_version = min_version;
+        (*new_vconn)->max_version = max_version;
     }
     return retval;
 }
@@ -1034,6 +1038,7 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status,
     vconn->error = connect_status;
     vconn->version = 0;
     vconn->min_version = 0;
+    vconn->max_version = 0;
     vconn->remote_ip = 0;
     vconn->remote_port = 0;
     vconn->local_ip = 0;
diff --git a/lib/vconn.h b/lib/vconn.h
index 1a0bc60..91d8118 100644
--- a/lib/vconn.h
+++ b/lib/vconn.h
@@ -34,8 +34,8 @@ void vconn_usage(bool active, bool passive, bool bootstrap);
 
 /* Active vconns: virtual connections to OpenFlow devices. */
 int vconn_verify_name(const char *name);
-int vconn_open(const char *name, int min_version,
-               struct vconn **, uint8_t dscp);
+int vconn_open(const char *name, enum ofp_version min_version,
+               enum ofp_version max_version, struct vconn **, uint8_t dscp);
 void vconn_close(struct vconn *);
 const char *vconn_get_name(const struct vconn *);
 ovs_be32 vconn_get_remote_ip(const struct vconn *);
@@ -56,7 +56,7 @@ void vconn_run(struct vconn *);
 void vconn_run_wait(struct vconn *);
 
 int vconn_open_block(const char *name, enum ofp_version min_version,
-                     struct vconn **);
+                     enum ofp_version max_version, struct vconn **);
 int vconn_connect_block(struct vconn *);
 int vconn_send_block(struct vconn *, struct ofpbuf *);
 int vconn_recv_block(struct vconn *, struct ofpbuf **);
@@ -76,7 +76,8 @@ int pvconn_verify_name(const char *name);
 int pvconn_open(const char *name, struct pvconn **, uint8_t dscp);
 const char *pvconn_get_name(const struct pvconn *);
 void pvconn_close(struct pvconn *);
-int pvconn_accept(struct pvconn *, int min_version, struct vconn **);
+int pvconn_accept(struct pvconn *, enum ofp_version min_version,
+                  enum ofp_version max_version, struct vconn **);
 void pvconn_wait(struct pvconn *);
 
 #ifdef __cplusplus
diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index 05e69c7..920d6ce 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -289,7 +289,8 @@ connmgr_run(struct connmgr *mgr,
         struct vconn *vconn;
         int retval;
 
-        retval = pvconn_accept(ofservice->pvconn, OFP10_VERSION, &vconn);
+        retval = pvconn_accept(ofservice->pvconn, OFP10_VERSION,
+                               OFP10_VERSION, &vconn);
         if (!retval) {
             struct rconn *rconn;
             char *name;
@@ -313,7 +314,8 @@ connmgr_run(struct connmgr *mgr,
         struct vconn *vconn;
         int retval;
 
-        retval = pvconn_accept(mgr->snoops[i], OFP10_VERSION, &vconn);
+        retval = pvconn_accept(mgr->snoops[i], OFP10_VERSION, OFP10_VERSION,
+                               &vconn);
         if (!retval) {
             add_snooper(mgr, vconn);
         } else if (retval != EAGAIN) {
diff --git a/tests/test-vconn.c b/tests/test-vconn.c
index 5dd38f0..589e85e 100644
--- a/tests/test-vconn.c
+++ b/tests/test-vconn.c
@@ -148,8 +148,8 @@ test_refuse_connection(int argc OVS_UNUSED, char *argv[])
     int error;
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
-                           DSCP_DEFAULT), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, OFP10_VERSION,
+                           &vconn, DSCP_DEFAULT), 0);
     fpv_close(&fpv);
     vconn_run(vconn);
 
@@ -179,8 +179,8 @@ test_accept_then_close(int argc OVS_UNUSED, char *argv[])
     int error;
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
-                           DSCP_DEFAULT), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, OFP10_VERSION,
+                           &vconn, DSCP_DEFAULT), 0);
     vconn_run(vconn);
     stream_close(fpv_accept(&fpv));
     fpv_close(&fpv);
@@ -212,8 +212,8 @@ test_read_hello(int argc OVS_UNUSED, char *argv[])
     int error;
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
-                           DSCP_DEFAULT), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, OFP10_VERSION,
+                           &vconn, DSCP_DEFAULT), 0);
     vconn_run(vconn);
     stream = fpv_accept(&fpv);
     fpv_destroy(&fpv);
@@ -266,8 +266,8 @@ test_send_hello(const char *type, const void *out, size_t out_size,
     size_t n_sent;
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
-                           DSCP_DEFAULT), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, OFP10_VERSION,
+                           &vconn, DSCP_DEFAULT), 0);
     vconn_run(vconn);
     stream = fpv_accept(&fpv);
     fpv_destroy(&fpv);
diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c
index 07e300b..9171445 100644
--- a/utilities/ovs-controller.c
+++ b/utilities/ovs-controller.c
@@ -114,7 +114,8 @@ main(int argc, char *argv[])
         const char *name = argv[i];
         struct vconn *vconn;
 
-        retval = vconn_open(name, OFP10_VERSION, &vconn, DSCP_DEFAULT);
+        retval = vconn_open(name, OFP10_VERSION, OFP10_VERSION,
+                            &vconn, DSCP_DEFAULT);
         if (!retval) {
             if (n_switches >= MAX_SWITCHES) {
                 ovs_fatal(0, "max %d switch connections", n_switches);
@@ -153,7 +154,8 @@ main(int argc, char *argv[])
         for (i = 0; i < n_listeners && n_switches < MAX_SWITCHES; ) {
             struct vconn *new_vconn;
 
-            retval = pvconn_accept(listeners[i], OFP10_VERSION, &new_vconn);
+            retval = pvconn_accept(listeners[i], OFP10_VERSION,
+                                   OFP10_VERSION, &new_vconn);
             if (!retval || retval == EAGAIN) {
                 if (!retval) {
                     new_switch(&switches[n_switches++], new_vconn);
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 39aed86..40e8139 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -336,7 +336,7 @@ open_vconn_socket(const char *name, struct vconn **vconnp)
 {
     char *vconn_name = xasprintf("unix:%s", name);
     VLOG_DBG("connecting to %s", vconn_name);
-    run(vconn_open_block(vconn_name, OFP10_VERSION, vconnp),
+    run(vconn_open_block(vconn_name, OFP10_VERSION, OFP10_VERSION, vconnp),
         "connecting to %s", vconn_name);
     free(vconn_name);
 }
@@ -360,7 +360,7 @@ open_vconn__(const char *name, const char *default_suffix,
     free(datapath_type);
 
     if (strchr(name, ':')) {
-        run(vconn_open_block(name, OFP10_VERSION, vconnp),
+        run(vconn_open_block(name, OFP10_VERSION, OFP10_VERSION, vconnp),
             "connecting to %s", name);
     } else if (!stat(name, &s) && S_ISSOCK(s.st_mode)) {
         open_vconn_socket(name, vconnp);
-- 
1.7.10.4




More information about the dev mailing list