lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 25 Mar 2019 18:08:55 +0100 (CET)
From:   Michal Kubecek <mkubecek@...e.cz>
To:     David Miller <davem@...emloft.net>, netdev@...r.kernel.org
Cc:     Jakub Kicinski <jakub.kicinski@...ronome.com>,
        Jiri Pirko <jiri@...nulli.us>, Andrew Lunn <andrew@...n.ch>,
        Florian Fainelli <f.fainelli@...il.com>,
        John Linville <linville@...driver.com>,
        Stephen Hemminger <stephen@...workplumber.org>,
        linux-kernel@...r.kernel.org
Subject: [PATCH net-next v5 20/22] ethtool: set WoL settings with SET_SETTINGS
 request

Allow enabling and disabling wake on LAN modes using SET_SETTINGS
request.

ETHA_SETTINGS_WOL nested attribute is used to set or modify enabled WoL
modes and SecureOn(tm) password.

Signed-off-by: Michal Kubecek <mkubecek@...e.cz>
---
 Documentation/networking/ethtool-netlink.txt | 12 +++-
 net/ethtool/settings.c                       | 60 +++++++++++++++++++-
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/ethtool-netlink.txt b/Documentation/networking/ethtool-netlink.txt
index bc7f28f0182f..3568d35ad7ec 100644
--- a/Documentation/networking/ethtool-netlink.txt
+++ b/Documentation/networking/ethtool-netlink.txt
@@ -335,6 +335,9 @@ to be passed with SET_SETTINGS request:
         ETHA_LINKMODES_OURS		(bitset)	advertised link modes
         ETHA_LINKMODES_SPEED		(u32)		link speed (Mb/s)
         ETHA_LINKMODES_DUPLEX		(u8)		duplex mode
+    ETHA_SETTINGS_WOL		(nested)	wake on LAN settings
+        ETHA_WOL_MODES			(bitfield32)	wake on LAN modes
+        ETHA_WOL_SOPASS			(binary)	SecureOn(tm) password
 
 ETHA_LINKMODES_OURS bit set allows setting advertised link modes. If
 autonegotiation is on (either set now or kept from before), advertised modes
@@ -345,6 +348,13 @@ autoselection is done on ethtool side with ioctl interface, netlink interface
 is supposed to allow requesting changes without knowing what exactly kernel
 supports.
 
+ETHA_WOL_MODES bitfield is interpreted in the usual way, i.e. bits set in the
+selector are set to 0 or 1 according to value. To allow the semantics of the
+ioctl interface where the whole bitmap is set rather than only modified,
+selectors may have also bits not supported by device set and an error is only
+issued if any of them is also set in the value (i.e. if userspace tries to
+enable mode not supported by device).
+
 
 Request translation
 -------------------
@@ -360,7 +370,7 @@ ETHTOOL_SSET			ETHNL_CMD_SET_SETTINGS
 ETHTOOL_GDRVINFO		ETHNL_CMD_GET_INFO
 ETHTOOL_GREGS			n/a
 ETHTOOL_GWOL			ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SWOL			n/a
+ETHTOOL_SWOL			ETHNL_CMD_SET_SETTINGS
 ETHTOOL_GMSGLVL			n/a
 ETHTOOL_SMSGLVL			n/a
 ETHTOOL_NWAY_RST		n/a
diff --git a/net/ethtool/settings.c b/net/ethtool/settings.c
index 56a045e5e916..ea5279dad826 100644
--- a/net/ethtool/settings.c
+++ b/net/ethtool/settings.c
@@ -108,6 +108,12 @@ static const struct link_mode_info link_mode_params[] = {
 	__DEFINE_LINK_MODE_PARAMS(200000, CR4, Full),
 };
 
+/* We want to allow ~0 as selector for backward compatibility (to just set
+ * given set of modes, whatever kernel supports) so that we allow all bits
+ * on validation and do our own sanity check later.
+ */
+static u32 all_bits = ~(u32)0;
+
 static const struct nla_policy get_settings_policy[ETHA_SETTINGS_MAX + 1] = {
 	[ETHA_SETTINGS_UNSPEC]		= { .type = NLA_REJECT },
 	[ETHA_SETTINGS_DEV]		= { .type = NLA_NESTED },
@@ -485,6 +491,14 @@ static const struct nla_policy set_linkmodes_policy[ETHA_LINKMODES_MAX + 1] = {
 	[ETHA_LINKMODES_DUPLEX]		= { .type = NLA_U8 },
 };
 
+static const struct nla_policy set_wol_policy[ETHA_LINKINFO_MAX + 1] = {
+	[ETHA_WOL_UNSPEC]		= { .type = NLA_REJECT },
+	[ETHA_WOL_MODES]		= { .type = NLA_BITFIELD32,
+					    .validation_data = &all_bits },
+	[ETHA_WOL_SOPASS]		= { .type = NLA_BINARY,
+					    .len = SOPASS_MAX },
+};
+
 static const struct nla_policy set_settings_policy[ETHA_SETTINGS_MAX + 1] = {
 	[ETHA_SETTINGS_UNSPEC]		= { .type = NLA_REJECT },
 	[ETHA_SETTINGS_DEV]		= { .type = NLA_NESTED },
@@ -493,7 +507,7 @@ static const struct nla_policy set_settings_policy[ETHA_SETTINGS_MAX + 1] = {
 	[ETHA_SETTINGS_LINK_INFO]	= { .type = NLA_NESTED },
 	[ETHA_SETTINGS_LINK_MODES]	= { .type = NLA_NESTED },
 	[ETHA_SETTINGS_LINK_STATE]	= { .type = NLA_REJECT },
-	[ETHA_SETTINGS_WOL]		= { .type = NLA_REJECT },
+	[ETHA_SETTINGS_WOL]		= { .type = NLA_NESTED },
 };
 
 static int ethnl_set_link_ksettings(struct genl_info *info,
@@ -641,6 +655,43 @@ static int ethnl_update_ksettings(struct genl_info *info, struct nlattr **tb,
 	return 0;
 }
 
+static int update_wol(struct genl_info *info, struct nlattr *nest,
+		      struct net_device *dev)
+{
+	struct nlattr *tb[ETHA_WOL_MAX + 1];
+	struct ethtool_wolinfo wolinfo = {};
+	int ret;
+
+	if (!nest)
+		return 0;
+	ret = nla_parse_nested_strict(tb, ETHA_WOL_MAX, nest, set_wol_policy,
+				      info->extack);
+	if (ret < 0)
+		return ret;
+
+	ret = ethnl_get_wol(info, dev, &wolinfo);
+	if (ret < 0) {
+		ETHNL_SET_ERRMSG(info, "failed to get wol settings");
+		return ret;
+	}
+
+	ret = 0;
+	if (ethnl_update_bitfield32(&wolinfo.wolopts, tb[ETHA_WOL_MODES]))
+		ret = 1;
+	if (ethnl_update_binary(wolinfo.sopass, SOPASS_MAX,
+				tb[ETHA_WOL_SOPASS]))
+		ret = 1;
+	if (ret) {
+		int ret2 = dev->ethtool_ops->set_wol(dev, &wolinfo);
+		if (ret2 < 0) {
+			ETHNL_SET_ERRMSG(info, "wol info update failed");
+			ret = ret2;
+		}
+	}
+
+	return ret;
+}
+
 int ethnl_set_settings(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *tb[ETHA_SETTINGS_MAX + 1];
@@ -668,6 +719,13 @@ int ethnl_set_settings(struct sk_buff *skb, struct genl_info *info)
 		if (ret < 0)
 			goto out_ops;
 	}
+	if (tb[ETHA_SETTINGS_WOL]) {
+		ret = update_wol(info, tb[ETHA_SETTINGS_WOL], dev);
+		if (ret < 0)
+			goto out_ops;
+		if (ret)
+			req_mask |= ETH_SETTINGS_IM_WOL;
+	}
 	ret = 0;
 
 out_ops:
-- 
2.21.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ