/* Returns 0 on success or a negative error code.  */
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy)
/* Returns 0 on success or a negative error code.  */
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy)
{
	struct nlattr *nla;
	int rem, err;
	memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
	nla_for_each_attr(nla, head, len, rem) {
		u16 type = nla_type(nla);
		if (type > 0 && type <= maxtype) {
			if (policy) {
				err = validate_nla(nla, maxtype, policy);
				if (err < 0)
					goto errout;
			}
			tb[type] = nla;
		}
	}
	if (unlikely(rem > 0))
		printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
		       "attributes.\n", rem);
	err = 0;
errout:
	return err;
}