The motivation for this is to avoid avoids needing to provide a minimu version parameter to pvconn_accept(). This will in turn avoid the need to pass version information to connmgr_run() when the range of accetable OpenFlow versions is made configurable.
Signed-off-by: Simon Horman <ho...@verge.net.au> --- lib/vconn-provider.h | 20 ++++++++++++++------ lib/vconn-stream.c | 20 +++++++++++--------- lib/vconn.c | 24 ++++++++++++------------ lib/vconn.h | 7 ++++--- ofproto/connmgr.c | 8 ++++---- utilities/ovs-controller.c | 4 ++-- 6 files changed, 47 insertions(+), 36 deletions(-) diff --git a/lib/vconn-provider.h b/lib/vconn-provider.h index 54ec2e6..e9dd441 100644 --- a/lib/vconn-provider.h +++ b/lib/vconn-provider.h @@ -43,7 +43,7 @@ struct vconn { }; void vconn_init(struct vconn *, struct vconn_class *, int connect_status, - const char *name); + const char *name, enum ofp_version min_version); 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,6 +62,9 @@ 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 + * negotiated for a connection. + * * 'suffix' is a copy of 'name' following the colon and may be modified. * 'dscp' is the DSCP value that the new connection should use in the IP * packets it sends. @@ -73,8 +76,8 @@ 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, char *suffix, struct vconn **vconnp, - uint8_t dscp); + int (*open)(const char *name, enum ofp_version min_version, char *suffix, + struct vconn **vconnp, uint8_t dscp); /* Closes 'vconn' and frees associated memory. */ void (*close)(struct vconn *vconn); @@ -135,9 +138,11 @@ struct vconn_class { struct pvconn { struct pvconn_class *class; char *name; + enum ofp_version min_version; }; -void pvconn_init(struct pvconn *, struct pvconn_class *, const char *name); +void pvconn_init(struct pvconn *, struct pvconn_class *, const char *name, + enum ofp_version min_version); static inline void pvconn_assert_class(const struct pvconn *pvconn, const struct pvconn_class *class) { @@ -152,6 +157,9 @@ 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 + * be negotiated for a session. + * * 'suffix' is a copy of 'name' following the colon and may be modified. * 'dscp' is the DSCP value that the new connection should use in the IP * packets it sends. @@ -163,8 +171,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, char *suffix, struct pvconn **pvconnp, - uint8_t dscp); + int (*listen)(const char *name, enum ofp_version min_version, + char *suffix, struct pvconn **pvconnp, uint8_t dscp); /* Closes 'pvconn' and frees associated memory. */ void (*close)(struct pvconn *pvconn); diff --git a/lib/vconn-stream.c b/lib/vconn-stream.c index d707e06..361fcb4 100644 --- a/lib/vconn-stream.c +++ b/lib/vconn-stream.c @@ -54,13 +54,14 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 25); static void vconn_stream_clear_txbuf(struct vconn_stream *); static struct vconn * -vconn_stream_new(struct stream *stream, int connect_status) +vconn_stream_new(struct stream *stream, int connect_status, + enum ofp_version min_version) { struct vconn_stream *s; s = xmalloc(sizeof *s); vconn_init(&s->vconn, &stream_vconn_class, connect_status, - stream_get_name(stream)); + stream_get_name(stream), min_version); s->stream = stream; s->txbuf = NULL; s->rxbuf = NULL; @@ -77,8 +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, char *suffix OVS_UNUSED, - struct vconn **vconnp, uint8_t dscp) +vconn_stream_open(const char *name, enum ofp_version min_version, + char *suffix OVS_UNUSED, struct vconn **vconnp, uint8_t dscp) { struct stream *stream; int error; @@ -88,7 +89,7 @@ vconn_stream_open(const char *name, char *suffix OVS_UNUSED, if (!error) { error = stream_connect(stream); if (!error || error == EAGAIN) { - *vconnp = vconn_stream_new(stream, error); + *vconnp = vconn_stream_new(stream, error, min_version); return 0; } } @@ -310,8 +311,9 @@ 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, char *suffix OVS_UNUSED, - struct pvconn **pvconnp, uint8_t dscp) +pvconn_pstream_listen(const char *name, enum ofp_version min_version, + char *suffix OVS_UNUSED, struct pvconn **pvconnp, + uint8_t dscp) { struct pvconn_pstream *ps; struct pstream *pstream; @@ -324,7 +326,7 @@ pvconn_pstream_listen(const char *name, char *suffix OVS_UNUSED, } ps = xmalloc(sizeof *ps); - pvconn_init(&ps->pvconn, &pstream_pvconn_class, name); + pvconn_init(&ps->pvconn, &pstream_pvconn_class, name, min_version); ps->pstream = pstream; *pvconnp = &ps->pvconn; return 0; @@ -354,7 +356,7 @@ pvconn_pstream_accept(struct pvconn *pvconn, struct vconn **new_vconnp) return error; } - *new_vconnp = vconn_stream_new(stream, 0); + *new_vconnp = vconn_stream_new(stream, 0, pvconn->min_version); return 0; } diff --git a/lib/vconn.c b/lib/vconn.c index 9271f4f..2dd4654 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -221,8 +221,8 @@ vconn_verify_name(const char *name) * 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, + struct vconn **vconnp, uint8_t dscp) { struct vconn_class *class; struct vconn *vconn; @@ -240,7 +240,7 @@ vconn_open(const char *name, int min_version, struct vconn **vconnp, /* Call class's "open" function. */ suffix_copy = xstrdup(strchr(name, ':') + 1); - error = class->open(name, suffix_copy, &vconn, dscp); + error = class->open(name, min_version, suffix_copy, &vconn, dscp); free(suffix_copy); if (error) { goto error; @@ -248,7 +248,6 @@ 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; *vconnp = vconn; return 0; @@ -925,7 +924,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, struct pvconn **pvconnp, uint8_t dscp) +pvconn_open(const char *name, enum ofp_version min_version, + struct pvconn **pvconnp, uint8_t dscp) { struct pvconn_class *class; struct pvconn *pvconn; @@ -942,7 +942,7 @@ pvconn_open(const char *name, struct pvconn **pvconnp, uint8_t dscp) /* Call class's "open" function. */ suffix_copy = xstrdup(strchr(name, ':') + 1); - error = class->listen(name, suffix_copy, &pvconn, dscp); + error = class->listen(name, min_version, suffix_copy, &pvconn, dscp); free(suffix_copy); if (error) { goto error; @@ -987,7 +987,7 @@ pvconn_close(struct pvconn *pvconn) * 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, struct vconn **new_vconn) { int retval = (pvconn->class->accept)(pvconn, new_vconn); if (retval) { @@ -995,7 +995,6 @@ pvconn_accept(struct pvconn *pvconn, int min_version, struct vconn **new_vconn) } else { assert((*new_vconn)->state != VCS_CONNECTING || (*new_vconn)->class->connect); - (*new_vconn)->min_version = min_version; } return retval; } @@ -1025,7 +1024,7 @@ 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) + const char *name, enum ofp_version min_version) { vconn->class = class; vconn->state = (connect_status == EAGAIN ? VCS_CONNECTING @@ -1033,7 +1032,7 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, : VCS_DISCONNECTED); vconn->error = connect_status; vconn->version = 0; - vconn->min_version = 0; + vconn->min_version = min_version; vconn->remote_ip = 0; vconn->remote_port = 0; vconn->local_ip = 0; @@ -1067,9 +1066,10 @@ vconn_set_local_port(struct vconn *vconn, ovs_be16 port) } void -pvconn_init(struct pvconn *pvconn, struct pvconn_class *class, - const char *name) +pvconn_init(struct pvconn *pvconn, struct pvconn_class *class, + const char *name, enum ofp_version min_version) { pvconn->class = class; pvconn->name = xstrdup(name); + pvconn->min_version = min_version; } diff --git a/lib/vconn.h b/lib/vconn.h index 1a0bc60..01d1c70 100644 --- a/lib/vconn.h +++ b/lib/vconn.h @@ -34,7 +34,7 @@ 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, +int vconn_open(const char *name, enum ofp_version min_version, struct vconn **, uint8_t dscp); void vconn_close(struct vconn *); const char *vconn_get_name(const struct vconn *); @@ -73,10 +73,11 @@ 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, struct pvconn **, uint8_t dscp); +int pvconn_open(const char *name, enum ofp_version min_version, + struct pvconn **pvconnp, 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 *, struct vconn **); void pvconn_wait(struct pvconn *); #ifdef __cplusplus diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 05e69c7..0c2a165 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -289,7 +289,7 @@ connmgr_run(struct connmgr *mgr, struct vconn *vconn; int retval; - retval = pvconn_accept(ofservice->pvconn, OFP10_VERSION, &vconn); + retval = pvconn_accept(ofservice->pvconn, &vconn); if (!retval) { struct rconn *rconn; char *name; @@ -313,7 +313,7 @@ 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], &vconn); if (!retval) { add_snooper(mgr, vconn); } else if (retval != EAGAIN) { @@ -721,7 +721,7 @@ set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp, struct pvconn *pvconn; int error; - error = pvconn_open(name, &pvconn, 0); + error = pvconn_open(name, OFP10_VERSION, &pvconn, 0); if (!error) { pvconns[n_pvconns++] = pvconn; } else { @@ -1625,7 +1625,7 @@ ofservice_create(struct connmgr *mgr, const char *target, uint8_t dscp) struct pvconn *pvconn; int error; - error = pvconn_open(target, &pvconn, dscp); + error = pvconn_open(target, OFP10_VERSION, &pvconn, dscp); if (error) { return error; } diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c index 07e300b..2f812a6 100644 --- a/utilities/ovs-controller.c +++ b/utilities/ovs-controller.c @@ -123,7 +123,7 @@ main(int argc, char *argv[]) continue; } else if (retval == EAFNOSUPPORT) { struct pvconn *pvconn; - retval = pvconn_open(name, &pvconn, DSCP_DEFAULT); + retval = pvconn_open(name, OFP10_VERSION, &pvconn, DSCP_DEFAULT); if (!retval) { if (n_listeners >= MAX_LISTENERS) { ovs_fatal(0, "max %d passive connections", n_listeners); @@ -153,7 +153,7 @@ 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], &new_vconn); if (!retval || retval == EAGAIN) { if (!retval) { new_switch(&switches[n_switches++], new_vconn); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev