[firefly] [PATCH 2/2] add support for sending OFPTYPE_ROLE_STATUS messages
Alexandru Copot
alex.mihai.c at gmail.com
Tue Oct 22 10:31:11 EEST 2013
Signed-off-by: Alexandru Copot <alex.mihai.c at gmail.com>
Cc: Daniel Baluta <dbaluta at ixiacom.com>
---
include/openflow/openflow-1.4.h | 3 +-
lib/ofp-print.c | 65 ++++++++++++++++++++++++++++++++---------
lib/ofp-util.c | 45 ++++++++++++++++++++++++++++
lib/ofp-util.h | 12 ++++++++
ofproto/connmgr.c | 18 +++++++++++-
ofproto/connmgr.h | 2 ++
tests/ofp-print.at | 30 +++++++++++++++++++
7 files changed, 159 insertions(+), 16 deletions(-)
diff --git a/include/openflow/openflow-1.4.h b/include/openflow/openflow-1.4.h
index 77fdb57..d71f74f 100644
--- a/include/openflow/openflow-1.4.h
+++ b/include/openflow/openflow-1.4.h
@@ -116,7 +116,6 @@ 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. */
@@ -124,7 +123,7 @@ struct ofp14_role_status {
/* 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 {
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 8bd7eef..f17eddc 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -1852,20 +1852,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;
@@ -1882,8 +1874,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();
}
}
@@ -2495,6 +2533,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:
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 2bf595a..6e75a6a 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -3906,6 +3906,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
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 937423e..7d4ad86 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -679,11 +679,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
diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index 8bb96f0..a5fcc65 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -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);
}
}
}
diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h
index 505a757..d2bce8c 100644
--- a/ofproto/connmgr.h
+++ b/ofproto/connmgr.h
@@ -143,6 +143,8 @@ void connmgr_send_flow_removed(struct connmgr *,
void connmgr_send_packet_in(struct connmgr *,
const struct ofputil_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 *);
void connmgr_set_fail_mode(struct connmgr *, enum ofproto_fail_mode);
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index 87d5da8..c0150e2 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -2048,6 +2048,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 "\
--
1.8.4.1
More information about the firefly
mailing list