X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofp-print.c;h=fcc6d254aa596e179f83bea1b9563bb0658ea3e1;hb=refs%2Fheads%2Fmanual;hp=678962570b740d05f65162dea2b58793de795094;hpb=78a3fff6c3b2f7943bcfd7301c666934834d2a0e;p=openvswitch diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 67896257..fcc6d254 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -63,7 +63,7 @@ ofp_packet_to_string(const void *data, size_t len) struct flow flow; ofpbuf_use_const(&buf, data, len); - flow_extract(&buf, 0, 0, 0, &flow); + flow_extract(&buf, 0, 0, NULL, 0, &flow); flow_format(&ds, &flow); if (buf.l7) { @@ -492,8 +492,13 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh) } ds_put_format(string, " dpid:%016"PRIx64"\n", features.datapath_id); - ds_put_format(string, "n_tables:%"PRIu8", n_buffers:%"PRIu32"\n", + + ds_put_format(string, "n_tables:%"PRIu8", n_buffers:%"PRIu32, features.n_tables, features.n_buffers); + if (features.auxiliary_id) { + ds_put_format(string, ", auxiliary_id:%"PRIu8, features.auxiliary_id); + } + ds_put_char(string, '\n'); ds_put_cstr(string, "capabilities: "); ofp_print_bit_names(string, features.capabilities, @@ -510,6 +515,8 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh) case OFP11_VERSION: case OFP12_VERSION: break; + case OFP13_VERSION: + return; /* no ports in ofp13_switch_features */ default: NOT_REACHED(); } @@ -617,6 +624,8 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity) } } else if (om->dl_type == htons(ETH_TYPE_ARP)) { ds_put_cstr(&f, "arp,"); + } else if (om->dl_type == htons(ETH_TYPE_RARP)){ + ds_put_cstr(&f, "rarp,"); } else { skip_type = false; } @@ -642,7 +651,8 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity) (w & OFPFW10_NW_DST_MASK) >> OFPFW10_NW_DST_SHIFT, verbosity); if (!skip_proto) { - if (om->dl_type == htons(ETH_TYPE_ARP)) { + if (om->dl_type == htons(ETH_TYPE_ARP) || + om->dl_type == htons(ETH_TYPE_RARP)) { print_wild(&f, "arp_op=", w & OFPFW10_NW_PROTO, verbosity, "%u", om->nw_proto); } else { @@ -669,6 +679,33 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity) return ds_cstr(&f); } +static void +ofp_print_flow_flags(struct ds *s, uint16_t flags) +{ + if (flags & OFPFF_SEND_FLOW_REM) { + ds_put_cstr(s, "send_flow_rem "); + } + if (flags & OFPFF_CHECK_OVERLAP) { + ds_put_cstr(s, "check_overlap "); + } + if (flags & OFPFF12_RESET_COUNTS) { + ds_put_cstr(s, "reset_counts "); + } + if (flags & OFPFF13_NO_PKT_COUNTS) { + ds_put_cstr(s, "no_packet_counts "); + } + if (flags & OFPFF13_NO_BYT_COUNTS) { + ds_put_cstr(s, "no_byte_counts "); + } + + flags &= ~(OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP + | OFPFF12_RESET_COUNTS + | OFPFF13_NO_PKT_COUNTS | OFPFF13_NO_BYT_COUNTS); + if (flags) { + ds_put_format(s, "flags:0x%"PRIx16" ", flags); + } +} + static void ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, int verbosity) { @@ -743,7 +780,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)) { + if (fm.new_cookie != htonll(0) && fm.new_cookie != htonll(UINT64_MAX)) { ds_put_format(s, "cookie:0x%"PRIx64" ", ntohll(fm.new_cookie)); } if (fm.cookie_mask != htonll(0)) { @@ -762,28 +799,13 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, int verbosity) if (fm.buffer_id != UINT32_MAX) { ds_put_format(s, "buf:0x%"PRIx32" ", fm.buffer_id); } - if (fm.out_port != OFPP_NONE) { + if (fm.out_port != OFPP_ANY) { ds_put_format(s, "out_port:"); ofputil_format_port(fm.out_port, s); ds_put_char(s, ' '); } if (fm.flags != 0) { - uint16_t flags = fm.flags; - - if (flags & OFPFF_SEND_FLOW_REM) { - ds_put_cstr(s, "send_flow_rem "); - } - if (flags & OFPFF_CHECK_OVERLAP) { - ds_put_cstr(s, "check_overlap "); - } - if (flags & OFPFF10_EMERG) { - ds_put_cstr(s, "emerg "); - } - - flags &= ~(OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF10_EMERG); - if (flags) { - ds_put_format(s, "flags:0x%"PRIx16" ", flags); - } + ofp_print_flow_flags(s, fm.flags); } ofpacts_format(fm.ofpacts, fm.ofpacts_len, s); @@ -843,6 +865,10 @@ ofp_print_flow_removed(struct ds *string, const struct ofp_header *oh) ds_put_format(string, " reason=%s", ofp_flow_removed_reason_to_string(fr.reason)); + if (fr.table_id != 255) { + ds_put_format(string, " table_id=%"PRIu8, fr.table_id); + } + if (fr.cookie != htonll(0)) { ds_put_format(string, " cookie:0x%"PRIx64, ntohll(fr.cookie)); } @@ -896,6 +922,23 @@ ofp_print_error(struct ds *string, enum ofperr error) ds_put_format(string, "***decode error: %s***\n", ofperr_get_name(error)); } +static void +ofp_print_hello(struct ds *string, const struct ofp_header *oh) +{ + uint32_t allowed_versions; + bool ok; + + ok = ofputil_decode_hello(oh, &allowed_versions); + + ds_put_cstr(string, "\n version bitmap: "); + ofputil_format_version_bitmap(string, allowed_versions); + + if (!ok) { + ds_put_cstr(string, "\n unknown data in hello:\n"); + ds_put_hex_dump(string, oh, ntohs(oh->length), 0, true); + } +} + static void ofp_print_error_msg(struct ds *string, const struct ofp_header *oh) { @@ -979,7 +1022,7 @@ ofp_print_flow_stats_request(struct ds *string, const struct ofp_header *oh) ds_put_format(string, " table=%"PRIu8, fsr.table_id); } - if (fsr.out_port != OFPP_NONE) { + if (fsr.out_port != OFPP_ANY) { ds_put_cstr(string, " out_port="); ofputil_format_port(fsr.out_port, string); } @@ -1004,6 +1047,9 @@ ofp_print_flow_stats(struct ds *string, struct ofputil_flow_stats *fs) if (fs->hard_timeout != OFP_FLOW_PERMANENT) { ds_put_format(string, "hard_timeout=%"PRIu16", ", fs->hard_timeout); } + if (fs->flags) { + ofp_print_flow_flags(string, fs->flags); + } if (fs->idle_age >= 0) { ds_put_format(string, "idle_age=%d, ", fs->idle_age); } @@ -1061,11 +1107,9 @@ ofp_print_aggregate_stats_reply(struct ds *string, const struct ofp_header *oh) ds_put_format(string, " flow_count=%"PRIu32, as.flow_count); } -static void print_port_stat(struct ds *string, const char *leader, - const ovs_32aligned_be64 *statp, int more) +static void +print_port_stat(struct ds *string, const char *leader, uint64_t stat, int more) { - uint64_t stat = ntohll(get_32aligned_be64(statp)); - ds_put_cstr(string, leader); if (stat != UINT64_MAX) { ds_put_format(string, "%"PRIu64, stat); @@ -1082,50 +1126,59 @@ static void print_port_stat(struct ds *string, const char *leader, static void ofp_print_ofpst_port_request(struct ds *string, const struct ofp_header *oh) { - const struct ofp10_port_stats_request *psr = ofpmsg_body(oh); - ds_put_format(string, " port_no=%"PRIu16, ntohs(psr->port_no)); + uint16_t ofp10_port; + enum ofperr error; + + error = ofputil_decode_port_stats_request(oh, &ofp10_port); + if (error) { + ofp_print_error(string, error); + return; + } + + ds_put_format(string, " port_no=%2"PRIu16, ofp10_port); } static void ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh, int verbosity) { - struct ofp10_port_stats *ps; struct ofpbuf b; - size_t n; - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - ofpraw_pull_assert(&b); - - n = b.size / sizeof *ps; - ds_put_format(string, " %zu ports\n", n); + ds_put_format(string, " %zu ports\n", ofputil_count_port_stats(oh)); if (verbosity < 1) { return; } + ofpbuf_use_const(&b, oh, ntohs(oh->length)); for (;;) { - ps = ofpbuf_try_pull(&b, sizeof *ps); - if (!ps) { + struct ofputil_port_stats ps; + int retval; + + retval = ofputil_decode_port_stats(&ps, &b); + if (retval) { + if (retval != EOF) { + ds_put_cstr(string, " ***parse error***"); + } return; } - ds_put_format(string, " port %2"PRIu16": ", ntohs(ps->port_no)); + ds_put_format(string, " port %2"PRIu16, ps.port_no); - ds_put_cstr(string, "rx "); - print_port_stat(string, "pkts=", &ps->rx_packets, 1); - print_port_stat(string, "bytes=", &ps->rx_bytes, 1); - print_port_stat(string, "drop=", &ps->rx_dropped, 1); - print_port_stat(string, "errs=", &ps->rx_errors, 1); - print_port_stat(string, "frame=", &ps->rx_frame_err, 1); - print_port_stat(string, "over=", &ps->rx_over_err, 1); - print_port_stat(string, "crc=", &ps->rx_crc_err, 0); + ds_put_cstr(string, ": rx "); + print_port_stat(string, "pkts=", ps.stats.rx_packets, 1); + print_port_stat(string, "bytes=", ps.stats.rx_bytes, 1); + print_port_stat(string, "drop=", ps.stats.rx_dropped, 1); + print_port_stat(string, "errs=", ps.stats.rx_errors, 1); + print_port_stat(string, "frame=", ps.stats.rx_frame_errors, 1); + print_port_stat(string, "over=", ps.stats.rx_over_errors, 1); + print_port_stat(string, "crc=", ps.stats.rx_crc_errors, 0); ds_put_cstr(string, " tx "); - print_port_stat(string, "pkts=", &ps->tx_packets, 1); - print_port_stat(string, "bytes=", &ps->tx_bytes, 1); - print_port_stat(string, "drop=", &ps->tx_dropped, 1); - print_port_stat(string, "errs=", &ps->tx_errors, 1); - print_port_stat(string, "coll=", &ps->collisions, 0); + print_port_stat(string, "pkts=", ps.stats.tx_packets, 1); + print_port_stat(string, "bytes=", ps.stats.tx_bytes, 1); + print_port_stat(string, "drop=", ps.stats.tx_dropped, 1); + print_port_stat(string, "errs=", ps.stats.tx_errors, 1); + print_port_stat(string, "coll=", ps.stats.collisions, 0); } } @@ -1135,6 +1188,11 @@ ofp_print_one_ofpst_table_reply(struct ds *string, enum ofp_version ofp_version, { char name_[OFP_MAX_TABLE_NAME_LEN + 1]; + /* ofp13_table_stats is different */ + if (ofp_version > OFP12_VERSION) { + return; + } + ovs_strlcpy(name_, name, sizeof name_); ds_put_format(string, " %d: %-8s: ", ts->table_id, name_); @@ -1178,6 +1236,36 @@ ofp_print_one_ofpst_table_reply(struct ds *string, enum ofp_version ofp_version, ntohll(ts->metadata_write)); } +static void +ofp_print_ofpst_table_reply13(struct ds *string, const struct ofp_header *oh, + int verbosity) +{ + struct ofp13_table_stats *ts; + struct ofpbuf b; + size_t n; + + ofpbuf_use_const(&b, oh, ntohs(oh->length)); + ofpraw_pull_assert(&b); + + n = b.size / sizeof *ts; + ds_put_format(string, " %zu tables\n", n); + if (verbosity < 1) { + return; + } + + for (;;) { + ts = ofpbuf_try_pull(&b, sizeof *ts); + if (!ts) { + return; + } + ds_put_format(string, + " %d: active=%"PRIu32", lookup=%"PRIu64 \ + ", matched=%"PRIu64"\n", + ts->table_id, ntohl(ts->active_count), + ntohll(ts->lookup_count), ntohll(ts->matched_count)); + } +} + static void ofp_print_ofpst_table_reply12(struct ds *string, const struct ofp_header *oh, int verbosity) @@ -1285,6 +1373,10 @@ ofp_print_ofpst_table_reply(struct ds *string, const struct ofp_header *oh, int verbosity) { switch ((enum ofp_version)oh->version) { + case OFP13_VERSION: + ofp_print_ofpst_table_reply13(string, oh, verbosity); + break; + case OFP12_VERSION: ofp_print_ofpst_table_reply12(string, oh, verbosity); break; @@ -1315,47 +1407,55 @@ ofp_print_queue_name(struct ds *string, uint32_t queue_id) static void ofp_print_ofpst_queue_request(struct ds *string, const struct ofp_header *oh) { - const struct ofp10_queue_stats_request *qsr = ofpmsg_body(oh); + struct ofputil_queue_stats_request oqsr; + enum ofperr error; + + error = ofputil_decode_queue_stats_request(oh, &oqsr); + if (error) { + ds_put_format(string, "***decode error: %s***\n", ofperr_get_name(error)); + return; + } ds_put_cstr(string, "port="); - ofputil_format_port(ntohs(qsr->port_no), string); + ofputil_format_port(oqsr.port_no, string); ds_put_cstr(string, " queue="); - ofp_print_queue_name(string, ntohl(qsr->queue_id)); + ofp_print_queue_name(string, oqsr.queue_id); } static void ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh, int verbosity) { - struct ofp10_queue_stats *qs; struct ofpbuf b; - size_t n; - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - ofpraw_pull_assert(&b); - - n = b.size / sizeof *qs; - ds_put_format(string, " %zu queues\n", n); + ds_put_format(string, " %zu queues\n", ofputil_count_queue_stats(oh)); if (verbosity < 1) { return; } + ofpbuf_use_const(&b, oh, ntohs(oh->length)); for (;;) { - qs = ofpbuf_try_pull(&b, sizeof *qs); - if (!qs) { + struct ofputil_queue_stats qs; + int retval; + + retval = ofputil_decode_queue_stats(&qs, &b); + if (retval) { + if (retval != EOF) { + ds_put_cstr(string, " ***parse error***"); + } return; } ds_put_cstr(string, " port "); - ofputil_format_port(ntohs(qs->port_no), string); + ofputil_format_port(qs.port_no, string); ds_put_cstr(string, " queue "); - ofp_print_queue_name(string, ntohl(qs->queue_id)); + ofp_print_queue_name(string, qs.queue_id); ds_put_cstr(string, ": "); - print_port_stat(string, "bytes=", &qs->tx_bytes, 1); - print_port_stat(string, "pkts=", &qs->tx_packets, 1); - print_port_stat(string, "errors=", &qs->tx_errors, 0); + print_port_stat(string, "bytes=", qs.stats.tx_bytes, 1); + print_port_stat(string, "pkts=", qs.stats.tx_packets, 1); + print_port_stat(string, "errors=", qs.stats.tx_errors, 0); } } @@ -1683,6 +1783,9 @@ ofp_print_version(const struct ofp_header *oh, case OFP12_VERSION: ds_put_cstr(string, " (OF1.2)"); break; + case OFP13_VERSION: + ds_put_cstr(string, " (OF1.3)"); + break; default: ds_put_format(string, " (OF 0x%02"PRIx8")", oh->version); break; @@ -1698,6 +1801,12 @@ ofp_header_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_print_version(oh, string); } +static void +ofp_print_not_implemented(struct ds *string) +{ + ds_put_cstr(string, "NOT IMPLEMENTED YET!\n"); +} + static void ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, struct ds *string, int verbosity) @@ -1706,10 +1815,30 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_header_to_string__(oh, raw, string); switch (ofptype_from_ofpraw(raw)) { + + /* FIXME: Change the following once they are implemented: */ + case OFPTYPE_GET_ASYNC_REQUEST: + case OFPTYPE_GET_ASYNC_REPLY: + case OFPTYPE_METER_MOD: + case OFPTYPE_GROUP_REQUEST: + case OFPTYPE_GROUP_REPLY: + case OFPTYPE_GROUP_DESC_REQUEST: + case OFPTYPE_GROUP_DESC_REPLY: + case OFPTYPE_GROUP_FEATURES_REQUEST: + case OFPTYPE_GROUP_FEATURES_REPLY: + case OFPTYPE_METER_REQUEST: + case OFPTYPE_METER_REPLY: + case OFPTYPE_METER_CONFIG_REQUEST: + case OFPTYPE_METER_CONFIG_REPLY: + case OFPTYPE_METER_FEATURES_REQUEST: + case OFPTYPE_METER_FEATURES_REPLY: + case OFPTYPE_TABLE_FEATURES_REQUEST: + case OFPTYPE_TABLE_FEATURES_REPLY: + ofp_print_not_implemented(string); + break; + case OFPTYPE_HELLO: - ds_put_char(string, '\n'); - ds_put_hex_dump(string, oh + 1, ntohs(oh->length) - sizeof *oh, - 0, true); + ofp_print_hello(string, oh); break; case OFPTYPE_ERROR: