This may be used by both ofputil_decode_flow_mod() and ofputil_decode_packet_in()
Signed-off-by: Simon Horman <ho...@verge.net.au> --- v4 * No change v3 * Do not pull ofpbuf_pull() in the case of a STANDARD match. This simplifies things a little. v2 * No change --- lib/ofp-util.c | 47 ++++++++++++++++++++++++++++++++++++++++------- lib/ofp-util.h | 5 +++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 1c67d59..f58665b 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -263,31 +263,64 @@ ofputil_cls_rule_to_ofp10_match(const struct cls_rule *rule, memset(match->pad2, '\0', sizeof match->pad2); } -enum ofperr -ofputil_pull_ofp11_match(struct ofpbuf *buf, unsigned int priority, - struct cls_rule *rule) +static enum ofperr +__ofputil_pull_ofp11_match(struct ofpbuf *buf, unsigned int priority, + struct cls_rule *rule, ovs_be64 *cookie, + ovs_be64 *cookie_mask, uint8_t max_version) { - struct ofp11_match_header *omh; - struct ofp11_match *om; + struct ofp11_match_header *omh = buf->data; + uint16_t match_len = ntohs(omh->length); if (buf->size < sizeof(struct ofp11_match_header)) { return OFPERR_OFPBMC_BAD_LEN; } - omh = buf->data; switch (ntohs(omh->type)) { - case OFPMT_STANDARD: + case OFPMT_STANDARD: { + struct ofp11_match *om; + if (omh->length != htons(sizeof *om) || buf->size < sizeof *om) { return OFPERR_OFPBMC_BAD_LEN; } om = ofpbuf_pull(buf, sizeof *om); return ofputil_cls_rule_from_ofp11_match(om, priority, rule); + } + + case OFPMT_OXM: { + enum ofperr error; + + if (max_version < OFP12_VERSION) { + error = OFPERR_OFPBMC_BAD_TYPE; + } else { + ofpbuf_pull(buf, sizeof *omh); + error = nx_pull_match(buf, match_len - sizeof *omh, sizeof *omh, + priority, rule, cookie, cookie_mask); + } + return error; + } default: return OFPERR_OFPBMC_BAD_TYPE; } } +enum ofperr +ofputil_pull_ofp11_match(struct ofpbuf *buf, unsigned int priority, + struct cls_rule *rule) +{ + return __ofputil_pull_ofp11_match(buf, priority, rule, NULL, NULL, + OFP11_VERSION); +} + +enum ofperr +ofputil_pull_ofp12_match(struct ofpbuf *buf, unsigned int priority, + struct cls_rule *rule, ovs_be64 *cookie, + ovs_be64 *cookie_mask) +{ + return __ofputil_pull_ofp11_match(buf, priority, rule, cookie, + cookie_mask, OFP12_VERSION); +} + /* Converts the ofp11_match in 'match' into a cls_rule in 'rule', with the * given 'priority'. Returns 0 if successful, otherwise an OFPERR_* value. */ enum ofperr diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 538278f..9f69fdd 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -204,6 +204,11 @@ enum ofperr ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *, void ofputil_cls_rule_to_ofp11_match(const struct cls_rule *, struct ofp11_match *); +/* Work with ofp12_match. */ +enum ofperr ofputil_pull_ofp12_match(struct ofpbuf *, unsigned int priority, + struct cls_rule *, ovs_be64 *cookie, + ovs_be64 *cookie_mask); + /* dl_type translation between OpenFlow and 'struct flow' format. */ ovs_be16 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type); ovs_be16 ofputil_dl_type_from_openflow(ovs_be16 ofp_dl_type); -- 1.7.10.2.484.gcd07cc5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev