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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190130221225.GE349@nanopsycho.orion>
Date:   Wed, 30 Jan 2019 23:12:25 +0100
From:   Jiri Pirko <jiri@...nulli.us>
To:     Jakub Kicinski <jakub.kicinski@...ronome.com>
Cc:     davem@...emloft.net, netdev@...r.kernel.org,
        oss-drivers@...ronome.com, andrew@...n.ch, f.fainelli@...il.com,
        mkubecek@...e.cz, eugenem@...com, jonathan.lemon@...il.com
Subject: Re: [PATCH net-next v2 7/7] ethtool: add compat for devlink info

Wed, Jan 30, 2019 at 08:05:13PM CET, jakub.kicinski@...ronome.com wrote:
>If driver did not fill the fw_version field, try to call into
>the new devlink get_info op and collect the versions that way.
>We assume ethtool was always reporting running versions.
>
>Signed-off-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
>---
> include/net/devlink.h |  7 ++++++
> net/core/devlink.c    | 52 ++++++++++++++++++++++++++++++++++++++++++-
> net/core/ethtool.c    |  7 ++++++
> 3 files changed, 65 insertions(+), 1 deletion(-)
>
>diff --git a/include/net/devlink.h b/include/net/devlink.h
>index c678ed0cb099..b4750e93303a 100644
>--- a/include/net/devlink.h
>+++ b/include/net/devlink.h
>@@ -640,6 +640,8 @@ int devlink_info_report_version(struct devlink_info_req *req,
> 				enum devlink_version_type type,
> 				const char *version_name,
> 				const char *version_value);
>+void devlink_compat_running_versions(struct net_device *dev,
>+				     char *buf, size_t len);
> 
> #else
> 
>@@ -957,6 +959,11 @@ devlink_info_report_version(struct devlink_info_req *req,
> {
> 	return 0;
> }
>+
>+static inline void
>+devlink_compat_running_versions(struct net_device *dev, char *buf, size_t len)
>+{
>+}
> #endif
> 
> #endif /* _NET_DEVLINK_H_ */
>diff --git a/net/core/devlink.c b/net/core/devlink.c
>index e2027d3a5e40..5313e5918ee2 100644
>--- a/net/core/devlink.c
>+++ b/net/core/devlink.c
>@@ -3715,12 +3715,18 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
> }
> 
> struct devlink_info_req {
>+	bool compat;
> 	struct sk_buff *msg;
>+	/* For compat call */
>+	char *buf;

union?


>+	size_t len;
> };
> 
> int devlink_info_report_driver_name(struct devlink_info_req *req,
> 				    const char *name)
> {
>+	if (req->compat)
>+		return 0;
> 	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRV_NAME, name);
> }
> EXPORT_SYMBOL_GPL(devlink_info_report_driver_name);
>@@ -3728,6 +3734,8 @@ EXPORT_SYMBOL_GPL(devlink_info_report_driver_name);
> int devlink_info_report_serial_number(struct devlink_info_req *req,
> 				      const char *sn)
> {
>+	if (req->compat)
>+		return 0;
> 	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
> }
> EXPORT_SYMBOL_GPL(devlink_info_report_serial_number);
>@@ -3743,7 +3751,15 @@ int devlink_info_report_version(struct devlink_info_req *req,
> 		[DEVLINK_VERSION_RUNNING] = DEVLINK_ATTR_INFO_VERSION_RUNNING,
> 	};
> 	struct nlattr *nest;
>-	int err;
>+	int len, err;
>+
>+	if (req->compat) {
>+		if (type == DEVLINK_VERSION_RUNNING) {
>+			len = strlcpy(req->buf, version_value, req->len);

If you have multiple running versions, shouldn't you concat them into a
single string for compat?

>+			req->len = max_t(size_t, 0, req->len - len);
>+		}
>+		return 0;
>+	}
> 
> 	if (type >= ARRAY_SIZE(type2attr) || !type2attr[type])
> 		return -EINVAL;
>@@ -3789,6 +3805,7 @@ devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
> 	if (devlink_nl_put_handle(msg, devlink))
> 		goto err_cancel_msg;
> 
>+	memset(&req, 0, sizeof(req));
> 	req.msg = msg;
> 	err = devlink->ops->info_get(devlink, &req, extack);
> 	if (err)
>@@ -5263,6 +5280,39 @@ int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
> }
> EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
> 
>+void devlink_compat_running_versions(struct net_device *dev,

Why "versionS?"


>+				     char *buf, size_t len)
>+{
>+	struct devlink_port *devlink_port;
>+	struct devlink_info_req req;
>+	struct devlink *devlink;
>+	bool found = false;
>+
>+	mutex_lock(&devlink_mutex);
>+	list_for_each_entry(devlink, &devlink_list, list) {
>+		mutex_lock(&devlink->lock);
>+		list_for_each_entry(devlink_port, &devlink->port_list, list) {
>+			if (devlink_port->type == DEVLINK_PORT_TYPE_ETH ||
>+			    devlink_port->type_dev == dev) {
>+				mutex_unlock(&devlink->lock);
>+				found = true;
>+				goto out;
>+			}
>+		}
>+		mutex_unlock(&devlink->lock);
>+	}
>+out:
>+	if (found && devlink->ops->info_get) {
>+		memset(&req, 0, sizeof(req));
>+		req.compat = true;
>+		req.buf = buf;
>+		req.len = len;
>+
>+		devlink->ops->info_get(devlink, &req, NULL);

I don't really like this compat bool and check in "put" functions.
I would rather like to run info_get() in case of both compat and
non-compat in the same way. Then for compat just pickup the info
which is needed and put to buf.
I don't see problem in using netlink skb for that direcly.


>+	}
>+	mutex_unlock(&devlink_mutex);
>+}
>+
> static int __init devlink_module_init(void)
> {
> 	return genl_register_family(&devlink_nl_family);
>diff --git a/net/core/ethtool.c b/net/core/ethtool.c
>index 158264f7cfaf..176b17d11f08 100644
>--- a/net/core/ethtool.c
>+++ b/net/core/ethtool.c
>@@ -27,6 +27,7 @@
> #include <linux/rtnetlink.h>
> #include <linux/sched/signal.h>
> #include <linux/net.h>
>+#include <net/devlink.h>
> #include <net/xdp_sock.h>
> 
> /*
>@@ -803,6 +804,12 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
> 	if (ops->get_eeprom_len)
> 		info.eedump_len = ops->get_eeprom_len(dev);
> 
>+	rtnl_unlock();
>+	if (!info.fw_version[0])
>+		devlink_compat_running_versions(dev, info.fw_version,
>+						ARRAY_SIZE(info.fw_version));

ARRAY_SIZE looks odd here. "sizeof()" would be better I think.


>+	rtnl_lock();
>+
> 	if (copy_to_user(useraddr, &info, sizeof(info)))
> 		return -EFAULT;
> 	return 0;
>-- 
>2.19.2
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ