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]
Message-Id: <5d1c101f83f74008b68c5ae53ab2d9e2cc87db75.1550513384.git.mkubecek@suse.cz>
Date:   Mon, 18 Feb 2019 19:22:55 +0100 (CET)
From:   Michal Kubecek <mkubecek@...e.cz>
To:     netdev@...r.kernel.org
Cc:     David Miller <davem@...emloft.net>, Andrew Lunn <andrew@...n.ch>,
        Jakub Kicinski <jakub.kicinski@...ronome.com>,
        Jiri Pirko <jiri@...nulli.us>, linux-kernel@...r.kernel.org
Subject: [RFC PATCH net-next v3 18/21] ethtool: provide link state in
 GET_SETTINGS request

Add information about device link state (as provided by ETHTOOL_GLINK ioctl
command) into the GET_SETTINGS reply when ETH_SETTINGS_IM_LINK flag is set
in the request.

Note: we cannot use NLA_FLAG for link state as we need three states: off,
on and unknown.

Signed-off-by: Michal Kubecek <mkubecek@...e.cz>
---
 Documentation/networking/ethtool-netlink.txt |  4 +++-
 include/uapi/linux/ethtool_netlink.h         |  4 +++-
 net/ethtool/common.c                         |  8 ++++++++
 net/ethtool/common.h                         |  1 +
 net/ethtool/ioctl.c                          |  8 ++++----
 net/ethtool/settings.c                       | 11 +++++++++++
 6 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/Documentation/networking/ethtool-netlink.txt b/Documentation/networking/ethtool-netlink.txt
index 057eb3213cfe..538dad93009f 100644
--- a/Documentation/networking/ethtool-netlink.txt
+++ b/Documentation/networking/ethtool-netlink.txt
@@ -285,6 +285,7 @@ Info mask bits meaning:
     ETH_SETTINGS_IM_LINKMODES		link modes from link_ksettings
     ETH_SETTINGS_IM_WOLINFO		struct ethtool_wolinfo
     ETH_SETTINGS_IM_MSGLEVEL		msglevel
+    ETH_SETTINGS_IM_LINK		link state
 
 Response contents:
 
@@ -304,6 +305,7 @@ Response contents:
         ETHA_WOL_MODES			(bitfield32)	wake on LAN modes
         ETHA_WOL_SOPASS			(binary)	SecureOn(tm) password
     ETHA_SETTINGS_MSGLEVEL	(bitfield32)	debug level
+    ETHA_SETTINGS_LINK		(u8)		link state
 
 Most of the attributes and their values have the same meaning as matching
 members of the corresponding ioctl structures. For ETHA_SETTINGS_LINK_MODES,
@@ -343,7 +345,7 @@ ETHTOOL_SWOL			n/a
 ETHTOOL_GMSGLVL			ETHNL_CMD_GET_SETTINGS
 ETHTOOL_SMSGLVL			n/a
 ETHTOOL_NWAY_RST		n/a
-ETHTOOL_GLINK			n/a
+ETHTOOL_GLINK			ETHNL_CMD_GET_SETTINGS
 ETHTOOL_GEEPROM			n/a
 ETHTOOL_SEEPROM			n/a
 ETHTOOL_GCOALESCE		n/a
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 360e20a73f19..06e78d94cacc 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -203,6 +203,7 @@ enum {
 	ETHA_SETTINGS_PEER_MODES,		/* bitset */
 	ETHA_SETTINGS_WOL,			/* nested */
 	ETHA_SETTINGS_MSGLEVEL,			/* bitfield32 */
+	ETHA_SETTINGS_LINK,			/* u8 */
 
 	__ETHA_SETTINGS_CNT,
 	ETHA_SETTINGS_MAX = (__ETHA_SETTINGS_CNT - 1)
@@ -212,8 +213,9 @@ enum {
 #define ETH_SETTINGS_IM_LINKMODES		0x02
 #define ETH_SETTINGS_IM_WOLINFO			0x04
 #define ETH_SETTINGS_IM_MSGLEVEL		0x08
+#define ETH_SETTINGS_IM_LINK			0x10
 
-#define ETH_SETTINGS_IM_ALL			0x0f
+#define ETH_SETTINGS_IM_ALL			0x1f
 
 enum {
 	ETHA_LINKINFO_UNSPEC,
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 9fba57f554dd..a188f07bcb4c 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -217,3 +217,11 @@ int __ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 
 	return 0;
 }
+
+int __ethtool_get_link(struct net_device *dev)
+{
+	if (!dev->ethtool_ops->get_link)
+		return -EOPNOTSUPP;
+
+	return netif_running(dev) && dev->ethtool_ops->get_link(dev);
+}
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
index ed3f1ca54660..e5b5c5c2a4b9 100644
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -18,6 +18,7 @@ phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
 int __ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 int __ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+int __ethtool_get_link(struct net_device *dev);
 
 bool convert_legacy_settings_to_link_ksettings(
 	struct ethtool_link_ksettings *link_ksettings,
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 945eaf551a4c..63662a3fa2ae 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1306,12 +1306,12 @@ static int ethtool_nway_reset(struct net_device *dev)
 static int ethtool_get_link(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_value edata = { .cmd = ETHTOOL_GLINK };
+	int link = __ethtool_get_link(dev);
 
-	if (!dev->ethtool_ops->get_link)
-		return -EOPNOTSUPP;
-
-	edata.data = netif_running(dev) && dev->ethtool_ops->get_link(dev);
+	if (link < 0)
+		return link;
 
+	edata.data = link;
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
 	return 0;
diff --git a/net/ethtool/settings.c b/net/ethtool/settings.c
index 58cd2d19a75d..099300901c12 100644
--- a/net/ethtool/settings.c
+++ b/net/ethtool/settings.c
@@ -14,6 +14,7 @@ struct settings_data {
 	struct ethtool_link_settings	*lsettings;
 	struct ethtool_wolinfo		wolinfo;
 	u32				msglevel;
+	int				link;
 	bool				lpm_empty;
 };
 
@@ -27,6 +28,7 @@ static const struct nla_policy get_settings_policy[ETHA_SETTINGS_MAX + 1] = {
 	[ETHA_SETTINGS_PEER_MODES]	= { .type = NLA_REJECT },
 	[ETHA_SETTINGS_WOL]		= { .type = NLA_REJECT },
 	[ETHA_SETTINGS_MSGLEVEL]	= { .type = NLA_REJECT },
+	[ETHA_SETTINGS_LINK]		= { .type = NLA_REJECT },
 };
 
 static int parse_settings(struct common_req_info *req_info,
@@ -99,6 +101,7 @@ static int prepare_settings(struct common_req_info *req_info,
 
 	data->lsettings = &data->ksettings.base;
 	data->lpm_empty = true;
+	data->link = -EOPNOTSUPP;
 
 	ret = ethnl_before_ops(dev);
 	if (ret < 0)
@@ -131,6 +134,8 @@ static int prepare_settings(struct common_req_info *req_info,
 		else
 			req_mask &= ~ETH_SETTINGS_IM_MSGLEVEL;
 	}
+	if (req_mask & ETH_SETTINGS_IM_LINK)
+		data->link = __ethtool_get_link(dev);
 	ethnl_after_ops(dev);
 
 	data->repdata_base.info_mask = req_mask;
@@ -209,6 +214,8 @@ static int settings_size(const struct common_req_info *req_info)
 		len += wol_size();
 	if (info_mask & ETH_SETTINGS_IM_MSGLEVEL)
 		len += nla_total_size(sizeof(struct nla_bitfield32));
+	if (info_mask & ETH_SETTINGS_IM_LINK)
+		len += nla_total_size(sizeof(u32));
 
 	return len;
 }
@@ -324,6 +331,10 @@ static int fill_settings(struct sk_buff *skb,
 				       data->msglevel, NETIF_MSG_ALL))
 			return -EMSGSIZE;
 	}
+	if (info_mask & ETH_SETTINGS_IM_LINK && data->link >= 0) {
+		if (nla_put_u8(skb, ETHA_SETTINGS_LINK, data->link))
+			return -EMSGSIZE;
+	}
 
 	return 0;
 }
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ