X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofp-print.c;h=56111435328e228d72b5762327a80c91fbb5489a;hb=a2ad9ecdd0d4ac9a641e8cef1f3f4681fd77d6b1;hp=4141b9f9b0e0a50d70b6e2e419ddcfa95efc571a;hpb=fab8fadba0670ab21c8f68eab22e106be40d2ceb;p=openvswitch diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 4141b9f9..56111435 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -298,6 +298,10 @@ ofp_print_action(struct ds *string, const struct ofp_action_header *ah, [OFPAT_SET_TP_DST] = { sizeof(struct ofp_action_tp_port), sizeof(struct ofp_action_tp_port), + }, + [OFPAT_ENQUEUE] = { + sizeof(struct ofp_action_enqueue), + sizeof(struct ofp_action_enqueue), } /* OFPAT_VENDOR is not here, since it would blow up the array size. */ }; @@ -848,6 +852,19 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, fm.n_actions * sizeof *fm.actions); } +static void +ofp_print_duration(struct ds *string, unsigned int sec, unsigned int nsec) +{ + ds_put_format(string, "%u", sec); + if (nsec > 0) { + ds_put_format(string, ".%09u", nsec); + while (string->string[string->length - 1] == '0') { + string->length--; + } + } + ds_put_char(string, 's'); +} + static void ofp_print_flow_removed(struct ds *string, const struct ofp_flow_removed *ofr, int verbosity) @@ -875,9 +892,10 @@ ofp_print_flow_removed(struct ds *string, const struct ofp_flow_removed *ofr, if (ofr->priority != htons(32768)) { ds_put_format(string, " pri:%"PRIu16, ntohs(ofr->priority)); } - ds_put_format(string, " secs%"PRIu32" nsecs%"PRIu32 - " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n", - ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec), + ds_put_cstr(string, " duration"); + ofp_print_duration(string, + ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec)); + ds_put_format(string, " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n", ntohs(ofr->idle_timeout), ntohll(ofr->packet_count), ntohll(ofr->byte_count)); } @@ -919,6 +937,13 @@ static const struct error_type error_types[] = { ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN), ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_EMPTY), ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_UNKNOWN), + /* Nicira error extensions. */ + ERROR_CODE(OFPET_BAD_REQUEST, NXBRC_NXM_INVALID), + ERROR_CODE(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_TYPE), + ERROR_CODE(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_VALUE), + ERROR_CODE(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_MASK), + ERROR_CODE(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_PREREQ), + ERROR_CODE(OFPET_BAD_REQUEST, NXBRC_NXM_DUP_TYPE), ERROR_TYPE(OFPET_BAD_ACTION), ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE), @@ -936,6 +961,9 @@ static const struct error_type error_types[] = { ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM), ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_EMERG_TIMEOUT), ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND), + /* Nicira error extenstions. */ + ERROR_CODE(OFPET_FLOW_MOD_FAILED, NXFMFC_HARDWARE), + ERROR_CODE(OFPET_FLOW_MOD_FAILED, NXFMFC_BAD_TABLE_ID), ERROR_TYPE(OFPET_PORT_MOD_FAILED), ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_PORT), @@ -982,6 +1010,24 @@ ofp_print_error(struct ds *string, int error) code, lookup_error_code(type, code)); } +static void +ofp_print_nx_error_msg(struct ds *string, const struct ofp_error_msg *oem) +{ + size_t len = ntohs(oem->header.length); + const struct nx_vendor_error *nve = (struct nx_vendor_error *)oem->data; + int vendor = ntohl(nve->vendor); + int type = ntohs(nve->type); + int code = ntohs(nve->code); + + ds_put_format(string, " vendor:%x type:%d(%s) code:%d(%s) payload:\n", + vendor, + type, lookup_error_type(type), + code, lookup_error_code(type, code)); + + ds_put_hex_dump(string, nve + 1, len - sizeof *oem - sizeof *nve, + 0, true); +} + static void ofp_print_error_msg(struct ds *string, const struct ofp_error_msg *oem) { @@ -990,6 +1036,19 @@ ofp_print_error_msg(struct ds *string, const struct ofp_error_msg *oem) int code = ntohs(oem->code); char *s; + + if (type == NXET_VENDOR && code == NXVC_VENDOR_ERROR) { + if (len < sizeof *oem + sizeof(struct nx_vendor_error)) { + ds_put_format(string, + "(***truncated extended error message is %zu bytes " + "when it should be at least %zu***)\n", + len, sizeof(struct nx_vendor_error)); + return; + } + + return ofp_print_nx_error_msg(string, oem); + } + ds_put_format(string, " type:%d(%s) code:%d(%s) payload:\n", type, lookup_error_type(type), code, lookup_error_code(type, code)); @@ -1043,18 +1102,28 @@ ofp_print_ofpst_desc_reply(struct ds *string, const struct ofp_header *oh) } static void -ofp_print_ofpst_flow_request(struct ds *string, const struct ofp_header *oh, - int verbosity) +ofp_print_flow_stats_request(struct ds *string, const struct ofp_header *oh) { - const struct ofp_flow_stats_request *fsr = ofputil_stats_body(oh); + struct flow_stats_request fsr; + int error; - if (fsr->table_id == 0xff) { - ds_put_format(string, " table_id=any, "); - } else { - ds_put_format(string, " table_id=%"PRIu8", ", fsr->table_id); + error = ofputil_decode_flow_stats_request(&fsr, oh, NXFF_OPENFLOW10); + if (error) { + ofp_print_error(string, error); + return; } - ofp_print_match(string, &fsr->match, verbosity); + if (fsr.table_id != 0xff) { + ds_put_format(string, " table_id=%"PRIu8, fsr.table_id); + } + + if (fsr.out_port != OFPP_NONE) { + ds_put_cstr(string, " out_port="); + ofp_print_port_name(string, fsr.out_port); + } + + ds_put_char(string, ' '); + cls_rule_format(&fsr.match, string); } static void @@ -1099,14 +1168,12 @@ ofp_print_ofpst_flow_reply(struct ds *string, const struct ofp_header *oh, break; } - ds_put_format(string, " cookie=0x%"PRIx64", ", ntohll(fs->cookie)); - ds_put_format(string, "duration_sec=%"PRIu32"s, ", - ntohl(fs->duration_sec)); - ds_put_format(string, "duration_nsec=%"PRIu32"ns, ", - ntohl(fs->duration_nsec)); - ds_put_format(string, "table_id=%"PRIu8", ", fs->table_id); - ds_put_format(string, "priority=%"PRIu16", ", - fs->match.wildcards ? ntohs(fs->priority) : (uint16_t)-1); + ds_put_format(string, " cookie=0x%"PRIx64", duration=", + ntohll(fs->cookie)); + ofp_print_duration(string, ntohl(fs->duration_sec), + ntohl(fs->duration_nsec)); + ds_put_format(string, ", table_id=%"PRIu8", ", fs->table_id); + ds_put_format(string, "priority=%"PRIu16", ", ntohs(fs->priority)); ds_put_format(string, "n_packets=%"PRIu64", ", ntohll(fs->packet_count)); ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count)); @@ -1119,6 +1186,7 @@ ofp_print_ofpst_flow_reply(struct ds *string, const struct ofp_header *oh, ntohs(fs->hard_timeout)); } ofp_print_match(string, &fs->match, verbosity); + ds_put_char(string, ' '); ofp_print_actions(string, fs->actions, length - sizeof *fs); pos += length; @@ -1126,30 +1194,102 @@ ofp_print_ofpst_flow_reply(struct ds *string, const struct ofp_header *oh, } static void -ofp_print_ofpst_aggregate_request(struct ds *string, - const struct ofp_header *oh, int verbosity) +ofp_print_nxst_flow_reply(struct ds *string, const struct ofp_header *oh) { - const struct ofp_aggregate_stats_request *asr = ofputil_stats_body(oh); + struct ofpbuf b; + + ofpbuf_use_const(&b, ofputil_nxstats_body(oh), + ofputil_nxstats_body_len(oh)); + while (b.size > 0) { + const struct nx_flow_stats *fs; + union ofp_action *actions; + struct cls_rule rule; + size_t actions_len, n_actions; + size_t length; + int match_len; + int error; - if (asr->table_id == 0xff) { - ds_put_format(string, " table_id=any, "); - } else { - ds_put_format(string, " table_id=%"PRIu8", ", asr->table_id); - } + fs = ofpbuf_try_pull(&b, sizeof *fs); + if (!fs) { + ds_put_format(string, " ***%td leftover bytes at end***", b.size); + break; + } + + length = ntohs(fs->length); + if (length < sizeof *fs) { + ds_put_format(string, " ***nx_flow_stats claims length %zu***", + length); + break; + } + + match_len = ntohs(fs->match_len); + if (match_len > length - sizeof *fs) { + ds_put_format(string, " ***length=%zu match_len=%d***", + length, match_len); + break; + } + + ds_put_format(string, " cookie=0x%"PRIx64", duration=", + ntohll(fs->cookie)); + ofp_print_duration(string, ntohl(fs->duration_sec), + ntohl(fs->duration_nsec)); + ds_put_format(string, ", table_id=%"PRIu8", ", fs->table_id); + ds_put_format(string, "priority=%"PRIu16", ", ntohs(fs->priority)); + ds_put_format(string, "n_packets=%"PRIu64", ", + ntohll(fs->packet_count)); + ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count)); + if (fs->idle_timeout != htons(OFP_FLOW_PERMANENT)) { + ds_put_format(string, "idle_timeout=%"PRIu16",", + ntohs(fs->idle_timeout)); + } + if (fs->hard_timeout != htons(OFP_FLOW_PERMANENT)) { + ds_put_format(string, "hard_timeout=%"PRIu16",", + ntohs(fs->hard_timeout)); + } + + error = nx_pull_match(&b, match_len, ntohs(fs->priority), &rule); + if (error) { + ofp_print_error(string, error); + break; + } - ofp_print_match(string, &asr->match, verbosity); + actions_len = length - sizeof *fs - ROUND_UP(match_len, 8); + error = ofputil_pull_actions(&b, actions_len, &actions, &n_actions); + if (error) { + ofp_print_error(string, error); + break; + } + + cls_rule_format(&rule, string); + ds_put_char(string, ' '); + ofp_print_actions(string, (const struct ofp_action_header *) actions, + n_actions * sizeof *actions); + ds_put_char(string, '\n'); + } } static void -ofp_print_ofpst_aggregate_reply(struct ds *string, const struct ofp_header *oh) +ofp_print_ofp_aggregate_stats_reply ( + struct ds *string, const struct ofp_aggregate_stats_reply *asr) { - const struct ofp_aggregate_stats_reply *asr = ofputil_stats_body(oh); - ds_put_format(string, " packet_count=%"PRIu64, ntohll(asr->packet_count)); ds_put_format(string, " byte_count=%"PRIu64, ntohll(asr->byte_count)); ds_put_format(string, " flow_count=%"PRIu32, ntohl(asr->flow_count)); } +static void +ofp_print_ofpst_aggregate_reply(struct ds *string, const struct ofp_header *oh) +{ + ofp_print_ofp_aggregate_stats_reply(string, ofputil_stats_body(oh)); +} + +static void +ofp_print_nxst_aggregate_reply(struct ds *string, + const struct nx_aggregate_stats_reply *nasr) +{ + ofp_print_ofp_aggregate_stats_reply(string, &nasr->asr); +} + static void print_port_stat(struct ds *string, const char *leader, uint64_t stat, int more) { @@ -1322,6 +1462,18 @@ ofp_print_echo(struct ds *string, const struct ofp_header *oh, int verbosity) } } +static void +ofp_print_nxt_status_message(struct ds *string, const struct ofp_header *oh) +{ + struct ofpbuf b; + + ofpbuf_use_const(&b, oh, ntohs(oh->length)); + ofpbuf_pull(&b, sizeof *oh); + ds_put_char(string, '"'); + ds_put_printable(string, b.data, b.size); + ds_put_char(string, '"'); +} + static void ofp_print_nxt_tun_id_from_cookie(struct ds *string, const struct nxt_tun_id_cookie *ntic) @@ -1329,6 +1481,24 @@ ofp_print_nxt_tun_id_from_cookie(struct ds *string, ds_put_format(string, " set=%"PRIu8, ntic->set); } +static void +ofp_print_nxt_role_message(struct ds *string, + const struct nx_role_request *nrr) +{ + unsigned int role = ntohl(nrr->role); + + ds_put_cstr(string, " role="); + if (role == NX_ROLE_OTHER) { + ds_put_cstr(string, "other"); + } else if (role == NX_ROLE_MASTER) { + ds_put_cstr(string, "master"); + } else if (role == NX_ROLE_SLAVE) { + ds_put_cstr(string, "slave"); + } else { + ds_put_format(string, "%u", role); + } +} + static void ofp_print_nxt_set_flow_format(struct ds *string, const struct nxt_set_flow_format *nsff) @@ -1424,13 +1594,11 @@ ofp_to_string__(const struct ofp_header *oh, break; case OFPUTIL_OFPST_FLOW_REQUEST: - ofp_print_stats_request(string, oh); - ofp_print_ofpst_flow_request(string, oh, verbosity); - break; - + case OFPUTIL_NXST_FLOW_REQUEST: case OFPUTIL_OFPST_AGGREGATE_REQUEST: + case OFPUTIL_NXST_AGGREGATE_REQUEST: ofp_print_stats_request(string, oh); - ofp_print_ofpst_aggregate_request(string, oh, verbosity); + ofp_print_flow_stats_request(string, oh); break; case OFPUTIL_OFPST_TABLE_REQUEST: @@ -1479,7 +1647,7 @@ ofp_to_string__(const struct ofp_header *oh, case OFPUTIL_NXT_STATUS_REQUEST: case OFPUTIL_NXT_STATUS_REPLY: - /* XXX */ + ofp_print_nxt_status_message(string, oh); break; case OFPUTIL_NXT_TUN_ID_FROM_COOKIE: @@ -1488,7 +1656,7 @@ ofp_to_string__(const struct ofp_header *oh, case OFPUTIL_NXT_ROLE_REQUEST: case OFPUTIL_NXT_ROLE_REPLY: - /* XXX */ + ofp_print_nxt_role_message(string, msg); break; case OFPUTIL_NXT_SET_FLOW_FORMAT: @@ -1500,11 +1668,16 @@ ofp_to_string__(const struct ofp_header *oh, break; case OFPUTIL_NXT_FLOW_REMOVED: - case OFPUTIL_NXST_FLOW_REQUEST: - case OFPUTIL_NXST_AGGREGATE_REQUEST: + /* XXX */ + break; + case OFPUTIL_NXST_FLOW_REPLY: + ofp_print_nxst_flow_reply(string, oh); + break; + case OFPUTIL_NXST_AGGREGATE_REPLY: - /* XXX */ + ofp_print_stats_reply(string, oh); + ofp_print_nxst_aggregate_reply(string, oh); break; } }