[ovs-dev] [PATCH] nx-match: Take into account leading header when calculating pad
Simon Horman
horms at verge.net.au
Fri Jul 20 01:29:36 UTC 2012
In the case of Open Flow 1.2, which is currently the only
time that OXM is be used, there is a 4 byte header before
the match which needs to be taken into account when calculating
the pad length.
This is not entirely pretty, but it does seem to be correct.
Signed-off-by: Simon Horman <horms at verge.net.au>
---
v7
* Correct the parse-oxm sub-command of ovs-ofputil
Rebase onto upstream master branch
v6
* No change
v5
* Move nx_padded_match_len into nx-match.h as it will
be used by code outside of nx-match.c added by subsequent patches.
v4
* Pad is needed even if match is zero length
(what was I thinking?!)
v3
* Initial post
fix
---
lib/nx-match.c | 29 ++++++++++++++++-------------
lib/nx-match.h | 14 ++++++++++----
lib/ofp-util.c | 21 +++++++++++----------
utilities/ovs-ofctl.c | 7 ++++---
4 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 0f67692..9fdfaa4 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -91,8 +91,8 @@ nx_entry_ok(const void *p, unsigned int match_len)
}
static enum ofperr
-nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
- uint16_t priority, struct cls_rule *rule,
+nx_pull_match__(struct ofpbuf *b, unsigned int match_len, size_t hdr_len,
+ bool strict, uint16_t priority, struct cls_rule *rule,
ovs_be64 *cookie, ovs_be64 *cookie_mask)
{
uint32_t header;
@@ -104,11 +104,11 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
if (cookie) {
*cookie = *cookie_mask = htonll(0);
}
- if (!match_len) {
+ if (!nx_padded_match_len(match_len, hdr_len)) {
return 0;
}
- p = ofpbuf_try_pull(b, ROUND_UP(match_len, 8));
+ p = ofpbuf_try_pull(b, nx_padded_match_len(match_len, hdr_len));
if (!p) {
VLOG_DBG_RL(&rl, "nx_match length %u, rounded up to a "
"multiple of 8, is longer than space in message (max "
@@ -208,23 +208,23 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
*
* Returns 0 if successful, otherwise an OpenFlow error code. */
enum ofperr
-nx_pull_match(struct ofpbuf *b, unsigned int match_len,
+nx_pull_match(struct ofpbuf *b, unsigned int match_len, size_t hdr_len,
uint16_t priority, struct cls_rule *rule,
ovs_be64 *cookie, ovs_be64 *cookie_mask)
{
- return nx_pull_match__(b, match_len, true, priority, rule, cookie,
- cookie_mask);
+ return nx_pull_match__(b, match_len, hdr_len, true, priority, rule,
+ cookie, cookie_mask);
}
/* Behaves the same as nx_pull_match() with one exception. Skips over unknown
* NXM headers instead of failing with an error when they are encountered. */
enum ofperr
-nx_pull_match_loose(struct ofpbuf *b, unsigned int match_len,
+nx_pull_match_loose(struct ofpbuf *b, unsigned int match_len, size_t hdr_len,
uint16_t priority, struct cls_rule *rule,
ovs_be64 *cookie, ovs_be64 *cookie_mask)
{
- return nx_pull_match__(b, match_len, false, priority, rule, cookie,
- cookie_mask);
+ return nx_pull_match__(b, match_len, hdr_len, false, priority, rule,
+ cookie, cookie_mask);
}
/* nx_put_match() and helpers.
@@ -490,6 +490,7 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr,
const flow_wildcards_t wc = cr->wc.wildcards;
const struct flow *flow = &cr->flow;
const size_t start_len = b->size;
+ size_t pad_len, hdr_len;
int match_len;
int i;
@@ -589,7 +590,9 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr,
nxm_put_64m(b, NXM_NX_COOKIE, cookie, cookie_mask);
match_len = b->size - start_len;
- ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len);
+ hdr_len = oxm ? sizeof(struct ofp11_match_header) : 0;
+ pad_len = nx_padded_match_len(match_len, hdr_len) - match_len;
+ ofpbuf_put_zeros(b, pad_len);
return match_len;
}
@@ -725,7 +728,7 @@ parse_nxm_field_name(const char *name, int name_len)
/* nx_match_from_string(). */
int
-nx_match_from_string(const char *s, struct ofpbuf *b)
+nx_match_from_string(const char *s, struct ofpbuf *b, size_t hdr_len)
{
const char *full_s = s;
const size_t start_len = b->size;
@@ -782,7 +785,7 @@ nx_match_from_string(const char *s, struct ofpbuf *b)
}
match_len = b->size - start_len;
- ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len);
+ ofpbuf_put_zeros(b, ROUND_UP(match_len + hdr_len, 8) - match_len - hdr_len);
return match_len;
}
diff --git a/lib/nx-match.h b/lib/nx-match.h
index 161733f..1048d5c 100644
--- a/lib/nx-match.h
+++ b/lib/nx-match.h
@@ -40,17 +40,23 @@ struct nx_action_reg_move;
* See include/openflow/nicira-ext.h for NXM specification.
*/
+static inline size_t nx_padded_match_len(size_t match_len, size_t hdr_len)
+{
+ return ROUND_UP(match_len + hdr_len, 8) - hdr_len;
+}
+
enum ofperr nx_pull_match(struct ofpbuf *, unsigned int match_len,
- uint16_t priority, struct cls_rule *,
+ size_t hdr_len, uint16_t priority, struct cls_rule *,
ovs_be64 *cookie, ovs_be64 *cookie_mask);
enum ofperr nx_pull_match_loose(struct ofpbuf *, unsigned int match_len,
- uint16_t priority, struct cls_rule *,
- ovs_be64 *cookie, ovs_be64 *cookie_mask);
+ size_t hdr_len, uint16_t priority,
+ struct cls_rule *, ovs_be64 *cookie,
+ ovs_be64 *cookie_mask);
int nx_put_match(struct ofpbuf *, bool oxm, const struct cls_rule *,
ovs_be64 cookie, ovs_be64 cookie_mask);
char *nx_match_to_string(const uint8_t *, unsigned int match_len);
-int nx_match_from_string(const char *, struct ofpbuf *);
+int nx_match_from_string(const char *, struct ofpbuf *, size_t hdr_len);
void nxm_parse_reg_move(struct ofpact_reg_move *, const char *);
void nxm_parse_reg_load(struct ofpact_reg_load *, const char *);
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index faa0687..dcca64c 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1731,8 +1731,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), 0,
+ ntohs(nfm->priority), &fm->cr,
+ &fm->cookie, &fm->cookie_mask);
if (error) {
return error;
}
@@ -1893,7 +1894,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), 0, 0, &fsr->match,
&fsr->cookie, &fsr->cookie_mask);
if (error) {
return error;
@@ -2104,7 +2105,7 @@ 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,
+ if (nx_pull_match(msg, match_len, 0, ntohs(nfs->priority), &fs->rule,
NULL, NULL)) {
return EINVAL;
}
@@ -2285,8 +2286,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), 0,
+ ntohs(nfr->priority), &fr->rule, NULL, NULL);
if (error) {
return error;
}
@@ -2395,8 +2396,8 @@ ofputil_decode_packet_in(struct ofputil_packet_in *pin,
ofpbuf_use_const(&b, oh, ntohs(oh->length));
npi = ofpbuf_pull(&b, sizeof *npi);
- error = nx_pull_match_loose(&b, ntohs(npi->match_len), 0, &rule, NULL,
- NULL);
+ error = nx_pull_match_loose(&b, ntohs(npi->match_len), 0, 0,
+ &rule, NULL, NULL);
if (error) {
return error;
}
@@ -3170,7 +3171,7 @@ ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *rq,
rq->out_port = ntohs(nfmr->out_port);
rq->table_id = nfmr->table_id;
- return nx_pull_match(msg, ntohs(nfmr->match_len), OFP_DEFAULT_PRIORITY,
+ return nx_pull_match(msg, ntohs(nfmr->match_len), 0, OFP_DEFAULT_PRIORITY,
&rq->match, NULL, NULL);
}
@@ -3277,7 +3278,7 @@ ofputil_decode_flow_update(struct ofputil_flow_update *update,
update->table_id = nfuf->table_id;
update->cookie = nfuf->cookie;
- error = nx_pull_match(msg, match_len, ntohs(nfuf->priority),
+ error = nx_pull_match(msg, match_len, 0, ntohs(nfuf->priority),
update->match, NULL, NULL);
if (error) {
return error;
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 39c3dae..b1d4f0c 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -2180,17 +2180,18 @@ ofctl_parse_nxm__(bool oxm)
/* Convert string to nx_match. */
ofpbuf_init(&nx_match, 0);
- match_len = nx_match_from_string(ds_cstr(&in), &nx_match);
+ match_len = nx_match_from_string(ds_cstr(&in), &nx_match, 0);
/* Convert nx_match to cls_rule. */
if (strict) {
- error = nx_pull_match(&nx_match, match_len, 0, &rule,
+ error = nx_pull_match(&nx_match, match_len, 0, 0, &rule,
&cookie, &cookie_mask);
} else {
- error = nx_pull_match_loose(&nx_match, match_len, 0, &rule,
+ error = nx_pull_match_loose(&nx_match, match_len, 0, 0, &rule,
&cookie, &cookie_mask);
}
+
if (!error) {
char *out;
--
1.7.10.2.484.gcd07cc5
More information about the dev
mailing list