[ovs-dev] [PATCH v4 06/14] ofp-prop: Add support for putting and parsing nested properties.
Jarno Rajahalme
jarno at ovn.org
Fri Feb 19 22:47:59 UTC 2016
With one comment below:
Acked-by: Jarno Rajahalme <jarno at ovn.org>
> On Feb 19, 2016, at 12:34 AM, Ben Pfaff <blp at ovn.org> wrote:
>
> It hadn't occurred to me before that any special support was actually
> necessary or useful for nested properties, but the functions introduced in
> this commit are nice wrappers to deal with the extra 4-byte padding that
> ensures that the nested properties begin on 8-byte boundaries just like
> the outer properties.
>
> Signed-off-by: Ben Pfaff <blp at ovn.org>
> ---
> lib/ofp-prop.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
> lib/ofp-prop.h | 4 ++++
> 2 files changed, 53 insertions(+)
>
> diff --git a/lib/ofp-prop.c b/lib/ofp-prop.c
> index d6fd3a6..b6395b6 100644
> --- a/lib/ofp-prop.c
> +++ b/lib/ofp-prop.c
> @@ -265,6 +265,27 @@ ofpprop_parse_uuid(const struct ofpbuf *property, struct uuid *uuid)
> return 0;
> }
>
> +/* Attempts to parse 'property' as a property that contains nested properties.
> + * If successful, stores the nested data into '*nested' and returns 0;
> + * otherwise returns an OpenFlow error.
> + *
> + * The only thing special about nested properties is that the property header
> + * is followed by 4 bytes of padding, so that the nested properties begin at an
> + * 8-byte aligned offset. This function can be used in other situations where
> + * this is the case. */
> +enum ofperr
> +ofpprop_parse_nested(const struct ofpbuf *property, struct ofpbuf *nested)
> +{
> + size_t nested_offset = ROUND_UP(ofpbuf_headersize(property), 8);
> + if (property->size < nested_offset) {
> + return OFPERR_OFPBPC_BAD_LEN;
> + }
> +
> + ofpbuf_use_const(nested, property->data, property->size);
> + ofpbuf_pull(nested, nested_offset);
> + 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
> @@ -392,6 +413,18 @@ ofpprop_put_uuid(struct ofpbuf *msg, uint64_t type, const struct uuid *uuid)
> ofpprop_put(msg, type, uuid, sizeof *uuid);
> }
>
> +/* Appends a property of type 'type' to 'msg' whose contents are padding to
> + * 8-byte alignment followed by 'nested'. This is a suitable way to add nested
> + * properties to 'msg'. */
> +void
> +ofpprop_put_nested(struct ofpbuf *msg, uint64_t type,
> + const struct ofpbuf *nested)
> +{
> + size_t start = ofpprop_start_nested(msg, type);
> + ofpbuf_put(msg, nested->data, nested->size);
> + ofpprop_end(msg, start);
> +}
> +
> /* Appends a header for a property of type 'type' to 'msg'. The caller should
> * add the contents of the property to 'msg', then finish it by calling
> * ofpprop_end(). Returns the offset of the beginning of the property (to pass
> @@ -429,6 +462,22 @@ ofpprop_end(struct ofpbuf *msg, size_t start_ofs)
> ofpbuf_padto(msg, ROUND_UP(msg->size, 8));
> }
>
> +/* Appends a header for a property of type 'type' to 'msg', followed by padding
> + * suitable for putting nested properties into the property; that is, padding
> + * to an 8-byte alignment.
> + *
> + * This otherwise works like ofpprop_start().
> + *
> + * There's no need for ofpprop_end_nested(), because ofpprop_end() works fine
> + * for this case. */
> +size_t
> +ofpprop_start_nested(struct ofpbuf *msg, uint64_t type)
> +{
> + size_t start_ofs = ofpprop_start(msg, type);
> + ofpbuf_put_zeros(msg, 4);
Somehow I find the ‘4’ here asymmetric to the ROUND_UP(ofpbuf_headersize(…)..) in ofpprop_parse_nested(). Maybe it would be better to simply pull ‘8’ there (with the comment that both the outer property and the padding are bypassed?
> + return start_ofs;
> +}
> +
> enum ofperr
> ofpprop_unknown(struct vlog_module *module, bool loose, const char *msg,
> uint64_t type)
> diff --git a/lib/ofp-prop.h b/lib/ofp-prop.h
> index 921b6c1..4f8e78d 100644
> --- a/lib/ofp-prop.h
> +++ b/lib/ofp-prop.h
> @@ -85,6 +85,7 @@ enum ofperr ofpprop_parse_u16(const struct ofpbuf *, uint16_t *value);
> enum ofperr ofpprop_parse_u32(const struct ofpbuf *, uint32_t *value);
> enum ofperr ofpprop_parse_u64(const struct ofpbuf *, uint64_t *value);
> enum ofperr ofpprop_parse_uuid(const struct ofpbuf *, struct uuid *);
> +enum ofperr ofpprop_parse_nested(const struct ofpbuf *, struct ofpbuf *);
>
> /* Serializing properties. */
> void ofpprop_put(struct ofpbuf *, uint64_t type,
> @@ -100,10 +101,13 @@ void ofpprop_put_u64(struct ofpbuf *, uint64_t type, uint64_t value);
> void ofpprop_put_bitmap(struct ofpbuf *, uint64_t type, uint64_t bitmap);
> void ofpprop_put_flag(struct ofpbuf *, uint64_t type);
> void ofpprop_put_uuid(struct ofpbuf *, uint64_t type, const struct uuid *);
> +void ofpprop_put_nested(struct ofpbuf *, uint64_t type, const struct ofpbuf *);
>
> size_t ofpprop_start(struct ofpbuf *, uint64_t type);
> void ofpprop_end(struct ofpbuf *, size_t start_ofs);
>
> +size_t ofpprop_start_nested(struct ofpbuf *, uint64_t type);
> +
> /* Logging errors while deserializing properties.
> *
> * The attitude that a piece of code should take when it deserializes an
> --
> 2.1.3
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
More information about the dev
mailing list