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 *);
* 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;
}
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).