Future patches will need the ability to skip over unsupported NXM headers in nx_pull_match().
Signed-off-by: Ethan Jackson <et...@nicira.com> --- lib/nx-match.c | 13 ++++++++++--- lib/nx-match.h | 6 ++++-- lib/ofp-util.c | 15 ++++++++------- utilities/ovs-ofctl.c | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/nx-match.c b/lib/nx-match.c index a93a693..3de2363 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -102,11 +102,14 @@ nx_entry_ok(const void *p, unsigned int match_len) * pointers, then the cookie and mask will be stored in them if a * "NXM_NX_COOKIE*" match is defined. Otherwise, 0 is stored in both. * + * If 'strict' is true, will fail with an error when encountering unknown NXM + * headers. + * * Returns 0 if successful, otherwise an OpenFlow error code. */ int -nx_pull_match(struct ofpbuf *b, unsigned int match_len, uint16_t priority, - struct cls_rule *rule, +nx_pull_match(struct ofpbuf *b, unsigned int match_len, bool strict, + uint16_t priority, struct cls_rule *rule, ovs_be64 *cookie, ovs_be64 *cookie_mask) { uint32_t header; @@ -133,7 +136,11 @@ nx_pull_match(struct ofpbuf *b, unsigned int match_len, uint16_t priority, mf = mf_from_nxm_header(header); if (!mf) { - error = NXM_BAD_TYPE; + if (strict) { + error = NXM_BAD_TYPE; + } else { + continue; + } } else if (!mf_are_prereqs_ok(mf, &rule->flow)) { error = NXM_BAD_PREREQ; } else if (!mf_is_all_wild(mf, &rule->wc)) { diff --git a/lib/nx-match.h b/lib/nx-match.h index c7ee0f8..7093637 100644 --- a/lib/nx-match.h +++ b/lib/nx-match.h @@ -17,6 +17,7 @@ #ifndef NX_MATCH_H #define NX_MATCH_H 1 +#include <stdbool.h> #include <stdint.h> #include <sys/types.h> #include <netinet/in.h> @@ -34,8 +35,9 @@ struct nx_action_reg_move; * See include/openflow/nicira-ext.h for NXM specification. */ -int nx_pull_match(struct ofpbuf *, unsigned int match_len, uint16_t priority, - struct cls_rule *, ovs_be64 *cookie, ovs_be64 *cookie_mask); +int nx_pull_match(struct ofpbuf *, unsigned int match_len, bool strict, + uint16_t priority, struct cls_rule *, + ovs_be64 *cookie, ovs_be64 *cookie_mask); int nx_put_match(struct ofpbuf *, const struct cls_rule *, ovs_be64 cookie, ovs_be64 cookie_mask); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 6873842..842a843 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1001,8 +1001,9 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, /* Dissect the message. */ nfm = ofpbuf_pull(&b, sizeof *nfm); - error = nx_pull_match(&b, ntohs(nfm->match_len), ntohs(nfm->priority), - &fm->cr, &fm->cookie, &fm->cookie_mask); + error = nx_pull_match(&b, ntohs(nfm->match_len), true, + ntohs(nfm->priority), &fm->cr, + &fm->cookie, &fm->cookie_mask); if (error) { return error; } @@ -1137,7 +1138,7 @@ ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr, ofpbuf_use_const(&b, oh, ntohs(oh->length)); nfsr = ofpbuf_pull(&b, sizeof *nfsr); - error = nx_pull_match(&b, ntohs(nfsr->match_len), 0, &fsr->match, + error = nx_pull_match(&b, ntohs(nfsr->match_len), true, 0, &fsr->match, &fsr->cookie, &fsr->cookie_mask); if (error) { return error; @@ -1309,8 +1310,8 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, "claims invalid length %zu", match_len, length); return EINVAL; } - if (nx_pull_match(msg, match_len, ntohs(nfs->priority), &fs->rule, - NULL, NULL)) { + if (nx_pull_match(msg, match_len, true, ntohs(nfs->priority), + &fs->rule, NULL, NULL)) { return EINVAL; } @@ -1472,8 +1473,8 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr, ofpbuf_use_const(&b, oh, ntohs(oh->length)); nfr = ofpbuf_pull(&b, sizeof *nfr); - error = nx_pull_match(&b, ntohs(nfr->match_len), ntohs(nfr->priority), - &fr->rule, NULL, NULL); + error = nx_pull_match(&b, ntohs(nfr->match_len), true, + ntohs(nfr->priority), &fr->rule, NULL, NULL); if (error) { return error; } diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 044f74c..51dd92f 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -1539,7 +1539,7 @@ do_parse_nx_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) match_len = nx_match_from_string(ds_cstr(&in), &nx_match); /* Convert nx_match to cls_rule. */ - error = nx_pull_match(&nx_match, match_len, 0, &rule, + error = nx_pull_match(&nx_match, match_len, true, 0, &rule, &cookie, &cookie_mask); if (!error) { char *out; -- 1.7.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev