This may be used by both ofputil_decode_flow_mod() and ofputil_decode_packet_in()
Signed-off-by: Simon Horman <[email protected]> --- v2 * No change --- lib/ofp-util.c | 43 ++++++++++++++++++++++++++++++++++++++----- lib/ofp-util.h | 5 +++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 5adb3a6..2a4a808 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -263,30 +263,63 @@ 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 = ofpbuf_pull(buf, sizeof *omh); - struct ofp11_match *om; + uint16_t match_len = ntohs(omh->length); if (buf->size < sizeof *omh) { return OFPERR_OFPBMC_BAD_LEN; } 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 { + error = nx_pull_match(buf, match_len - 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 8f38c54..0903a02 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 [email protected] http://openvswitch.org/mailman/listinfo/dev
