Replace minimum version with bitmap of allowed versions. This is in preparation for allowing the range of allowed OpenFlow versions to be configured.
Signed-off-by: Simon Horman <ho...@verge.net.au> --- lib/rconn.c | 5 ++- lib/vconn-provider.h | 26 ++++++----- lib/vconn-stream.c | 17 ++++--- lib/vconn.c | 107 ++++++++++++++++++++++++++++++++------------ lib/vconn.h | 14 ++++-- ofproto/connmgr.c | 10 ++++- tests/test-vconn.c | 24 ++++++---- utilities/ovs-controller.c | 8 +++- utilities/ovs-ofctl.c | 11 +++-- 9 files changed, 156 insertions(+), 66 deletions(-) diff --git a/lib/rconn.c b/lib/rconn.c index ddf578c..904e01f 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -349,12 +349,15 @@ static void reconnect(struct rconn *rc) { int retval; + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; if (rconn_logging_connection_attempts__(rc)) { VLOG_INFO("%s: connecting...", rc->name); } rc->n_attempted_connections++; - retval = vconn_open(rc->target, OFP10_VERSION, &rc->vconn, rc->dscp); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + retval = vconn_open(rc->target, &ovb, &rc->vconn, rc->dscp); + ofputil_version_bitmap_free_data(&ovb); 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 e9dd441..d4b20bf 100644 --- a/lib/vconn-provider.h +++ b/lib/vconn-provider.h @@ -23,6 +23,7 @@ #include <assert.h> #include "vconn.h" #include "openflow/openflow-common.h" +#include "lib/ofp-util.h" /* Active virtual connection to an OpenFlow device. */ @@ -33,7 +34,7 @@ struct vconn { struct vconn_class *class; int state; int error; - enum ofp_version min_version; + struct ofputil_version_bitmap allowed_versions; enum ofp_version version; ovs_be32 remote_ip; ovs_be16 remote_port; @@ -43,7 +44,9 @@ struct vconn { }; void vconn_init(struct vconn *, struct vconn_class *, int connect_status, - const char *name, enum ofp_version min_version); + const char *name, + const struct ofputil_version_bitmap *allowed_versions); +void vconn_free_data(struct vconn *vconn); void vconn_set_remote_ip(struct vconn *, ovs_be32 remote_ip); void vconn_set_remote_port(struct vconn *, ovs_be16 remote_port); void vconn_set_local_ip(struct vconn *, ovs_be32 local_ip); @@ -62,7 +65,7 @@ struct vconn_class { * connection name provided by the user, e.g. "tcp:1.2.3.4". This name is * useful for error messages but must not be modified. * - * 'min_version' is the minimum OpenFlow version that will be + * 'allowed_verions' is the OpenFlow versions that may be * negotiated for a connection. * * 'suffix' is a copy of 'name' following the colon and may be modified. @@ -76,8 +79,9 @@ struct vconn_class { * If the connection cannot be completed immediately, it should return * EAGAIN (not EINPROGRESS, as returned by the connect system call) and * continue the connection in the background. */ - int (*open)(const char *name, enum ofp_version min_version, char *suffix, - struct vconn **vconnp, uint8_t dscp); + int (*open)(const char *name, + const struct ofputil_version_bitmap *allowed_versions, + char *suffix, struct vconn **vconnp, uint8_t dscp); /* Closes 'vconn' and frees associated memory. */ void (*close)(struct vconn *vconn); @@ -138,11 +142,12 @@ struct vconn_class { struct pvconn { struct pvconn_class *class; char *name; - enum ofp_version min_version; + struct ofputil_version_bitmap allowed_versions; }; -void pvconn_init(struct pvconn *, struct pvconn_class *, const char *name, - enum ofp_version min_version); +void pvconn_init(struct pvconn *pvconn, struct pvconn_class *class, + const char *name, + const struct ofputil_version_bitmap *allowed_versions); static inline void pvconn_assert_class(const struct pvconn *pvconn, const struct pvconn_class *class) { @@ -157,7 +162,7 @@ struct pvconn_class { * full connection name provided by the user, e.g. "ptcp:1234". This name * is useful for error messages but must not be modified. * - * 'min_version' is the minimum OpenFlow protocol version that may + * 'allowed_versions' is the OpenFlow protocol versions that may * be negotiated for a session. * * 'suffix' is a copy of 'name' following the colon and may be modified. @@ -171,7 +176,8 @@ struct pvconn_class { * completed immediately, it should return EAGAIN (not EINPROGRESS, as * returned by the connect system call) and continue the connection in the * background. */ - int (*listen)(const char *name, enum ofp_version min_version, + int (*listen)(const char *name, + const struct ofputil_version_bitmap *allowed_versions, char *suffix, struct pvconn **pvconnp, uint8_t dscp); /* Closes 'pvconn' and frees associated memory. */ diff --git a/lib/vconn-stream.c b/lib/vconn-stream.c index 361fcb4..4b6539d 100644 --- a/lib/vconn-stream.c +++ b/lib/vconn-stream.c @@ -55,13 +55,13 @@ static void vconn_stream_clear_txbuf(struct vconn_stream *); static struct vconn * vconn_stream_new(struct stream *stream, int connect_status, - enum ofp_version min_version) + const struct ofputil_version_bitmap *allowed_versions) { struct vconn_stream *s; s = xmalloc(sizeof *s); vconn_init(&s->vconn, &stream_vconn_class, connect_status, - stream_get_name(stream), min_version); + stream_get_name(stream), allowed_versions); s->stream = stream; s->txbuf = NULL; s->rxbuf = NULL; @@ -78,7 +78,8 @@ vconn_stream_new(struct stream *stream, int connect_status, * * Returns 0 if successful, otherwise a positive errno value. */ static int -vconn_stream_open(const char *name, enum ofp_version min_version, +vconn_stream_open(const char *name, + const struct ofputil_version_bitmap *allowed_versions, char *suffix OVS_UNUSED, struct vconn **vconnp, uint8_t dscp) { struct stream *stream; @@ -89,7 +90,7 @@ vconn_stream_open(const char *name, enum ofp_version min_version, if (!error) { error = stream_connect(stream); if (!error || error == EAGAIN) { - *vconnp = vconn_stream_new(stream, error, min_version); + *vconnp = vconn_stream_new(stream, error, allowed_versions); return 0; } } @@ -117,6 +118,7 @@ vconn_stream_close(struct vconn *vconn) stream_close(s->stream); vconn_stream_clear_txbuf(s); ofpbuf_delete(s->rxbuf); + vconn_free_data(&s->vconn); free(s); } @@ -311,7 +313,8 @@ pvconn_pstream_cast(struct pvconn *pvconn) * Returns 0 if successful, otherwise a positive errno value. (The current * implementation never fails.) */ static int -pvconn_pstream_listen(const char *name, enum ofp_version min_version, +pvconn_pstream_listen(const char *name, + const struct ofputil_version_bitmap *allowed_versions, char *suffix OVS_UNUSED, struct pvconn **pvconnp, uint8_t dscp) { @@ -326,7 +329,7 @@ pvconn_pstream_listen(const char *name, enum ofp_version min_version, } ps = xmalloc(sizeof *ps); - pvconn_init(&ps->pvconn, &pstream_pvconn_class, name, min_version); + pvconn_init(&ps->pvconn, &pstream_pvconn_class, name, allowed_versions); ps->pstream = pstream; *pvconnp = &ps->pvconn; return 0; @@ -356,7 +359,7 @@ pvconn_pstream_accept(struct pvconn *pvconn, struct vconn **new_vconnp) return error; } - *new_vconnp = vconn_stream_new(stream, 0, pvconn->min_version); + *new_vconnp = vconn_stream_new(stream, 0, &pvconn->allowed_versions); return 0; } diff --git a/lib/vconn.c b/lib/vconn.c index 2dd4654..8603ad1 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -215,13 +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, enum ofp_version min_version, +vconn_open(const char *name, + const struct ofputil_version_bitmap *allowed_versions, struct vconn **vconnp, uint8_t dscp) { struct vconn_class *class; @@ -240,7 +241,7 @@ vconn_open(const char *name, enum ofp_version min_version, /* Call class's "open" function. */ suffix_copy = xstrdup(strchr(name, ':') + 1); - error = class->open(name, min_version, suffix_copy, &vconn, dscp); + error = class->open(name, allowed_versions, suffix_copy, &vconn, dscp); free(suffix_copy); if (error) { goto error; @@ -289,7 +290,8 @@ vconn_run_wait(struct vconn *vconn) } int -vconn_open_block(const char *name, enum ofp_version min_version, +vconn_open_block(const char *name, + const struct ofputil_version_bitmap *allowed_versions, struct vconn **vconnp) { struct vconn *vconn; @@ -297,7 +299,7 @@ vconn_open_block(const char *name, enum ofp_version min_version, fatal_signal_run(); - error = vconn_open(name, min_version, &vconn, DSCP_DEFAULT); + error = vconn_open(name, allowed_versions, &vconn, DSCP_DEFAULT); if (!error) { error = vconn_connect_block(vconn); } @@ -329,6 +331,14 @@ vconn_get_name(const struct vconn *vconn) return vconn->name; } +/* Returns the allowed_versions of 'vconn', that is, + * the allowed_versions passed to vconn_open(). */ +const struct ofputil_version_bitmap * +vconn_get_allowed_versions(const struct vconn *vconn) +{ + return &vconn->allowed_versions; +} + /* Returns the IP address of the peer, or 0 if the peer is not connected over * an IP-based protocol or if its IP address is not yet known. */ ovs_be32 @@ -387,12 +397,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; @@ -406,6 +416,24 @@ vcs_send_hello(struct vconn *vconn) } static void +format_versions(struct ds *msg, struct ofputil_version_bitmap *ovb) +{ + size_t n = ofputil_version_bitmap_count_set(ovb); + if (!n) { + ds_put_cstr(msg, "no versions"); + return; + } + + if (n == 1) { + ds_put_cstr(msg, "version "); + } else { + ds_put_cstr(msg, "versions "); + } + + ofputil_format_version_bitmap(msg, ovb); +} + +static void vcs_recv_hello(struct vconn *vconn) { struct ofpbuf *b; @@ -427,21 +455,26 @@ vcs_recv_hello(struct vconn *vconn) ds_destroy(&msg); } - vconn->version = MIN(OFP10_VERSION, oh->version); - if (vconn->version < vconn->min_version) { + vconn->version = + ofputil_version_bitmap_scanr(&vconn->allowed_versions); + if (vconn->version == oh->version + 1) { + struct ds msg = DS_EMPTY_INITIALIZER; + format_versions(&msg, &vconn->allowed_versions); 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, - oh->version); + "%s but peer " "supports no later than " + "version 0x%02"PRIx8, vconn->name, + ds_cstr(&msg), oh->version); + ds_destroy(&msg); vconn->state = VCS_SEND_ERROR; } else { + struct ds msg = DS_EMPTY_INITIALIZER; + format_versions(&msg, &vconn->allowed_versions); VLOG_DBG("%s: negotiated OpenFlow version 0x%02x " - "(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); + "(we support %s, peer no later than " + "version 0x%02"PRIx8")", vconn->name, + vconn->version, ds_cstr(&msg), oh->version); + ds_destroy(&msg); vconn->state = VCS_CONNECTED; } ofpbuf_delete(b); @@ -469,10 +502,12 @@ vcs_send_error(struct vconn *vconn) struct ofpbuf *b; char s[128]; int retval; + struct ds msg = DS_EMPTY_INITIALIZER; - 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); + format_versions(&msg, &vconn->allowed_versions); + snprintf(s, sizeof s, "We support %s but you support no later than " + "version 0x%02"PRIx8".", ds_cstr(&msg), vconn->version); + ds_destroy(&msg); b = ofperr_encode_hello(OFPERR_OFPHFC_INCOMPATIBLE, vconn->version, s); retval = do_send(vconn, b); if (retval) { @@ -492,8 +527,11 @@ int vconn_connect(struct vconn *vconn) { enum vconn_state last_state; + enum ofp_version max_version; + struct ofputil_version_bitmap *versions = &vconn->allowed_versions; - assert(vconn->min_version > 0); + max_version = ofputil_version_bitmap_scanr(versions); + assert(max_version != versions->n_bits); do { last_state = vconn->state; switch (vconn->state) { @@ -502,7 +540,7 @@ vconn_connect(struct vconn *vconn) break; case VCS_SEND_HELLO: - vcs_send_hello(vconn); + vcs_send_hello(vconn, max_version); break; case VCS_RECV_HELLO: @@ -924,7 +962,8 @@ pvconn_verify_name(const char *name) * stores a pointer to the new connection in '*pvconnp', otherwise a null * pointer. */ int -pvconn_open(const char *name, enum ofp_version min_version, +pvconn_open(const char *name, + const struct ofputil_version_bitmap *allowed_versions, struct pvconn **pvconnp, uint8_t dscp) { struct pvconn_class *class; @@ -942,7 +981,7 @@ pvconn_open(const char *name, enum ofp_version min_version, /* Call class's "open" function. */ suffix_copy = xstrdup(strchr(name, ':') + 1); - error = class->listen(name, min_version, suffix_copy, &pvconn, dscp); + error = class->listen(name, allowed_versions, suffix_copy, &pvconn, dscp); free(suffix_copy); if (error) { goto error; @@ -982,7 +1021,7 @@ 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. */ @@ -1024,7 +1063,8 @@ pvconn_wait(struct pvconn *pvconn) * The caller retains ownership of 'name'. */ void vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, - const char *name, enum ofp_version min_version) + const char *name, + const struct ofputil_version_bitmap *allowed_versions) { vconn->class = class; vconn->state = (connect_status == EAGAIN ? VCS_CONNECTING @@ -1032,7 +1072,8 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, : VCS_DISCONNECTED); vconn->error = connect_status; vconn->version = 0; - vconn->min_version = min_version; + ofputil_version_bitmap_clone_data(allowed_versions, + &vconn->allowed_versions); vconn->remote_ip = 0; vconn->remote_port = 0; vconn->local_ip = 0; @@ -1042,6 +1083,12 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, } void +vconn_free_data(struct vconn *vconn) +{ + ofputil_version_bitmap_free_data(&vconn->allowed_versions); +} + +void vconn_set_remote_ip(struct vconn *vconn, ovs_be32 ip) { vconn->remote_ip = ip; @@ -1067,9 +1114,11 @@ vconn_set_local_port(struct vconn *vconn, ovs_be16 port) void pvconn_init(struct pvconn *pvconn, struct pvconn_class *class, - const char *name, enum ofp_version min_version) + const char *name, + const struct ofputil_version_bitmap *allowed_versions) { pvconn->class = class; pvconn->name = xstrdup(name); - pvconn->min_version = min_version; + ofputil_version_bitmap_clone_data(allowed_versions, + &pvconn->allowed_versions); } diff --git a/lib/vconn.h b/lib/vconn.h index 01d1c70..e4ab654 100644 --- a/lib/vconn.h +++ b/lib/vconn.h @@ -20,6 +20,7 @@ #include <stdbool.h> #include "openvswitch/types.h" #include "openflow/openflow.h" +#include "lib/ofp-util.h" #ifdef __cplusplus extern "C" { @@ -34,10 +35,13 @@ 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, enum ofp_version min_version, - struct vconn **, uint8_t dscp); +int vconn_open(const char *name, + const struct ofputil_version_bitmap *allowed_versions, + struct vconn **vconnp, uint8_t dscp); void vconn_close(struct vconn *); const char *vconn_get_name(const struct vconn *); +const struct ofputil_version_bitmap * +vconn_get_allowed_versions(const struct vconn *vconn); ovs_be32 vconn_get_remote_ip(const struct vconn *); ovs_be16 vconn_get_remote_port(const struct vconn *); ovs_be32 vconn_get_local_ip(const struct vconn *); @@ -55,7 +59,8 @@ int vconn_transact_multiple_noreply(struct vconn *, struct list *requests, void vconn_run(struct vconn *); void vconn_run_wait(struct vconn *); -int vconn_open_block(const char *name, enum ofp_version min_version, +int vconn_open_block(const char *name, + const struct ofputil_version_bitmap *allowed_versions, struct vconn **); int vconn_connect_block(struct vconn *); int vconn_send_block(struct vconn *, struct ofpbuf *); @@ -73,7 +78,8 @@ void vconn_send_wait(struct vconn *); /* Passive vconns: virtual listeners for incoming OpenFlow connections. */ int pvconn_verify_name(const char *name); -int pvconn_open(const char *name, enum ofp_version min_version, +int pvconn_open(const char *name, + const struct ofputil_version_bitmap *allowed_versions, struct pvconn **pvconnp, uint8_t dscp); const char *pvconn_get_name(const struct pvconn *); void pvconn_close(struct pvconn *); diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 0c2a165..d63a166 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -718,10 +718,13 @@ set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp, pvconns = xmalloc(sset_count(sset) * sizeof *pvconns); n_pvconns = 0; SSET_FOR_EACH (name, sset) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; struct pvconn *pvconn; int error; - error = pvconn_open(name, OFP10_VERSION, &pvconn, 0); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + error = pvconn_open(name, &ovb, &pvconn, 0); + ofputil_version_bitmap_free_data(&ovb); if (!error) { pvconns[n_pvconns++] = pvconn; } else { @@ -1621,11 +1624,14 @@ connmgr_flushed(struct connmgr *mgr) static int ofservice_create(struct connmgr *mgr, const char *target, uint8_t dscp) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; struct ofservice *ofservice; struct pvconn *pvconn; int error; - error = pvconn_open(target, OFP10_VERSION, &pvconn, dscp); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + error = pvconn_open(target, &ovb, &pvconn, dscp); + ofputil_version_bitmap_free_data(&ovb); if (error) { return error; } diff --git a/tests/test-vconn.c b/tests/test-vconn.c index 5dd38f0..6c21313 100644 --- a/tests/test-vconn.c +++ b/tests/test-vconn.c @@ -142,14 +142,16 @@ fpv_destroy(struct fake_pvconn *fpv) static void test_refuse_connection(int argc OVS_UNUSED, char *argv[]) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; const char *type = argv[1]; struct fake_pvconn fpv; struct vconn *vconn; int error; fpv_create(type, &fpv); - CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn, - DSCP_DEFAULT), 0); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + CHECK_ERRNO(vconn_open(fpv.vconn_name, &ovb, &vconn, DSCP_DEFAULT), 0); + ofputil_version_bitmap_free_data(&ovb); fpv_close(&fpv); vconn_run(vconn); @@ -173,14 +175,16 @@ test_refuse_connection(int argc OVS_UNUSED, char *argv[]) static void test_accept_then_close(int argc OVS_UNUSED, char *argv[]) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; const char *type = argv[1]; struct fake_pvconn fpv; struct vconn *vconn; int error; fpv_create(type, &fpv); - CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn, - DSCP_DEFAULT), 0); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + CHECK_ERRNO(vconn_open(fpv.vconn_name, &ovb, &vconn, DSCP_DEFAULT), 0); + ofputil_version_bitmap_free_data(&ovb); vconn_run(vconn); stream_close(fpv_accept(&fpv)); fpv_close(&fpv); @@ -205,6 +209,7 @@ test_accept_then_close(int argc OVS_UNUSED, char *argv[]) static void test_read_hello(int argc OVS_UNUSED, char *argv[]) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; const char *type = argv[1]; struct fake_pvconn fpv; struct vconn *vconn; @@ -212,8 +217,9 @@ 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); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + CHECK_ERRNO(vconn_open(fpv.vconn_name, &ovb, &vconn, DSCP_DEFAULT), 0); + ofputil_version_bitmap_free_data(&ovb); vconn_run(vconn); stream = fpv_accept(&fpv); fpv_destroy(&fpv); @@ -258,6 +264,7 @@ static void test_send_hello(const char *type, const void *out, size_t out_size, int expect_connect_error) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; struct fake_pvconn fpv; struct vconn *vconn; bool read_hello, connected; @@ -266,8 +273,9 @@ 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); + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + CHECK_ERRNO(vconn_open(fpv.vconn_name, &ovb, &vconn, DSCP_DEFAULT), 0); + ofputil_version_bitmap_free_data(&ovb); vconn_run(vconn); stream = fpv_accept(&fpv); fpv_destroy(&fpv); diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c index 2f812a6..4adf61f 100644 --- a/utilities/ovs-controller.c +++ b/utilities/ovs-controller.c @@ -92,6 +92,7 @@ static void usage(void) NO_RETURN; int main(int argc, char *argv[]) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; struct unixctl_server *unixctl; struct switch_ switches[MAX_SWITCHES]; struct pvconn *listeners[MAX_LISTENERS]; @@ -109,12 +110,14 @@ main(int argc, char *argv[]) "use --help for usage"); } + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + n_switches = n_listeners = 0; for (i = optind; i < argc; i++) { const char *name = argv[i]; struct vconn *vconn; - retval = vconn_open(name, OFP10_VERSION, &vconn, DSCP_DEFAULT); + retval = vconn_open(name, &ovb, &vconn, DSCP_DEFAULT); if (!retval) { if (n_switches >= MAX_SWITCHES) { ovs_fatal(0, "max %d switch connections", n_switches); @@ -123,7 +126,7 @@ main(int argc, char *argv[]) continue; } else if (retval == EAFNOSUPPORT) { struct pvconn *pvconn; - retval = pvconn_open(name, OFP10_VERSION, &pvconn, DSCP_DEFAULT); + retval = pvconn_open(name, &ovb, &pvconn, DSCP_DEFAULT); if (!retval) { if (n_listeners >= MAX_LISTENERS) { ovs_fatal(0, "max %d passive connections", n_listeners); @@ -139,6 +142,7 @@ main(int argc, char *argv[]) ovs_fatal(0, "no active or passive switch connections"); } + ofputil_version_bitmap_free_data(&ovb); daemonize_start(); retval = unixctl_server_create(unixctl_path, &unixctl); diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index a0b7079..4753d9e 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -334,10 +334,13 @@ static void run(int retval, const char *message, ...) static void open_vconn_socket(const char *name, struct vconn **vconnp) { + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; char *vconn_name = xasprintf("unix:%s", name); VLOG_DBG("connecting to %s", vconn_name); - run(vconn_open_block(vconn_name, OFP10_VERSION, vconnp), + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + run(vconn_open_block(vconn_name, &ovb, vconnp), "connecting to %s", vconn_name); + ofputil_version_bitmap_free_data(&ovb); free(vconn_name); } @@ -360,8 +363,10 @@ open_vconn__(const char *name, const char *default_suffix, free(datapath_type); if (strchr(name, ':')) { - run(vconn_open_block(name, OFP10_VERSION, vconnp), - "connecting to %s", name); + struct ofputil_version_bitmap ovb = OFPUTIL_VERSION_BITMAP_INITIALIZER; + ofputil_version_bitmap_set1(&ovb, OFP10_VERSION); + run(vconn_open_block(name, &ovb, vconnp), "connecting to %s", name); + ofputil_version_bitmap_free_data(&ovb); } else if (!stat(name, &s) && S_ISSOCK(s.st_mode)) { open_vconn_socket(name, vconnp); } else if (!stat(bridge_path, &s) && S_ISSOCK(s.st_mode)) { -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev