Skip to content

Commit

Permalink
ofproto: Add support for sending OFPTYPE_ROLE_STATUS messages.
Browse files Browse the repository at this point in the history
When a controller changes its role to MASTER, the others are marked
as SLAVE. This patch makes it possible to notify the controllers
of this change.

Signed-off-by: Alexandru Copot <[email protected]>
Cc: Daniel Baluta <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
ketotek authored and blp committed Oct 29, 2013
1 parent 252f341 commit 00467f7
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 16 deletions.
3 changes: 1 addition & 2 deletions include/openflow/openflow-1.4.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,14 @@ OFP_ASSERT(sizeof(struct ofp14_role_prop_header) == 4);

/* Role status event message. */
struct ofp14_role_status {
struct ofp_header header; /* Type OFPT_ROLE_REQUEST/OFPT_ROLE_REPLY. */
ovs_be32 role; /* One of OFPCR_ROLE_*. */
uint8_t reason; /* One of OFPCRR_*. */
uint8_t pad[3]; /* Align to 64 bits. */
ovs_be64 generation_id; /* Master Election Generation Id */

/* Followed by a list of struct ofp14_role_prop_header */
};
OFP_ASSERT(sizeof(struct ofp14_role_status) == 24);
OFP_ASSERT(sizeof(struct ofp14_role_status) == 16);

/* What changed about the controller role */
enum ofp14_controller_role_reason {
Expand Down
65 changes: 52 additions & 13 deletions lib/ofp-print.c
Original file line number Diff line number Diff line change
Expand Up @@ -1917,20 +1917,12 @@ ofp_print_echo(struct ds *string, const struct ofp_header *oh, int verbosity)
}

static void
ofp_print_role_message(struct ds *string, const struct ofp_header *oh)
ofp_print_role_generic(struct ds *string, enum ofp12_controller_role role,
uint64_t generation_id)
{
struct ofputil_role_request rr;
enum ofperr error;

error = ofputil_decode_role_message(oh, &rr);
if (error) {
ofp_print_error(string, error);
return;
}

ds_put_cstr(string, " role=");

switch (rr.role) {
switch (role) {
case OFPCR12_ROLE_NOCHANGE:
ds_put_cstr(string, "nochange");
break;
Expand All @@ -1947,8 +1939,54 @@ ofp_print_role_message(struct ds *string, const struct ofp_header *oh)
NOT_REACHED();
}

if (rr.have_generation_id) {
ds_put_format(string, " generation_id=%"PRIu64, rr.generation_id);
if (generation_id != UINT64_MAX) {
ds_put_format(string, " generation_id=%"PRIu64, generation_id);
}
}

static void
ofp_print_role_message(struct ds *string, const struct ofp_header *oh)
{
struct ofputil_role_request rr;
enum ofperr error;

error = ofputil_decode_role_message(oh, &rr);
if (error) {
ofp_print_error(string, error);
return;
}

ofp_print_role_generic(string, rr.role, rr.have_generation_id ? rr.generation_id : UINT64_MAX);
}

static void
ofp_print_role_status_message(struct ds *string, const struct ofp_header *oh)
{
struct ofputil_role_status rs;
enum ofperr error;

error = ofputil_decode_role_status(oh, &rs);
if (error) {
ofp_print_error(string, error);
return;
}

ofp_print_role_generic(string, rs.role, rs.generation_id);

ds_put_cstr(string, " reason=");

switch (rs.reason) {
case OFPCRR_MASTER_REQUEST:
ds_put_cstr(string, "master_request");
break;
case OFPCRR_CONFIG:
ds_put_cstr(string, "configuration_changed");
break;
case OFPCRR_EXPERIMENTER:
ds_put_cstr(string, "experimenter_data_changed");
break;
default:
NOT_REACHED();
}
}

Expand Down Expand Up @@ -2566,6 +2604,7 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
ofp_print_role_message(string, oh);
break;
case OFPTYPE_ROLE_STATUS:
ofp_print_role_status_message(string, oh);
break;

case OFPTYPE_METER_STATS_REQUEST:
Expand Down
45 changes: 45 additions & 0 deletions lib/ofp-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -4186,6 +4186,51 @@ ofputil_encode_role_reply(const struct ofp_header *request,
return buf;
}

struct ofpbuf *
ofputil_encode_role_status(const struct ofputil_role_status *status,
enum ofputil_protocol protocol)
{
struct ofpbuf *buf;
enum ofp_version version;
struct ofp14_role_status *rstatus;

version = ofputil_protocol_to_ofp_version(protocol);
buf = ofpraw_alloc_xid(OFPRAW_OFPT14_ROLE_STATUS, version, htonl(0), 0);
rstatus = ofpbuf_put_zeros(buf, sizeof *rstatus);
rstatus->role = htonl(status->role);
rstatus->reason = status->reason;
rstatus->generation_id = htonll(status->generation_id);

return buf;
}

enum ofperr
ofputil_decode_role_status(const struct ofp_header *oh,
struct ofputil_role_status *rs)
{
struct ofpbuf b;
enum ofpraw raw;
const struct ofp14_role_status *r;

ofpbuf_use_const(&b, oh, ntohs(oh->length));
raw = ofpraw_pull_assert(&b);
ovs_assert(raw == OFPRAW_OFPT14_ROLE_STATUS);

r = b.l3;
if (r->role != htonl(OFPCR12_ROLE_NOCHANGE) &&
r->role != htonl(OFPCR12_ROLE_EQUAL) &&
r->role != htonl(OFPCR12_ROLE_MASTER) &&
r->role != htonl(OFPCR12_ROLE_SLAVE)) {
return OFPERR_OFPRRFC_BAD_ROLE;
}

rs->role = ntohl(r->role);
rs->generation_id = ntohll(r->generation_id);
rs->reason = r->reason;

return 0;
}

/* Table stats. */

static void
Expand Down
12 changes: 12 additions & 0 deletions lib/ofp-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,23 @@ struct ofputil_role_request {
uint64_t generation_id;
};

struct ofputil_role_status {
enum ofp12_controller_role role;
enum ofp14_controller_role_reason reason;
uint64_t generation_id;
};

enum ofperr ofputil_decode_role_message(const struct ofp_header *,
struct ofputil_role_request *);
struct ofpbuf *ofputil_encode_role_reply(const struct ofp_header *,
const struct ofputil_role_request *);

struct ofpbuf *ofputil_encode_role_status(
const struct ofputil_role_status *status,
enum ofputil_protocol protocol);

enum ofperr ofputil_decode_role_status(const struct ofp_header *oh,
struct ofputil_role_status *rs);
/* Abstract table stats.
*
* For now we use ofp12_table_stats as a superset of the other protocol
Expand Down
18 changes: 17 additions & 1 deletion ofproto/connmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,17 +912,33 @@ ofconn_get_role(const struct ofconn *ofconn)
return ofconn->role;
}

void
ofconn_send_role_status(struct ofconn *ofconn, uint32_t role, uint8_t reason)
{
struct ofputil_role_status status;
struct ofpbuf *buf;

status.reason = reason;
status.role = role;
ofconn_get_master_election_id(ofconn, &status.generation_id);

buf = ofputil_encode_role_status(&status, ofconn_get_protocol(ofconn));

ofconn_send(ofconn, buf, NULL);
}

/* Changes 'ofconn''s role to 'role'. If 'role' is OFPCR12_ROLE_MASTER then
* any existing master is demoted to a slave. */
void
ofconn_set_role(struct ofconn *ofconn, enum ofp12_controller_role role)
{
if (role == OFPCR12_ROLE_MASTER) {
if (role != ofconn->role && role == OFPCR12_ROLE_MASTER) {
struct ofconn *other;

HMAP_FOR_EACH (other, hmap_node, &ofconn->connmgr->controllers) {
if (other->role == OFPCR12_ROLE_MASTER) {
other->role = OFPCR12_ROLE_SLAVE;
ofconn_send_role_status(other, OFPCR12_ROLE_SLAVE, OFPCRR_MASTER_REQUEST);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions ofproto/connmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ void connmgr_send_flow_removed(struct connmgr *,
const struct ofputil_flow_removed *);
void connmgr_send_packet_in(struct connmgr *,
const struct ofproto_packet_in *);
void ofconn_send_role_status(struct ofconn *ofconn, uint32_t role,
uint8_t reason);

/* Fail-open settings. */
enum ofproto_fail_mode connmgr_get_fail_mode(const struct connmgr *);
Expand Down
30 changes: 30 additions & 0 deletions tests/ofp-print.at
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,36 @@ NXT_ROLE_REPLY (xid=0x2): role=slave
])
AT_CLEANUP

AT_SETUP([OFP_ROLE_STATUS - master, experimenter - OF1.4])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
05 1e 00 18 00 00 00 0a \
00 00 00 02 02 00 00 00 ff ff ff ff ff ff ff ff \
"], [0], [dnl
OFPT_ROLE_STATUS (OF 0x05) (xid=0xa): role=master reason=experimenter_data_changed
])
AT_CLEANUP

AT_SETUP([OFP_ROLE_STATUS - master, config - OF1.4])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
05 1e 00 18 00 00 00 0a \
00 00 00 02 01 00 00 00 ff ff ff ff ff ff ff ff \
"], [0], [dnl
OFPT_ROLE_STATUS (OF 0x05) (xid=0xa): role=master reason=configuration_changed
])
AT_CLEANUP

AT_SETUP([OFP_ROLE_STATUS - master, config,generation - OF1.4])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
05 1e 00 18 00 00 00 0a \
00 00 00 02 01 00 00 00 00 00 00 00 00 00 00 10 \
"], [0], [dnl
OFPT_ROLE_STATUS (OF 0x05) (xid=0xa): role=master generation_id=16 reason=configuration_changed
])
AT_CLEANUP

AT_SETUP([NXT_SET_PACKET_IN])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
Expand Down

0 comments on commit 00467f7

Please sign in to comment.