Skip to content

Commit

Permalink
net: genetlink: parse attrs and store in contect info struct during d…
Browse files Browse the repository at this point in the history
…umpit

Extend the dumpit info struct for attrs. Instead of existing attribute
validation do parse them and save in the info struct. Caller can benefit
from this and does not have to do parse itself. In order to properly
free attrs, genl_family pointer needs to be added to dumpit info struct
as well.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jiri Pirko authored and David S. Miller committed Oct 6, 2019
1 parent c10e6cf commit bf813b0
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
4 changes: 4 additions & 0 deletions include/net/genetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,14 @@ enum genl_validate_flags {

/**
* struct genl_info - info that is available during dumpit op call
* @family: generic netlink family - for internal genl code usage
* @ops: generic netlink ops - for internal genl code usage
* @attrs: netlink attributes
*/
struct genl_dumpit_info {
const struct genl_family *family;
const struct genl_ops *ops;
struct nlattr **attrs;
};

static inline const struct genl_dumpit_info *
Expand Down
39 changes: 22 additions & 17 deletions net/netlink/genetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ static int genl_lock_done(struct netlink_callback *cb)
rc = ops->done(cb);
genl_unlock();
}
genl_family_rcv_msg_attrs_free(info->family, info->attrs);
genl_dumpit_info_free(info);
return rc;
}
Expand All @@ -554,6 +555,7 @@ static int genl_parallel_done(struct netlink_callback *cb)

if (ops->done)
rc = ops->done(cb);
genl_family_rcv_msg_attrs_free(info->family, info->attrs);
genl_dumpit_info_free(info);
return rc;
}
Expand All @@ -566,35 +568,38 @@ static int genl_family_rcv_msg_dumpit(const struct genl_family *family,
int hdrlen, struct net *net)
{
struct genl_dumpit_info *info;
struct nlattr **attrs = NULL;
int err;

if (!ops->dumpit)
return -EOPNOTSUPP;

if (!(ops->validate & GENL_DONT_VALIDATE_DUMP)) {
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
return -EINVAL;
if (ops->validate & GENL_DONT_VALIDATE_DUMP)
goto no_attrs;

if (family->maxattr) {
unsigned int validate = NL_VALIDATE_STRICT;

if (ops->validate & GENL_DONT_VALIDATE_DUMP_STRICT)
validate = NL_VALIDATE_LIBERAL;
err = __nla_validate(nlmsg_attrdata(nlh, hdrlen),
nlmsg_attrlen(nlh, hdrlen),
family->maxattr, family->policy,
validate, extack);
if (err)
return err;
}
}
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
return -EINVAL;

if (!family->maxattr)
goto no_attrs;

attrs = genl_family_rcv_msg_attrs_parse(family, nlh, extack,
ops, hdrlen,
GENL_DONT_VALIDATE_DUMP_STRICT);
if (IS_ERR(attrs))
return PTR_ERR(attrs);

no_attrs:
/* Allocate dumpit info. It is going to be freed by done() callback. */
info = genl_dumpit_info_alloc();
if (!info)
if (!info) {
genl_family_rcv_msg_attrs_free(family, attrs);
return -ENOMEM;
}

info->family = family;
info->ops = ops;
info->attrs = attrs;

if (!family->parallel_ops) {
struct netlink_dump_control c = {
Expand Down

0 comments on commit bf813b0

Please sign in to comment.