This seems fine. I was trying to think of a way to reduce the boilerplate in this file, but this stuff changes rarely. I don't think it's worth it.
Ethan On Tue, Sep 27, 2011 at 16:26, Ben Pfaff <[email protected]> wrote: > These are really just copies of the corresponding "put" functions. An > upcoming commit will introduce a user of nl_msg_push_u32(). I thought I > might as well create all of these while I was at it. > --- > lib/netlink.c | 122 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/netlink.h | 17 +++++++- > 2 files changed, 138 insertions(+), 1 deletions(-) > > diff --git a/lib/netlink.c b/lib/netlink.c > index b4de3ed..7529534 100644 > --- a/lib/netlink.c > +++ b/lib/netlink.c > @@ -201,6 +201,29 @@ nl_msg_put_uninit(struct ofpbuf *msg, size_t size) > return p; > } > > +/* Prepends the 'size' bytes of data in 'p', plus Netlink padding if needed, > to > + * the head end of 'msg'. Data in 'msg' is reallocated and copied if > + * necessary. */ > +void > +nl_msg_push(struct ofpbuf *msg, const void *data, size_t size) > +{ > + memcpy(nl_msg_push_uninit(msg, size), data, size); > +} > + > +/* Prepends 'size' bytes of data, plus Netlink padding if needed, to the head > + * end of 'msg', reallocating and copying its data if necessary. Returns a > + * pointer to the first byte of the new data, which is left uninitialized. */ > +void * > +nl_msg_push_uninit(struct ofpbuf *msg, size_t size) > +{ > + size_t pad = NLMSG_ALIGN(size) - size; > + char *p = ofpbuf_push_uninit(msg, size + pad); > + if (pad) { > + memset(p + size, 0, pad); > + } > + return p; > +} > + > /* Appends a Netlink attribute of the given 'type' and room for 'size' bytes > of > * data as its payload, plus Netlink padding if needed, to the tail end of > * 'msg', reallocating and copying its data if necessary. Returns a pointer > to > @@ -300,6 +323,105 @@ nl_msg_put_string(struct ofpbuf *msg, uint16_t type, > const char *value) > nl_msg_put_unspec(msg, type, value, strlen(value) + 1); > } > > +/* Prepends a Netlink attribute of the given 'type' and room for 'size' bytes > + * of data as its payload, plus Netlink padding if needed, to the head end of > + * 'msg', reallocating and copying its data if necessary. Returns a pointer > to > + * the first byte of data in the attribute, which is left uninitialized. */ > +void * > +nl_msg_push_unspec_uninit(struct ofpbuf *msg, uint16_t type, size_t size) > +{ > + size_t total_size = NLA_HDRLEN + size; > + struct nlattr* nla = nl_msg_push_uninit(msg, total_size); > + assert(NLA_ALIGN(total_size) <= UINT16_MAX); > + nla->nla_len = total_size; > + nla->nla_type = type; > + return nla + 1; > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the 'size' bytes of > + * 'data' as its payload, to the head end of 'msg', reallocating and copying > + * its data if necessary. Returns a pointer to the first byte of data in the > + * attribute, which is left uninitialized. */ > +void > +nl_msg_push_unspec(struct ofpbuf *msg, uint16_t type, > + const void *data, size_t size) > +{ > + memcpy(nl_msg_push_unspec_uninit(msg, type, size), data, size); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and no payload to 'msg'. > + * (Some Netlink protocols use the presence or absence of an attribute as a > + * Boolean flag.) */ > +void > +nl_msg_push_flag(struct ofpbuf *msg, uint16_t type) > +{ > + nl_msg_push_unspec(msg, type, NULL, 0); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 8-bit > 'value' > + * to 'msg'. */ > +void > +nl_msg_push_u8(struct ofpbuf *msg, uint16_t type, uint8_t value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 16-bit host > + * byte order 'value' to 'msg'. */ > +void > +nl_msg_push_u16(struct ofpbuf *msg, uint16_t type, uint16_t value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 32-bit host > + * byte order 'value' to 'msg'. */ > +void > +nl_msg_push_u32(struct ofpbuf *msg, uint16_t type, uint32_t value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 64-bit host > + * byte order 'value' to 'msg'. */ > +void > +nl_msg_push_u64(struct ofpbuf *msg, uint16_t type, uint64_t value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 16-bit > + * network byte order 'value' to 'msg'. */ > +void > +nl_msg_push_be16(struct ofpbuf *msg, uint16_t type, ovs_be16 value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 32-bit > + * network byte order 'value' to 'msg'. */ > +void > +nl_msg_push_be32(struct ofpbuf *msg, uint16_t type, ovs_be32 value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given 64-bit > + * network byte order 'value' to 'msg'. */ > +void > +nl_msg_push_be64(struct ofpbuf *msg, uint16_t type, ovs_be64 value) > +{ > + nl_msg_push_unspec(msg, type, &value, sizeof value); > +} > + > +/* Prepends a Netlink attribute of the given 'type' and the given > + * null-terminated string 'value' to 'msg'. */ > +void > +nl_msg_push_string(struct ofpbuf *msg, uint16_t type, const char *value) > +{ > + nl_msg_push_unspec(msg, type, value, strlen(value) + 1); > +} > + > /* Adds the header for nested Netlink attributes to 'msg', with the specified > * 'type', and returns the header's offset within 'msg'. The caller should > add > * the content for the nested Netlink attribute to 'msg' (e.g. using the other > diff --git a/lib/netlink.h b/lib/netlink.h > index 2206339..3a3d1bb 100644 > --- a/lib/netlink.h > +++ b/lib/netlink.h > @@ -46,7 +46,7 @@ struct genlmsghdr *nl_msg_genlmsghdr(const struct ofpbuf *); > bool nl_msg_nlmsgerr(const struct ofpbuf *, int *error); > void nl_msg_reserve(struct ofpbuf *, size_t); > > -/* Appending headers and raw data. */ > +/* Appending and prepending headers and raw data. */ > void nl_msg_put_nlmsghdr(struct ofpbuf *, size_t expected_payload, > uint32_t type, uint32_t flags); > void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t expected_payload, > @@ -54,6 +54,8 @@ void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t > expected_payload, > uint8_t cmd, uint8_t version); > void nl_msg_put(struct ofpbuf *, const void *, size_t); > void *nl_msg_put_uninit(struct ofpbuf *, size_t); > +void nl_msg_push(struct ofpbuf *, const void *, size_t); > +void *nl_msg_push_uninit(struct ofpbuf *, size_t); > > /* Appending attributes. */ > void *nl_msg_put_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); > @@ -73,6 +75,19 @@ void nl_msg_end_nested(struct ofpbuf *, size_t offset); > void nl_msg_put_nested(struct ofpbuf *, uint16_t type, > const void *data, size_t size); > > +/* Prepending attributes. */ > +void *nl_msg_push_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); > +void nl_msg_push_unspec(struct ofpbuf *, uint16_t type, const void *, > size_t); > +void nl_msg_push_flag(struct ofpbuf *, uint16_t type); > +void nl_msg_push_u8(struct ofpbuf *, uint16_t type, uint8_t value); > +void nl_msg_push_u16(struct ofpbuf *, uint16_t type, uint16_t value); > +void nl_msg_push_u32(struct ofpbuf *, uint16_t type, uint32_t value); > +void nl_msg_push_u64(struct ofpbuf *, uint16_t type, uint64_t value); > +void nl_msg_push_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); > +void nl_msg_push_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); > +void nl_msg_push_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); > +void nl_msg_push_string(struct ofpbuf *, uint16_t type, const char *value); > + > /* Separating buffers into individual messages. */ > struct nlmsghdr *nl_msg_next(struct ofpbuf *buffer, struct ofpbuf *msg); > > -- > 1.7.4.4 > > _______________________________________________ > dev mailing list > [email protected] > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
