[ovs-dev] [optimize 03/13] netlink: New functions for putting attributes at the beginning of a buffer.
Ben Pfaff
blp at nicira.com
Tue Sep 27 23:26:58 UTC 2011
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
More information about the dev
mailing list