ethtool: netlink: convert commands to common SET

Convert all SET commands where new common code is applicable.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jakub Kicinski
2023-01-25 15:05:19 -08:00
committed by David S. Miller
parent 99132b6eb7
commit 04007961bf
16 changed files with 614 additions and 831 deletions

View File

@@ -151,18 +151,6 @@ static int linkmodes_fill_reply(struct sk_buff *skb,
return 0;
}
const struct ethnl_request_ops ethnl_linkmodes_request_ops = {
.request_cmd = ETHTOOL_MSG_LINKMODES_GET,
.reply_cmd = ETHTOOL_MSG_LINKMODES_GET_REPLY,
.hdr_attr = ETHTOOL_A_LINKMODES_HEADER,
.req_info_size = sizeof(struct linkmodes_req_info),
.reply_data_size = sizeof(struct linkmodes_reply_data),
.prepare_data = linkmodes_prepare_data,
.reply_size = linkmodes_reply_size,
.fill_reply = linkmodes_fill_reply,
};
/* LINKMODES_SET */
const struct nla_policy ethnl_linkmodes_set_policy[] = {
@@ -310,59 +298,64 @@ static int ethnl_update_linkmodes(struct genl_info *info, struct nlattr **tb,
return 0;
}
int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info)
static int
ethnl_set_linkmodes_validate(struct ethnl_req_info *req_info,
struct genl_info *info)
{
struct ethtool_link_ksettings ksettings = {};
struct ethnl_req_info req_info = {};
struct nlattr **tb = info->attrs;
struct net_device *dev;
bool mod = false;
const struct ethtool_ops *ops = req_info->dev->ethtool_ops;
int ret;
ret = ethnl_check_linkmodes(info, tb);
ret = ethnl_check_linkmodes(info, info->attrs);
if (ret < 0)
return ret;
ret = ethnl_parse_header_dev_get(&req_info,
tb[ETHTOOL_A_LINKMODES_HEADER],
genl_info_net(info), info->extack,
true);
if (ret < 0)
return ret;
dev = req_info.dev;
ret = -EOPNOTSUPP;
if (!dev->ethtool_ops->get_link_ksettings ||
!dev->ethtool_ops->set_link_ksettings)
goto out_dev;
if (!ops->get_link_ksettings || !ops->set_link_ksettings)
return -EOPNOTSUPP;
return 1;
}
rtnl_lock();
ret = ethnl_ops_begin(dev);
if (ret < 0)
goto out_rtnl;
static int
ethnl_set_linkmodes(struct ethnl_req_info *req_info, struct genl_info *info)
{
struct ethtool_link_ksettings ksettings = {};
struct net_device *dev = req_info->dev;
struct nlattr **tb = info->attrs;
bool mod = false;
int ret;
ret = __ethtool_get_link_ksettings(dev, &ksettings);
if (ret < 0) {
GENL_SET_ERR_MSG(info, "failed to retrieve link settings");
goto out_ops;
return ret;
}
ret = ethnl_update_linkmodes(info, tb, &ksettings, &mod, dev);
if (ret < 0)
goto out_ops;
return ret;
if (!mod)
return 0;
if (mod) {
ret = dev->ethtool_ops->set_link_ksettings(dev, &ksettings);
if (ret < 0)
GENL_SET_ERR_MSG(info, "link settings update failed");
else
ethtool_notify(dev, ETHTOOL_MSG_LINKMODES_NTF, NULL);
ret = dev->ethtool_ops->set_link_ksettings(dev, &ksettings);
if (ret < 0) {
GENL_SET_ERR_MSG(info, "link settings update failed");
return ret;
}
out_ops:
ethnl_ops_complete(dev);
out_rtnl:
rtnl_unlock();
out_dev:
ethnl_parse_header_dev_put(&req_info);
return ret;
return 1;
}
const struct ethnl_request_ops ethnl_linkmodes_request_ops = {
.request_cmd = ETHTOOL_MSG_LINKMODES_GET,
.reply_cmd = ETHTOOL_MSG_LINKMODES_GET_REPLY,
.hdr_attr = ETHTOOL_A_LINKMODES_HEADER,
.req_info_size = sizeof(struct linkmodes_req_info),
.reply_data_size = sizeof(struct linkmodes_reply_data),
.prepare_data = linkmodes_prepare_data,
.reply_size = linkmodes_reply_size,
.fill_reply = linkmodes_fill_reply,
.set_validate = ethnl_set_linkmodes_validate,
.set = ethnl_set_linkmodes,
.set_ntf_cmd = ETHTOOL_MSG_LINKMODES_NTF,
};