summaryrefslogtreecommitdiff
path: root/lib/ofp-print.c
diff options
context:
space:
mode:
authorNiti Rohilla <niti.rohilla@tcs.com>2015-07-23 17:05:44 +0530
committerBen Pfaff <blp@nicira.com>2015-07-27 10:15:28 -0700
commit980904823303ef02af605e62a30c9bebda25f1ef (patch)
tree8eaa7e6ba07398c8225d1c869bdaa003c2bd6753 /lib/ofp-print.c
parentad2e649834be20dd01b1632799fe778106a96a2d (diff)
downloadopenvswitch-980904823303ef02af605e62a30c9bebda25f1ef.tar.gz
ofproto: Implement OF1.4 Set/Get asynchronous configuration messages.
This patch adds support for Openflow1.4 set/get asynchronous configuration messages. OpenVSwitch already supports set/get asynchronous configuration messages for Openflow1.3. In this patch OFPT_SET_ASYNC_CONFIG message allows the controllers to set the configuration for OFPT_ROLE_STATUS, OFPT_TABLE_STATUS and OFPT_REQUESTFORWARD in addition to the Openflow1.3 messages. In a OFPT_SET_ASYNC, only the properties that shall be changed need to be included, properties that are omitted from the message are unchanged. The OFPT_GET_ASYNC_CONFIG is used to query the asynchronous configuration of switch. In a OFPT_GET_ASYNC_REPLY message, all properties must be included. According to Openflow1.4 the initial configuration shall be: - In the “master” or “equal” role, enable all OFPT_PACKET_IN messages, except those with reason OFPR_INVALID_TTL, enable all OFPT_PORT_STATUS and OFPT_FLOW_REMOVED messages, and disable all OFPT_ROLE_STATUS, OFPT_TABLE_STATUS and OFPT_REQUESTFORWARD messages. - In the “slave” role, enable all OFPT_PORT_STATUS messages and disable all OFPT_PACKET_IN, OFPT_FLOW_REMOVED, OFPT_ROLE_STATUS, OFPT_TABLE_STATUS and OFPT_REQUESTFORWARD messages. Signed-off-by: Niti Rohilla <niti.rohilla@tcs.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/ofp-print.c')
-rw-r--r--lib/ofp-print.c238
1 files changed, 197 insertions, 41 deletions
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 4603bb7cc..6db32d14b 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -1903,64 +1903,220 @@ ofp_port_reason_to_string(enum ofp_port_reason reason,
}
}
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
+static const char*
+ofp_role_reason_to_string(enum ofp14_controller_role_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPCRR_MASTER_REQUEST:
+ return "master_request";
+
+ case OFPCRR_CONFIG:
+ return "configuration_changed";
+
+ case OFPCRR_EXPERIMENTER:
+ return "experimenter_data_changed";
+
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
+static const char*
+ofp_table_reason_to_string(enum ofp14_table_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPTR_VACANCY_DOWN:
+ return "vacancy_down";
+
+ case OFPTR_VACANCY_UP:
+ return "vacancy_up";
+
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
+static const char*
+ofp_requestforward_reason_to_string(enum ofp14_requestforward_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPRFR_GROUP_MOD:
+ return "group_mod_request";
+
+ case OFPRFR_METER_MOD:
+ return "meter_mod_request";
+
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
+static const char *
+ofp_async_config_reason_to_string(uint32_t reason,
+ enum ofputil_async_msg_type type,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (type) {
+ case OAM_PACKET_IN:
+ return ofputil_packet_in_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_PORT_STATUS:
+ return ofp_port_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_FLOW_REMOVED:
+ return ofp_flow_removed_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_ROLE_STATUS:
+ return ofp_role_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_TABLE_STATUS:
+ return ofp_table_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_REQUESTFORWARD:
+ return ofp_requestforward_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_N_TYPES:
+ default:
+ return "Unknown asynchronous configuration message type";
+ }
+}
+
+
+#define OFP_ASYNC_CONFIG_REASON_BUFSIZE (INT_STRLEN(int) + 1)
static void
ofp_print_nxt_set_async_config(struct ds *string,
- const struct nx_async_config *nac)
+ const struct ofp_header *oh)
{
- int i;
+ int i, j;
+ enum ofpraw raw;
- for (i = 0; i < 2; i++) {
- int j;
+ ofpraw_decode(&raw, oh);
+
+ if (raw == OFPRAW_OFPT13_SET_ASYNC ||
+ raw == OFPRAW_NXT_SET_ASYNC_CONFIG ||
+ raw == OFPRAW_OFPT13_GET_ASYNC_REPLY) {
+ const struct nx_async_config *nac = ofpmsg_body(oh);
+
+ for (i = 0; i < 2; i++) {
- ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
+ ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
- ds_put_cstr(string, " PACKET_IN:");
- for (j = 0; j < 32; j++) {
- if (nac->packet_in_mask[i] & htonl(1u << j)) {
- char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
- const char *reason;
+ ds_put_cstr(string, " PACKET_IN:");
+ for (j = 0; j < 32; j++) {
+ if (nac->packet_in_mask[i] & htonl(1u << j)) {
+ char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
+ const char *reason;
- reason = ofputil_packet_in_reason_to_string(j, reasonbuf,
+ reason = ofputil_packet_in_reason_to_string(j, reasonbuf,
sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
+ ds_put_format(string, " %s", reason);
+ }
}
- }
- if (!nac->packet_in_mask[i]) {
- ds_put_cstr(string, " (off)");
- }
- ds_put_char(string, '\n');
+ if (!nac->packet_in_mask[i]) {
+ ds_put_cstr(string, " (off)");
+ }
+ ds_put_char(string, '\n');
- ds_put_cstr(string, " PORT_STATUS:");
- for (j = 0; j < 32; j++) {
- if (nac->port_status_mask[i] & htonl(1u << j)) {
- char reasonbuf[OFP_PORT_REASON_BUFSIZE];
- const char *reason;
+ ds_put_cstr(string, " PORT_STATUS:");
+ for (j = 0; j < 32; j++) {
+ if (nac->port_status_mask[i] & htonl(1u << j)) {
+ char reasonbuf[OFP_PORT_REASON_BUFSIZE];
+ const char *reason;
- reason = ofp_port_reason_to_string(j, reasonbuf,
- sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
+ reason = ofp_port_reason_to_string(j, reasonbuf,
+ sizeof reasonbuf);
+ ds_put_format(string, " %s", reason);
+ }
}
- }
- if (!nac->port_status_mask[i]) {
- ds_put_cstr(string, " (off)");
- }
- ds_put_char(string, '\n');
+ if (!nac->port_status_mask[i]) {
+ ds_put_cstr(string, " (off)");
+ }
+ ds_put_char(string, '\n');
- ds_put_cstr(string, " FLOW_REMOVED:");
- for (j = 0; j < 32; j++) {
- if (nac->flow_removed_mask[i] & htonl(1u << j)) {
- char reasonbuf[OFP_FLOW_REMOVED_REASON_BUFSIZE];
- const char *reason;
+ ds_put_cstr(string, " FLOW_REMOVED:");
+ for (j = 0; j < 32; j++) {
+ if (nac->flow_removed_mask[i] & htonl(1u << j)) {
+ char reasonbuf[OFP_FLOW_REMOVED_REASON_BUFSIZE];
+ const char *reason;
- reason = ofp_flow_removed_reason_to_string(j, reasonbuf,
+ reason = ofp_flow_removed_reason_to_string(j, reasonbuf,
sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
+ ds_put_format(string, " %s", reason);
+ }
}
+ if (!nac->flow_removed_mask[i]) {
+ ds_put_cstr(string, " (off)");
+ }
+ ds_put_char(string, '\n');
}
- if (!nac->flow_removed_mask[i]) {
- ds_put_cstr(string, " (off)");
+ } else if (raw == OFPRAW_OFPT14_SET_ASYNC ||
+ raw == OFPRAW_OFPT14_GET_ASYNC_REPLY) {
+ uint32_t role[2][OAM_N_TYPES] = {{0}};
+ uint32_t type;
+
+ ofputil_decode_set_async_config(oh, role[0], role[1], true);
+ for (i = 0; i < 2; i++) {
+
+ ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
+ for (type = 0; type < OAM_N_TYPES; type++) {
+ switch (type) {
+ case OAM_PACKET_IN:
+ ds_put_cstr(string, " PACKET_IN:");
+ break;
+
+ case OAM_PORT_STATUS:
+ ds_put_cstr(string, " PORT_STATUS:");
+ break;
+
+ case OAM_FLOW_REMOVED:
+ ds_put_cstr(string, " FLOW_REMOVED:");
+ break;
+
+ case OAM_ROLE_STATUS:
+ ds_put_cstr(string, " ROLE_STATUS:");
+ break;
+
+ case OAM_TABLE_STATUS:
+ ds_put_cstr(string, " TABLE_STATUS:");
+ break;
+
+ case OAM_REQUESTFORWARD:
+ ds_put_cstr(string, " REQUESTFORWARD:");
+ break;
+ }
+
+ for (j = 0; j < 32; j++) {
+ if (role[i][type] & (1u << j)) {
+ char reasonbuf[OFP_ASYNC_CONFIG_REASON_BUFSIZE];
+ const char *reason;
+
+ reason = ofp_async_config_reason_to_string(j, type,
+ reasonbuf,
+ sizeof reasonbuf);
+ ds_put_format(string, " %s", reason);
+ }
+ }
+ if (!role[i][type]) {
+ ds_put_cstr(string, " (off)");
+ }
+ ds_put_char(string, '\n');
+ }
}
- ds_put_char(string, '\n');
}
}
@@ -3040,7 +3196,7 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
case OFPTYPE_GET_ASYNC_REPLY:
case OFPTYPE_SET_ASYNC_CONFIG:
- ofp_print_nxt_set_async_config(string, ofpmsg_body(oh));
+ ofp_print_nxt_set_async_config(string, oh);
break;
case OFPTYPE_GET_ASYNC_REQUEST:
break;