X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofp-util.c;h=ad291742433401b27235f414f4288d36d421d86c;hb=a64f0b0fcd00da464aa87a93d303f7564a29e1a1;hp=edcc1636d30a88cb59d3b7b60c7cc50675e920fc;hpb=eefbf18198a131d479762b1d37be3552e7271acb;p=openvswitch diff --git a/lib/ofp-util.c b/lib/ofp-util.c index edcc1636..ad291742 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1453,7 +1453,7 @@ ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request *fsr, ofpbuf_use_const(&b, oh, ntohs(oh->length)); raw = ofpraw_pull_assert(&b); switch ((int) raw) { - case OFPRAW_OFPST_FLOW_REQUEST: + case OFPRAW_OFPST10_FLOW_REQUEST: return ofputil_decode_ofpst_flow_request(fsr, b.data, false); case OFPRAW_OFPST_AGGREGATE_REQUEST: @@ -1487,7 +1487,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr, raw = (fsr->aggregate ? OFPRAW_OFPST_AGGREGATE_REQUEST - : OFPRAW_OFPST_FLOW_REQUEST); + : OFPRAW_OFPST11_FLOW_REQUEST); msg = ofpraw_alloc(raw, OFP12_VERSION, NXM_TYPICAL_LEN); ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr); ofsr->table_id = fsr->table_id; @@ -1505,7 +1505,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr, raw = (fsr->aggregate ? OFPRAW_OFPST_AGGREGATE_REQUEST - : OFPRAW_OFPST_FLOW_REQUEST); + : OFPRAW_OFPST10_FLOW_REQUEST); msg = ofpraw_alloc(raw, OFP10_VERSION, 0); ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr); ofputil_cls_rule_to_ofp10_match(&fsr->match, &ofsr->match); @@ -1596,7 +1596,48 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, if (!msg->size) { return EOF; - } else if (raw == OFPRAW_OFPST_FLOW_REPLY) { + } else if (raw == OFPRAW_OFPST11_FLOW_REPLY) { + const struct ofp11_flow_stats *ofs; + size_t length; + uint16_t padded_match_len; + + ofs = ofpbuf_try_pull(msg, sizeof *ofs); + if (!ofs) { + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %zu leftover " + "bytes at end", msg->size); + return EINVAL; + } + + length = ntohs(ofs->length); + if (length < sizeof *ofs) { + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply claims invalid " + "length %zu", length); + return EINVAL; + } + + if (ofputil_pull_ofp11_match(msg, ntohs(ofs->priority), &fs->rule, + &padded_match_len)) { + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad match"); + return EINVAL; + } + + if (ofpacts_pull_openflow11_instructions(msg, length - sizeof *ofs - + padded_match_len, ofpacts)) { + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions"); + return EINVAL; + } + + fs->table_id = ofs->table_id; + fs->duration_sec = ntohl(ofs->duration_sec); + fs->duration_nsec = ntohl(ofs->duration_nsec); + fs->idle_timeout = ntohs(ofs->idle_timeout); + fs->hard_timeout = ntohs(ofs->hard_timeout); + fs->idle_age = -1; + fs->hard_age = -1; + fs->cookie = ofs->cookie; + fs->packet_count = ntohll(ofs->packet_count); + fs->byte_count = ntohll(ofs->byte_count); + } else if (raw == OFPRAW_OFPST10_FLOW_REPLY) { const struct ofp10_flow_stats *ofs; size_t length; @@ -1708,7 +1749,28 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs, enum ofpraw raw; ofpraw_decode_partial(&raw, reply->data, reply->size); - if (raw == OFPRAW_OFPST_FLOW_REPLY) { + if (raw == OFPRAW_OFPST11_FLOW_REPLY) { + struct ofp11_flow_stats *ofs; + + ofpbuf_put_uninit(reply, sizeof *ofs); + oxm_put_match(reply, &fs->rule); + ofpacts_put_openflow11_instructions(fs->ofpacts, fs->ofpacts_len, + reply); + + ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs); + ofs->length = htons(reply->size - start_ofs); + ofs->table_id = fs->table_id; + ofs->pad = 0; + ofs->duration_sec = htonl(fs->duration_sec); + ofs->duration_nsec = htonl(fs->duration_nsec); + ofs->priority = htons(fs->rule.priority); + ofs->idle_timeout = htons(fs->idle_timeout); + ofs->hard_timeout = htons(fs->hard_timeout); + memset(ofs->pad2, 0, sizeof ofs->pad2); + ofs->cookie = fs->cookie; + ofs->packet_count = htonll(unknown_to_zero(fs->packet_count)); + ofs->byte_count = htonll(unknown_to_zero(fs->byte_count)); + } else if (raw == OFPRAW_OFPST10_FLOW_REPLY) { struct ofp10_flow_stats *ofs; ofpbuf_put_uninit(reply, sizeof *ofs); @@ -2846,12 +2908,13 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm, break; } - case OFP11_VERSION: { + case OFP11_VERSION: + case OFP12_VERSION: { struct ofp11_port_mod *opm; b = ofpraw_alloc(OFPRAW_OFPT11_PORT_MOD, ofp_version, 0); opm = ofpbuf_put_zeros(b, sizeof *opm); - opm->port_no = htonl(pm->port_no); + opm->port_no = ofputil_port_to_ofp11(pm->port_no); memcpy(opm->hw_addr, pm->hw_addr, ETH_ADDR_LEN); opm->config = htonl(pm->config & OFPPC11_ALL); opm->mask = htonl(pm->mask & OFPPC11_ALL); @@ -2859,7 +2922,6 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm, break; } - case OFP12_VERSION: default: NOT_REACHED(); }