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: <20190425135956.3970-15-jiri@resnulli.us>
Date:   Thu, 25 Apr 2019 15:59:54 +0200
From:   Jiri Pirko <jiri@...nulli.us>
To:     netdev@...r.kernel.org
Cc:     davem@...emloft.net, mlxsw@...lanox.com,
        jakub.kicinski@...ronome.com, dsahern@...il.com
Subject: [patch net-next v4 14/16] netdevsim: extend device attrs to support port addition and deletion

From: Jiri Pirko <jiri@...lanox.com>

In order to test flows in core, it is beneficial to maintain previously
supported possibility to add and delete ports during netdevsim lifetime.
Do it by extending device sysfs attrs by "new_port" and "del_port".

Signed-off-by: Jiri Pirko <jiri@...lanox.com>
---
v3->v4:
- fix wrapping of function declararions according to Jakub's rules.
v1->v2:
- new patch
---
 drivers/net/netdevsim/bus.c       | 36 ++++++++++++++++++++
 drivers/net/netdevsim/dev.c       | 55 ++++++++++++++++++++++++++++---
 drivers/net/netdevsim/netdevsim.h |  5 +++
 3 files changed, 92 insertions(+), 4 deletions(-)

diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index 1ee14e1bb12d..549c399f29da 100644
--- a/drivers/net/netdevsim/bus.c
+++ b/drivers/net/netdevsim/bus.c
@@ -91,8 +91,44 @@ static struct device_attribute nsim_bus_dev_numvfs_attr =
 	__ATTR(sriov_numvfs, 0664, nsim_bus_dev_numvfs_show,
 	       nsim_bus_dev_numvfs_store);
 
+static ssize_t
+new_port_store(struct device *dev, struct device_attribute *attr,
+	       const char *buf, size_t count)
+{
+	struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
+	unsigned int port_index;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &port_index);
+	if (ret)
+		return ret;
+	ret = nsim_dev_port_add(nsim_bus_dev, port_index);
+	return ret ? ret : count;
+}
+
+static struct device_attribute nsim_bus_dev_new_port_attr = __ATTR_WO(new_port);
+
+static ssize_t
+del_port_store(struct device *dev, struct device_attribute *attr,
+	       const char *buf, size_t count)
+{
+	struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
+	unsigned int port_index;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &port_index);
+	if (ret)
+		return ret;
+	ret = nsim_dev_port_del(nsim_bus_dev, port_index);
+	return ret ? ret : count;
+}
+
+static struct device_attribute nsim_bus_dev_del_port_attr = __ATTR_WO(del_port);
+
 static struct attribute *nsim_bus_dev_attrs[] = {
 	&nsim_bus_dev_numvfs_attr.attr,
+	&nsim_bus_dev_new_port_attr.attr,
+	&nsim_bus_dev_del_port_attr.attr,
 	NULL,
 };
 
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 6ee9d43ae252..2fa1b2061370 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -18,6 +18,7 @@
 #include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/random.h>
 #include <linux/rtnetlink.h>
 #include <net/devlink.h>
@@ -238,6 +239,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
 	nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
 	get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
 	INIT_LIST_HEAD(&nsim_dev->port_list);
+	mutex_init(&nsim_dev->port_list_lock);
 
 	nsim_dev->fib_data = nsim_fib_create();
 	if (IS_ERR(nsim_dev->fib_data)) {
@@ -285,10 +287,12 @@ void nsim_dev_destroy(struct nsim_dev *nsim_dev)
 	devlink_unregister(devlink);
 	devlink_resources_unregister(devlink, NULL);
 	nsim_fib_destroy(nsim_dev->fib_data);
+	mutex_destroy(&nsim_dev->port_list_lock);
 	devlink_free(devlink);
 }
 
-static int nsim_dev_port_add(struct nsim_dev *nsim_dev, unsigned int port_index)
+static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
+			       unsigned int port_index)
 {
 	struct nsim_dev_port *nsim_dev_port;
 	struct devlink_port *devlink_port;
@@ -324,7 +328,7 @@ static int nsim_dev_port_add(struct nsim_dev *nsim_dev, unsigned int port_index)
 	return err;
 }
 
-static void nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
+static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
 {
 	struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
 
@@ -340,7 +344,7 @@ static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
 
 	list_for_each_entry_safe(nsim_dev_port, tmp,
 				 &nsim_dev->port_list, list)
-		nsim_dev_port_del(nsim_dev_port);
+		__nsim_dev_port_del(nsim_dev_port);
 }
 
 int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
@@ -355,7 +359,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
 	dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
 
 	for (i = 0; i < nsim_bus_dev->port_count; i++) {
-		err = nsim_dev_port_add(nsim_dev, i);
+		err = __nsim_dev_port_add(nsim_dev, i);
 		if (err)
 			goto err_port_del_all;
 	}
@@ -375,6 +379,49 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
 	nsim_dev_destroy(nsim_dev);
 }
 
+static struct nsim_dev_port *
+__nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index)
+{
+	struct nsim_dev_port *nsim_dev_port;
+
+	list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list)
+		if (nsim_dev_port->port_index == port_index)
+			return nsim_dev_port;
+	return NULL;
+}
+
+int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev,
+		      unsigned int port_index)
+{
+	struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
+	int err;
+
+	mutex_lock(&nsim_dev->port_list_lock);
+	if (__nsim_dev_port_lookup(nsim_dev, port_index))
+		err = -EEXIST;
+	else
+		err = __nsim_dev_port_add(nsim_dev, port_index);
+	mutex_unlock(&nsim_dev->port_list_lock);
+	return err;
+}
+
+int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
+		      unsigned int port_index)
+{
+	struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
+	struct nsim_dev_port *nsim_dev_port;
+	int err = 0;
+
+	mutex_lock(&nsim_dev->port_list_lock);
+	nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, port_index);
+	if (!nsim_dev_port)
+		err = -ENOENT;
+	else
+		__nsim_dev_port_del(nsim_dev_port);
+	mutex_unlock(&nsim_dev->port_list_lock);
+	return err;
+}
+
 int nsim_dev_init(void)
 {
 	nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 0e6ca85e5487..6b60589cab91 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -152,12 +152,17 @@ struct nsim_dev {
 	struct list_head bpf_bound_maps;
 	struct netdev_phys_item_id switch_id;
 	struct list_head port_list;
+	struct mutex port_list_lock; /* protects port list */
 };
 
 int nsim_dev_init(void);
 void nsim_dev_exit(void);
 int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev);
 void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev);
+int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev,
+		      unsigned int port_index);
+int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
+		      unsigned int port_index);
 
 struct nsim_fib_data *nsim_fib_create(void);
 void nsim_fib_destroy(struct nsim_fib_data *fib_data);
-- 
2.17.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ