X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-print.c;h=f7872cb34d2c5984284b8a0a9ca1653db2e922f9;hb=67680b012be30d9c26eab999b83b08c6eb32dbd2;hp=9123f2f9379dc05484f91a1bc6693ffa3ee1b489;hpb=95216219538e532732df6d2f51c0d7b69addae8c;p=sliver-openvswitch.git diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 9123f2f93..f7872cb34 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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(); } @@ -562,6 +569,22 @@ static void print_wild(struct ds *string, const char *leader, int is_wild, ds_put_char(string, ','); } +static void +print_wild_port(struct ds *string, const char *leader, int is_wild, + int verbosity, uint16_t port) +{ + if (is_wild && verbosity < 2) { + return; + } + ds_put_cstr(string, leader); + if (!is_wild) { + ofputil_format_port(port, string); + } else { + ds_put_char(string, '*'); + } + ds_put_char(string, ','); +} + static void print_ip_netmask(struct ds *string, const char *leader, ovs_be32 ip, uint32_t wild_bits, int verbosity) @@ -571,7 +594,7 @@ print_ip_netmask(struct ds *string, const char *leader, ovs_be32 ip, } ds_put_cstr(string, leader); if (wild_bits < 32) { - ds_put_format(string, IP_FMT, IP_ARGS(&ip)); + ds_put_format(string, IP_FMT, IP_ARGS(ip)); if (wild_bits) { ds_put_format(string, "/%d", 32 - wild_bits); } @@ -617,12 +640,18 @@ 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 if (om->dl_type == htons(ETH_TYPE_MPLS)) { + ds_put_cstr(&f, "mpls,"); + } else if (om->dl_type == htons(ETH_TYPE_MPLS_MCAST)) { + ds_put_cstr(&f, "mplsm,"); } else { skip_type = false; } } - print_wild(&f, "in_port=", w & OFPFW10_IN_PORT, verbosity, - "%d", ntohs(om->in_port)); + print_wild_port(&f, "in_port=", w & OFPFW10_IN_PORT, verbosity, + ntohs(om->in_port)); print_wild(&f, "dl_vlan=", w & OFPFW10_DL_VLAN, verbosity, "%d", ntohs(om->dl_vlan)); print_wild(&f, "dl_vlan_pcp=", w & OFPFW10_DL_VLAN_PCP, verbosity, @@ -642,7 +671,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 +699,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 +800,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 +819,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); @@ -874,20 +916,22 @@ ofp_print_port_mod(struct ds *string, const struct ofp_header *oh) return; } - ds_put_format(string, "port: %"PRIu16": addr:"ETH_ADDR_FMT"\n", - pm.port_no, ETH_ADDR_ARGS(pm.hw_addr)); + 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)); - ds_put_format(string, " config: "); + ds_put_cstr(string, " config: "); ofp_print_port_config(string, pm.config); - ds_put_format(string, " mask: "); + ds_put_cstr(string, " mask: "); ofp_print_port_config(string, pm.mask); - ds_put_format(string, " advertise: "); + ds_put_cstr(string, " advertise: "); if (pm.advertise) { ofp_print_port_features(string, pm.advertise); } else { - ds_put_format(string, "UNCHANGED\n"); + ds_put_cstr(string, "UNCHANGED\n"); } } @@ -900,6 +944,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) { @@ -983,7 +1044,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); } @@ -1008,6 +1069,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); } @@ -1065,11 +1129,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); @@ -1086,50 +1148,64 @@ 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_cstr(string, " port_no="); + ofputil_format_port(ofp10_port, string); } 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_cstr(string, " port "); + if (ps.port_no < 10) { + ds_put_char(string, ' '); + } + ofputil_format_port(ps.port_no, string); - 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); } } @@ -1139,6 +1215,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_); @@ -1182,6 +1263,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) @@ -1289,6 +1400,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; @@ -1319,47 +1434,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); } } @@ -1415,20 +1538,38 @@ ofp_print_echo(struct ds *string, const struct ofp_header *oh, int verbosity) } static void -ofp_print_nxt_role_message(struct ds *string, - const struct nx_role_request *nrr) +ofp_print_role_message(struct ds *string, const struct ofp_header *oh) { - unsigned int role = ntohl(nrr->role); + 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="); - if (role == NX_ROLE_OTHER) { - ds_put_cstr(string, "other"); - } else if (role == NX_ROLE_MASTER) { + + switch (rr.role) { + case OFPCR12_ROLE_NOCHANGE: + ds_put_cstr(string, "nochange"); + break; + case OFPCR12_ROLE_EQUAL: + ds_put_cstr(string, "equal"); /* OF 1.2 wording */ + break; + case OFPCR12_ROLE_MASTER: ds_put_cstr(string, "master"); - } else if (role == NX_ROLE_SLAVE) { + break; + case OFPCR12_ROLE_SLAVE: ds_put_cstr(string, "slave"); - } else { - ds_put_format(string, "%u", role); + break; + default: + NOT_REACHED(); + } + + if (rr.have_generation_id) { + ds_put_format(string, " generation_id=%"PRIu64, rr.generation_id); } } @@ -1687,6 +1828,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; @@ -1702,6 +1846,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) @@ -1710,10 +1860,32 @@ 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_QUEUE_GET_CONFIG_REQUEST: + case OFPTYPE_QUEUE_GET_CONFIG_REPLY: + 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: @@ -1768,6 +1940,11 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, case OFPTYPE_BARRIER_REPLY: break; + case OFPTYPE_ROLE_REQUEST: + case OFPTYPE_ROLE_REPLY: + ofp_print_role_message(string, oh); + break; + case OFPTYPE_DESC_STATS_REQUEST: case OFPTYPE_PORT_DESC_STATS_REQUEST: ofp_print_stats_request(string, oh); @@ -1828,11 +2005,6 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw, ofp_print_ofpst_port_desc_reply(string, oh); break; - case OFPTYPE_ROLE_REQUEST: - case OFPTYPE_ROLE_REPLY: - ofp_print_nxt_role_message(string, ofpmsg_body(oh)); - break; - case OFPTYPE_FLOW_MOD_TABLE_ID: ofp_print_nxt_flow_mod_table_id(string, ofpmsg_body(oh)); break;