[ovs-dev] [PATCH 23/63] ofp-util: Add ofputil_ofp12_decode_match()

Simon Horman horms at verge.net.au
Wed Jun 27 08:19:59 UTC 2012


This may be used by both ofputil_decode_flow_mod() and
ofputil_decode_packet_in()

Signed-off-by: Simon Horman <horms at verge.net.au>

---

v5
* Add padded_match_len parameter to
  ofputil_pull_ofp12_match() and __ofputil_pull_ofp11_match().
  This will be used when decoding messages that need
  to know the match length.
* Read mach_length from omh after the length of buf has been verified,
  else an over-run may occur.

v4
* No change

v3
* Do not pull ofpbuf_pull() in the case of a STANDARD match.
  This simplifies things a little.

v2
* No change
---
 lib/ofp-util.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 lib/ofp-util.h |  6 ++++++
 2 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 1c67d59..7caf096 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -263,31 +263,76 @@ 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, uint16_t *padded_match_len,
+                           uint8_t max_version)
 {
-    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)) {
         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: {
+        enum ofperr error;
+
+        if (max_version < OFP12_VERSION) {
+            error = OFPERR_OFPBMC_BAD_TYPE;
+        } else {
+            if (padded_match_len) {
+                *padded_match_len =
+                    nx_padded_match_len(match_len - sizeof *omh, sizeof *omh) +
+                    sizeof *omh;
+            }
+            ofpbuf_pull(buf, sizeof *omh);
+            error = nx_pull_match(buf, match_len - sizeof *omh, 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,
+                                      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, uint16_t *padded_match_len)
+{
+    return __ofputil_pull_ofp11_match(buf, priority, rule, cookie,
+                                      cookie_mask, padded_match_len,
+                                      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 538278f..36a98fa 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -204,6 +204,12 @@ 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,
+                                     uint16_t *padded_match_len);
+
 /* 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




More information about the dev mailing list