Skip to content

Commit

Permalink
ofp-util: Make ofputil_encode_set_protocol() able to return failure.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
  • Loading branch information
blp committed Nov 16, 2012
1 parent 7cd9035 commit e43928f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
20 changes: 12 additions & 8 deletions lib/learning-switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 11 additions & 1 deletion lib/ofp-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion utilities/ovs-ofctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down

0 comments on commit e43928f

Please sign in to comment.