From: Ben Pfaff Date: Fri, 16 Nov 2012 06:09:07 +0000 (-0800) Subject: ofp-util: Make ofputil_encode_set_protocol() able to return failure. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=openvswitch;a=commitdiff_plain;h=e43928f2862b83a3c13e8662490a22fa25405be5 ofp-util: Make ofputil_encode_set_protocol() able to return failure. Soon, it's not going to be possible to switch between every possible protocol on an established OpenFlow connection, yet ofputil_encode_set_protocol() didn't have a documented way to report such a problem. This commit adds a means for reporting and makes its callers able to handle the problem. Also, initially make ofputil_encode_set_protocol() fail when the current and requested protocols are for different OpenFlow versions. Signed-off-by: Ben Pfaff Reviewed-by: Simon Horman --- diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 7a60f3c3..eeaa3064 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -200,15 +200,19 @@ lswitch_handshake(struct lswitch *sw) error = rconn_send(sw->rconn, msg, NULL); } } + if (protocol & usable_protocols) { + for (i = 0; !error && i < sw->n_default_flows; i++) { + msg = ofputil_encode_flow_mod(&sw->default_flows[i], protocol); + error = rconn_send(sw->rconn, msg, NULL); + } - for (i = 0; !error && i < sw->n_default_flows; i++) { - msg = ofputil_encode_flow_mod(&sw->default_flows[i], protocol); - error = rconn_send(sw->rconn, msg, NULL); - } - - if (error) { - VLOG_INFO_RL(&rl, "%s: failed to queue default flows (%s)", - rconn_get_name(sw->rconn), strerror(error)); + if (error) { + VLOG_INFO_RL(&rl, "%s: failed to queue default flows (%s)", + rconn_get_name(sw->rconn), strerror(error)); + } + } else { + VLOG_INFO_RL(&rl, "%s: failed to set usable protocol", + rconn_get_name(sw->rconn)); } } sw->protocol = protocol; diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 6ff9df89..ad3fb369 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1201,15 +1201,25 @@ ofputil_encode_hello(uint32_t allowed_versions) * connection if the switch processes the returned message correctly. (If * '*next != want' then the caller will have to iterate.) * - * If 'current == want', returns NULL and stores 'current' in '*next'. */ + * If 'current == want', or if it is not possible to transition from 'current' + * to 'want' (because, for example, 'current' and 'want' use different OpenFlow + * protocol versions), returns NULL and stores 'current' in '*next'. */ struct ofpbuf * ofputil_encode_set_protocol(enum ofputil_protocol current, enum ofputil_protocol want, enum ofputil_protocol *next) { + enum ofp_version cur_version, want_version; enum ofputil_protocol cur_base, want_base; bool cur_tid, want_tid; + cur_version = ofputil_protocol_to_ofp_version(current); + want_version = ofputil_protocol_to_ofp_version(want); + if (cur_version != want_version) { + *next = current; + return NULL; + } + cur_base = ofputil_protocol_to_base(current); want_base = ofputil_protocol_to_base(want); if (cur_base != want_base) { diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 914be984..08c3aa92 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -763,7 +763,7 @@ try_set_protocol(struct vconn *vconn, enum ofputil_protocol want, request = ofputil_encode_set_protocol(*cur, want, &next); if (!request) { - return true; + return *cur == want; } run(vconn_transact_noreply(vconn, request, &reply),