]> granicus.if.org Git - libnl/commitdiff
Improve message/attribute construction documentation and add nlmsg_expand()
authorThomas Graf <tgr@deb.localdomain>
Mon, 14 Jan 2008 15:46:17 +0000 (16:46 +0100)
committerThomas Graf <tgr@deb.localdomain>
Mon, 14 Jan 2008 15:46:17 +0000 (16:46 +0100)
include/netlink/msg.h
lib/attr.c
lib/msg.c

index 5d0ecd2da9a37d9ff38ca234e10110f678888ca9..732e66f3516dd943daccd98f75a5fcb11009e1f8 100644 (file)
@@ -81,6 +81,7 @@ extern struct nl_msg *          nlmsg_inherit(struct nlmsghdr *);
 extern struct nl_msg *   nlmsg_convert(struct nlmsghdr *);
 extern void *            nlmsg_reserve(struct nl_msg *, size_t, int);
 extern int               nlmsg_append(struct nl_msg *, void *, size_t, int);
+extern int               nlmsg_expand(struct nl_msg *, size_t);
 
 extern struct nlmsghdr *  nlmsg_put(struct nl_msg *, uint32_t, uint32_t,
                                    int, int, int);
@@ -90,6 +91,7 @@ extern void             nlmsg_free(struct nl_msg *);
 /* attribute modification */
 extern void              nlmsg_set_proto(struct nl_msg *, int);
 extern int               nlmsg_get_proto(struct nl_msg *);
+extern size_t            nlmsg_get_max_size(struct nl_msg *);
 extern void              nlmsg_set_src(struct nl_msg *, struct sockaddr_nl *);
 extern struct sockaddr_nl *nlmsg_get_src(struct nl_msg *);
 extern void              nlmsg_set_dst(struct nl_msg *, struct sockaddr_nl *);
index 8d9fdfac8f8f1ca5188342c64fa49a6c4a62c2f7..8568d3299d1019802ac5a9be6ef0700d023fb884 100644 (file)
  * @code
  * int param1 = 10;
  * char *param2 = "parameter text";
- * struct nlmsghdr hdr = {
- *     .nlmsg_type = MY_ACTION,
- * };
- * struct nl_msg *m = nlmsg_build(&hdr);
- * nla_put_u32(m, 1, param1);
- * nla_put_string(m, 2, param2);
+ *
+ * struct nl_msg *msg = nlmsg_alloc();
+ * nla_put_u32(msg, 1, param1);
+ * nla_put_string(msg, 2, param2);
  * 
- * nl_send_auto_complete(handle, nl_msg_get(m));
- * nlmsg_free(m);
+ * nl_send_auto_complete(handle, nl_msg_get(msg));
+ * nlmsg_free(msg);
  * @endcode
  *
  * @par 2) Constructing nested attributes
  * struct nl_msg * nested_config(void)
  * {
  *     int a = 5, int b = 10;
- *     struct nl_msg *n = nlmsg_build(NULL);
+ *     struct nl_msg *n = nlmsg_alloc();
  *     nla_put_u32(n, 10, a);
  *     nla_put_u32(n, 20, b);
  *     return n;
  * }
  *
  * ...
- * struct nl_msg *m = nlmsg_build(&hdr);
+ * struct nl_msg *m = nlmsg_alloc();
  * struct nl_msg *nest = nested_config();
  * nla_put_nested(m, 1, nest);
  *
index 80b689f29f00544b28d558fa153149fcf273e4de..3d4fbc63a1f78214aea4f72ed6bf679e98487da6 100644 (file)
--- a/lib/msg.c
+++ b/lib/msg.c
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * @endcode
  *
- * @par 1) Creating a new netlink message
+ * @par Example
  * @code
- * // Netlink messages can be allocated in various ways, you may
- * // allocate an empty netlink message by using nlmsg_alloc():
+ * // Various methods exist to create/allocate a new netlink
+ * // message. 
+ * //
+ * // nlmsg_alloc() will allocate an empty netlink message with
+ * // a maximum payload size which defaults to the page size of
+ * // the system. This default size can be modified using the
+ * // function nlmsg_set_default_size().
  * struct nl_msg *msg = nlmsg_alloc();
  *
  * // Very often, the message type and message flags are known
  * struct nl_msg *msg = nlmsg_alloc_simple(MY_TYPE, MY_FLAGS);
  *
  * // Alternatively an existing netlink message header can be used
- * // to inherit header values from:
+ * // to inherit the header values:
  * struct nlmsghdr hdr = {
  *     .nlmsg_type = MY_TYPE,
  *     .nlmsg_flags = MY_FLAGS,
  * struct nl_msg *msg = nlmsg_inherit(&hdr);
  *
  * // Last but not least, netlink messages received from netlink sockets
- * // can be converted into nl_msg objects using nlmsg_convert():
+ * // can be converted into nl_msg objects using nlmsg_convert(). This
+ * // will create a message with a maximum payload size which equals the
+ * // length of the existing netlink message, therefore no more data can
+ * // be appened without calling nlmsg_expand() first.
  * struct nl_msg *msg = nlmsg_convert(nlh_from_nl_sock);
  *
- * // The header can later be retrieved with nlmsg_hdr() and changed again:
- * nlmsg_hdr(msg)->nlmsg_flags |= YET_ANOTHER_FLAG;
- * @endcode
- *
- * @par 2) Appending data to the message
- * @code
  * // Payload may be added to the message via nlmsg_append(). The fourth
  * // parameter specifies the number of alignment bytes the data should
  * // be padding with at the end. Common values are 0 to disable it or
  * // the actual copying to a later point, nlmsg_reserve() can be used
  * // for this purpose:
  * void *data = nlmsg_reserve(msg, sizeof(mydata), NLMSG_ALIGNTO);
- * @endcode
  *
- * @par 3) Cleaning up message construction
- * @code
+ * // Attributes may be added using the attributes interface.
+ *
  * // After successful use of the message, the memory must be freed
  * // using nlmsg_free()
  * nlmsg_free(msg);
@@ -559,6 +560,37 @@ int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
        return 0;
 }
 
+/**
+ * Expand maximum payload size of a netlink message
+ * @arg n              Netlink message.
+ * @arg newlen         New maximum payload size.
+ *
+ * Reallocates the payload section of a netlink message and increases
+ * the maximum payload size of the message.
+ *
+ * @note Any pointers pointing to old payload block will be stale and
+ *       need to be refetched. Therfore, do not expand while constructing
+ *       nested attributes or while reserved data blocks are held.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int nlmsg_expand(struct nl_msg *n, size_t newlen)
+{
+       void *tmp;
+
+       if (newlen <= n->nm_size)
+               return nl_errno(EINVAL);
+
+       tmp = realloc(n->nm_nlh, newlen);
+       if (tmp == NULL)
+               return nl_errno(ENOMEM);
+
+       n->nm_nlh = tmp;
+       n->nm_size = newlen;
+
+       return 0;
+}
+
 /**
  * Add a netlink message header to a netlink message
  * @arg n              netlink message
@@ -648,6 +680,11 @@ int nlmsg_get_proto(struct nl_msg *msg)
        return msg->nm_protocol;
 }
 
+size_t nlmsg_get_max_size(struct nl_msg *msg)
+{
+       return msg->nm_size;
+}
+
 void nlmsg_set_src(struct nl_msg *msg, struct sockaddr_nl *addr)
 {
        memcpy(&msg->nm_src, addr, sizeof(*addr));