Signed-off-by: Simon Horman <ho...@verge.net.au> ---
v5 * Manual rebase * Use padded_match_len parameter of ofputil_pull_ofp12_match() to obtain the length of a match. Using the remaining length of the message only works for the last flow. v4 * Don't explicitly pill the pad of the header of the message. This is now handled ofputil_pull_stats_msg() * Use OFPST11_FLOW as the message code, it already exists and seems appropriate as struct ofp11_flow_stats is used. * Log a warning if match parsing fails * Log a warning if instruction parsing fails * Correct length passed to ofpacts_pull_openflow11_instructions() v3 * Initial post --- lib/ofp-util.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 615e5f5..6b7f4cb 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -962,6 +962,7 @@ static const struct ofputil_msg_type ofputil_msg_types[] = { } OFPST12_REPLY(OFPST_DESC, OFPST_DESC, sizeof(struct ofp_desc_stats), 0), + OFPST12_REPLY(OFPST11_FLOW, OFPST_FLOW, 0, 1), OFPST12_REPLY(OFPST_PORT_DESC, OFPST_PORT_DESC, 0, sizeof(struct ofp11_port)), #undef OFPST12_REPLY @@ -2184,9 +2185,10 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, struct ofpbuf *ofpacts) { const struct ofputil_msg_type *type; + const struct ofp_header *oh = msg->l2 ? msg->l2 : msg->data; int code; - ofputil_decode_msg_type(msg->l2 ? msg->l2 : msg->data, &type); + ofputil_decode_msg_type(oh, &type); code = ofputil_msg_type_code(type); if (!msg->l2) { msg->l2 = msg->data; @@ -2195,6 +2197,47 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, if (!msg->size) { return EOF; + } else if (code == OFPUTIL_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_ofp12_match(msg, ntohs(ofs->priority), &fs->rule, + NULL, NULL, &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 (code == OFPUTIL_OFPST10_FLOW_REPLY) { const struct ofp10_flow_stats *ofs; size_t length; -- 1.7.10.2.484.gcd07cc5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev