This is a start at extending the stats message helpers to support OF1.1 stats messages too. It isn't complete, doesn't compile, and I'm not fond of the approach.
Signed-off-by: Ben Pfaff <b...@nicira.com> --- lib/ofp-util.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++------- lib/ofp-util.h | 7 +++++ 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index a7b006c..7378772 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -3223,17 +3223,49 @@ ofputil_postappend_stats_reply(size_t start_ofs, struct list *replies) } } -size_t -ofputil_stats_msg_len(const struct ofp_header *oh) +bool +ofputil_is_stats_msg(const struct ofp_header *oh) { - const struct ofp10_stats_msg *osm; + return ( + oh->version == OFP10_VERSION + ? oh->type == OFPT10_STATS_REQUEST || oh->type == OFPT10_STATS_REPLY + : oh->type == OFPT11_STATS_REQUEST || oh->type == OFPT11_STATS_REPLY); +} + +bool +ofputil_is_vendor_stats_msg(const struct ofp_header *oh) +{ + int min_len = (oh->version == OFP10_VERSION + ? sizeof(struct ofp10_vendor_stats_msg) + : sizeof(struct ofp11_vendor_stats_msg)); + return (ofputil_is_stats_msg(oh) + && ntohs(oh->length) >= min_len + && ofputil_decode_stats_msg_type(oh) == OFPST_VENDOR); +} + +bool +ofputil_is_nx_stats_msg(const struct ofp_header *oh) +{ + BUILD_ASSERT_DECL(sizeof(struct nicira10_stats_msg) == + sizeof(struct nicira11_stats_msg)); - assert(oh->type == OFPT10_STATS_REQUEST || oh->type == OFPT10_STATS_REPLY); + return (ofputil_is_vendor_stats_msg(oh) + && ntohs(oh->length) >= sizeof(struct nicira10_stats_msg) + && ofputil_decode_stats_msg_vendor(oh) == NX_VENDOR_ID); +} - osm = (const struct ofp10_stats_msg *) oh; - return (osm->type == htons(OFPST_VENDOR) - ? sizeof(struct nicira10_stats_msg) - : sizeof(struct ofp10_stats_msg)); +size_t +ofputil_stats_msg_len(const struct ofp_header *oh) +{ + if (ofputil_decode_stats_msg_type(oh) == OFPST_VENDOR) { + return (oh->version == OFP10_VERSION + ? sizeof(struct nicira10_stats_msg) + : sizeof(struct nicira11_stats_msg)); + } else { + return (oh->version == OFP10_VERSION + ? sizeof(struct ofp10_stats_msg) + : sizeof(struct ofp11_stats_msg)); + } } void @@ -3251,14 +3283,36 @@ ofputil_stats_msg_body(const struct ofp_header *oh) uint16_t ofputil_decode_stats_msg_type(const struct ofp_header *oh) { - assert(oh->type == OFPT10_STATS_REQUEST || oh->type == OFPT10_STATS_REPLY); + BUILD_ASSERT_DECL(offsetof(struct ofp10_stats_msg, type) == + offsetof(struct ofp11_stats_msg, type)); + assert(ofputil_is_stats_msg(oh)); return ntohs(((const struct ofp10_stats_msg *) oh)->type); } +uint32_t +ofputil_decode_stats_msg_vendor(const struct ofp_header *oh) +{ + assert(ofputil_is_vendor_stats_msg(oh)); + return ntohl(oh->version == OFP10_VERSION + ? ((const struct ofp10_vendor_stats_msg *) oh)->vendor + : ((const struct ofp11_vendor_stats_msg *) oh)->vendor); +} + +uint32_t +ofputil_decode_stats_msg_subtype(const struct ofp_header *oh) +{ + assert(ofputil_is_nx_stats_msg(oh)); + return ntohl(oh->version == OFP10_VERSION + ? ((const struct nicira10_stats_msg *) oh)->subtype + : ((const struct nicira11_stats_msg *) oh)->subtype); +} + uint16_t ofputil_decode_stats_msg_flags(const struct ofp_header *oh) { - assert(oh->type == OFPT10_STATS_REQUEST || oh->type == OFPT10_STATS_REPLY); + BUILD_ASSERT_DECL(offsetof(struct ofp10_stats_msg, type) == + offsetof(struct ofp11_stats_msg, type)); + assert(ofputil_is_stats_msg(oh)); return ntohs(((const struct ofp10_stats_msg *) oh)->flags); } diff --git a/lib/ofp-util.h b/lib/ofp-util.h index e154fa9..3395a38 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -543,10 +543,17 @@ void ofputil_append_port_desc_stats_reply(uint8_t ofp_version, struct list *replies); /* Decoding OpenFlow stats messages. */ +bool ofputil_is_stats_msg(const struct ofp_header *); +bool ofputil_is_vendor_stats_msg(const struct ofp_header *); +bool ofputil_is_nx_stats_msg(const struct ofp_header *); + size_t ofputil_stats_msg_len(const struct ofp_header *); void ofputil_pull_stats_msg(struct ofpbuf *msg); void *ofputil_stats_msg_body(const struct ofp_header *); + uint16_t ofputil_decode_stats_msg_type(const struct ofp_header *); +uint32_t ofputil_decode_stats_msg_vendor(const struct ofp_header *); +uint32_t ofputil_decode_stats_msg_subtype(const struct ofp_header *); uint16_t ofputil_decode_stats_msg_flags(const struct ofp_header *); /* Encoding simple OpenFlow messages. */ -- 1.7.2.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev