diff options
author | Niti Rohilla <niti.rohilla@tcs.com> | 2015-07-23 17:05:44 +0530 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2015-07-27 10:15:28 -0700 |
commit | 980904823303ef02af605e62a30c9bebda25f1ef (patch) | |
tree | 8eaa7e6ba07398c8225d1c869bdaa003c2bd6753 /lib/ofp-print.c | |
parent | ad2e649834be20dd01b1632799fe778106a96a2d (diff) | |
download | openvswitch-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.c | 238 |
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; |