From 36a16881d032fce280e54de2f261640a52bf04c7 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 8 Aug 2012 06:49:36 +0900 Subject: [PATCH] ofp-util: ofputil_pull_ofp11_match: Allow OXM match * Allow OXM matches which specified in OpenFlow 1.2. Also allow them for OpenFlow 1.1 as there seems little reason not to. * Pass padded_match_len parameter which if on NULL will be set to the padded match len. This will be used when decoding flow statistics response messages. Signed-off-by: Simon Horman Signed-off-by: Ben Pfaff --- lib/ofp-util.c | 30 ++++++++++++++++++++++-------- lib/ofp-util.h | 3 ++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 030c8129..bd0cb348 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -267,23 +267,36 @@ ofputil_cls_rule_to_ofp10_match(const struct cls_rule *rule, enum ofperr ofputil_pull_ofp11_match(struct ofpbuf *buf, unsigned int priority, - struct cls_rule *rule) + struct cls_rule *rule, uint16_t *padded_match_len) { - struct ofp11_match_header *omh; - struct ofp11_match *om; + struct ofp11_match_header *omh = buf->data; + uint16_t match_len; - if (buf->size < sizeof(struct ofp11_match_header)) { + if (buf->size < sizeof *omh) { return OFPERR_OFPBMC_BAD_LEN; } - omh = buf->data; + match_len = ntohs(omh->length); + switch (ntohs(omh->type)) { - case OFPMT_STANDARD: - if (omh->length != htons(sizeof *om) || buf->size < sizeof *om) { + case OFPMT_STANDARD: { + struct ofp11_match *om; + + if (match_len != sizeof *om || buf->size < sizeof *om) { return OFPERR_OFPBMC_BAD_LEN; } om = ofpbuf_pull(buf, sizeof *om); + if (padded_match_len) { + *padded_match_len = match_len; + } return ofputil_cls_rule_from_ofp11_match(om, priority, rule); + } + + case OFPMT_OXM: + if (padded_match_len) { + *padded_match_len = ROUND_UP(match_len, 8); + } + return oxm_pull_match(buf, priority, rule); default: return OFPERR_OFPBMC_BAD_TYPE; @@ -1137,7 +1150,8 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, ofm = ofpbuf_pull(&b, sizeof *ofm); - error = ofputil_pull_ofp11_match(&b, ntohs(ofm->priority), &fm->cr); + error = ofputil_pull_ofp11_match(&b, ntohs(ofm->priority), &fm->cr, + NULL); if (error) { return error; } diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 7b30e878..bea37eee 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -120,7 +120,8 @@ void ofputil_cls_rule_to_ofp10_match(const struct cls_rule *, /* Work with ofp11_match. */ enum ofperr ofputil_pull_ofp11_match(struct ofpbuf *, unsigned int priority, - struct cls_rule *); + struct cls_rule *, + uint16_t *padded_match_len); enum ofperr ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *, unsigned int priority, struct cls_rule *); -- 2.30.2