[ovs-dev] [PATCH 02/34] nx-match: Take into account leading header when calculating pad
Simon Horman
horms at verge.net.au
Tue Jun 19 00:48:40 PDT 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>
---
v3
* Initial post
---
lib/nx-match.c | 30 ++++++++++++++++++------------
lib/nx-match.h | 9 +++++----
lib/ofp-util.c | 17 +++++++++--------
utilities/ovs-ofctl.c | 7 ++++---
4 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/lib/nx-match.c b/lib/nx-match.c
index eb055dd..ffe70cf 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -90,16 +90,18 @@ 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;
uint8_t *p;
+ size_t pull_len;
assert((cookie != NULL) == (cookie_mask != NULL));
- p = ofpbuf_try_pull(b, ROUND_UP(match_len, 8));
+ pull_len = match_len ? ROUND_UP(match_len + hdr_len, 8) - hdr_len : 0;
+ p = ofpbuf_try_pull(b, pull_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 "
@@ -203,23 +205,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.
@@ -589,7 +591,11 @@ 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);
+ if (match_len) {
+ size_t hdr_len = oxm ? sizeof(struct ofp11_match_header) : 0;
+ size_t pad_len = ROUND_UP(match_len + hdr_len, 8) - match_len - hdr_len;
+ ofpbuf_put_zeros(b, pad_len);
+ }
return match_len;
}
@@ -725,7 +731,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 +788,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 495178b..1d7fad5 100644
--- a/lib/nx-match.h
+++ b/lib/nx-match.h
@@ -41,16 +41,17 @@ struct nx_action_reg_move;
*/
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 3713c03..ee0cb34 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1624,8 +1624,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;
}
@@ -1780,7 +1781,7 @@ ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr,
enum ofperr error;
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;
@@ -1986,7 +1987,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;
}
@@ -2168,8 +2169,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;
}
@@ -2278,8 +2279,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;
}
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 838ba00..6a65dc1 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -1924,17 +1924,18 @@ do_parse_nxm__(bool oxm)
ovs_be64 cookie, cookie_mask;
enum ofperr error;
int match_len;
+ size_t hdr_len = oxm ? sizeof(struct ofp11_match_header) : 0;
/* 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, hdr_len);
/* 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, hdr_len, 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, hdr_len, 0, &rule,
&cookie, &cookie_mask);
}
--
1.7.10.2.484.gcd07cc5
More information about the dev
mailing list