X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fofp-print.c;h=271b095b7f250c7a5a7cef97a1a5e047666246be;hb=6c6eedc5d6730835a0d9724e2e8cfe9cdf03b07d;hp=6e32d4d3a6e5db211fed4bbe5d66438ced9e1c34;hpb=6c52e6d8c0e54f1876502bda9aeffd20b85f5cde;p=cascardo%2Fovs.git diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 6e32d4d3a..271b095b7 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,58 +94,119 @@ ofp_packet_to_string(const void *data, size_t len) return ds_cstr(&ds); } +static void +format_hex_arg(struct ds *s, const uint8_t *data, size_t len) +{ + for (size_t i = 0; i < len; i++) { + if (i) { + ds_put_char(s, '.'); + } + ds_put_format(s, "%02"PRIx8, data[i]); + } +} + static void ofp_print_packet_in(struct ds *string, const struct ofp_header *oh, int verbosity) { char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE]; - struct ofputil_packet_in pin; - int error; + struct ofputil_packet_in_private pin; + const struct ofputil_packet_in *public = &pin.public; + uint32_t buffer_id; + size_t total_len; + enum ofperr error; - error = ofputil_decode_packet_in(&pin, oh); + error = ofputil_decode_packet_in_private(oh, true, + &pin, &total_len, &buffer_id); if (error) { ofp_print_error(string, error); return; } - if (pin.table_id) { - ds_put_format(string, " table_id=%"PRIu8, pin.table_id); + if (public->table_id) { + ds_put_format(string, " table_id=%"PRIu8, public->table_id); } - if (pin.cookie != OVS_BE64_MAX) { - ds_put_format(string, " cookie=0x%"PRIx64, ntohll(pin.cookie)); + if (public->cookie != OVS_BE64_MAX) { + ds_put_format(string, " cookie=0x%"PRIx64, ntohll(public->cookie)); } - ds_put_format(string, " total_len=%"PRIuSIZE" ", pin.total_len); + ds_put_format(string, " total_len=%"PRIuSIZE" ", total_len); - match_format(&pin.flow_metadata, string, OFP_DEFAULT_PRIORITY); + match_format(&public->flow_metadata, string, OFP_DEFAULT_PRIORITY); ds_put_format(string, " (via %s)", - ofputil_packet_in_reason_to_string(pin.reason, reasonbuf, + ofputil_packet_in_reason_to_string(public->reason, + reasonbuf, sizeof reasonbuf)); - ds_put_format(string, " data_len=%"PRIuSIZE, pin.packet_len); - if (pin.buffer_id == UINT32_MAX) { + ds_put_format(string, " data_len=%"PRIuSIZE, public->packet_len); + if (buffer_id == UINT32_MAX) { ds_put_format(string, " (unbuffered)"); - if (pin.total_len != pin.packet_len) { + if (total_len != public->packet_len) { ds_put_format(string, " (***total_len != data_len***)"); } } else { - ds_put_format(string, " buffer=0x%08"PRIx32, pin.buffer_id); - if (pin.total_len < pin.packet_len) { + ds_put_format(string, " buffer=0x%08"PRIx32, buffer_id); + if (total_len < public->packet_len) { ds_put_format(string, " (***total_len < data_len***)"); } } ds_put_char(string, '\n'); + if (public->userdata_len) { + ds_put_cstr(string, " userdata="); + format_hex_arg(string, pin.public.userdata, pin.public.userdata_len); + ds_put_char(string, '\n'); + } + + if (!uuid_is_zero(&pin.bridge)) { + ds_put_format(string, " continuation.bridge="UUID_FMT"\n", + UUID_ARGS(&pin.bridge)); + } + + if (pin.n_stack) { + ds_put_cstr(string, " continuation.stack="); + for (size_t i = 0; i < pin.n_stack; i++) { + if (i) { + ds_put_char(string, ' '); + } + mf_subvalue_format(&pin.stack[i], string); + } + } + + if (pin.mirrors) { + ds_put_format(string, " continuation.mirrors=0x%"PRIx32"\n", + pin.mirrors); + } + + if (pin.conntracked) { + ds_put_cstr(string, " continuation.conntracked=true\n"); + } + + if (pin.actions_len) { + ds_put_cstr(string, " continuation.actions="); + ofpacts_format(pin.actions, pin.actions_len, string); + ds_put_char(string, '\n'); + } + + if (pin.action_set_len) { + ds_put_cstr(string, " continuation.action_set="); + ofpacts_format(pin.action_set, pin.action_set_len, string); + ds_put_char(string, '\n'); + } + if (verbosity > 0) { - char *packet = ofp_packet_to_string(pin.packet, pin.packet_len); + char *packet = ofp_packet_to_string(public->packet, + public->packet_len); ds_put_cstr(string, packet); free(packet); } if (verbosity > 2) { - ds_put_hex_dump(string, pin.packet, pin.packet_len, 0, false); + ds_put_hex_dump(string, public->packet, public->packet_len, 0, false); } + + ofputil_packet_in_private_destroy(&pin); } static void @@ -452,10 +513,8 @@ static void ofp_print_switch_features(struct ds *string, const struct ofp_header *oh) { struct ofputil_switch_features features; - enum ofperr error; - struct ofpbuf b; - - error = ofputil_decode_switch_features(oh, &features, &b); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); + enum ofperr error = ofputil_pull_switch_features(&b, &features); if (error) { ofp_print_error(string, error); return; @@ -496,25 +555,39 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh) } static void -ofp_print_switch_config(struct ds *string, const struct ofp_switch_config *osc) +ofp_print_switch_config(struct ds *string, + const struct ofputil_switch_config *config) { - enum ofp_config_flags flags; - - flags = ntohs(osc->flags); + ds_put_format(string, " frags=%s", + ofputil_frag_handling_to_string(config->frag)); - ds_put_format(string, " frags=%s", ofputil_frag_handling_to_string(flags)); - flags &= ~OFPC_FRAG_MASK; - - if (flags & OFPC_INVALID_TTL_TO_CONTROLLER) { + if (config->invalid_ttl_to_controller > 0) { ds_put_format(string, " invalid_ttl_to_controller"); - flags &= ~OFPC_INVALID_TTL_TO_CONTROLLER; } - if (flags) { - ds_put_format(string, " ***unknown flags 0x%04"PRIx16"***", flags); + ds_put_format(string, " miss_send_len=%"PRIu16"\n", config->miss_send_len); +} + +static void +ofp_print_set_config(struct ds *string, const struct ofp_header *oh) +{ + struct ofputil_switch_config config; + enum ofperr error; + + error = ofputil_decode_set_config(oh, &config); + if (error) { + ofp_print_error(string, error); + return; } + ofp_print_switch_config(string, &config); +} - ds_put_format(string, " miss_send_len=%"PRIu16"\n", ntohs(osc->miss_send_len)); +static void +ofp_print_get_config_reply(struct ds *string, const struct ofp_header *oh) +{ + struct ofputil_switch_config config; + ofputil_decode_get_config_reply(oh, &config); + ofp_print_switch_config(string, &config); } static void print_wild(struct ds *string, const char *leader, int is_wild, @@ -920,7 +993,7 @@ ofp_print_port_mod(struct ds *string, const struct ofp_header *oh) return; } - ds_put_cstr(string, "port: "); + ds_put_cstr(string, " port: "); ofputil_format_port(pm.port_no, string); ds_put_format(string, ": addr:"ETH_ADDR_FMT"\n", ETH_ADDR_ARGS(pm.hw_addr)); @@ -990,6 +1063,18 @@ ofputil_put_eviction_flags(struct ds *string, uint32_t eviction_flags) } } +static const char * +ofputil_table_vacancy_to_string(enum ofputil_table_vacancy vacancy) +{ + switch (vacancy) { + case OFPUTIL_TABLE_VACANCY_DEFAULT: return "default"; + case OFPUTIL_TABLE_VACANCY_ON: return "on"; + case OFPUTIL_TABLE_VACANCY_OFF: return "off"; + default: return "***error***"; + } + +} + static void ofp_print_table_mod(struct ds *string, const struct ofp_header *oh) { @@ -1020,6 +1105,15 @@ ofp_print_table_mod(struct ds *string, const struct ofp_header *oh) ds_put_cstr(string, "eviction_flags="); ofputil_put_eviction_flags(string, pm.eviction_flags); } + if (pm.vacancy != OFPUTIL_TABLE_VACANCY_DEFAULT) { + ds_put_format(string, ", vacancy=%s", + ofputil_table_vacancy_to_string(pm.vacancy)); + if (pm.vacancy == OFPUTIL_TABLE_VACANCY_ON) { + ds_put_format(string, " vacancy:%"PRIu8"" + ",%"PRIu8"", pm.table_vacancy.vacancy_down, + pm.table_vacancy.vacancy_up); + } + } } /* This function will print the Table description properties. */ @@ -1032,6 +1126,39 @@ ofp_print_table_desc(struct ds *string, const struct ofputil_table_desc *td) ofputil_table_eviction_to_string(td->eviction)); ofputil_put_eviction_flags(string, td->eviction_flags); ds_put_char(string, '\n'); + ds_put_format(string, " vacancy=%s", + ofputil_table_vacancy_to_string(td->vacancy)); + if (td->vacancy == OFPUTIL_TABLE_VACANCY_ON) { + ds_put_format(string, " vacancy_down=%"PRIu8"%%", + td->table_vacancy.vacancy_down); + ds_put_format(string, " vacancy_up=%"PRIu8"%%", + td->table_vacancy.vacancy_up); + ds_put_format(string, " vacancy=%"PRIu8"%%", + td->table_vacancy.vacancy); + } + ds_put_char(string, '\n'); +} + +static void +ofp_print_table_status_message(struct ds *string, const struct ofp_header *oh) +{ + struct ofputil_table_status ts; + enum ofperr error; + + error = ofputil_decode_table_status(oh, &ts); + if (error) { + ofp_print_error(string, error); + return; + } + + if (ts.reason == OFPTR_VACANCY_DOWN) { + ds_put_format(string, " reason=VACANCY_DOWN"); + } else if (ts.reason == OFPTR_VACANCY_UP) { + ds_put_format(string, " reason=VACANCY_UP"); + } + + ds_put_format(string, "\ntable_desc:-"); + ofp_print_table_desc(string, &ts.desc); } static void @@ -1040,8 +1167,9 @@ ofp_print_queue_get_config_request(struct ds *string, { enum ofperr error; ofp_port_t port; + uint32_t queue; - error = ofputil_decode_queue_get_config_request(oh, &port); + error = ofputil_decode_queue_get_config_request(oh, &port, &queue); if (error) { ofp_print_error(string, error); return; @@ -1049,6 +1177,11 @@ ofp_print_queue_get_config_request(struct ds *string, ds_put_cstr(string, " port="); ofputil_format_port(port, string); + + if (queue != OFPQ_ALL) { + ds_put_cstr(string, " queue="); + ofp_print_queue_name(string, queue); + } } static void @@ -1065,21 +1198,10 @@ static void ofp_print_queue_get_config_reply(struct ds *string, const struct ofp_header *oh) { - enum ofperr error; - struct ofpbuf b; - ofp_port_t port; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - error = ofputil_decode_queue_get_config_reply(&b, &port); - if (error) { - ofp_print_error(string, error); - return; - } - - ds_put_cstr(string, " port="); - ofputil_format_port(port, string); - ds_put_char(string, '\n'); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); + ofp_port_t port = 0; + ds_put_char(string, ' '); for (;;) { struct ofputil_queue_config queue; int retval; @@ -1089,10 +1211,19 @@ ofp_print_queue_get_config_reply(struct ds *string, if (retval != EOF) { ofp_print_error(string, retval); } + ds_chomp(string, ' '); break; } - ds_put_format(string, "queue %"PRIu32":", queue.queue_id); + if (queue.port != port) { + port = queue.port; + + ds_put_cstr(string, "port="); + ofputil_format_port(port, string); + ds_put_char(string, '\n'); + } + + ds_put_format(string, "queue %"PRIu32":", queue.queue); print_queue_rate(string, "min_rate", queue.min_rate); print_queue_rate(string, "max_rate", queue.max_rate); ds_put_char(string, '\n'); @@ -1185,21 +1316,9 @@ ofp_print_meter_config(struct ds *s, const struct ofputil_meter_config *mc) } static void -ofp_print_meter_mod(struct ds *s, const struct ofp_header *oh) +ofp_print_meter_mod__(struct ds *s, const struct ofputil_meter_mod *mm) { - struct ofputil_meter_mod mm; - struct ofpbuf bands; - enum ofperr error; - - ofpbuf_init(&bands, 64); - error = ofputil_decode_meter_mod(oh, &mm, &bands); - if (error) { - ofpbuf_uninit(&bands); - ofp_print_error(s, error); - return; - } - - switch (mm.command) { + switch (mm->command) { case OFPMC13_ADD: ds_put_cstr(s, " ADD "); break; @@ -1210,10 +1329,26 @@ ofp_print_meter_mod(struct ds *s, const struct ofp_header *oh) ds_put_cstr(s, " DEL "); break; default: - ds_put_format(s, " cmd:%d ", mm.command); + ds_put_format(s, " cmd:%d ", mm->command); } - ofp_print_meter_config(s, &mm.meter); + ofp_print_meter_config(s, &mm->meter); +} + +static void +ofp_print_meter_mod(struct ds *s, const struct ofp_header *oh) +{ + struct ofputil_meter_mod mm; + struct ofpbuf bands; + enum ofperr error; + + ofpbuf_init(&bands, 64); + error = ofputil_decode_meter_mod(oh, &mm, &bands); + if (error) { + ofp_print_error(s, error); + } else { + ofp_print_meter_mod__(s, &mm); + } ofpbuf_uninit(&bands); } @@ -1278,10 +1413,9 @@ ofp_print_meter_features_reply(struct ds *s, const struct ofp_header *oh) static void ofp_print_meter_config_reply(struct ds *s, const struct ofp_header *oh) { + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); struct ofpbuf bands; - struct ofpbuf b; - ofpbuf_use_const(&b, oh, ntohs(oh->length)); ofpbuf_init(&bands, 64); for (;;) { struct ofputil_meter_config mc; @@ -1303,10 +1437,9 @@ ofp_print_meter_config_reply(struct ds *s, const struct ofp_header *oh) static void ofp_print_meter_stats_reply(struct ds *s, const struct ofp_header *oh) { + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); struct ofpbuf bands; - struct ofpbuf b; - ofpbuf_use_const(&b, oh, ntohs(oh->length)); ofpbuf_init(&bands, 64); for (;;) { struct ofputil_meter_stats ms; @@ -1485,10 +1618,9 @@ ofp_print_flow_stats(struct ds *string, struct ofputil_flow_stats *fs) static void ofp_print_flow_stats_reply(struct ds *string, const struct ofp_header *oh) { + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); struct ofpbuf ofpacts; - struct ofpbuf b; - ofpbuf_use_const(&b, oh, ntohs(oh->length)); ofpbuf_init(&ofpacts, 64); for (;;) { struct ofputil_flow_stats fs; @@ -1560,14 +1692,12 @@ static void ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh, int verbosity) { - struct ofpbuf b; - ds_put_format(string, " %"PRIuSIZE" ports\n", ofputil_count_port_stats(oh)); if (verbosity < 1) { return; } - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_port_stats ps; int retval; @@ -1613,9 +1743,7 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh, static void ofp_print_table_stats_reply(struct ds *string, const struct ofp_header *oh) { - struct ofpbuf b; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); ofpraw_pull_assert(&b); struct ofputil_table_features prev_features; @@ -1664,7 +1792,7 @@ ofp_print_ofpst_queue_request(struct ds *string, const struct ofp_header *oh) return; } - ds_put_cstr(string, "port="); + ds_put_cstr(string, " port="); ofputil_format_port(oqsr.port_no, string); ds_put_cstr(string, " queue="); @@ -1675,14 +1803,12 @@ static void ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh, int verbosity) { - struct ofpbuf b; - ds_put_format(string, " %"PRIuSIZE" queues\n", ofputil_count_queue_stats(oh)); if (verbosity < 1) { return; } - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_queue_stats qs; int retval; @@ -1736,9 +1862,7 @@ static void ofp_print_ofpst_port_desc_reply(struct ds *string, const struct ofp_header *oh) { - struct ofpbuf b; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); ofpraw_pull_assert(&b); ds_put_char(string, '\n'); ofp_print_phy_ports(string, oh->version, &b); @@ -1843,6 +1967,7 @@ ofp_print_role_status_message(struct ds *string, const struct ofp_header *oh) case OFPCRR_EXPERIMENTER: ds_put_cstr(string, "experimenter_data_changed"); break; + case OFPCRR_N_REASONS: default: OVS_NOT_REACHED(); } @@ -1901,6 +2026,7 @@ ofp_port_reason_to_string(enum ofp_port_reason reason, case OFPPR_MODIFY: return "modify"; + case OFPPR_N_REASONS: default: snprintf(reasonbuf, bufsize, "%d", (int) reason); return reasonbuf; @@ -1924,6 +2050,7 @@ ofp_role_reason_to_string(enum ofp14_controller_role_reason reason, case OFPCRR_EXPERIMENTER: return "experimenter_data_changed"; + case OFPCRR_N_REASONS: default: snprintf(reasonbuf, bufsize, "%d", (int) reason); return reasonbuf; @@ -1964,6 +2091,7 @@ ofp_requestforward_reason_to_string(enum ofp14_requestforward_reason reason, case OFPRFR_METER_MOD: return "meter_mod_request"; + case OFPRFR_N_REASONS: default: snprintf(reasonbuf, bufsize, "%d", (int) reason); return reasonbuf; @@ -2003,124 +2131,44 @@ ofp_async_config_reason_to_string(uint32_t reason, #define OFP_ASYNC_CONFIG_REASON_BUFSIZE (INT_STRLEN(int) + 1) static void -ofp_print_nxt_set_async_config(struct ds *string, - const struct ofp_header *oh) +ofp_print_set_async_config(struct ds *string, const struct ofp_header *oh, + enum ofptype type) { - int i, j; - enum ofpraw raw; - - ofpraw_decode(&raw, oh); + struct ofputil_async_cfg basis = OFPUTIL_ASYNC_CFG_INIT; + struct ofputil_async_cfg ac; - 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_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, - sizeof reasonbuf); - ds_put_format(string, " %s", reason); - } - } - 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; + bool is_reply = type == OFPTYPE_GET_ASYNC_REPLY; + enum ofperr error = ofputil_decode_set_async_config(oh, is_reply, + &basis, &ac); + if (error) { + ofp_print_error(string, error); + return; + } - 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'); + for (int i = 0; i < 2; i++) { + ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave"); + for (uint32_t type = 0; type < OAM_N_TYPES; type++) { + ds_put_format(string, "%16s:", + ofputil_async_msg_type_to_string(type)); - 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]; + uint32_t role = i == 0 ? ac.master[type] : ac.slave[type]; + for (int j = 0; j < 32; j++) { + if (role & (1u << j)) { + char reasonbuf[OFP_ASYNC_CONFIG_REASON_BUFSIZE]; const char *reason; - reason = ofp_flow_removed_reason_to_string(j, reasonbuf, - sizeof reasonbuf); - ds_put_format(string, " %s", reason); + reason = ofp_async_config_reason_to_string( + j, type, reasonbuf, sizeof reasonbuf); + if (reason[0]) { + ds_put_format(string, " %s", reason); + } } } - if (!nac->flow_removed_mask[i]) { + if (!role) { ds_put_cstr(string, " (off)"); } ds_put_char(string, '\n'); } - } 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'); - } - } } } @@ -2160,9 +2208,7 @@ static void ofp_print_nxst_flow_monitor_request(struct ds *string, const struct ofp_header *oh) { - struct ofpbuf b; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_flow_monitor_request request; int retval; @@ -2199,11 +2245,9 @@ ofp_print_nxst_flow_monitor_reply(struct ds *string, const struct ofp_header *oh) { uint64_t ofpacts_stub[1024 / 8]; - struct ofpbuf ofpacts; - struct ofpbuf b; + struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub); for (;;) { char reasonbuf[OFP_FLOW_REMOVED_REASON_BUFSIZE]; struct ofputil_flow_update update; @@ -2333,7 +2377,8 @@ ofp_print_bucket_id(struct ds *s, const char *label, uint32_t bucket_id, static void ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type, - struct ovs_list *p_buckets, struct ofputil_group_props *props, + const struct ovs_list *p_buckets, + const struct ofputil_group_props *props, enum ofp_version ofp_version, bool suppress_type) { struct ofputil_bucket *bucket; @@ -2347,22 +2392,20 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type, } if (props->selection_method[0]) { - size_t mark, start; - - ds_put_format(s, ",selection_method=%s,", props->selection_method); + ds_put_format(s, ",selection_method=%s", props->selection_method); if (props->selection_method_param) { - ds_put_format(s, "selection_method_param=%"PRIu64",", + ds_put_format(s, ",selection_method_param=%"PRIu64, props->selection_method_param); } - /* Allow rewinding to immediately before the trailing ',' */ - mark = s->length - 1; - - ds_put_cstr(s, "fields="); - start = s->length; - oxm_format_field_array(s, &props->fields); - if (s->length == start) { - ds_truncate(s, mark); + size_t n = bitmap_count1(props->fields.used.bm, MFF_N_IDS); + if (n == 1) { + ds_put_cstr(s, ",fields="); + oxm_format_field_array(s, &props->fields); + } else if (n > 1) { + ds_put_cstr(s, ",fields("); + oxm_format_field_array(s, &props->fields); + ds_put_char(s, ')'); } } @@ -2382,7 +2425,7 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type, if (bucket->watch_port != OFPP_NONE) { ds_put_format(s, "watch_port:%"PRIu32",", bucket->watch_port); } - if (bucket->watch_group != OFPG11_ANY) { + if (bucket->watch_group != OFPG_ANY) { ds_put_format(s, "watch_group:%"PRIu32",", bucket->watch_group); } @@ -2406,9 +2449,7 @@ ofp_print_ofpst_group_desc_request(struct ds *string, static void ofp_print_group_desc(struct ds *s, const struct ofp_header *oh) { - struct ofpbuf b; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_group_desc gd; int retval; @@ -2448,11 +2489,7 @@ ofp_print_ofpst_group_request(struct ds *string, const struct ofp_header *oh) static void ofp_print_group_stats(struct ds *s, const struct ofp_header *oh) { - struct ofpbuf b; - uint32_t bucket_i; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_group_stats gs; int retval; @@ -2479,7 +2516,7 @@ ofp_print_group_stats(struct ds *s, const struct ofp_header *oh) ds_put_format(s, "packet_count=%"PRIu64",", gs.packet_count); ds_put_format(s, "byte_count=%"PRIu64"", gs.byte_count); - for (bucket_i = 0; bucket_i < gs.n_buckets; bucket_i++) { + for (uint32_t bucket_i = 0; bucket_i < gs.n_buckets; bucket_i++) { if (gs.bucket_stats[bucket_i].packet_count != UINT64_MAX) { ds_put_format(s, ",bucket%"PRIu32":", bucket_i); ds_put_format(s, "packet_count=%"PRIu64",", gs.bucket_stats[bucket_i].packet_count); @@ -2529,22 +2566,15 @@ ofp_print_group_features(struct ds *string, const struct ofp_header *oh) } static void -ofp_print_group_mod(struct ds *s, const struct ofp_header *oh) +ofp_print_group_mod__(struct ds *s, enum ofp_version ofp_version, + const struct ofputil_group_mod *gm) { - struct ofputil_group_mod gm; - int error; bool bucket_command = false; - error = ofputil_decode_group_mod(oh, &gm); - if (error) { - ofp_print_error(s, error); - return; - } - ds_put_char(s, '\n'); ds_put_char(s, ' '); - switch (gm.command) { + switch (gm->command) { case OFPGC11_ADD: ds_put_cstr(s, "ADD"); break; @@ -2568,17 +2598,31 @@ ofp_print_group_mod(struct ds *s, const struct ofp_header *oh) break; default: - ds_put_format(s, "cmd:%"PRIu16"", gm.command); + ds_put_format(s, "cmd:%"PRIu16"", gm->command); } ds_put_char(s, ' '); if (bucket_command) { ofp_print_bucket_id(s, "command_bucket_id:", - gm.command_bucket_id, oh->version); + gm->command_bucket_id, ofp_version); } - ofp_print_group(s, gm.group_id, gm.type, &gm.buckets, &gm.props, - oh->version, bucket_command); + ofp_print_group(s, gm->group_id, gm->type, &gm->buckets, &gm->props, + ofp_version, bucket_command); +} + +static void +ofp_print_group_mod(struct ds *s, const struct ofp_header *oh) +{ + struct ofputil_group_mod gm; + int error; + + error = ofputil_decode_group_mod(oh, &gm); + if (error) { + ofp_print_error(s, error); + return; + } + ofp_print_group_mod__(s, oh->version, &gm); ofputil_bucket_list_destroy(&gm.buckets); } @@ -2842,9 +2886,7 @@ ofp_print_table_features(struct ds *s, static void ofp_print_table_features_reply(struct ds *s, const struct ofp_header *oh) { - struct ofpbuf b; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); struct ofputil_table_features prev; for (int i = 0; ; i++) { @@ -2868,10 +2910,7 @@ ofp_print_table_features_reply(struct ds *s, const struct ofp_header *oh) static void ofp_print_table_desc_reply(struct ds *s, const struct ofp_header *oh) { - struct ofpbuf b; - - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - + struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_table_desc td; int retval; @@ -2951,7 +2990,6 @@ ofp_print_bundle_add(struct ds *s, const struct ofp_header *oh, int verbosity) { int error; struct ofputil_bundle_add_msg badd; - char *msg; error = ofputil_decode_bundle_add(oh, &badd, NULL); if (error) { @@ -2965,16 +3003,14 @@ ofp_print_bundle_add(struct ds *s, const struct ofp_header *oh, int verbosity) ofp_print_bit_names(s, badd.flags, bundle_flags_to_name, ' '); ds_put_char(s, '\n'); - msg = ofp_to_string(badd.msg, ntohs(badd.msg->length), verbosity); - if (msg) { - ds_put_cstr(s, msg); - } + char *msg = ofp_to_string(badd.msg, ntohs(badd.msg->length), verbosity); + ds_put_and_free_cstr(s, msg); } static void -print_geneve_table(struct ds *s, struct ovs_list *mappings) +print_tlv_table(struct ds *s, struct ovs_list *mappings) { - struct ofputil_geneve_map *map; + struct ofputil_tlv_map *map; ds_put_cstr(s, " mapping table:\n"); ds_put_cstr(s, " class\ttype\tlength\tmatch field\n"); @@ -2989,12 +3025,12 @@ print_geneve_table(struct ds *s, struct ovs_list *mappings) } static void -ofp_print_geneve_table_mod(struct ds *s, const struct ofp_header *oh) +ofp_print_tlv_table_mod(struct ds *s, const struct ofp_header *oh) { int error; - struct ofputil_geneve_table_mod gtm; + struct ofputil_tlv_table_mod ttm; - error = ofputil_decode_geneve_table_mod(oh, >m); + error = ofputil_decode_tlv_table_mod(oh, &ttm); if (error) { ofp_print_error(s, error); return; @@ -3002,34 +3038,34 @@ ofp_print_geneve_table_mod(struct ds *s, const struct ofp_header *oh) ds_put_cstr(s, "\n "); - switch (gtm.command) { - case NXGTMC_ADD: + switch (ttm.command) { + case NXTTMC_ADD: ds_put_cstr(s, "ADD"); break; - case NXGTMC_DELETE: + case NXTTMC_DELETE: ds_put_cstr(s, "DEL"); break; - case NXGTMC_CLEAR: + case NXTTMC_CLEAR: ds_put_cstr(s, "CLEAR"); break; } - if (gtm.command != NXGTMC_CLEAR) { - print_geneve_table(s, >m.mappings); + if (ttm.command != NXTTMC_CLEAR) { + print_tlv_table(s, &ttm.mappings); } - ofputil_uninit_geneve_table(>m.mappings); + ofputil_uninit_tlv_table(&ttm.mappings); } static void -ofp_print_geneve_table_reply(struct ds *s, const struct ofp_header *oh) +ofp_print_tlv_table_reply(struct ds *s, const struct ofp_header *oh) { int error; - struct ofputil_geneve_table_reply gtr; - struct ofputil_geneve_map *map; + struct ofputil_tlv_table_reply ttr; + struct ofputil_tlv_map *map; int allocated_space = 0; - error = ofputil_decode_geneve_table_reply(oh, >r); + error = ofputil_decode_tlv_table_reply(oh, &ttr); if (error) { ofp_print_error(s, error); return; @@ -3037,17 +3073,50 @@ ofp_print_geneve_table_reply(struct ds *s, const struct ofp_header *oh) ds_put_char(s, '\n'); - LIST_FOR_EACH (map, list_node, >r.mappings) { + LIST_FOR_EACH (map, list_node, &ttr.mappings) { allocated_space += map->option_len; } ds_put_format(s, " max option space=%"PRIu32" max fields=%"PRIu16"\n", - gtr.max_option_space, gtr.max_fields); + ttr.max_option_space, ttr.max_fields); ds_put_format(s, " allocated option space=%d\n", allocated_space); ds_put_char(s, '\n'); - print_geneve_table(s, >r.mappings); + print_tlv_table(s, &ttr.mappings); + + ofputil_uninit_tlv_table(&ttr.mappings); +} - ofputil_uninit_geneve_table(>r.mappings); +/* This function will print the request forward message. The reason for + * request forward is taken from rf.request.type */ +static void +ofp_print_requestforward(struct ds *string, const struct ofp_header *oh) +{ + struct ofputil_requestforward rf; + enum ofperr error; + + error = ofputil_decode_requestforward(oh, &rf); + if (error) { + ofp_print_error(string, error); + return; + } + + ds_put_cstr(string, " reason="); + + switch (rf.reason) { + case OFPRFR_GROUP_MOD: + ds_put_cstr(string, "group_mod"); + ofp_print_group_mod__(string, oh->version, rf.group_mod); + break; + + case OFPRFR_METER_MOD: + ds_put_cstr(string, "meter_mod"); + ofp_print_meter_mod__(string, rf.meter_mod); + break; + + case OFPRFR_N_REASONS: + OVS_NOT_REACHED(); + } + ofputil_destroy_requestforward(&rf); } static void @@ -3057,8 +3126,9 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, const void *msg = oh; ofp_header_to_string__(oh, raw, string); - switch (ofptype_from_ofpraw(raw)) { + enum ofptype type = ofptype_from_ofpraw(raw); + switch (type) { case OFPTYPE_GROUP_STATS_REQUEST: ofp_print_stats(string, oh); ofp_print_ofpst_group_request(string, oh); @@ -3123,8 +3193,11 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, break; case OFPTYPE_GET_CONFIG_REPLY: + ofp_print_get_config_reply(string, oh); + break; + case OFPTYPE_SET_CONFIG: - ofp_print_switch_config(string, ofpmsg_body(oh)); + ofp_print_set_config(string, oh); break; case OFPTYPE_PACKET_IN: @@ -3179,6 +3252,14 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_print_role_status_message(string, oh); break; + case OFPTYPE_REQUESTFORWARD: + ofp_print_requestforward(string, oh); + break; + + case OFPTYPE_TABLE_STATUS: + ofp_print_table_status_message(string, oh); + break; + case OFPTYPE_METER_STATS_REQUEST: case OFPTYPE_METER_CONFIG_STATS_REQUEST: ofp_print_stats(string, oh); @@ -3286,7 +3367,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, oh); + ofp_print_set_async_config(string, oh, type); break; case OFPTYPE_GET_ASYNC_REQUEST: break; @@ -3314,17 +3395,20 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_print_bundle_add(string, msg, verbosity); break; - case OFPTYPE_NXT_GENEVE_TABLE_MOD: - ofp_print_geneve_table_mod(string, msg); + case OFPTYPE_NXT_TLV_TABLE_MOD: + ofp_print_tlv_table_mod(string, msg); break; - case OFPTYPE_NXT_GENEVE_TABLE_REQUEST: + case OFPTYPE_NXT_TLV_TABLE_REQUEST: break; - case OFPTYPE_NXT_GENEVE_TABLE_REPLY: - ofp_print_geneve_table_reply(string, msg); + case OFPTYPE_NXT_TLV_TABLE_REPLY: + ofp_print_tlv_table_reply(string, msg); break; + case OFPTYPE_NXT_RESUME: + ofp_print_packet_in(string, msg, verbosity); + break; } }