ofp-util: ofputil_pull_ofp11_match: Allow OXM match
authorSimon Horman <horms@verge.net.au>
Tue, 7 Aug 2012 21:49:36 +0000 (06:49 +0900)
committerBen Pfaff <blp@nicira.com>
Wed, 8 Aug 2012 23:16:20 +0000 (16:16 -0700)
* 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 <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/ofp-util.c
lib/ofp-util.h

index 030c8129ca141b75f8020f38853139655fbe86db..bd0cb3481c9a281549fdea65496eb7d410218162 100644 (file)
@@ -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;
         }
index 7b30e8786298a371817e3fff0ccc9b428fb766bb..bea37eee5b137f35e2e996de7f9ef9071b5a9091 100644 (file)
@@ -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 *);