@@ -117,7 +117,6 @@ netlink_skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
#define NLMSG_DEFAULT_SIZE (NLMSG_GOODSIZE - NLMSG_HDRLEN)
-
struct netlink_callback {
struct sk_buff *skb;
const struct nlmsghdr *nlh;
@@ -149,6 +149,8 @@
* nla_find() find attribute in stream of attributes
* nla_find_nested() find attribute in nested attributes
* nla_parse() parse and validate stream of attrs
+ * nla_parse_cb() parse stream of attrs and call to
+ * callback for every nlattr
* nla_parse_nested() parse nested attribuets
* nla_for_each_attr() loop over all attributes
* nla_for_each_nested() loop over the nested attributes
@@ -237,6 +239,9 @@ int nla_validate(const struct nlattr *head, int len, int maxtype,
const struct nla_policy *policy);
int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
int len, const struct nla_policy *policy);
+int nla_parse_cb(struct nlattr **tb, int maxtype, const struct nlattr *head,
+ int len, const struct nla_policy *policy,
+ int (*cb)(const struct nlattr *, void *), void *cb_priv);
int nla_policy_len(const struct nla_policy *, int);
struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
@@ -165,22 +165,28 @@ nla_policy_len(const struct nla_policy *p, int n)
EXPORT_SYMBOL(nla_policy_len);
/**
- * nla_parse - Parse a stream of attributes into a tb buffer
+ * nla_parse_cb - Parse a stream of attributes into a tb buffer with callback
* @tb: destination array with maxtype+1 elements
* @maxtype: maximum attribute type to be expected
* @head: head of attribute stream
* @len: length of attribute stream
* @policy: validation policy
+ * @cb: callback function and data, must not be NULL
+ * @cb_priv: private data for the callback
*
* Parses a stream of attributes and stores a pointer to each attribute in
* the tb array accessible via the attribute type. Attributes with a type
* exceeding maxtype will be silently ignored for backwards compatibility
* reasons. policy may be set to NULL if no validation is required.
+ * For every validated nla, the function calls the user-space callback.
+ * If the callback fails (returns with non-zero value), parsing is terminated
+ * and this value is returned as error.
*
* Returns 0 on success or a negative error code.
*/
-int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
- int len, const struct nla_policy *policy)
+int nla_parse_cb(struct nlattr **tb, int maxtype, const struct nlattr *head,
+ int len, const struct nla_policy *policy,
+ int (*cb)(const struct nlattr *, void *), void *cb_priv)
{
const struct nlattr *nla;
int rem, err;
@@ -196,6 +202,9 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
if (err < 0)
goto errout;
}
+ err = cb(nla, cb_priv);
+ if (err)
+ goto errout;
tb[type] = (struct nlattr *)nla;
}
@@ -209,6 +218,34 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
errout:
return err;
}
+EXPORT_SYMBOL(nla_parse_cb);
+
+static int nla_pass_all_cb(const struct nlattr *nla, void *priv)
+{
+ return 0;
+}
+
+/**
+ * nla_parse - Parse a stream of attributes into a tb buffer
+ * @tb: destination array with maxtype+1 elements
+ * @maxtype: maximum attribute type to be expected
+ * @head: head of attribute stream
+ * @len: length of attribute stream
+ * @policy: validation policy
+ *
+ * Parses a stream of attributes and stores a pointer to each attribute in
+ * the tb array accessible via the attribute type. Attributes with a type
+ * exceeding maxtype will be silently ignored for backwards compatibility
+ * reasons. policy may be set to NULL if no validation is required.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
+ int len, const struct nla_policy *policy)
+{
+ return nla_parse_cb(tb, maxtype, head, len, policy, nla_pass_all_cb,
+ NULL);
+}
EXPORT_SYMBOL(nla_parse);
/**