These will see increasing use in upcoming commits. Signed-off-by: Ben Pfaff <b...@ovn.org> --- lib/ofp-prop.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ofp-prop.h | 7 +++++ lib/ofp-util.c | 42 +++--------------------------- 3 files changed, 91 insertions(+), 38 deletions(-)
diff --git a/lib/ofp-prop.c b/lib/ofp-prop.c index 2d90e1b..080e25c 100644 --- a/lib/ofp-prop.c +++ b/lib/ofp-prop.c @@ -23,6 +23,21 @@ #include "ofp-errors.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); + /* Pulls a property, beginning with struct ofp_prop_header, from the beginning * of 'msg'. Stores the type of the property in '*typep' and, if 'property' is * nonnull, the entire property, including the header, in '*property'. Returns @@ -71,6 +86,36 @@ ofpprop_pull(struct ofpbuf *msg, struct ofpbuf *property, uint16_t *typep) return ofpprop_pull__(msg, property, 8, 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_u16(const struct ofpbuf *property, uint16_t *value) +{ + struct ofp_prop_be16 *prop = property->data; + + if (property->size != sizeof *prop) { + return OFPERR_OFPBPC_BAD_LEN; + } + *value = ntohs(prop->value); + 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) +{ + struct ofp_prop_be32 *prop = property->data; + + if (property->size != sizeof *prop) { + return OFPERR_OFPBPC_BAD_LEN; + } + *value = ntohl(prop->value); + 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 @@ -81,6 +126,41 @@ ofpprop_put(struct ofpbuf *msg, uint16_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, uint16_t type, ovs_be16 value) +{ + /* The OpenFlow specs consistently (thankfully!) insists that properties + * with a 16-bit integer value have a length of 8, not 6, so add two bytes + * of padding before ending the property. */ + size_t start_ofs = ofpprop_start(msg, type); + ofpbuf_put(msg, &value, 2); + ofpbuf_put_zeros(msg, 2); + ofpprop_end(msg, start_ofs); +} + +/* Adds a property with the given 'type' and 32-bit 'value' to 'msg'. */ +void +ofpprop_put_be32(struct ofpbuf *msg, uint16_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, uint16_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, uint16_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 07d9799..96b3c2c 100644 --- a/lib/ofp-prop.h +++ b/lib/ofp-prop.h @@ -38,9 +38,16 @@ enum ofperr ofpprop_pull__(struct ofpbuf *msg, struct ofpbuf *property, enum ofperr ofpprop_pull(struct ofpbuf *msg, struct ofpbuf *property, uint16_t *typep); +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 *, uint16_t type, const void *value, size_t len); +void ofpprop_put_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); +void ofpprop_put_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); +void ofpprop_put_u16(struct ofpbuf *, uint16_t type, uint16_t value); +void ofpprop_put_u32(struct ofpbuf *, uint16_t type, uint32_t value); void ofpprop_put_bitmap(struct ofpbuf *, uint16_t type, uint64_t bitmap); size_t ofpprop_start(struct ofpbuf *, uint16_t type); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index e0eef1e..38d1473 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -7711,34 +7711,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) @@ -7755,20 +7727,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); -- 2.1.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev