Skip to content

Commit 8d425b1

Browse files
mkubecekdavem330
authored andcommitted
ethtool: set wake-on-lan settings with WOL_SET request
Implement WOL_SET netlink request to set wake-on-lan settings. This is equivalent to ETHTOOL_SWOL ioctl request. Signed-off-by: Michal Kubecek <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 51ea22b commit 8d425b1

File tree

5 files changed

+102
-1
lines changed

5 files changed

+102
-1
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ Userspace to kernel:
188188
``ETHTOOL_MSG_DEBUG_GET`` get debugging settings
189189
``ETHTOOL_MSG_DEBUG_SET`` set debugging settings
190190
``ETHTOOL_MSG_WOL_GET`` get wake-on-lan settings
191+
``ETHTOOL_MSG_WOL_SET`` set wake-on-lan settings
191192
===================================== ================================
192193

193194
Kernel to userspace:
@@ -502,6 +503,23 @@ device, value of modes which are enabled. ``ETHTOOL_A_WOL_SOPASS`` is only
502503
included in reply if ``WAKE_MAGICSECURE`` mode is supported.
503504

504505

506+
WOL_SET
507+
=======
508+
509+
Set or update wake-on-lan settings.
510+
511+
Request contents:
512+
513+
==================================== ====== ==========================
514+
``ETHTOOL_A_WOL_HEADER`` nested request header
515+
``ETHTOOL_A_WOL_MODES`` bitset enabled WoL modes
516+
``ETHTOOL_A_WOL_SOPASS`` binary SecureOn(tm) password
517+
==================================== ====== ==========================
518+
519+
``ETHTOOL_A_WOL_SOPASS`` is only allowed for devices supporting
520+
``WAKE_MAGICSECURE`` mode.
521+
522+
505523
Request translation
506524
===================
507525

@@ -519,7 +537,7 @@ have their netlink replacement yet.
519537
``ETHTOOL_GDRVINFO`` n/a
520538
``ETHTOOL_GREGS`` n/a
521539
``ETHTOOL_GWOL`` ``ETHTOOL_MSG_WOL_GET``
522-
``ETHTOOL_SWOL`` n/a
540+
``ETHTOOL_SWOL`` ``ETHTOOL_MSG_WOL_SET``
523541
``ETHTOOL_GMSGLVL`` ``ETHTOOL_MSG_DEBUG_GET``
524542
``ETHTOOL_SMSGLVL`` ``ETHTOOL_MSG_DEBUG_SET``
525543
``ETHTOOL_NWAY_RST`` n/a

include/uapi/linux/ethtool_netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum {
2323
ETHTOOL_MSG_DEBUG_GET,
2424
ETHTOOL_MSG_DEBUG_SET,
2525
ETHTOOL_MSG_WOL_GET,
26+
ETHTOOL_MSG_WOL_SET,
2627

2728
/* add new constants above here */
2829
__ETHTOOL_MSG_USER_CNT,

net/ethtool/netlink.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,11 @@ static const struct genl_ops ethtool_genl_ops[] = {
688688
.dumpit = ethnl_default_dumpit,
689689
.done = ethnl_default_done,
690690
},
691+
{
692+
.cmd = ETHTOOL_MSG_WOL_SET,
693+
.flags = GENL_UNS_ADMIN_PERM,
694+
.doit = ethnl_set_wol,
695+
},
691696
};
692697

693698
static const struct genl_multicast_group ethtool_nl_mcgrps[] = {

net/ethtool/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,5 +340,6 @@ extern const struct ethnl_request_ops ethnl_wol_request_ops;
340340
int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
341341
int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);
342342
int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info);
343+
int ethnl_set_wol(struct sk_buff *skb, struct genl_info *info);
343344

344345
#endif /* _NET_ETHTOOL_NETLINK_H */

net/ethtool/wol.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,79 @@ const struct ethnl_request_ops ethnl_wol_request_ops = {
9797
.reply_size = wol_reply_size,
9898
.fill_reply = wol_fill_reply,
9999
};
100+
101+
/* WOL_SET */
102+
103+
static const struct nla_policy
104+
wol_set_policy[ETHTOOL_A_WOL_MAX + 1] = {
105+
[ETHTOOL_A_WOL_UNSPEC] = { .type = NLA_REJECT },
106+
[ETHTOOL_A_WOL_HEADER] = { .type = NLA_NESTED },
107+
[ETHTOOL_A_WOL_MODES] = { .type = NLA_NESTED },
108+
[ETHTOOL_A_WOL_SOPASS] = { .type = NLA_BINARY,
109+
.len = SOPASS_MAX },
110+
};
111+
112+
int ethnl_set_wol(struct sk_buff *skb, struct genl_info *info)
113+
{
114+
struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
115+
struct nlattr *tb[ETHTOOL_A_WOL_MAX + 1];
116+
struct ethnl_req_info req_info = {};
117+
struct net_device *dev;
118+
bool mod = false;
119+
int ret;
120+
121+
ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb, ETHTOOL_A_WOL_MAX,
122+
wol_set_policy, info->extack);
123+
if (ret < 0)
124+
return ret;
125+
ret = ethnl_parse_header(&req_info, tb[ETHTOOL_A_WOL_HEADER],
126+
genl_info_net(info), info->extack, true);
127+
if (ret < 0)
128+
return ret;
129+
dev = req_info.dev;
130+
if (!dev->ethtool_ops->get_wol || !dev->ethtool_ops->set_wol)
131+
return -EOPNOTSUPP;
132+
133+
rtnl_lock();
134+
ret = ethnl_ops_begin(dev);
135+
if (ret < 0)
136+
goto out_rtnl;
137+
138+
dev->ethtool_ops->get_wol(dev, &wol);
139+
ret = ethnl_update_bitset32(&wol.wolopts, WOL_MODE_COUNT,
140+
tb[ETHTOOL_A_WOL_MODES], wol_mode_names,
141+
info->extack, &mod);
142+
if (ret < 0)
143+
goto out_ops;
144+
if (wol.wolopts & ~wol.supported) {
145+
NL_SET_ERR_MSG_ATTR(info->extack, tb[ETHTOOL_A_WOL_MODES],
146+
"cannot enable unsupported WoL mode");
147+
ret = -EINVAL;
148+
goto out_ops;
149+
}
150+
if (tb[ETHTOOL_A_WOL_SOPASS]) {
151+
if (!(wol.supported & WAKE_MAGICSECURE)) {
152+
NL_SET_ERR_MSG_ATTR(info->extack,
153+
tb[ETHTOOL_A_WOL_SOPASS],
154+
"magicsecure not supported, cannot set password");
155+
ret = -EINVAL;
156+
goto out_ops;
157+
}
158+
ethnl_update_binary(wol.sopass, sizeof(wol.sopass),
159+
tb[ETHTOOL_A_WOL_SOPASS], &mod);
160+
}
161+
162+
if (!mod)
163+
goto out_ops;
164+
ret = dev->ethtool_ops->set_wol(dev, &wol);
165+
if (ret)
166+
goto out_ops;
167+
dev->wol_enabled = !!wol.wolopts;
168+
169+
out_ops:
170+
ethnl_ops_complete(dev);
171+
out_rtnl:
172+
rtnl_unlock();
173+
dev_put(dev);
174+
return ret;
175+
}

0 commit comments

Comments
 (0)