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:   Wed, 12 Jun 2019 18:05:24 +0200
From:   Andrew Lunn <andrew@...n.ch>
To:     netdev <netdev@...r.kernel.org>
Cc:     Florian Fainelli <f.fainelli@...il.com>,
        Heiner Kallweit <hkallweit1@...il.com>,
        Raju.Lakkaraju@...rochip.com, Andrew Lunn <andrew@...n.ch>
Subject: [PATCH RFC 03/13] net: ethtool: netlink: Add support for triggering a cable test

Add new ethtool netlink calls to trigger the starting of a PHY cable
test.

Signed-off-by: Andrew Lunn <andrew@...n.ch>
---
 drivers/net/phy/Kconfig              |  1 +
 include/uapi/linux/ethtool_netlink.h | 12 +++++
 net/ethtool/actions.c                | 77 ++++++++++++++++++++++++++++
 net/ethtool/netlink.c                |  6 +++
 net/ethtool/netlink.h                |  4 ++
 5 files changed, 100 insertions(+)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index d6299710d634..fc2be56fd2f8 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -208,6 +208,7 @@ menuconfig PHYLIB
 	tristate "PHY Device support and infrastructure"
 	depends on NETDEVICES
 	select MDIO_DEVICE
+	select ETHTOOL_NETLINK
 	help
 	  Ethernet controllers are usually attached to PHY
 	  devices.  This option provides infrastructure for
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index c6686ebb35b2..e9d0d6fac23b 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -27,6 +27,7 @@ enum {
 	ETHNL_CMD_ACT_RESET,
 	ETHNL_CMD_GET_RXFLOW,
 	ETHNL_CMD_SET_RXFLOW,
+	ETHNL_CMD_ACT_CABLE_TEST,
 
 	__ETHNL_CMD_CNT,
 	ETHNL_CMD_MAX = (__ETHNL_CMD_CNT - 1)
@@ -106,6 +107,7 @@ enum {
 	ETHTOOL_A_EVENT_NEWDEV,			/* nest - ETHTOOL_A_NEWDEV_* */
 	ETHTOOL_A_EVENT_DELDEV,			/* nest - ETHTOOL_A_DELDEV_* */
 	ETHTOOL_A_EVENT_RENAMEDEV,		/* nest - ETHTOOL_A_RENAMEDEV_* */
+	ETHTOOL_A_EVENT_CABLE_TEST,		/* nest - ETHTOOL_A_CABLE_TEST_* */
 
 	__ETHTOOL_A_EVENT_CNT,
 	ETHTOOL_A_EVENT_MAX = (__ETHTOOL_A_EVENT_CNT - 1)
@@ -504,6 +506,16 @@ enum {
 	ETHTOOL_A_RXHASHOPT_MAX = (__ETHTOOL_A_RXHASHOPT_CNT - 1)
 };
 
+/* ACT_CABLE_TEST */
+
+enum {
+	ETHTOOL_A_CABLE_TEST_UNSPEC,
+	ETHTOOL_A_CABLE_TEST_DEV,		/* nest - ETHTOOL_A_DEV_* */
+
+	__ETHTOOL_A_CABLE_TEST_CNT,
+	ETHTOOL_A_CABLE_TEST_MAX = (__ETHTOOL_A_CABLE_TEST_CNT - 1)
+};
+
 enum {
 	ETHTOOL_A_INDTBL_UNSPEC,
 	ETHTOOL_A_INDTBL_BLOCK32,		/* nest - ETH_ITBLK_* */
diff --git a/net/ethtool/actions.c b/net/ethtool/actions.c
index 1fa630cf303f..8a26ae1b2ada 100644
--- a/net/ethtool/actions.c
+++ b/net/ethtool/actions.c
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 
+#include <linux/phy.h>
 #include "netlink.h"
 #include "common.h"
 #include "bitset.h"
@@ -375,3 +376,79 @@ int ethnl_act_reset(struct sk_buff *skb, struct genl_info *info)
 		GENL_SET_ERR_MSG(info, "failed to send reply message");
 	return ret;
 }
+
+/* ACT_CABLE_TEST */
+
+static const struct
+nla_policy cable_test_policy[ETHTOOL_A_CABLE_TEST_MAX + 1] = {
+	[ETHTOOL_A_CABLE_TEST_UNSPEC]	= { .type = NLA_REJECT },
+	[ETHTOOL_A_CABLE_TEST_DEV]		= { .type = NLA_NESTED },
+};
+
+void ethnl_cable_test_notify(struct net_device *dev,
+			     struct netlink_ext_ack *extack, unsigned int cmd,
+			     u32 req_mask, const void *data)
+{
+	struct sk_buff *skb;
+	void *msg_payload;
+	int msg_len;
+	int ret;
+
+	msg_len = dev_ident_size();
+	skb = genlmsg_new(msg_len, GFP_KERNEL);
+	if (!skb)
+		return;
+
+	msg_payload = ethnl_bcastmsg_put(skb, ETHNL_CMD_ACT_CABLE_TEST);
+	if (!msg_payload)
+		goto err_skb;
+
+	ret = ethnl_fill_dev(skb, dev, ETHTOOL_A_CABLE_TEST_DEV);
+	if (ret < 0)
+		goto err_skb;
+
+	genlmsg_end(skb, msg_payload);
+	ethnl_multicast(skb, dev);
+	return;
+
+err_skb:
+	nlmsg_free(skb);
+}
+
+int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr *tb[ETHTOOL_A_CABLE_TEST_MAX + 1];
+	struct net_device *dev;
+	int ret;
+
+	ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb,
+			  ETHTOOL_A_CABLE_TEST_MAX, cable_test_policy,
+			  info->extack);
+	if (ret < 0)
+		return ret;
+
+	dev = ethnl_dev_get(info, tb[ETHTOOL_A_CABLE_TEST_DEV]);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	ret = -EOPNOTSUPP;
+	if (!dev->phydev)
+		goto out_dev;
+
+	rtnl_lock();
+	ret = ethnl_before_ops(dev);
+	if (ret < 0)
+		goto out_rtnl;
+
+	ret = phy_start_cable_test(dev->phydev, info->extack);
+	ethnl_after_ops(dev);
+
+	if (ret == 0)
+		ethtool_notify(dev, NULL, ETHNL_CMD_ACT_CABLE_TEST, 0, NULL);
+
+out_rtnl:
+	rtnl_unlock();
+out_dev:
+	dev_put(dev);
+	return ret;
+}
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index 540c92091fe9..894dc81536c9 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -589,6 +589,7 @@ static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
 	[ETHNL_CMD_ACT_PHYS_ID]		= ethnl_physid_notify,
 	[ETHNL_CMD_ACT_RESET]		= ethnl_reset_notify,
 	[ETHNL_CMD_SET_RXFLOW]		= ethnl_rxflow_notify,
+	[ETHNL_CMD_ACT_CABLE_TEST]	= ethnl_cable_test_notify,
 };
 
 void ethtool_notify(struct net_device *dev, struct netlink_ext_ack *extack,
@@ -747,6 +748,11 @@ static const struct genl_ops ethtool_genl_ops[] = {
 		.flags	= GENL_UNS_ADMIN_PERM,
 		.doit	= ethnl_set_rxflow,
 	},
+	{
+		.cmd	= ETHNL_CMD_ACT_CABLE_TEST,
+		.flags	= GENL_UNS_ADMIN_PERM,
+		.doit	= ethnl_act_cable_test,
+	},
 };
 
 static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index cb7dce82cc7e..4e7b40a8401d 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -269,6 +269,7 @@ int ethnl_set_rxflow(struct sk_buff *skb, struct genl_info *info);
 int ethnl_act_nway_rst(struct sk_buff *skb, struct genl_info *info);
 int ethnl_act_phys_id(struct sk_buff *skb, struct genl_info *info);
 int ethnl_act_reset(struct sk_buff *skb, struct genl_info *info);
+int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
 
 /* notify handlers */
 
@@ -281,5 +282,8 @@ void ethnl_reset_notify(struct net_device *dev, struct netlink_ext_ack *extack,
 			unsigned int cmd, u32 req_mask, const void *data);
 void ethnl_rxflow_notify(struct net_device *dev, struct netlink_ext_ack *extack,
 			 unsigned int cmd, u32 req_mask, const void *data);
+void ethnl_cable_test_notify(struct net_device *dev,
+			     struct netlink_ext_ack *extack,
+			     unsigned int cmd, u32 req_mask, const void *data);
 
 #endif /* _NET_ETHTOOL_NETLINK_H */
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ