]> granicus.if.org Git - libnl/commitdiff
attr: Add nla_nest_cancel() to remove partially added nested attributes
authorThomas Graf <tgraf@suug.ch>
Wed, 13 Mar 2013 15:53:07 +0000 (16:53 +0100)
committerThomas Graf <tgraf@suug.ch>
Thu, 14 Mar 2013 11:46:01 +0000 (12:46 +0100)
Signed-off-by: Thomas Graf <tgraf@suug.ch>
doc/core.txt
include/netlink/attr.h
lib/attr.c

index 8a26dbadd6cf0ca0c0502247e612488322f2e4fa..1e951d032b3f3b13c27b5221c8281876fc47424a 100644 (file)
@@ -2316,6 +2316,7 @@ int put_opts(struct nl_msg *msg)
        return 0;
 
 nla_put_failure:
+       nla_nest_cancel(msg, opts);
        return -EMSGSIZE;
 }
 --------
index 69ecb08da2de6cd753805c98d0086f0408844408..0ed3da3a7158ac318b748c341a53ff5447063c80 100644 (file)
@@ -124,6 +124,7 @@ extern int          nla_put_msecs(struct nl_msg *, int, unsigned long);
 extern int             nla_put_nested(struct nl_msg *, int, struct nl_msg *);
 extern struct nlattr * nla_nest_start(struct nl_msg *, int);
 extern int             nla_nest_end(struct nl_msg *, struct nlattr *);
+extern void            nla_nest_cancel(struct nl_msg *, struct nlattr *);
 extern int             nla_parse_nested(struct nlattr **, int, struct nlattr *,
                                         struct nla_policy *);
 extern int             nla_is_nested(struct nlattr *);
index 26bece3d4a599dad4d0ae63db1e79f2c040a396f..2c03fa15019c24cbbbfaf6e5a564360a48542234 100644 (file)
@@ -820,8 +820,7 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
                 * Kernel can't handle empty nested attributes, trim the
                 * attribute header again
                 */
-               msg->nm_nlh->nlmsg_len -= NLA_HDRLEN;
-               memset(nlmsg_tail(msg->nm_nlh), 0, NLA_HDRLEN);
+               nla_nest_cancel(msg, start);
 
                return 0;
        }
@@ -849,6 +848,28 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
        return 0;
 }
 
+/**
+ * Cancel the addition of a nested attribute
+ * @arg msg            Netlink message
+ * @arg attr           Nested netlink attribute
+ *
+ * Removes any partially added nested Netlink attribute from the message
+ * by resetting the message to the size before the call to nla_nest_start()
+ * and by overwriting any potentially touched message segments with 0.
+ */
+void nla_nest_cancel(struct nl_msg *msg, struct nlattr *attr)
+{
+       ssize_t len;
+
+       len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) attr;
+       if (len < 0)
+               BUG();
+       else if (len > 0) {
+               msg->nm_nlh->nlmsg_len -= len;
+               memset(nlmsg_tail(msg->nm_nlh), 0, len);
+       }
+}
+
 /**
  * Create attribute index based on nested attribute
  * @arg tb             Index array to be filled (maxtype+1 elements).