net: genetlink: push doit/dumpit code from genl_family_rcv_msg
Currently the function genl_family_rcv_msg() is quite big. Since it is quite convenient, push code that is related to doit and dumpit ops into separate functions. Do small changes on the way, like rc/err unification, NULL check etc. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
248d45f1e1
commit
be064defab
|
@ -498,63 +498,33 @@ static int genl_lock_done(struct netlink_callback *cb)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int genl_family_rcv_msg(const struct genl_family *family,
|
static int genl_family_rcv_msg_dumpit(const struct genl_family *family,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct nlmsghdr *nlh,
|
struct nlmsghdr *nlh,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack,
|
||||||
|
const struct genl_ops *ops,
|
||||||
|
int hdrlen, struct net *net)
|
||||||
{
|
{
|
||||||
const struct genl_ops *ops;
|
int err;
|
||||||
struct net *net = sock_net(skb->sk);
|
|
||||||
struct genl_info info;
|
|
||||||
struct genlmsghdr *hdr = nlmsg_data(nlh);
|
|
||||||
struct nlattr **attrbuf;
|
|
||||||
int hdrlen, err;
|
|
||||||
|
|
||||||
/* this family doesn't exist in this netns */
|
if (!ops->dumpit)
|
||||||
if (!family->netnsok && !net_eq(net, &init_net))
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
hdrlen = GENL_HDRLEN + family->hdrsize;
|
|
||||||
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ops = genl_get_cmd(hdr->cmd, family);
|
|
||||||
if (ops == NULL)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
if ((ops->flags & GENL_ADMIN_PERM) &&
|
|
||||||
!netlink_capable(skb, CAP_NET_ADMIN))
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
if ((ops->flags & GENL_UNS_ADMIN_PERM) &&
|
|
||||||
!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (ops->dumpit == NULL)
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (!(ops->validate & GENL_DONT_VALIDATE_DUMP)) {
|
if (!(ops->validate & GENL_DONT_VALIDATE_DUMP)) {
|
||||||
int hdrlen = GENL_HDRLEN + family->hdrsize;
|
|
||||||
|
|
||||||
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (family->maxattr) {
|
if (family->maxattr) {
|
||||||
unsigned int validate = NL_VALIDATE_STRICT;
|
unsigned int validate = NL_VALIDATE_STRICT;
|
||||||
|
|
||||||
if (ops->validate &
|
if (ops->validate & GENL_DONT_VALIDATE_DUMP_STRICT)
|
||||||
GENL_DONT_VALIDATE_DUMP_STRICT)
|
|
||||||
validate = NL_VALIDATE_LIBERAL;
|
validate = NL_VALIDATE_LIBERAL;
|
||||||
rc = __nla_validate(nlmsg_attrdata(nlh, hdrlen),
|
err = __nla_validate(nlmsg_attrdata(nlh, hdrlen),
|
||||||
nlmsg_attrlen(nlh, hdrlen),
|
nlmsg_attrlen(nlh, hdrlen),
|
||||||
family->maxattr,
|
family->maxattr, family->policy,
|
||||||
family->policy,
|
|
||||||
validate, extack);
|
validate, extack);
|
||||||
if (rc)
|
if (err)
|
||||||
return rc;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,7 +539,7 @@ static int genl_family_rcv_msg(const struct genl_family *family,
|
||||||
};
|
};
|
||||||
|
|
||||||
genl_unlock();
|
genl_unlock();
|
||||||
rc = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
|
err = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
|
||||||
genl_lock();
|
genl_lock();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -580,13 +550,24 @@ static int genl_family_rcv_msg(const struct genl_family *family,
|
||||||
.done = ops->done,
|
.done = ops->done,
|
||||||
};
|
};
|
||||||
|
|
||||||
rc = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
|
err = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ops->doit == NULL)
|
static int genl_family_rcv_msg_doit(const struct genl_family *family,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct nlmsghdr *nlh,
|
||||||
|
struct netlink_ext_ack *extack,
|
||||||
|
const struct genl_ops *ops,
|
||||||
|
int hdrlen, struct net *net)
|
||||||
|
{
|
||||||
|
struct nlattr **attrbuf;
|
||||||
|
struct genl_info info;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!ops->doit)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (family->maxattr && family->parallel_ops) {
|
if (family->maxattr && family->parallel_ops) {
|
||||||
|
@ -638,6 +619,44 @@ out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int genl_family_rcv_msg(const struct genl_family *family,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct nlmsghdr *nlh,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
const struct genl_ops *ops;
|
||||||
|
struct net *net = sock_net(skb->sk);
|
||||||
|
struct genlmsghdr *hdr = nlmsg_data(nlh);
|
||||||
|
int hdrlen;
|
||||||
|
|
||||||
|
/* this family doesn't exist in this netns */
|
||||||
|
if (!family->netnsok && !net_eq(net, &init_net))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
hdrlen = GENL_HDRLEN + family->hdrsize;
|
||||||
|
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ops = genl_get_cmd(hdr->cmd, family);
|
||||||
|
if (ops == NULL)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if ((ops->flags & GENL_ADMIN_PERM) &&
|
||||||
|
!netlink_capable(skb, CAP_NET_ADMIN))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if ((ops->flags & GENL_UNS_ADMIN_PERM) &&
|
||||||
|
!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP)
|
||||||
|
return genl_family_rcv_msg_dumpit(family, skb, nlh, extack,
|
||||||
|
ops, hdrlen, net);
|
||||||
|
else
|
||||||
|
return genl_family_rcv_msg_doit(family, skb, nlh, extack,
|
||||||
|
ops, hdrlen, net);
|
||||||
|
}
|
||||||
|
|
||||||
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue