Commit 4f30974f authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

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: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02da0b61
...@@ -17,8 +17,8 @@ struct channels_reply_data { ...@@ -17,8 +17,8 @@ struct channels_reply_data {
#define CHANNELS_REPDATA(__reply_base) \ #define CHANNELS_REPDATA(__reply_base) \
container_of(__reply_base, struct channels_reply_data, base) container_of(__reply_base, struct channels_reply_data, base)
static const struct nla_policy const struct nla_policy
channels_get_policy[ETHTOOL_A_CHANNELS_MAX + 1] = { ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_MAX + 1] = {
[ETHTOOL_A_CHANNELS_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_CHANNELS_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_CHANNELS_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_CHANNELS_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_CHANNELS_RX_MAX] = { .type = NLA_REJECT }, [ETHTOOL_A_CHANNELS_RX_MAX] = { .type = NLA_REJECT },
...@@ -99,10 +99,8 @@ const struct ethnl_request_ops ethnl_channels_request_ops = { ...@@ -99,10 +99,8 @@ const struct ethnl_request_ops ethnl_channels_request_ops = {
.request_cmd = ETHTOOL_MSG_CHANNELS_GET, .request_cmd = ETHTOOL_MSG_CHANNELS_GET,
.reply_cmd = ETHTOOL_MSG_CHANNELS_GET_REPLY, .reply_cmd = ETHTOOL_MSG_CHANNELS_GET_REPLY,
.hdr_attr = ETHTOOL_A_CHANNELS_HEADER, .hdr_attr = ETHTOOL_A_CHANNELS_HEADER,
.max_attr = ETHTOOL_A_CHANNELS_MAX,
.req_info_size = sizeof(struct channels_req_info), .req_info_size = sizeof(struct channels_req_info),
.reply_data_size = sizeof(struct channels_reply_data), .reply_data_size = sizeof(struct channels_reply_data),
.request_policy = channels_get_policy,
.prepare_data = channels_prepare_data, .prepare_data = channels_prepare_data,
.reply_size = channels_reply_size, .reply_size = channels_reply_size,
......
...@@ -51,8 +51,8 @@ __CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS_HIGH); ...@@ -51,8 +51,8 @@ __CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES_HIGH); __CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_RATE_SAMPLE_INTERVAL); __CHECK_SUPPORTED_OFFSET(COALESCE_RATE_SAMPLE_INTERVAL);
static const struct nla_policy const struct nla_policy
coalesce_get_policy[ETHTOOL_A_COALESCE_MAX + 1] = { ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_MAX + 1] = {
[ETHTOOL_A_COALESCE_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_COALESCE_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_COALESCE_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_COALESCE_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_COALESCE_RX_USECS] = { .type = NLA_REJECT }, [ETHTOOL_A_COALESCE_RX_USECS] = { .type = NLA_REJECT },
...@@ -203,10 +203,8 @@ const struct ethnl_request_ops ethnl_coalesce_request_ops = { ...@@ -203,10 +203,8 @@ const struct ethnl_request_ops ethnl_coalesce_request_ops = {
.request_cmd = ETHTOOL_MSG_COALESCE_GET, .request_cmd = ETHTOOL_MSG_COALESCE_GET,
.reply_cmd = ETHTOOL_MSG_COALESCE_GET_REPLY, .reply_cmd = ETHTOOL_MSG_COALESCE_GET_REPLY,
.hdr_attr = ETHTOOL_A_COALESCE_HEADER, .hdr_attr = ETHTOOL_A_COALESCE_HEADER,
.max_attr = ETHTOOL_A_COALESCE_MAX,
.req_info_size = sizeof(struct coalesce_req_info), .req_info_size = sizeof(struct coalesce_req_info),
.reply_data_size = sizeof(struct coalesce_reply_data), .reply_data_size = sizeof(struct coalesce_reply_data),
.request_policy = coalesce_get_policy,
.prepare_data = coalesce_prepare_data, .prepare_data = coalesce_prepare_data,
.reply_size = coalesce_reply_size, .reply_size = coalesce_reply_size,
......
...@@ -16,8 +16,7 @@ struct debug_reply_data { ...@@ -16,8 +16,7 @@ struct debug_reply_data {
#define DEBUG_REPDATA(__reply_base) \ #define DEBUG_REPDATA(__reply_base) \
container_of(__reply_base, struct debug_reply_data, base) container_of(__reply_base, struct debug_reply_data, base)
static const struct nla_policy const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_MAX + 1] = {
debug_get_policy[ETHTOOL_A_DEBUG_MAX + 1] = {
[ETHTOOL_A_DEBUG_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_DEBUG_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_DEBUG_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_DEBUG_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_DEBUG_MSGMASK] = { .type = NLA_REJECT }, [ETHTOOL_A_DEBUG_MSGMASK] = { .type = NLA_REJECT },
...@@ -69,10 +68,8 @@ const struct ethnl_request_ops ethnl_debug_request_ops = { ...@@ -69,10 +68,8 @@ const struct ethnl_request_ops ethnl_debug_request_ops = {
.request_cmd = ETHTOOL_MSG_DEBUG_GET, .request_cmd = ETHTOOL_MSG_DEBUG_GET,
.reply_cmd = ETHTOOL_MSG_DEBUG_GET_REPLY, .reply_cmd = ETHTOOL_MSG_DEBUG_GET_REPLY,
.hdr_attr = ETHTOOL_A_DEBUG_HEADER, .hdr_attr = ETHTOOL_A_DEBUG_HEADER,
.max_attr = ETHTOOL_A_DEBUG_MAX,
.req_info_size = sizeof(struct debug_req_info), .req_info_size = sizeof(struct debug_req_info),
.reply_data_size = sizeof(struct debug_reply_data), .reply_data_size = sizeof(struct debug_reply_data),
.request_policy = debug_get_policy,
.prepare_data = debug_prepare_data, .prepare_data = debug_prepare_data,
.reply_size = debug_reply_size, .reply_size = debug_reply_size,
......
...@@ -19,8 +19,7 @@ struct eee_reply_data { ...@@ -19,8 +19,7 @@ struct eee_reply_data {
#define EEE_REPDATA(__reply_base) \ #define EEE_REPDATA(__reply_base) \
container_of(__reply_base, struct eee_reply_data, base) container_of(__reply_base, struct eee_reply_data, base)
static const struct nla_policy const struct nla_policy ethnl_eee_get_policy[ETHTOOL_A_EEE_MAX + 1] = {
eee_get_policy[ETHTOOL_A_EEE_MAX + 1] = {
[ETHTOOL_A_EEE_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_EEE_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_EEE_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_EEE_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_EEE_MODES_OURS] = { .type = NLA_REJECT }, [ETHTOOL_A_EEE_MODES_OURS] = { .type = NLA_REJECT },
...@@ -119,10 +118,8 @@ const struct ethnl_request_ops ethnl_eee_request_ops = { ...@@ -119,10 +118,8 @@ const struct ethnl_request_ops ethnl_eee_request_ops = {
.request_cmd = ETHTOOL_MSG_EEE_GET, .request_cmd = ETHTOOL_MSG_EEE_GET,
.reply_cmd = ETHTOOL_MSG_EEE_GET_REPLY, .reply_cmd = ETHTOOL_MSG_EEE_GET_REPLY,
.hdr_attr = ETHTOOL_A_EEE_HEADER, .hdr_attr = ETHTOOL_A_EEE_HEADER,
.max_attr = ETHTOOL_A_EEE_MAX,
.req_info_size = sizeof(struct eee_req_info), .req_info_size = sizeof(struct eee_req_info),
.reply_data_size = sizeof(struct eee_reply_data), .reply_data_size = sizeof(struct eee_reply_data),
.request_policy = eee_get_policy,
.prepare_data = eee_prepare_data, .prepare_data = eee_prepare_data,
.reply_size = eee_reply_size, .reply_size = eee_reply_size,
......
...@@ -20,8 +20,8 @@ struct features_reply_data { ...@@ -20,8 +20,8 @@ struct features_reply_data {
#define FEATURES_REPDATA(__reply_base) \ #define FEATURES_REPDATA(__reply_base) \
container_of(__reply_base, struct features_reply_data, base) container_of(__reply_base, struct features_reply_data, base)
static const struct nla_policy const struct nla_policy
features_get_policy[ETHTOOL_A_FEATURES_MAX + 1] = { ethnl_features_get_policy[ETHTOOL_A_FEATURES_MAX + 1] = {
[ETHTOOL_A_FEATURES_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_FEATURES_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_FEATURES_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_FEATURES_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_FEATURES_HW] = { .type = NLA_REJECT }, [ETHTOOL_A_FEATURES_HW] = { .type = NLA_REJECT },
...@@ -120,10 +120,8 @@ const struct ethnl_request_ops ethnl_features_request_ops = { ...@@ -120,10 +120,8 @@ const struct ethnl_request_ops ethnl_features_request_ops = {
.request_cmd = ETHTOOL_MSG_FEATURES_GET, .request_cmd = ETHTOOL_MSG_FEATURES_GET,
.reply_cmd = ETHTOOL_MSG_FEATURES_GET_REPLY, .reply_cmd = ETHTOOL_MSG_FEATURES_GET_REPLY,
.hdr_attr = ETHTOOL_A_FEATURES_HEADER, .hdr_attr = ETHTOOL_A_FEATURES_HEADER,
.max_attr = ETHTOOL_A_FEATURES_MAX,
.req_info_size = sizeof(struct features_req_info), .req_info_size = sizeof(struct features_req_info),
.reply_data_size = sizeof(struct features_reply_data), .reply_data_size = sizeof(struct features_reply_data),
.request_policy = features_get_policy,
.prepare_data = features_prepare_data, .prepare_data = features_prepare_data,
.reply_size = features_reply_size, .reply_size = features_reply_size,
......
...@@ -16,8 +16,8 @@ struct linkinfo_reply_data { ...@@ -16,8 +16,8 @@ struct linkinfo_reply_data {
#define LINKINFO_REPDATA(__reply_base) \ #define LINKINFO_REPDATA(__reply_base) \
container_of(__reply_base, struct linkinfo_reply_data, base) container_of(__reply_base, struct linkinfo_reply_data, base)
static const struct nla_policy const struct nla_policy
linkinfo_get_policy[ETHTOOL_A_LINKINFO_MAX + 1] = { ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_MAX + 1] = {
[ETHTOOL_A_LINKINFO_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_LINKINFO_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_LINKINFO_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_LINKINFO_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_LINKINFO_PORT] = { .type = NLA_REJECT }, [ETHTOOL_A_LINKINFO_PORT] = { .type = NLA_REJECT },
...@@ -83,10 +83,8 @@ const struct ethnl_request_ops ethnl_linkinfo_request_ops = { ...@@ -83,10 +83,8 @@ const struct ethnl_request_ops ethnl_linkinfo_request_ops = {
.request_cmd = ETHTOOL_MSG_LINKINFO_GET, .request_cmd = ETHTOOL_MSG_LINKINFO_GET,
.reply_cmd = ETHTOOL_MSG_LINKINFO_GET_REPLY, .reply_cmd = ETHTOOL_MSG_LINKINFO_GET_REPLY,
.hdr_attr = ETHTOOL_A_LINKINFO_HEADER, .hdr_attr = ETHTOOL_A_LINKINFO_HEADER,
.max_attr = ETHTOOL_A_LINKINFO_MAX,
.req_info_size = sizeof(struct linkinfo_req_info), .req_info_size = sizeof(struct linkinfo_req_info),
.reply_data_size = sizeof(struct linkinfo_reply_data), .reply_data_size = sizeof(struct linkinfo_reply_data),
.request_policy = linkinfo_get_policy,
.prepare_data = linkinfo_prepare_data, .prepare_data = linkinfo_prepare_data,
.reply_size = linkinfo_reply_size, .reply_size = linkinfo_reply_size,
......
...@@ -18,8 +18,8 @@ struct linkmodes_reply_data { ...@@ -18,8 +18,8 @@ struct linkmodes_reply_data {
#define LINKMODES_REPDATA(__reply_base) \ #define LINKMODES_REPDATA(__reply_base) \
container_of(__reply_base, struct linkmodes_reply_data, base) container_of(__reply_base, struct linkmodes_reply_data, base)
static const struct nla_policy const struct nla_policy
linkmodes_get_policy[ETHTOOL_A_LINKMODES_MAX + 1] = { ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_MAX + 1] = {
[ETHTOOL_A_LINKMODES_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_LINKMODES_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_LINKMODES_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_LINKMODES_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_LINKMODES_AUTONEG] = { .type = NLA_REJECT }, [ETHTOOL_A_LINKMODES_AUTONEG] = { .type = NLA_REJECT },
...@@ -148,10 +148,8 @@ const struct ethnl_request_ops ethnl_linkmodes_request_ops = { ...@@ -148,10 +148,8 @@ const struct ethnl_request_ops ethnl_linkmodes_request_ops = {
.request_cmd = ETHTOOL_MSG_LINKMODES_GET, .request_cmd = ETHTOOL_MSG_LINKMODES_GET,
.reply_cmd = ETHTOOL_MSG_LINKMODES_GET_REPLY, .reply_cmd = ETHTOOL_MSG_LINKMODES_GET_REPLY,
.hdr_attr = ETHTOOL_A_LINKMODES_HEADER, .hdr_attr = ETHTOOL_A_LINKMODES_HEADER,
.max_attr = ETHTOOL_A_LINKMODES_MAX,
.req_info_size = sizeof(struct linkmodes_req_info), .req_info_size = sizeof(struct linkmodes_req_info),
.reply_data_size = sizeof(struct linkmodes_reply_data), .reply_data_size = sizeof(struct linkmodes_reply_data),
.request_policy = linkmodes_get_policy,
.prepare_data = linkmodes_prepare_data, .prepare_data = linkmodes_prepare_data,
.reply_size = linkmodes_reply_size, .reply_size = linkmodes_reply_size,
......
...@@ -20,8 +20,8 @@ struct linkstate_reply_data { ...@@ -20,8 +20,8 @@ struct linkstate_reply_data {
#define LINKSTATE_REPDATA(__reply_base) \ #define LINKSTATE_REPDATA(__reply_base) \
container_of(__reply_base, struct linkstate_reply_data, base) container_of(__reply_base, struct linkstate_reply_data, base)
static const struct nla_policy const struct nla_policy
linkstate_get_policy[ETHTOOL_A_LINKSTATE_MAX + 1] = { ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_MAX + 1] = {
[ETHTOOL_A_LINKSTATE_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_LINKSTATE_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_LINKSTATE_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_LINKSTATE_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_LINKSTATE_LINK] = { .type = NLA_REJECT }, [ETHTOOL_A_LINKSTATE_LINK] = { .type = NLA_REJECT },
...@@ -179,10 +179,8 @@ const struct ethnl_request_ops ethnl_linkstate_request_ops = { ...@@ -179,10 +179,8 @@ const struct ethnl_request_ops ethnl_linkstate_request_ops = {
.request_cmd = ETHTOOL_MSG_LINKSTATE_GET, .request_cmd = ETHTOOL_MSG_LINKSTATE_GET,
.reply_cmd = ETHTOOL_MSG_LINKSTATE_GET_REPLY, .reply_cmd = ETHTOOL_MSG_LINKSTATE_GET_REPLY,
.hdr_attr = ETHTOOL_A_LINKSTATE_HEADER, .hdr_attr = ETHTOOL_A_LINKSTATE_HEADER,
.max_attr = ETHTOOL_A_LINKSTATE_MAX,
.req_info_size = sizeof(struct linkstate_req_info), .req_info_size = sizeof(struct linkstate_req_info),
.reply_data_size = sizeof(struct linkstate_reply_data), .reply_data_size = sizeof(struct linkstate_reply_data),
.request_policy = linkstate_get_policy,
.prepare_data = linkstate_prepare_data, .prepare_data = linkstate_prepare_data,
.reply_size = linkstate_reply_size, .reply_size = linkstate_reply_size,
......
...@@ -247,7 +247,7 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb) ...@@ -247,7 +247,7 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
/** /**
* ethnl_default_parse() - Parse request message * ethnl_default_parse() - Parse request message
* @req_info: pointer to structure to put data into * @req_info: pointer to structure to put data into
* @nlhdr: pointer to request message header * @tb: parsed attributes
* @net: request netns * @net: request netns
* @request_ops: struct request_ops for request type * @request_ops: struct request_ops for request type
* @extack: netlink extack for error reporting * @extack: netlink extack for error reporting
...@@ -259,37 +259,24 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb) ...@@ -259,37 +259,24 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
* Return: 0 on success or negative error code * Return: 0 on success or negative error code
*/ */
static int ethnl_default_parse(struct ethnl_req_info *req_info, 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, const struct ethnl_request_ops *request_ops,
struct netlink_ext_ack *extack, bool require_dev) struct netlink_ext_ack *extack, bool require_dev)
{ {
struct nlattr **tb;
int ret; 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], ret = ethnl_parse_header_dev_get(req_info, tb[request_ops->hdr_attr],
net, extack, require_dev); net, extack, require_dev);
if (ret < 0) if (ret < 0)
goto out; return ret;
if (request_ops->parse_request) { if (request_ops->parse_request) {
ret = request_ops->parse_request(req_info, tb, extack); ret = request_ops->parse_request(req_info, tb, extack);
if (ret < 0) if (ret < 0)
goto out; return ret;
} }
ret = 0; return 0;
out:
kfree(tb);
return ret;
} }
/** /**
...@@ -334,8 +321,8 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info) ...@@ -334,8 +321,8 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM; return -ENOMEM;
} }
ret = ethnl_default_parse(req_info, info->nlhdr, genl_info_net(info), ops, ret = ethnl_default_parse(req_info, info->attrs, genl_info_net(info),
info->extack, !ops->allow_nodev_do); ops, info->extack, !ops->allow_nodev_do);
if (ret < 0) if (ret < 0)
goto err_dev; goto err_dev;
ethnl_init_reply_data(reply_data, ops, req_info->dev); ethnl_init_reply_data(reply_data, ops, req_info->dev);
...@@ -480,6 +467,7 @@ static int ethnl_default_dumpit(struct sk_buff *skb, ...@@ -480,6 +467,7 @@ static int ethnl_default_dumpit(struct sk_buff *skb,
/* generic ->start() handler for GET requests */ /* generic ->start() handler for GET requests */
static int ethnl_default_start(struct netlink_callback *cb) 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_dump_ctx *ctx = ethnl_dump_context(cb);
struct ethnl_reply_data *reply_data; struct ethnl_reply_data *reply_data;
const struct ethnl_request_ops *ops; const struct ethnl_request_ops *ops;
...@@ -502,8 +490,8 @@ static int ethnl_default_start(struct netlink_callback *cb) ...@@ -502,8 +490,8 @@ static int ethnl_default_start(struct netlink_callback *cb)
goto free_req_info; goto free_req_info;
} }
ret = ethnl_default_parse(req_info, cb->nlh, sock_net(cb->skb->sk), ops, ret = ethnl_default_parse(req_info, info->attrs, sock_net(cb->skb->sk),
cb->extack, false); ops, cb->extack, false);
if (req_info->dev) { if (req_info->dev) {
/* We ignore device specification in dump requests but as the /* We ignore device specification in dump requests but as the
* same parser as for non-dump (doit) requests is used, it * same parser as for non-dump (doit) requests is used, it
...@@ -696,6 +684,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -696,6 +684,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_strset_get_policy,
.maxattr = ARRAY_SIZE(ethnl_strset_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_LINKINFO_GET, .cmd = ETHTOOL_MSG_LINKINFO_GET,
...@@ -703,6 +693,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -703,6 +693,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_linkinfo_get_policy,
.maxattr = ARRAY_SIZE(ethnl_linkinfo_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_LINKINFO_SET, .cmd = ETHTOOL_MSG_LINKINFO_SET,
...@@ -715,6 +707,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -715,6 +707,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_linkmodes_get_policy,
.maxattr = ARRAY_SIZE(ethnl_linkmodes_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_LINKMODES_SET, .cmd = ETHTOOL_MSG_LINKMODES_SET,
...@@ -727,6 +721,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -727,6 +721,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_linkstate_get_policy,
.maxattr = ARRAY_SIZE(ethnl_linkstate_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_DEBUG_GET, .cmd = ETHTOOL_MSG_DEBUG_GET,
...@@ -734,6 +730,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -734,6 +730,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_debug_get_policy,
.maxattr = ARRAY_SIZE(ethnl_debug_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_DEBUG_SET, .cmd = ETHTOOL_MSG_DEBUG_SET,
...@@ -747,6 +745,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -747,6 +745,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_wol_get_policy,
.maxattr = ARRAY_SIZE(ethnl_wol_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_WOL_SET, .cmd = ETHTOOL_MSG_WOL_SET,
...@@ -759,6 +759,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -759,6 +759,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_features_get_policy,
.maxattr = ARRAY_SIZE(ethnl_features_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_FEATURES_SET, .cmd = ETHTOOL_MSG_FEATURES_SET,
...@@ -771,6 +773,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -771,6 +773,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_privflags_get_policy,
.maxattr = ARRAY_SIZE(ethnl_privflags_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_PRIVFLAGS_SET, .cmd = ETHTOOL_MSG_PRIVFLAGS_SET,
...@@ -783,6 +787,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -783,6 +787,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_rings_get_policy,
.maxattr = ARRAY_SIZE(ethnl_rings_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_RINGS_SET, .cmd = ETHTOOL_MSG_RINGS_SET,
...@@ -795,6 +801,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -795,6 +801,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_channels_get_policy,
.maxattr = ARRAY_SIZE(ethnl_channels_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_CHANNELS_SET, .cmd = ETHTOOL_MSG_CHANNELS_SET,
...@@ -807,6 +815,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -807,6 +815,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_coalesce_get_policy,
.maxattr = ARRAY_SIZE(ethnl_coalesce_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_COALESCE_SET, .cmd = ETHTOOL_MSG_COALESCE_SET,
...@@ -819,6 +829,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -819,6 +829,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_pause_get_policy,
.maxattr = ARRAY_SIZE(ethnl_pause_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_PAUSE_SET, .cmd = ETHTOOL_MSG_PAUSE_SET,
...@@ -831,6 +843,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -831,6 +843,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_eee_get_policy,
.maxattr = ARRAY_SIZE(ethnl_eee_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_EEE_SET, .cmd = ETHTOOL_MSG_EEE_SET,
...@@ -843,6 +857,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -843,6 +857,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.start = ethnl_default_start, .start = ethnl_default_start,
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
.policy = ethnl_tsinfo_get_policy,
.maxattr = ARRAY_SIZE(ethnl_tsinfo_get_policy) - 1,
}, },
{ {
.cmd = ETHTOOL_MSG_CABLE_TEST_ACT, .cmd = ETHTOOL_MSG_CABLE_TEST_ACT,
...@@ -859,6 +875,8 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -859,6 +875,8 @@ static const struct genl_ops ethtool_genl_ops[] = {
.doit = ethnl_tunnel_info_doit, .doit = ethnl_tunnel_info_doit,
.start = ethnl_tunnel_info_start, .start = ethnl_tunnel_info_start,
.dumpit = ethnl_tunnel_info_dumpit, .dumpit = ethnl_tunnel_info_dumpit,
.policy = ethnl_tunnel_info_get_policy,
.maxattr = ARRAY_SIZE(ethnl_tunnel_info_get_policy) - 1,
}, },
}; };
......
...@@ -266,10 +266,8 @@ static inline void ethnl_ops_complete(struct net_device *dev) ...@@ -266,10 +266,8 @@ static inline void ethnl_ops_complete(struct net_device *dev)
* @request_cmd: command id for request (GET) * @request_cmd: command id for request (GET)
* @reply_cmd: command id for reply (GET_REPLY) * @reply_cmd: command id for reply (GET_REPLY)
* @hdr_attr: attribute type for request header * @hdr_attr: attribute type for request header
* @max_attr: maximum (top level) attribute type
* @req_info_size: size of request info * @req_info_size: size of request info
* @reply_data_size: size of reply data * @reply_data_size: size of reply data
* @request_policy: netlink policy for message contents
* @allow_nodev_do: allow non-dump request with no device identification * @allow_nodev_do: allow non-dump request with no device identification
* @parse_request: * @parse_request:
* Parse request except common header (struct ethnl_req_info). Common * Parse request except common header (struct ethnl_req_info). Common
...@@ -312,10 +310,8 @@ struct ethnl_request_ops { ...@@ -312,10 +310,8 @@ struct ethnl_request_ops {
u8 request_cmd; u8 request_cmd;
u8 reply_cmd; u8 reply_cmd;
u16 hdr_attr; u16 hdr_attr;
unsigned int max_attr;
unsigned int req_info_size; unsigned int req_info_size;
unsigned int reply_data_size; unsigned int reply_data_size;
const struct nla_policy *request_policy;
bool allow_nodev_do; bool allow_nodev_do;
int (*parse_request)(struct ethnl_req_info *req_info, int (*parse_request)(struct ethnl_req_info *req_info,
...@@ -349,6 +345,22 @@ extern const struct ethnl_request_ops ethnl_pause_request_ops; ...@@ -349,6 +345,22 @@ extern const struct ethnl_request_ops ethnl_pause_request_ops;
extern const struct ethnl_request_ops ethnl_eee_request_ops; extern const struct ethnl_request_ops ethnl_eee_request_ops;
extern const struct ethnl_request_ops ethnl_tsinfo_request_ops; extern const struct ethnl_request_ops ethnl_tsinfo_request_ops;
extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_MAX + 1];
extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_MAX + 1];
extern const struct nla_policy ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_MAX + 1];
extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_MAX + 1];
extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_MAX + 1];
extern const struct nla_policy ethnl_wol_get_policy[ETHTOOL_A_WOL_MAX + 1];
extern const struct nla_policy ethnl_features_get_policy[ETHTOOL_A_FEATURES_MAX + 1];
extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_MAX + 1];
extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_MAX + 1];
extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_MAX + 1];
extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_MAX + 1];
extern const struct nla_policy ethnl_pause_get_policy[ETHTOOL_A_PAUSE_MAX + 1];
extern const struct nla_policy ethnl_eee_get_policy[ETHTOOL_A_EEE_MAX + 1];
extern const struct nla_policy ethnl_tsinfo_get_policy[ETHTOOL_A_TSINFO_MAX + 1];
extern const struct nla_policy ethnl_tunnel_info_get_policy[ETHTOOL_A_TUNNEL_INFO_MAX + 1];
int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info); int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info); int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);
int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info); int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info);
......
...@@ -16,8 +16,7 @@ struct pause_reply_data { ...@@ -16,8 +16,7 @@ struct pause_reply_data {
#define PAUSE_REPDATA(__reply_base) \ #define PAUSE_REPDATA(__reply_base) \
container_of(__reply_base, struct pause_reply_data, base) container_of(__reply_base, struct pause_reply_data, base)
static const struct nla_policy const struct nla_policy ethnl_pause_get_policy[ETHTOOL_A_PAUSE_MAX + 1] = {
pause_get_policy[ETHTOOL_A_PAUSE_MAX + 1] = {
[ETHTOOL_A_PAUSE_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_PAUSE_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_PAUSE_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_PAUSE_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_PAUSE_AUTONEG] = { .type = NLA_REJECT }, [ETHTOOL_A_PAUSE_AUTONEG] = { .type = NLA_REJECT },
...@@ -130,10 +129,8 @@ const struct ethnl_request_ops ethnl_pause_request_ops = { ...@@ -130,10 +129,8 @@ const struct ethnl_request_ops ethnl_pause_request_ops = {
.request_cmd = ETHTOOL_MSG_PAUSE_GET, .request_cmd = ETHTOOL_MSG_PAUSE_GET,
.reply_cmd = ETHTOOL_MSG_PAUSE_GET_REPLY, .reply_cmd = ETHTOOL_MSG_PAUSE_GET_REPLY,
.hdr_attr = ETHTOOL_A_PAUSE_HEADER, .hdr_attr = ETHTOOL_A_PAUSE_HEADER,
.max_attr = ETHTOOL_A_PAUSE_MAX,
.req_info_size = sizeof(struct pause_req_info), .req_info_size = sizeof(struct pause_req_info),
.reply_data_size = sizeof(struct pause_reply_data), .reply_data_size = sizeof(struct pause_reply_data),
.request_policy = pause_get_policy,
.prepare_data = pause_prepare_data, .prepare_data = pause_prepare_data,
.reply_size = pause_reply_size, .reply_size = pause_reply_size,
......
...@@ -18,8 +18,8 @@ struct privflags_reply_data { ...@@ -18,8 +18,8 @@ struct privflags_reply_data {
#define PRIVFLAGS_REPDATA(__reply_base) \ #define PRIVFLAGS_REPDATA(__reply_base) \
container_of(__reply_base, struct privflags_reply_data, base) container_of(__reply_base, struct privflags_reply_data, base)
static const struct nla_policy const struct nla_policy
privflags_get_policy[ETHTOOL_A_PRIVFLAGS_MAX + 1] = { ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_MAX + 1] = {
[ETHTOOL_A_PRIVFLAGS_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_PRIVFLAGS_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_PRIVFLAGS_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_PRIVFLAGS_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_PRIVFLAGS_FLAGS] = { .type = NLA_REJECT }, [ETHTOOL_A_PRIVFLAGS_FLAGS] = { .type = NLA_REJECT },
...@@ -124,10 +124,8 @@ const struct ethnl_request_ops ethnl_privflags_request_ops = { ...@@ -124,10 +124,8 @@ const struct ethnl_request_ops ethnl_privflags_request_ops = {
.request_cmd = ETHTOOL_MSG_PRIVFLAGS_GET, .request_cmd = ETHTOOL_MSG_PRIVFLAGS_GET,
.reply_cmd = ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, .reply_cmd = ETHTOOL_MSG_PRIVFLAGS_GET_REPLY,
.hdr_attr = ETHTOOL_A_PRIVFLAGS_HEADER, .hdr_attr = ETHTOOL_A_PRIVFLAGS_HEADER,
.max_attr = ETHTOOL_A_PRIVFLAGS_MAX,
.req_info_size = sizeof(struct privflags_req_info), .req_info_size = sizeof(struct privflags_req_info),
.reply_data_size = sizeof(struct privflags_reply_data), .reply_data_size = sizeof(struct privflags_reply_data),
.request_policy = privflags_get_policy,
.prepare_data = privflags_prepare_data, .prepare_data = privflags_prepare_data,
.reply_size = privflags_reply_size, .reply_size = privflags_reply_size,
......
...@@ -15,8 +15,7 @@ struct rings_reply_data { ...@@ -15,8 +15,7 @@ struct rings_reply_data {
#define RINGS_REPDATA(__reply_base) \ #define RINGS_REPDATA(__reply_base) \
container_of(__reply_base, struct rings_reply_data, base) container_of(__reply_base, struct rings_reply_data, base)
static const struct nla_policy const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_MAX + 1] = {
rings_get_policy[ETHTOOL_A_RINGS_MAX + 1] = {
[ETHTOOL_A_RINGS_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_RINGS_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_RINGS_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_RINGS_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_RINGS_RX_MAX] = { .type = NLA_REJECT }, [ETHTOOL_A_RINGS_RX_MAX] = { .type = NLA_REJECT },
...@@ -97,10 +96,8 @@ const struct ethnl_request_ops ethnl_rings_request_ops = { ...@@ -97,10 +96,8 @@ const struct ethnl_request_ops ethnl_rings_request_ops = {
.request_cmd = ETHTOOL_MSG_RINGS_GET, .request_cmd = ETHTOOL_MSG_RINGS_GET,
.reply_cmd = ETHTOOL_MSG_RINGS_GET_REPLY, .reply_cmd = ETHTOOL_MSG_RINGS_GET_REPLY,
.hdr_attr = ETHTOOL_A_RINGS_HEADER, .hdr_attr = ETHTOOL_A_RINGS_HEADER,
.max_attr = ETHTOOL_A_RINGS_MAX,
.req_info_size = sizeof(struct rings_req_info), .req_info_size = sizeof(struct rings_req_info),
.reply_data_size = sizeof(struct rings_reply_data), .reply_data_size = sizeof(struct rings_reply_data),
.request_policy = rings_get_policy,
.prepare_data = rings_prepare_data, .prepare_data = rings_prepare_data,
.reply_size = rings_reply_size, .reply_size = rings_reply_size,
......
...@@ -99,7 +99,7 @@ struct strset_reply_data { ...@@ -99,7 +99,7 @@ struct strset_reply_data {
#define STRSET_REPDATA(__reply_base) \ #define STRSET_REPDATA(__reply_base) \
container_of(__reply_base, struct strset_reply_data, base) container_of(__reply_base, struct strset_reply_data, base)
static const struct nla_policy strset_get_policy[ETHTOOL_A_STRSET_MAX + 1] = { const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_MAX + 1] = {
[ETHTOOL_A_STRSET_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_STRSET_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_STRSET_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_STRSET_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_STRSET_STRINGSETS] = { .type = NLA_NESTED }, [ETHTOOL_A_STRSET_STRINGSETS] = { .type = NLA_NESTED },
...@@ -445,10 +445,8 @@ const struct ethnl_request_ops ethnl_strset_request_ops = { ...@@ -445,10 +445,8 @@ const struct ethnl_request_ops ethnl_strset_request_ops = {
.request_cmd = ETHTOOL_MSG_STRSET_GET, .request_cmd = ETHTOOL_MSG_STRSET_GET,
.reply_cmd = ETHTOOL_MSG_STRSET_GET_REPLY, .reply_cmd = ETHTOOL_MSG_STRSET_GET_REPLY,
.hdr_attr = ETHTOOL_A_STRSET_HEADER, .hdr_attr = ETHTOOL_A_STRSET_HEADER,
.max_attr = ETHTOOL_A_STRSET_MAX,
.req_info_size = sizeof(struct strset_req_info), .req_info_size = sizeof(struct strset_req_info),
.reply_data_size = sizeof(struct strset_reply_data), .reply_data_size = sizeof(struct strset_reply_data),
.request_policy = strset_get_policy,
.allow_nodev_do = true, .allow_nodev_do = true,
.parse_request = strset_parse_request, .parse_request = strset_parse_request,
......
...@@ -18,8 +18,7 @@ struct tsinfo_reply_data { ...@@ -18,8 +18,7 @@ struct tsinfo_reply_data {
#define TSINFO_REPDATA(__reply_base) \ #define TSINFO_REPDATA(__reply_base) \
container_of(__reply_base, struct tsinfo_reply_data, base) container_of(__reply_base, struct tsinfo_reply_data, base)
static const struct nla_policy const struct nla_policy ethnl_tsinfo_get_policy[ETHTOOL_A_TSINFO_MAX + 1] = {
tsinfo_get_policy[ETHTOOL_A_TSINFO_MAX + 1] = {
[ETHTOOL_A_TSINFO_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_TSINFO_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_TSINFO_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_TSINFO_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_TSINFO_TIMESTAMPING] = { .type = NLA_REJECT }, [ETHTOOL_A_TSINFO_TIMESTAMPING] = { .type = NLA_REJECT },
...@@ -132,10 +131,8 @@ const struct ethnl_request_ops ethnl_tsinfo_request_ops = { ...@@ -132,10 +131,8 @@ const struct ethnl_request_ops ethnl_tsinfo_request_ops = {
.request_cmd = ETHTOOL_MSG_TSINFO_GET, .request_cmd = ETHTOOL_MSG_TSINFO_GET,
.reply_cmd = ETHTOOL_MSG_TSINFO_GET_REPLY, .reply_cmd = ETHTOOL_MSG_TSINFO_GET_REPLY,
.hdr_attr = ETHTOOL_A_TSINFO_HEADER, .hdr_attr = ETHTOOL_A_TSINFO_HEADER,
.max_attr = ETHTOOL_A_TSINFO_MAX,
.req_info_size = sizeof(struct tsinfo_req_info), .req_info_size = sizeof(struct tsinfo_req_info),
.reply_data_size = sizeof(struct tsinfo_reply_data), .reply_data_size = sizeof(struct tsinfo_reply_data),
.request_policy = tsinfo_get_policy,
.prepare_data = tsinfo_prepare_data, .prepare_data = tsinfo_prepare_data,
.reply_size = tsinfo_reply_size, .reply_size = tsinfo_reply_size,
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
#include "common.h" #include "common.h"
#include "netlink.h" #include "netlink.h"
static const struct nla_policy const struct nla_policy
ethtool_tunnel_info_policy[ETHTOOL_A_TUNNEL_INFO_MAX + 1] = { ethnl_tunnel_info_get_policy[ETHTOOL_A_TUNNEL_INFO_MAX + 1] = {
[ETHTOOL_A_TUNNEL_INFO_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_TUNNEL_INFO_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_TUNNEL_INFO_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_TUNNEL_INFO_HEADER] = { .type = NLA_NESTED },
}; };
...@@ -161,35 +161,19 @@ ethnl_tunnel_info_fill_reply(const struct ethnl_req_info *req_base, ...@@ -161,35 +161,19 @@ ethnl_tunnel_info_fill_reply(const struct ethnl_req_info *req_base,
return -EMSGSIZE; return -EMSGSIZE;
} }
static int
ethnl_tunnel_info_req_parse(struct ethnl_req_info *req_info,
const struct nlmsghdr *nlhdr, struct net *net,
struct netlink_ext_ack *extack, bool require_dev)
{
struct nlattr *tb[ETHTOOL_A_TUNNEL_INFO_MAX + 1];
int ret;
ret = nlmsg_parse(nlhdr, GENL_HDRLEN, tb, ETHTOOL_A_TUNNEL_INFO_MAX,
ethtool_tunnel_info_policy, extack);
if (ret < 0)
return ret;
return ethnl_parse_header_dev_get(req_info,
tb[ETHTOOL_A_TUNNEL_INFO_HEADER],
net, extack, require_dev);
}
int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info) int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info)
{ {
struct ethnl_req_info req_info = {}; struct ethnl_req_info req_info = {};
struct nlattr **tb = info->attrs;
struct sk_buff *rskb; struct sk_buff *rskb;
void *reply_payload; void *reply_payload;
int reply_len; int reply_len;
int ret; int ret;
ret = ethnl_tunnel_info_req_parse(&req_info, info->nlhdr, ret = ethnl_parse_header_dev_get(&req_info,
genl_info_net(info), info->extack, tb[ETHTOOL_A_TUNNEL_INFO_HEADER],
true); genl_info_net(info), info->extack,
true);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -233,16 +217,19 @@ struct ethnl_tunnel_info_dump_ctx { ...@@ -233,16 +217,19 @@ struct ethnl_tunnel_info_dump_ctx {
int ethnl_tunnel_info_start(struct netlink_callback *cb) int ethnl_tunnel_info_start(struct netlink_callback *cb)
{ {
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
struct ethnl_tunnel_info_dump_ctx *ctx = (void *)cb->ctx; struct ethnl_tunnel_info_dump_ctx *ctx = (void *)cb->ctx;
struct nlattr **tb = info->attrs;
int ret; int ret;
BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx)); BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
ret = ethnl_tunnel_info_req_parse(&ctx->req_info, cb->nlh, ret = ethnl_parse_header_dev_get(&ctx->req_info,
sock_net(cb->skb->sk), cb->extack, tb[ETHTOOL_A_TUNNEL_INFO_HEADER],
false); sock_net(cb->skb->sk), cb->extack,
false);
if (ctx->req_info.dev) { if (ctx->req_info.dev) {
dev_put(ctx->req_info.dev); dev_put(ctx->req_info.dev);
ctx->req_info.dev = NULL; ctx->req_info.dev = NULL;
......
...@@ -17,8 +17,7 @@ struct wol_reply_data { ...@@ -17,8 +17,7 @@ struct wol_reply_data {
#define WOL_REPDATA(__reply_base) \ #define WOL_REPDATA(__reply_base) \
container_of(__reply_base, struct wol_reply_data, base) container_of(__reply_base, struct wol_reply_data, base)
static const struct nla_policy const struct nla_policy ethnl_wol_get_policy[ETHTOOL_A_WOL_MAX + 1] = {
wol_get_policy[ETHTOOL_A_WOL_MAX + 1] = {
[ETHTOOL_A_WOL_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_WOL_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_WOL_HEADER] = { .type = NLA_NESTED }, [ETHTOOL_A_WOL_HEADER] = { .type = NLA_NESTED },
[ETHTOOL_A_WOL_MODES] = { .type = NLA_REJECT }, [ETHTOOL_A_WOL_MODES] = { .type = NLA_REJECT },
...@@ -89,10 +88,8 @@ const struct ethnl_request_ops ethnl_wol_request_ops = { ...@@ -89,10 +88,8 @@ const struct ethnl_request_ops ethnl_wol_request_ops = {
.request_cmd = ETHTOOL_MSG_WOL_GET, .request_cmd = ETHTOOL_MSG_WOL_GET,
.reply_cmd = ETHTOOL_MSG_WOL_GET_REPLY, .reply_cmd = ETHTOOL_MSG_WOL_GET_REPLY,
.hdr_attr = ETHTOOL_A_WOL_HEADER, .hdr_attr = ETHTOOL_A_WOL_HEADER,
.max_attr = ETHTOOL_A_WOL_MAX,
.req_info_size = sizeof(struct wol_req_info), .req_info_size = sizeof(struct wol_req_info),
.reply_data_size = sizeof(struct wol_reply_data), .reply_data_size = sizeof(struct wol_reply_data),
.request_policy = wol_get_policy,
.prepare_data = wol_prepare_data, .prepare_data = wol_prepare_data,
.reply_size = wol_reply_size, .reply_size = wol_reply_size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment