ethtool: wire up get policies to ops
Wire up policies for get commands in struct nla_policy of the ethtool family. Make use of genetlink code attr validation and parsing, as well as allow dumping policies to user space. For every ETHTOOL_MSG_*_GET: - add 'ethnl_' prefix to policy name - add extern declaration in net/ethtool/netlink.h - wire up the policy & attr in ethtool_genl_ops[]. - remove .request_policy and .max_attr from ethnl_request_ops. Obviously core only records the first "layer" of parsed attrs so we still need to parse the sub-attrs of the nested header attribute. v2: - merge of patches 1 and 2 from v1 - remove stray empty lines in ops - also remove .max_attr Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
02da0b615b
commit
4f30974feb
@@ -247,7 +247,7 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
|
||||
/**
|
||||
* ethnl_default_parse() - Parse request message
|
||||
* @req_info: pointer to structure to put data into
|
||||
* @nlhdr: pointer to request message header
|
||||
* @tb: parsed attributes
|
||||
* @net: request netns
|
||||
* @request_ops: struct request_ops for request type
|
||||
* @extack: netlink extack for error reporting
|
||||
@@ -259,37 +259,24 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
|
||||
* Return: 0 on success or negative error code
|
||||
*/
|
||||
static int ethnl_default_parse(struct ethnl_req_info *req_info,
|
||||
const struct nlmsghdr *nlhdr, struct net *net,
|
||||
struct nlattr **tb, struct net *net,
|
||||
const struct ethnl_request_ops *request_ops,
|
||||
struct netlink_ext_ack *extack, bool require_dev)
|
||||
{
|
||||
struct nlattr **tb;
|
||||
int ret;
|
||||
|
||||
tb = kmalloc_array(request_ops->max_attr + 1, sizeof(tb[0]),
|
||||
GFP_KERNEL);
|
||||
if (!tb)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nlmsg_parse(nlhdr, GENL_HDRLEN, tb, request_ops->max_attr,
|
||||
request_ops->request_policy, extack);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = ethnl_parse_header_dev_get(req_info, tb[request_ops->hdr_attr],
|
||||
net, extack, require_dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
if (request_ops->parse_request) {
|
||||
ret = request_ops->parse_request(req_info, tb, extack);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(tb);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,8 +321,8 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = ethnl_default_parse(req_info, info->nlhdr, genl_info_net(info), ops,
|
||||
info->extack, !ops->allow_nodev_do);
|
||||
ret = ethnl_default_parse(req_info, info->attrs, genl_info_net(info),
|
||||
ops, info->extack, !ops->allow_nodev_do);
|
||||
if (ret < 0)
|
||||
goto err_dev;
|
||||
ethnl_init_reply_data(reply_data, ops, req_info->dev);
|
||||
@@ -480,6 +467,7 @@ out:
|
||||
/* generic ->start() handler for GET requests */
|
||||
static int ethnl_default_start(struct netlink_callback *cb)
|
||||
{
|
||||
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
|
||||
struct ethnl_dump_ctx *ctx = ethnl_dump_context(cb);
|
||||
struct ethnl_reply_data *reply_data;
|
||||
const struct ethnl_request_ops *ops;
|
||||
@@ -502,8 +490,8 @@ static int ethnl_default_start(struct netlink_callback *cb)
|
||||
goto free_req_info;
|
||||
}
|
||||
|
||||
ret = ethnl_default_parse(req_info, cb->nlh, sock_net(cb->skb->sk), ops,
|
||||
cb->extack, false);
|
||||
ret = ethnl_default_parse(req_info, info->attrs, sock_net(cb->skb->sk),
|
||||
ops, cb->extack, false);
|
||||
if (req_info->dev) {
|
||||
/* We ignore device specification in dump requests but as the
|
||||
* same parser as for non-dump (doit) requests is used, it
|
||||
@@ -696,6 +684,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_strset_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_strset_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_LINKINFO_GET,
|
||||
@@ -703,6 +693,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_linkinfo_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_linkinfo_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_LINKINFO_SET,
|
||||
@@ -715,6 +707,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_linkmodes_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_linkmodes_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_LINKMODES_SET,
|
||||
@@ -727,6 +721,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_linkstate_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_linkstate_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_DEBUG_GET,
|
||||
@@ -734,6 +730,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_debug_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_debug_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_DEBUG_SET,
|
||||
@@ -747,6 +745,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_wol_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_wol_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_WOL_SET,
|
||||
@@ -759,6 +759,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_features_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_features_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_FEATURES_SET,
|
||||
@@ -771,6 +773,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_privflags_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_privflags_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_PRIVFLAGS_SET,
|
||||
@@ -783,6 +787,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_rings_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_rings_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_RINGS_SET,
|
||||
@@ -795,6 +801,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_channels_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_channels_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_CHANNELS_SET,
|
||||
@@ -807,6 +815,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_coalesce_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_coalesce_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_COALESCE_SET,
|
||||
@@ -819,6 +829,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_pause_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_pause_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_PAUSE_SET,
|
||||
@@ -831,6 +843,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_eee_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_eee_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_EEE_SET,
|
||||
@@ -843,6 +857,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.start = ethnl_default_start,
|
||||
.dumpit = ethnl_default_dumpit,
|
||||
.done = ethnl_default_done,
|
||||
.policy = ethnl_tsinfo_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_tsinfo_get_policy) - 1,
|
||||
},
|
||||
{
|
||||
.cmd = ETHTOOL_MSG_CABLE_TEST_ACT,
|
||||
@@ -859,6 +875,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
|
||||
.doit = ethnl_tunnel_info_doit,
|
||||
.start = ethnl_tunnel_info_start,
|
||||
.dumpit = ethnl_tunnel_info_dumpit,
|
||||
.policy = ethnl_tunnel_info_get_policy,
|
||||
.maxattr = ARRAY_SIZE(ethnl_tunnel_info_get_policy) - 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user