X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-print.c;h=4c89b3676e7246de9e7d504cd2b4babb1608cd04;hb=90b4feffb9a9031775b949090db6c1c3f963779a;hp=b280a3738b833948e8e48dfd674334bad04ee17f;hpb=db09e4308a18f12d93191d057dc9e2b938ff4649;p=sliver-openvswitch.git diff --git a/lib/ofp-print.c b/lib/ofp-print.c index b280a3738..4c89b3676 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -105,11 +105,11 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh, ds_put_format(string, " table_id=%"PRIu8, pin.table_id); } - if (pin.cookie) { + if (pin.cookie != OVS_BE64_MAX) { ds_put_format(string, " cookie=0x%"PRIx64, ntohll(pin.cookie)); } - ds_put_format(string, " total_len=%"PRIu16" in_port=", pin.total_len); + ds_put_format(string, " total_len=%"PRIuSIZE" in_port=", pin.total_len); ofputil_format_port(pin.fmd.in_port, string); if (pin.fmd.tun_id != htonll(0)) { @@ -142,7 +142,7 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh, ofputil_packet_in_reason_to_string(pin.reason, reasonbuf, sizeof reasonbuf)); - ds_put_format(string, " data_len=%zu", pin.packet_len); + ds_put_format(string, " data_len=%"PRIuSIZE, pin.packet_len); if (pin.buffer_id == UINT32_MAX) { ds_put_format(string, " (unbuffered)"); if (pin.total_len != pin.packet_len) { @@ -185,11 +185,11 @@ ofp_print_packet_out(struct ds *string, const struct ofp_header *oh, ds_put_cstr(string, " in_port="); ofputil_format_port(po.in_port, string); - ds_put_char(string, ' '); + ds_put_cstr(string, " actions="); ofpacts_format(po.ofpacts, po.ofpacts_len, string); if (po.buffer_id == UINT32_MAX) { - ds_put_format(string, " data_len=%zu", po.packet_len); + ds_put_format(string, " data_len=%"PRIuSIZE, po.packet_len); if (verbosity > 0 && po.packet_len > 0) { char *packet = ofp_packet_to_string(po.packet, po.packet_len); ds_put_char(string, '\n'); @@ -540,7 +540,7 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh) case OFP13_VERSION: return; /* no ports in ofp13_switch_features */ default: - NOT_REACHED(); + OVS_NOT_REACHED(); } ofp_print_phy_ports(string, oh->version, &b); @@ -757,7 +757,8 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, int verbosity) protocol = ofputil_protocol_set_tid(protocol, true); ofpbuf_init(&ofpacts, 64); - error = ofputil_decode_flow_mod(&fm, oh, protocol, &ofpacts); + error = ofputil_decode_flow_mod(&fm, oh, protocol, &ofpacts, + OFPP_MAX, 255); if (error) { ofpbuf_uninit(&ofpacts); ofp_print_error(s, error); @@ -817,7 +818,7 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, int verbosity) if (ds_last(s) != ' ') { ds_put_char(s, ' '); } - if (fm.new_cookie != htonll(0) && fm.new_cookie != htonll(UINT64_MAX)) { + if (fm.new_cookie != htonll(0) && fm.new_cookie != OVS_BE64_MAX) { ds_put_format(s, "cookie:0x%"PRIx64" ", ntohll(fm.new_cookie)); } if (fm.cookie_mask != htonll(0)) { @@ -850,6 +851,7 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, int verbosity) } ofp_print_flow_flags(s, fm.flags); + ds_put_cstr(s, "actions="); ofpacts_format(fm.ofpacts, fm.ofpacts_len, s); ofpbuf_uninit(&ofpacts); } @@ -858,10 +860,26 @@ static void ofp_print_duration(struct ds *string, unsigned int sec, unsigned int nsec) { ds_put_format(string, "%u", sec); + + /* If there are no fractional seconds, don't print any decimals. + * + * If the fractional seconds can be expressed exactly as milliseconds, + * print 3 decimals. Open vSwitch provides millisecond precision for most + * time measurements, so printing 3 decimals every time makes it easier to + * spot real changes in flow dumps that refresh themselves quickly. + * + * If the fractional seconds are more precise than milliseconds, print the + * number of decimals needed to express them exactly. + */ if (nsec > 0) { - ds_put_format(string, ".%09u", nsec); - while (string->string[string->length - 1] == '0') { - string->length--; + unsigned int msec = nsec / 1000000; + if (msec * 1000000 == nsec) { + ds_put_format(string, ".%03u", msec); + } else { + ds_put_format(string, ".%09u", nsec); + while (string->string[string->length - 1] == '0') { + string->length--; + } } } ds_put_char(string, 's'); @@ -964,6 +982,114 @@ ofp_print_port_mod(struct ds *string, const struct ofp_header *oh) } } +static void +ofp_print_table_miss_config(struct ds *string, const uint32_t config) +{ + uint32_t table_miss_config = config & OFPTC11_TABLE_MISS_MASK; + + switch (table_miss_config) { + case OFPTC11_TABLE_MISS_CONTROLLER: + ds_put_cstr(string, "controller\n"); + break; + case OFPTC11_TABLE_MISS_CONTINUE: + ds_put_cstr(string, "continue\n"); + break; + case OFPTC11_TABLE_MISS_DROP: + ds_put_cstr(string, "drop\n"); + break; + default: + ds_put_cstr(string, "Unknown\n"); + break; + } +} + +static void +ofp_print_table_mod(struct ds *string, const struct ofp_header *oh) +{ + struct ofputil_table_mod pm; + enum ofperr error; + + error = ofputil_decode_table_mod(oh, &pm); + if (error) { + ofp_print_error(string, error); + return; + } + + if (pm.table_id == 0xff) { + ds_put_cstr(string, " table_id: ALL_TABLES"); + } else { + ds_put_format(string, " table_id=%"PRIu8, pm.table_id); + } + + ds_put_cstr(string, ", flow_miss_config="); + ofp_print_table_miss_config(string, pm.config); +} + +static void +ofp_print_queue_get_config_request(struct ds *string, + const struct ofp_header *oh) +{ + enum ofperr error; + ofp_port_t port; + + error = ofputil_decode_queue_get_config_request(oh, &port); + if (error) { + ofp_print_error(string, error); + return; + } + + ds_put_cstr(string, " port="); + ofputil_format_port(port, string); +} + +static void +print_queue_rate(struct ds *string, const char *name, unsigned int rate) +{ + if (rate <= 1000) { + ds_put_format(string, " %s:%u.%u%%", name, rate / 10, rate % 10); + } else if (rate < UINT16_MAX) { + ds_put_format(string, " %s:(disabled)", name); + } +} + +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'); + + for (;;) { + struct ofputil_queue_config queue; + int retval; + + retval = ofputil_pull_queue_get_config_reply(&b, &queue); + if (retval) { + if (retval != EOF) { + ofp_print_error(string, retval); + } + break; + } + + ds_put_format(string, "queue %"PRIu32":", queue.queue_id); + print_queue_rate(string, "min_rate", queue.min_rate); + print_queue_rate(string, "max_rate", queue.max_rate); + ds_put_char(string, '\n'); + } +} + static void ofp_print_meter_flags(struct ds *s, uint16_t flags) { @@ -1339,6 +1465,7 @@ ofp_print_flow_stats(struct ds *string, struct ofputil_flow_stats *fs) ds_put_char(string, ' '); } + ds_put_cstr(string, "actions="); ofpacts_format(fs->ofpacts, fs->ofpacts_len, string); } @@ -1422,7 +1549,7 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh, { struct ofpbuf b; - ds_put_format(string, " %zu ports\n", ofputil_count_port_stats(oh)); + ds_put_format(string, " %"PRIuSIZE" ports\n", ofputil_count_port_stats(oh)); if (verbosity < 1) { return; } @@ -1536,7 +1663,7 @@ ofp_print_ofpst_table_reply13(struct ds *string, const struct ofp_header *oh, ofpraw_pull_assert(&b); n = b.size / sizeof *ts; - ds_put_format(string, " %zu tables\n", n); + ds_put_format(string, " %"PRIuSIZE" tables\n", n); if (verbosity < 1) { return; } @@ -1566,7 +1693,7 @@ ofp_print_ofpst_table_reply12(struct ds *string, const struct ofp_header *oh, ofpraw_pull_assert(&b); n = b.size / sizeof *ts; - ds_put_format(string, " %zu tables\n", n); + ds_put_format(string, " %"PRIuSIZE" tables\n", n); if (verbosity < 1) { return; } @@ -1593,7 +1720,7 @@ ofp_print_ofpst_table_reply11(struct ds *string, const struct ofp_header *oh, ofpraw_pull_assert(&b); n = b.size / sizeof *ts; - ds_put_format(string, " %zu tables\n", n); + ds_put_format(string, " %"PRIuSIZE" tables\n", n); if (verbosity < 1) { return; } @@ -1633,7 +1760,7 @@ ofp_print_ofpst_table_reply10(struct ds *string, const struct ofp_header *oh, ofpraw_pull_assert(&b); n = b.size / sizeof *ts; - ds_put_format(string, " %zu tables\n", n); + ds_put_format(string, " %"PRIuSIZE" tables\n", n); if (verbosity < 1) { return; } @@ -1678,7 +1805,7 @@ ofp_print_ofpst_table_reply(struct ds *string, const struct ofp_header *oh, break; default: - NOT_REACHED(); + OVS_NOT_REACHED(); } } @@ -1717,7 +1844,7 @@ ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh, { struct ofpbuf b; - ds_put_format(string, " %zu queues\n", ofputil_count_queue_stats(oh)); + ds_put_format(string, " %"PRIuSIZE" queues\n", ofputil_count_queue_stats(oh)); if (verbosity < 1) { return; } @@ -1800,27 +1927,19 @@ ofp_print_echo(struct ds *string, const struct ofp_header *oh, int verbosity) { size_t len = ntohs(oh->length); - ds_put_format(string, " %zu bytes of payload\n", len - sizeof *oh); + ds_put_format(string, " %"PRIuSIZE" bytes of payload\n", len - sizeof *oh); if (verbosity > 1) { ds_put_hex_dump(string, oh + 1, len - sizeof *oh, 0, true); } } 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; @@ -1834,11 +1953,57 @@ ofp_print_role_message(struct ds *string, const struct ofp_header *oh) ds_put_cstr(string, "slave"); break; default: - NOT_REACHED(); + OVS_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: + OVS_NOT_REACHED(); } } @@ -2098,6 +2263,7 @@ ofp_print_nxst_flow_monitor_reply(struct ds *string, if (string->string[string->length - 1] != ' ') { ds_put_char(string, ' '); } + ds_put_cstr(string, "actions="); ofpacts_format(update.ofpacts, update.ofpacts_len, string); } } @@ -2167,6 +2333,7 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type, ds_put_format(s, "watch_group:%"PRIu32",", bucket->watch_group); } + ds_put_cstr(s, "actions="); ofpacts_format(bucket->ofpacts, bucket->ofpacts_len, s); } } @@ -2181,7 +2348,7 @@ ofp_print_group_desc(struct ds *s, const struct ofp_header *oh) struct ofputil_group_desc gd; int retval; - retval = ofputil_decode_group_desc_reply(&gd, &b); + retval = ofputil_decode_group_desc_reply(&gd, &b, oh->version); if (retval) { if (retval != EOF) { ds_put_cstr(s, " ***parse error***"); @@ -2372,8 +2539,6 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_print_group_mod(string, oh); break; - case OFPTYPE_QUEUE_GET_CONFIG_REQUEST: - case OFPTYPE_QUEUE_GET_CONFIG_REPLY: case OFPTYPE_TABLE_FEATURES_STATS_REQUEST: case OFPTYPE_TABLE_FEATURES_STATS_REPLY: ofp_print_not_implemented(string); @@ -2431,6 +2596,10 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_print_port_mod(string, oh); break; + case OFPTYPE_TABLE_MOD: + ofp_print_table_mod(string, oh); + break; + case OFPTYPE_METER_MOD: ofp_print_meter_mod(string, oh); break; @@ -2439,10 +2608,21 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, case OFPTYPE_BARRIER_REPLY: break; + case OFPTYPE_QUEUE_GET_CONFIG_REQUEST: + ofp_print_queue_get_config_request(string, oh); + break; + + case OFPTYPE_QUEUE_GET_CONFIG_REPLY: + ofp_print_queue_get_config_reply(string, oh); + break; + case OFPTYPE_ROLE_REQUEST: case OFPTYPE_ROLE_REPLY: ofp_print_role_message(string, oh); break; + case OFPTYPE_ROLE_STATUS: + ofp_print_role_status_message(string, oh); + break; case OFPTYPE_METER_STATS_REQUEST: case OFPTYPE_METER_CONFIG_STATS_REQUEST: @@ -2582,7 +2762,7 @@ ofp_to_string(const void *oh_, size_t len, int verbosity) if (!len) { ds_put_cstr(&string, "OpenFlow message is empty\n"); } else if (len < sizeof(struct ofp_header)) { - ds_put_format(&string, "OpenFlow packet too short (only %zu bytes):\n", + ds_put_format(&string, "OpenFlow packet too short (only %"PRIuSIZE" bytes):\n", len); } else if (ntohs(oh->length) > len) { enum ofperr error; @@ -2595,11 +2775,11 @@ ofp_to_string(const void *oh_, size_t len, int verbosity) } ds_put_format(&string, - "(***truncated to %zu bytes from %"PRIu16"***)\n", + "(***truncated to %"PRIuSIZE" bytes from %"PRIu16"***)\n", len, ntohs(oh->length)); } else if (ntohs(oh->length) < len) { ds_put_format(&string, - "(***only uses %"PRIu16" bytes out of %zu***)\n", + "(***only uses %"PRIu16" bytes out of %"PRIuSIZE"***)\n", ntohs(oh->length), len); } else { enum ofperr error;