[ovs-dev] [PATCH 17/41] ofp-prop: Add generic functions for working with 16- and 32-bit properties.

Ben Pfaff blp at ovn.org
Tue Jan 19 07:27:04 UTC 2016


These will see increasing use in upcoming commits.

Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 include/openflow/openflow-1.4.h |  27 -----
 include/openflow/openflow-1.5.h |  18 ----
 lib/ofp-prop.c                  | 126 ++++++++++++++++++++++-
 lib/ofp-prop.h                  |   9 ++
 lib/ofp-util.c                  | 218 ++++++++++------------------------------
 lib/ofpbuf.h                    |  11 +-
 6 files changed, 192 insertions(+), 217 deletions(-)

diff --git a/include/openflow/openflow-1.4.h b/include/openflow/openflow-1.4.h
index daf6cf4..b65eeb8 100644
--- a/include/openflow/openflow-1.4.h
+++ b/include/openflow/openflow-1.4.h
@@ -94,15 +94,6 @@ enum ofp14_port_mod_prop_type {
     OFPPMPT14_EXPERIMENTER      = 0xFFFF, /* Experimenter property. */
 };
 
-/* Ethernet port mod property. */
-struct ofp14_port_mod_prop_ethernet {
-    ovs_be16      type;       /* OFPPMPT14_ETHERNET. */
-    ovs_be16      length;     /* Length in bytes of this property. */
-    ovs_be32      advertise;  /* Bitmap of OFPPF_*.  Zero all bits to prevent
-                                 any action taking place. */
-};
-OFP_ASSERT(sizeof(struct ofp14_port_mod_prop_ethernet) == 8);
-
 struct ofp14_port_mod {
     ovs_be32 port_no;
     uint8_t pad[4];
@@ -137,13 +128,6 @@ enum ofp14_table_reason {
     OFPTR_N_REASONS            /* Denotes number of reasons. */
 };
 
-struct ofp14_table_mod_prop_eviction {
-    ovs_be16         type;    /* OFPTMPT14_EVICTION. */
-    ovs_be16         length;  /* Length in bytes of this property. */
-    ovs_be32         flags;   /* Bitmap of OFPTMPEF14_* flags */
-};
-OFP_ASSERT(sizeof(struct ofp14_table_mod_prop_eviction) == 8);
-
 struct ofp14_table_mod_prop_vacancy {
     ovs_be16         type;   /* OFPTMPT14_VACANCY. */
     ovs_be16         length; /* Length in bytes of this property. */
@@ -273,17 +257,6 @@ enum ofp14_async_config_prop_type {
     OFPTFPT_EXPERIMENTER_MASTER   = 0xFFFF, /* Experimenter for master. */
 };
 
-/* Various reason based properties */
-struct ofp14_async_config_prop_reasons {
-    /* 'type' is one of OFPACPT_PACKET_IN_*, OFPACPT_PORT_STATUS_*,
-     * OFPACPT_FLOW_REMOVED_*, OFPACPT_ROLE_STATUS_*,
-     * OFPACPT_TABLE_STATUS_*, OFPACPT_REQUESTFORWARD_*. */
-    ovs_be16    type;
-    ovs_be16    length; /* Length in bytes of this property. */
-    ovs_be32    mask;   /* Bitmasks of reason values. */
-};
-OFP_ASSERT(sizeof(struct ofp14_async_config_prop_reasons) == 8);
-
 /* Experimenter async config property */
 struct ofp14_async_config_prop_experimenter {
     ovs_be16        type;       /* One of OFPTFPT_EXPERIMENTER_SLAVE,
diff --git a/include/openflow/openflow-1.5.h b/include/openflow/openflow-1.5.h
index b3deb2d..0c478d1 100644
--- a/include/openflow/openflow-1.5.h
+++ b/include/openflow/openflow-1.5.h
@@ -69,24 +69,6 @@ enum ofp15_group_bucket_prop_type {
     OFPGBPT15_EXPERIMENTER      = 0xFFFF,  /* Experimenter defined. */
 };
 
-/* Group bucket weight property, for select groups only. */
-struct ofp15_group_bucket_prop_weight {
-    ovs_be16         type;    /* OFPGBPT15_WEIGHT. */
-    ovs_be16         length;  /* 8. */
-    ovs_be16         weight;  /* Relative weight of bucket. */
-    uint8_t          pad[2];  /* Pad to 64 bits. */
-};
-OFP_ASSERT(sizeof(struct ofp15_group_bucket_prop_weight) == 8);
-
-/* Group bucket watch port or watch group property, for fast failover groups
- * only. */
-struct ofp15_group_bucket_prop_watch {
-    ovs_be16         type;    /* OFPGBPT15_WATCH_PORT or OFPGBPT15_WATCH_GROUP. */
-    ovs_be16         length;  /* 8. */
-    ovs_be32         watch;   /* The port or the group.  */
-};
-OFP_ASSERT(sizeof(struct ofp15_group_bucket_prop_watch) == 8);
-
 /* Bucket for use in groups. */
 struct ofp15_bucket {
     ovs_be16 len;                   /* Length the bucket in bytes, including
diff --git a/lib/ofp-prop.c b/lib/ofp-prop.c
index 83d72ab..4215e40 100644
--- a/lib/ofp-prop.c
+++ b/lib/ofp-prop.c
@@ -24,6 +24,21 @@
 #include "openvswitch/vlog.h"
 #include "util.h"
 
+struct ofp_prop_be16 {
+    ovs_be16 type;
+    ovs_be16 len;
+    ovs_be16 value;
+    uint8_t pad[2];
+};
+BUILD_ASSERT_DECL(sizeof(struct ofp_prop_be16) == 8);
+
+struct ofp_prop_be32 {
+    ovs_be16 type;
+    ovs_be16 len;
+    ovs_be32 value;
+};
+BUILD_ASSERT_DECL(sizeof(struct ofp_prop_be32) == 8);
+
 static uint32_t
 ofpprop_type_to_experimenter(uint64_t type)
 {
@@ -84,11 +99,11 @@ ofpprop_pull__(struct ofpbuf *msg, struct ofpbuf *property,
 
     if (property) {
         ofpbuf_use_const(property, msg->data, len);
-        msg->header = msg->data;
-        msg->msg = ((uint8_t *) msg->data
-                    + (type < min_exp
-                       ? sizeof(struct ofp_prop_header)
-                       : sizeof(struct ofp_prop_experimenter)));
+        property->header = property->data;
+        property->msg = ((uint8_t *) property->data
+                         + (type < min_exp
+                            ? sizeof(struct ofp_prop_header)
+                            : sizeof(struct ofp_prop_experimenter)));
     }
     ofpbuf_pull(msg, padded_len);
     return 0;
@@ -107,6 +122,68 @@ ofpprop_pull(struct ofpbuf *msg, struct ofpbuf *property, uint64_t *typep)
     return ofpprop_pull__(msg, property, 8, 0xffff, typep);
 }
 
+/* Attempts to parse 'property' as a property containing a 16-bit value.  If
+ * successful, stores the value into '*value' and returns 0; otherwise returns
+ * an OpenFlow error. */
+enum ofperr
+ofpprop_parse_be16(const struct ofpbuf *property, ovs_be16 *value)
+{
+    /* OpenFlow uses 8-byte properties for 16-bit values, which doesn't really
+     * make sense.  Be forgiving by allowing any size payload as long as it's
+     * at least big enough.  */
+    ovs_be16 *p = property->msg;
+    if (ofpbuf_msgsize(property) < sizeof *p) {
+        return OFPERR_OFPBPC_BAD_LEN;
+    }
+    *value = *p;
+    return 0;
+}
+
+/* Attempts to parse 'property' as a property containing a 32-bit value.  If
+ * successful, stores the value into '*value' and returns 0; otherwise returns
+ * an OpenFlow error. */
+enum ofperr
+ofpprop_parse_be32(const struct ofpbuf *property, ovs_be32 *value)
+{
+    ovs_be32 *p = property->msg;
+    if (ofpbuf_msgsize(property) != sizeof *p) {
+        return OFPERR_OFPBPC_BAD_LEN;
+    }
+    *value = *p;
+    return 0;
+}
+
+/* Attempts to parse 'property' as a property containing a 16-bit value.  If
+ * successful, stores the value into '*value' and returns 0; otherwise returns
+ * an OpenFlow error. */
+enum ofperr
+ofpprop_parse_u16(const struct ofpbuf *property, uint16_t *value)
+{
+    /* OpenFlow uses 8-byte properties for 16-bit values, which doesn't really
+     * make sense.  Be forgiving by allowing any size payload as long as it's
+     * at least big enough.  */
+    ovs_be16 *p = property->msg;
+    if (ofpbuf_msgsize(property) < sizeof *p) {
+        return OFPERR_OFPBPC_BAD_LEN;
+    }
+    *value = ntohs(*p);
+    return 0;
+}
+
+/* Attempts to parse 'property' as a property containing a 32-bit value.  If
+ * successful, stores the value into '*value' and returns 0; otherwise returns
+ * an OpenFlow error. */
+enum ofperr
+ofpprop_parse_u32(const struct ofpbuf *property, uint32_t *value)
+{
+    ovs_be32 *p = property->msg;
+    if (ofpbuf_msgsize(property) != sizeof *p) {
+        return OFPERR_OFPBPC_BAD_LEN;
+    }
+    *value = ntohl(*p);
+    return 0;
+}
+
 /* Adds a property with the given 'type' and 'len'-byte contents 'value' to
  * 'msg', padding the property out to a multiple of 8 bytes. */
 void
@@ -117,6 +194,45 @@ ofpprop_put(struct ofpbuf *msg, uint64_t type, const void *value, size_t len)
     ofpprop_end(msg, start_ofs);
 }
 
+/* Adds a property with the given 'type' and 16-bit 'value' to 'msg'. */
+void
+ofpprop_put_be16(struct ofpbuf *msg, uint64_t type, ovs_be16 value)
+{
+    if (!ofpprop_is_experimenter(type)) {
+        /* The OpenFlow specs consistently (at least they're consistent!)  give
+         * properties with a 16-bit integer value a length of 8, not 6, so add
+         * two bytes of padding.  */
+        ovs_be16 padded_value[2] = { value, 0 };
+        ofpprop_put(msg, type, padded_value, sizeof padded_value);
+    } else {
+        /* There's no precedent but let's assume that this is generally done
+         * sanely. */
+        ofpprop_put(msg, type, &value, sizeof value);
+    }
+}
+
+/* Adds a property with the given 'type' and 32-bit 'value' to 'msg'. */
+void
+ofpprop_put_be32(struct ofpbuf *msg, uint64_t type, ovs_be32 value)
+{
+    ofpprop_put(msg, type, &value, sizeof value);
+}
+
+/* Adds a property with the given 'type' and 16-bit 'value' to 'msg'. */
+void
+ofpprop_put_u16(struct ofpbuf *msg, uint64_t type, uint16_t value)
+{
+    ofpprop_put_be16(msg, type, htons(value));
+}
+
+/* Adds a property with the given 'type' and 32-bit 'value' to 'msg'. */
+void
+ofpprop_put_u32(struct ofpbuf *msg, uint64_t type, uint32_t value)
+{
+    ofpprop_put_be32(msg, type, htonl(value));
+}
+
+/* Adds a property header to 'msg' for each 1-bit in 'bitmap'. */
 /* Appends a property to 'msg' whose type is 'type' and whose contents is a
  * series of property headers, one for each 1-bit in 'bitmap'. */
 void
diff --git a/lib/ofp-prop.h b/lib/ofp-prop.h
index fc0c76d..2b4908a 100644
--- a/lib/ofp-prop.h
+++ b/lib/ofp-prop.h
@@ -72,9 +72,18 @@ enum ofperr ofpprop_pull__(struct ofpbuf *msg, struct ofpbuf *property,
 enum ofperr ofpprop_pull(struct ofpbuf *msg, struct ofpbuf *property,
                          uint64_t *typep);
 
+enum ofperr ofpprop_parse_be16(const struct ofpbuf *, ovs_be16 *value);
+enum ofperr ofpprop_parse_be32(const struct ofpbuf *, ovs_be32 *value);
+enum ofperr ofpprop_parse_u16(const struct ofpbuf *, uint16_t *value);
+enum ofperr ofpprop_parse_u32(const struct ofpbuf *, uint32_t *value);
+
 /* Serializing properties. */
 void ofpprop_put(struct ofpbuf *, uint64_t type,
                  const void *value, size_t len);
+void ofpprop_put_be16(struct ofpbuf *, uint64_t type, ovs_be16 value);
+void ofpprop_put_be32(struct ofpbuf *, uint64_t type, ovs_be32 value);
+void ofpprop_put_u16(struct ofpbuf *, uint64_t type, uint16_t value);
+void ofpprop_put_u32(struct ofpbuf *, uint64_t type, uint32_t value);
 void ofpprop_put_bitmap(struct ofpbuf *, uint64_t type, uint64_t bitmap);
 
 size_t ofpprop_start(struct ofpbuf *, uint64_t type);
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 449f383..c813afd 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -4327,14 +4327,14 @@ static enum ofperr
 parse_port_mod_ethernet_property(struct ofpbuf *property,
                                  struct ofputil_port_mod *pm)
 {
-    struct ofp14_port_mod_prop_ethernet *eth = property->data;
+    ovs_be32 advertise;
+    enum ofperr error;
 
-    if (property->size != sizeof *eth) {
-        return OFPERR_OFPBRC_BAD_LEN;
+    error = ofpprop_parse_be32(property, &advertise);
+    if (!error) {
+        pm->advertise = netdev_port_features_from_ofp11(advertise);
     }
-
-    pm->advertise = netdev_port_features_from_ofp11(eth->advertise);
-    return 0;
+    return error;
 }
 
 /* Decodes the OpenFlow "port mod" message in '*oh' into an abstract form in
@@ -4457,10 +4457,9 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm,
     }
     case OFP14_VERSION:
     case OFP15_VERSION: {
-        struct ofp14_port_mod_prop_ethernet *eth;
         struct ofp14_port_mod *opm;
 
-        b = ofpraw_alloc(OFPRAW_OFPT14_PORT_MOD, ofp_version, sizeof *eth);
+        b = ofpraw_alloc(OFPRAW_OFPT14_PORT_MOD, ofp_version, 0);
         opm = ofpbuf_put_zeros(b, sizeof *opm);
         opm->port_no = ofputil_port_to_ofp11(pm->port_no);
         opm->hw_addr = pm->hw_addr;
@@ -4468,10 +4467,8 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm,
         opm->mask = htonl(pm->mask & OFPPC11_ALL);
 
         if (pm->advertise) {
-            eth = ofpbuf_put_zeros(b, sizeof *eth);
-            eth->type = htons(OFPPMPT14_ETHERNET);
-            eth->length = htons(sizeof *eth);
-            eth->advertise = netdev_port_features_to_ofp11(pm->advertise);
+            ofpprop_put_be32(b, OFPPMPT14_ETHERNET,
+                             netdev_port_features_to_ofp11(pm->advertise));
         }
         break;
     }
@@ -4492,7 +4489,7 @@ pull_table_feature_property(struct ofpbuf *msg, struct ofpbuf *payload,
 
     error = ofpprop_pull(msg, payload, typep);
     if (payload && !error) {
-        ofpbuf_pull(payload, (uint8_t *)msg->msg - (uint8_t *)msg->header);
+        ofpbuf_pull(payload, (char *)payload->msg - (char *)payload->data);
     }
     return error;
 }
@@ -4889,20 +4886,6 @@ ofputil_append_table_features_reply(const struct ofputil_table_features *tf,
 }
 
 static enum ofperr
-parse_table_desc_eviction_property(struct ofpbuf *property,
-                                   struct ofputil_table_desc *td)
-{
-    struct ofp14_table_mod_prop_eviction *ote = property->data;
-
-    if (property->size != sizeof *ote) {
-        return OFPERR_OFPBPC_BAD_LEN;
-    }
-
-    td->eviction_flags = ntohl(ote->flags);
-    return 0;
-}
-
-static enum ofperr
 parse_table_desc_vacancy_property(struct ofpbuf *property,
                                   struct ofputil_table_desc *td)
 {
@@ -4974,7 +4957,7 @@ ofputil_decode_table_desc(struct ofpbuf *msg,
 
         switch (type) {
         case OFPTMPT14_EVICTION:
-            error = parse_table_desc_eviction_property(&payload, td);
+            error = ofpprop_parse_u32(&payload, &td->eviction_flags);
             break;
 
         case OFPTMPT14_VACANCY:
@@ -5025,12 +5008,7 @@ ofputil_append_table_desc_reply(const struct ofputil_table_desc *td,
     start_otd = reply->size;
     ofpbuf_put_zeros(reply, sizeof *otd);
     if (td->eviction_flags != UINT32_MAX) {
-        struct ofp14_table_mod_prop_eviction *ote;
-
-        ote = ofpbuf_put_zeros(reply, sizeof *ote);
-        ote->type = htons(OFPTMPT14_EVICTION);
-        ote->length = htons(sizeof *ote);
-        ote->flags = htonl(td->eviction_flags);
+        ofpprop_put_u32(reply, OFPTMPT14_EVICTION, td->eviction_flags);
     }
     if (td->vacancy == OFPUTIL_TABLE_VACANCY_ON) {
         struct ofp14_table_mod_prop_vacancy *otv;
@@ -5103,20 +5081,6 @@ ofputil_decode_table_vacancy(ovs_be32 config, enum ofp_version version)
             : OFPUTIL_TABLE_VACANCY_OFF);
 }
 
-static enum ofperr
-parse_table_mod_eviction_property(struct ofpbuf *property,
-                                  struct ofputil_table_mod *tm)
-{
-    struct ofp14_table_mod_prop_eviction *ote = property->data;
-
-    if (property->size != sizeof *ote) {
-        return OFPERR_OFPBPC_BAD_LEN;
-    }
-
-    tm->eviction_flags = ntohl(ote->flags);
-    return 0;
-}
-
 /* Given 'config', taken from an OpenFlow 'version' message that specifies
  * table configuration (a table mod, table stats, or table features message),
  * returns the table eviction configuration that it specifies.
@@ -5261,7 +5225,7 @@ ofputil_decode_table_mod(const struct ofp_header *oh,
 
             switch (type) {
             case OFPTMPT14_EVICTION:
-                error = parse_table_mod_eviction_property(&property, pm);
+                error = ofpprop_parse_u32(&property, &pm->eviction);
                 break;
 
             case OFPTMPT14_VACANCY:
@@ -5315,7 +5279,6 @@ ofputil_encode_table_mod(const struct ofputil_table_mod *tm,
     case OFP14_VERSION:
     case OFP15_VERSION: {
         struct ofp14_table_mod *otm;
-        struct ofp14_table_mod_prop_eviction *ote;
         struct ofp14_table_mod_prop_vacancy *otv;
 
         b = ofpraw_alloc(OFPRAW_OFPT14_TABLE_MOD, ofp_version, 0);
@@ -5325,10 +5288,7 @@ ofputil_encode_table_mod(const struct ofputil_table_mod *tm,
                                                   tm->vacancy, ofp_version);
 
         if (tm->eviction_flags != UINT32_MAX) {
-            ote = ofpbuf_put_zeros(b, sizeof *ote);
-            ote->type = htons(OFPTMPT14_EVICTION);
-            ote->length = htons(sizeof *ote);
-            ote->flags = htonl(tm->eviction_flags);
+            ofpprop_put_u32(b, OFPTMPT14_EVICTION, tm->eviction_flags);
         }
         if (tm->vacancy == OFPUTIL_TABLE_VACANCY_ON) {
             otv = ofpbuf_put_zeros(b, sizeof *otv);
@@ -7782,34 +7742,6 @@ ofputil_put_ofp11_bucket(const struct ofputil_bucket *bucket,
 }
 
 static void
-ofputil_put_ofp15_group_bucket_prop_weight(ovs_be16 weight,
-                                           struct ofpbuf *openflow)
-{
-    size_t start_ofs;
-    struct ofp15_group_bucket_prop_weight *prop;
-
-    start_ofs = ofpprop_start(openflow, OFPGBPT15_WEIGHT);
-    ofpbuf_put_zeros(openflow, sizeof *prop - sizeof(struct ofp_prop_header));
-    prop = ofpbuf_at_assert(openflow, start_ofs, sizeof *prop);
-    prop->weight = weight;
-    ofpprop_end(openflow, start_ofs);
-}
-
-static void
-ofputil_put_ofp15_group_bucket_prop_watch(ovs_be32 watch, uint16_t type,
-                                          struct ofpbuf *openflow)
-{
-    size_t start_ofs;
-    struct ofp15_group_bucket_prop_watch *prop;
-
-    start_ofs = ofpprop_start(openflow, type);
-    ofpbuf_put_zeros(openflow, sizeof *prop - sizeof(struct ofp_prop_header));
-    prop = ofpbuf_at_assert(openflow, start_ofs, sizeof *prop);
-    prop->watch = watch;
-    ofpprop_end(openflow, start_ofs);
-}
-
-static void
 ofputil_put_ofp15_bucket(const struct ofputil_bucket *bucket,
                          uint32_t bucket_id, enum ofp11_group_type group_type,
                          struct ofpbuf *openflow, enum ofp_version ofp_version)
@@ -7826,20 +7758,14 @@ ofputil_put_ofp15_bucket(const struct ofputil_bucket *bucket,
     actions_len = openflow->size - actions_start;
 
     if (group_type == OFPGT11_SELECT) {
-        ofputil_put_ofp15_group_bucket_prop_weight(htons(bucket->weight),
-                                                   openflow);
+        ofpprop_put_u16(openflow, OFPGBPT15_WEIGHT, bucket->weight);
     }
     if (bucket->watch_port != OFPP_ANY) {
-        ovs_be32 port = ofputil_port_to_ofp11(bucket->watch_port);
-        ofputil_put_ofp15_group_bucket_prop_watch(port,
-                                                  OFPGBPT15_WATCH_PORT,
-                                                  openflow);
+        ofpprop_put_be32(openflow, OFPGBPT15_WATCH_PORT,
+                         ofputil_port_to_ofp11(bucket->watch_port));
     }
     if (bucket->watch_group != OFPG_ANY) {
-        ovs_be32 group = htonl(bucket->watch_group);
-        ofputil_put_ofp15_group_bucket_prop_watch(group,
-                                                  OFPGBPT15_WATCH_GROUP,
-                                                  openflow);
+        ofpprop_put_u32(openflow, OFPGBPT15_WATCH_GROUP, bucket->watch_group);
     }
 
     ob = ofpbuf_at_assert(openflow, start, sizeof *ob);
@@ -8019,40 +7945,6 @@ ofputil_pull_ofp11_buckets(struct ofpbuf *msg, size_t buckets_length,
 }
 
 static enum ofperr
-parse_ofp15_group_bucket_prop_weight(const struct ofpbuf *payload,
-                                     ovs_be16 *weight)
-{
-    struct ofp15_group_bucket_prop_weight *prop = payload->data;
-
-    if (payload->size != sizeof *prop) {
-        OFPPROP_LOG(&bad_ofmsg_rl, false, "OpenFlow bucket weight property "
-                    "length %u is not valid", payload->size);
-        return OFPERR_OFPBPC_BAD_LEN;
-    }
-
-    *weight = prop->weight;
-
-    return 0;
-}
-
-static enum ofperr
-parse_ofp15_group_bucket_prop_watch(const struct ofpbuf *payload,
-                                    ovs_be32 *watch)
-{
-    struct ofp15_group_bucket_prop_watch *prop = payload->data;
-
-    if (payload->size != sizeof *prop) {
-        OFPPROP_LOG(&bad_ofmsg_rl, false, "OpenFlow bucket watch port or "
-                    "group property length %u is not valid", payload->size);
-        return OFPERR_OFPBPC_BAD_LEN;
-    }
-
-    *watch = prop->watch;
-
-    return 0;
-}
-
-static enum ofperr
 ofputil_pull_ofp15_buckets(struct ofpbuf *msg, size_t buckets_length,
                            enum ofp_version version, uint8_t group_type,
                            struct ovs_list *buckets)
@@ -8121,17 +8013,15 @@ ofputil_pull_ofp15_buckets(struct ofpbuf *msg, size_t buckets_length,
 
             switch (type) {
             case OFPGBPT15_WEIGHT:
-                err = parse_ofp15_group_bucket_prop_weight(&payload, &weight);
+                err = ofpprop_parse_be16(&payload, &weight);
                 break;
 
             case OFPGBPT15_WATCH_PORT:
-                err = parse_ofp15_group_bucket_prop_watch(&payload,
-                                                          &watch_port);
+                err = ofpprop_parse_be32(&payload, &watch_port);
                 break;
 
             case OFPGBPT15_WATCH_GROUP:
-                err = parse_ofp15_group_bucket_prop_watch(&payload,
-                                                          &watch_group);
+                err = ofpprop_parse_be32(&payload, &watch_group);
                 break;
 
             default:
@@ -9517,24 +9407,23 @@ ofputil_decode_set_async_config(const struct ofp_header *oh,
                raw == OFPRAW_OFPT14_GET_ASYNC_REPLY) {
 
         while (b.size > 0) {
-            struct ofp14_async_config_prop_reasons *msg;
             struct ofpbuf property;
             enum ofperr error;
             uint64_t type;
+            uint32_t mask;
 
             error = ofpprop_pull__(&b, &property, 8, 0xfffe, &type);
             if (error) {
                 return error;
             }
 
-            msg = property.data;
-
-            if (property.size != sizeof *msg) {
-                return OFPERR_OFPBRC_BAD_LEN;
+            error = ofpprop_parse_u32(&property, &mask);
+            if (error) {
+                return error;
             }
 
             if (!loose) {
-                error = ofputil_check_mask(type, ntohl(msg->mask));
+                error = ofputil_check_mask(type, mask);
                 if (error) {
                     return error;
                 }
@@ -9542,51 +9431,51 @@ ofputil_decode_set_async_config(const struct ofp_header *oh,
 
             switch (type) {
             case OFPACPT_PACKET_IN_SLAVE:
-                slave[OAM_PACKET_IN] = ntohl(msg->mask);
+                slave[OAM_PACKET_IN] = mask;
                 break;
 
             case OFPACPT_PACKET_IN_MASTER:
-                master[OAM_PACKET_IN] = ntohl(msg->mask);
+                master[OAM_PACKET_IN] = mask;
                 break;
 
             case OFPACPT_PORT_STATUS_SLAVE:
-                slave[OAM_PORT_STATUS] = ntohl(msg->mask);
+                slave[OAM_PORT_STATUS] = mask;
                 break;
 
             case OFPACPT_PORT_STATUS_MASTER:
-                master[OAM_PORT_STATUS] = ntohl(msg->mask);
+                master[OAM_PORT_STATUS] = mask;
                 break;
 
             case OFPACPT_FLOW_REMOVED_SLAVE:
-                slave[OAM_FLOW_REMOVED] = ntohl(msg->mask);
+                slave[OAM_FLOW_REMOVED] = mask;
                 break;
 
             case OFPACPT_FLOW_REMOVED_MASTER:
-                master[OAM_FLOW_REMOVED] = ntohl(msg->mask);
+                master[OAM_FLOW_REMOVED] = mask;
                 break;
 
             case OFPACPT_ROLE_STATUS_SLAVE:
-                slave[OAM_ROLE_STATUS] = ntohl(msg->mask);
+                slave[OAM_ROLE_STATUS] = mask;
                 break;
 
             case OFPACPT_ROLE_STATUS_MASTER:
-                master[OAM_ROLE_STATUS] = ntohl(msg->mask);
+                master[OAM_ROLE_STATUS] = mask;
                 break;
 
             case OFPACPT_TABLE_STATUS_SLAVE:
-                slave[OAM_TABLE_STATUS] = ntohl(msg->mask);
+                slave[OAM_TABLE_STATUS] = mask;
                 break;
 
             case OFPACPT_TABLE_STATUS_MASTER:
-                master[OAM_TABLE_STATUS] = ntohl(msg->mask);
+                master[OAM_TABLE_STATUS] = mask;
                 break;
 
             case OFPACPT_REQUESTFORWARD_SLAVE:
-                slave[OAM_REQUESTFORWARD] = ntohl(msg->mask);
+                slave[OAM_REQUESTFORWARD] = mask;
                 break;
 
             case OFPACPT_REQUESTFORWARD_MASTER:
-                master[OAM_REQUESTFORWARD] = ntohl(msg->mask);
+                master[OAM_REQUESTFORWARD] = mask;
                 break;
 
             default:
@@ -9610,46 +9499,43 @@ ofputil_get_async_reply(struct ofpbuf *buf, const uint32_t master_mask,
     int role;
 
     for (role = 0; role < 2; role++) {
-        struct ofp14_async_config_prop_reasons *msg;
-
-        msg = ofpbuf_put_zeros(buf, sizeof *msg);
+        enum ofp14_async_config_prop_type prop_type;
 
         switch (type) {
         case OAM_PACKET_IN:
-            msg->type = (role ? htons(OFPACPT_PACKET_IN_SLAVE)
-                              : htons(OFPACPT_PACKET_IN_MASTER));
+            prop_type = (role ? OFPACPT_PACKET_IN_SLAVE
+                              : OFPACPT_PACKET_IN_MASTER);
             break;
 
         case OAM_PORT_STATUS:
-            msg->type = (role ? htons(OFPACPT_PORT_STATUS_SLAVE)
-                              : htons(OFPACPT_PORT_STATUS_MASTER));
+            prop_type = (role ? OFPACPT_PORT_STATUS_SLAVE
+                              : OFPACPT_PORT_STATUS_MASTER);
             break;
 
         case OAM_FLOW_REMOVED:
-            msg->type = (role ? htons(OFPACPT_FLOW_REMOVED_SLAVE)
-                              : htons(OFPACPT_FLOW_REMOVED_MASTER));
+            prop_type = (role ? OFPACPT_FLOW_REMOVED_SLAVE
+                              : OFPACPT_FLOW_REMOVED_MASTER);
             break;
 
         case OAM_ROLE_STATUS:
-            msg->type = (role ? htons(OFPACPT_ROLE_STATUS_SLAVE)
-                              : htons(OFPACPT_ROLE_STATUS_MASTER));
+            prop_type = (role ? OFPACPT_ROLE_STATUS_SLAVE
+                              : OFPACPT_ROLE_STATUS_MASTER);
             break;
 
         case OAM_TABLE_STATUS:
-            msg->type = (role ? htons(OFPACPT_TABLE_STATUS_SLAVE)
-                              : htons(OFPACPT_TABLE_STATUS_MASTER));
+            prop_type = (role ? OFPACPT_TABLE_STATUS_SLAVE
+                              : OFPACPT_TABLE_STATUS_MASTER);
             break;
 
         case OAM_REQUESTFORWARD:
-            msg->type = (role ? htons(OFPACPT_REQUESTFORWARD_SLAVE)
-                              : htons(OFPACPT_REQUESTFORWARD_MASTER));
+            prop_type = (role ? OFPACPT_REQUESTFORWARD_SLAVE
+                              : OFPACPT_REQUESTFORWARD_MASTER);
             break;
 
         default:
             return OFPERR_OFPBRC_BAD_TYPE;
         }
-        msg->length = htons(sizeof *msg);
-        msg->mask = (role ? htonl(slave_mask) : htonl(master_mask));
+        ofpprop_put_u32(buf, prop_type, role ? slave_mask : master_mask);
     }
 
     return 0;
diff --git a/lib/ofpbuf.h b/lib/ofpbuf.h
index 873065e..678b1f1 100644
--- a/lib/ofpbuf.h
+++ b/lib/ofpbuf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -120,6 +120,7 @@ void *ofpbuf_push(struct ofpbuf *b, const void *, size_t);
 
 static inline size_t ofpbuf_headroom(const struct ofpbuf *);
 static inline size_t ofpbuf_tailroom(const struct ofpbuf *);
+static inline size_t ofpbuf_msgsize(const struct ofpbuf *);
 void ofpbuf_prealloc_headroom(struct ofpbuf *, size_t);
 void ofpbuf_prealloc_tailroom(struct ofpbuf *, size_t);
 void ofpbuf_trim(struct ofpbuf *);
@@ -193,6 +194,14 @@ static inline size_t ofpbuf_tailroom(const struct ofpbuf *b)
     return (char*)ofpbuf_end(b) - (char*)ofpbuf_tail(b);
 }
 
+/* Returns the number of bytes from 'b->msg' to 'b->data + b->size', that is,
+ * the length of the used space in 'b' starting from 'msg'. */
+static inline size_t
+ofpbuf_msgsize(const struct ofpbuf *b)
+{
+    return (char *)ofpbuf_tail(b) - (char *)b->msg;
+}
+
 /* Clears any data from 'b'. */
 static inline void ofpbuf_clear(struct ofpbuf *b)
 {
-- 
2.1.3




More information about the dev mailing list