summaryrefslogtreecommitdiff
path: root/drivers/net/netdevsim
diff options
context:
space:
mode:
authorJiri Pirko <jiri@mellanox.com>2019-04-25 16:59:55 +0300
committerDavid S. Miller <davem@davemloft.net>2019-04-26 08:52:03 +0300
commite05b2d141fef22cfac1928cf0eb6890e5dae4216 (patch)
tree055d8c4330e6e9002a2bf4e9829febe8df84d59f /drivers/net/netdevsim
parent794b2c05ca1c4ded4a023d11833e3855a0ed6ea8 (diff)
downloadlinux-e05b2d141fef22cfac1928cf0eb6890e5dae4216.tar.xz
netdevsim: move netdev creation/destruction to dev probe
Remove the existing way to create netdevsim over rtnetlink and move the netdev creation/destruction to dev probe, so for every probed port, a netdevsim-netdev instance is created. Adjust selftests to work with new interface. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netdevsim')
-rw-r--r--drivers/net/netdevsim/bpf.c13
-rw-r--r--drivers/net/netdevsim/bus.c25
-rw-r--r--drivers/net/netdevsim/dev.c13
-rw-r--r--drivers/net/netdevsim/ipsec.c3
-rw-r--r--drivers/net/netdevsim/netdev.c138
-rw-r--r--drivers/net/netdevsim/netdevsim.h11
6 files changed, 85 insertions, 118 deletions
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index 89980b223adc..2b74425822ab 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -612,6 +612,7 @@ void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev)
int nsim_bpf_init(struct netdevsim *ns)
{
+ struct dentry *ddir = ns->nsim_dev_port->ddir;
int err;
err = bpf_offload_dev_netdev_register(ns->nsim_dev->bpf_dev,
@@ -619,23 +620,23 @@ int nsim_bpf_init(struct netdevsim *ns)
if (err)
return err;
- debugfs_create_u32("bpf_offloaded_id", 0400, ns->ddir,
+ debugfs_create_u32("bpf_offloaded_id", 0400, ddir,
&ns->bpf_offloaded_id);
ns->bpf_tc_accept = true;
- debugfs_create_bool("bpf_tc_accept", 0600, ns->ddir,
+ debugfs_create_bool("bpf_tc_accept", 0600, ddir,
&ns->bpf_tc_accept);
- debugfs_create_bool("bpf_tc_non_bound_accept", 0600, ns->ddir,
+ debugfs_create_bool("bpf_tc_non_bound_accept", 0600, ddir,
&ns->bpf_tc_non_bound_accept);
ns->bpf_xdpdrv_accept = true;
- debugfs_create_bool("bpf_xdpdrv_accept", 0600, ns->ddir,
+ debugfs_create_bool("bpf_xdpdrv_accept", 0600, ddir,
&ns->bpf_xdpdrv_accept);
ns->bpf_xdpoffload_accept = true;
- debugfs_create_bool("bpf_xdpoffload_accept", 0600, ns->ddir,
+ debugfs_create_bool("bpf_xdpoffload_accept", 0600, ddir,
&ns->bpf_xdpoffload_accept);
ns->bpf_map_accept = true;
- debugfs_create_bool("bpf_map_accept", 0600, ns->ddir,
+ debugfs_create_bool("bpf_map_accept", 0600, ddir,
&ns->bpf_map_accept);
return 0;
diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index 549c399f29da..ae482347b67b 100644
--- a/drivers/net/netdevsim/bus.c
+++ b/drivers/net/netdevsim/bus.c
@@ -153,6 +153,9 @@ static struct device_type nsim_bus_dev_type = {
.release = nsim_bus_dev_release,
};
+static struct nsim_bus_dev *
+nsim_bus_dev_new(unsigned int id, unsigned int port_count);
+
static ssize_t
new_device_store(struct bus_type *bus, const char *buf, size_t count)
{
@@ -188,6 +191,8 @@ new_device_store(struct bus_type *bus, const char *buf, size_t count)
}
static BUS_ATTR_WO(new_device);
+static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
+
static ssize_t
del_device_store(struct bus_type *bus, const char *buf, size_t count)
{
@@ -261,7 +266,8 @@ static struct bus_type nsim_bus = {
.num_vf = nsim_num_vf,
};
-struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count)
+static struct nsim_bus_dev *
+nsim_bus_dev_new(unsigned int id, unsigned int port_count)
{
struct nsim_bus_dev *nsim_bus_dev;
int err;
@@ -270,8 +276,7 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count)
if (!nsim_bus_dev)
return ERR_PTR(-ENOMEM);
- err = ida_alloc_range(&nsim_bus_dev_ids,
- id == ~0 ? 0 : id, id, GFP_KERNEL);
+ err = ida_alloc_range(&nsim_bus_dev_ids, id, id, GFP_KERNEL);
if (err < 0)
goto err_nsim_bus_dev_free;
nsim_bus_dev->dev.id = err;
@@ -291,19 +296,7 @@ err_nsim_bus_dev_free:
return ERR_PTR(err);
}
-struct nsim_bus_dev *nsim_bus_dev_new_with_ns(struct netdevsim *ns)
-{
- struct nsim_bus_dev *nsim_bus_dev;
-
- dev_hold(ns->netdev);
- rtnl_unlock();
- nsim_bus_dev = nsim_bus_dev_new(~0, 0);
- rtnl_lock();
- dev_put(ns->netdev);
- return nsim_bus_dev;
-}
-
-void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
+static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
{
device_unregister(&nsim_bus_dev->dev);
ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 2fa1b2061370..b509b941d5ca 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -278,7 +278,7 @@ err_devlink_free:
return ERR_PTR(err);
}
-void nsim_dev_destroy(struct nsim_dev *nsim_dev)
+static void nsim_dev_destroy(struct nsim_dev *nsim_dev)
{
struct devlink *devlink = priv_to_devlink(nsim_dev);
@@ -317,10 +317,19 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
if (err)
goto err_dl_port_unregister;
+ nsim_dev_port->ns = nsim_create(nsim_dev, nsim_dev_port);
+ if (IS_ERR(nsim_dev_port->ns)) {
+ err = PTR_ERR(nsim_dev_port->ns);
+ goto err_port_debugfs_exit;
+ }
+
+ devlink_port_type_eth_set(devlink_port, nsim_dev_port->ns->netdev);
list_add(&nsim_dev_port->list, &nsim_dev->port_list);
return 0;
+err_port_debugfs_exit:
+ nsim_dev_port_debugfs_exit(nsim_dev_port);
err_dl_port_unregister:
devlink_port_unregister(devlink_port);
err_port_free:
@@ -333,6 +342,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
list_del(&nsim_dev_port->list);
+ devlink_port_type_clear(devlink_port);
+ nsim_destroy(nsim_dev_port->ns);
nsim_dev_port_debugfs_exit(nsim_dev_port);
devlink_port_unregister(devlink_port);
kfree(nsim_dev_port);
diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
index 76e11d889bb6..e27fc1a4516d 100644
--- a/drivers/net/netdevsim/ipsec.c
+++ b/drivers/net/netdevsim/ipsec.c
@@ -283,7 +283,8 @@ void nsim_ipsec_init(struct netdevsim *ns)
ns->netdev->features |= NSIM_ESP_FEATURES;
ns->netdev->hw_enc_features |= NSIM_ESP_FEATURES;
- ns->ipsec.pfile = debugfs_create_file("ipsec", 0400, ns->ddir, ns,
+ ns->ipsec.pfile = debugfs_create_file("ipsec", 0400,
+ ns->nsim_dev_port->ddir, ns,
&ipsec_dbg_fops);
}
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 99169fe521f2..040c390d0c01 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -25,59 +25,6 @@
#include "netdevsim.h"
-static int nsim_get_port_parent_id(struct net_device *dev,
- struct netdev_phys_item_id *ppid)
-{
- struct netdevsim *ns = netdev_priv(dev);
-
- memcpy(ppid, &ns->nsim_dev->switch_id, sizeof(*ppid));
- return 0;
-}
-
-static int nsim_init(struct net_device *dev)
-{
- struct netdevsim *ns = netdev_priv(dev);
- char dev_link_name[32];
- int err;
-
- ns->ddir = debugfs_create_dir("0", ns->nsim_dev->ports_ddir);
- if (IS_ERR_OR_NULL(ns->ddir))
- return -ENOMEM;
-
- sprintf(dev_link_name, "../../../" DRV_NAME "%u",
- ns->nsim_dev->nsim_bus_dev->dev.id);
- debugfs_create_symlink("dev", ns->ddir, dev_link_name);
-
- err = nsim_bpf_init(ns);
- if (err)
- goto err_debugfs_destroy;
-
- nsim_ipsec_init(ns);
-
- return 0;
-
-err_debugfs_destroy:
- debugfs_remove_recursive(ns->ddir);
- return err;
-}
-
-static void nsim_uninit(struct net_device *dev)
-{
- struct netdevsim *ns = netdev_priv(dev);
-
- nsim_ipsec_teardown(ns);
- debugfs_remove_recursive(ns->ddir);
- nsim_bpf_uninit(ns);
-}
-
-static void nsim_free(struct net_device *dev)
-{
- struct netdevsim *ns = netdev_priv(dev);
-
- nsim_bus_dev_del(ns->nsim_bus_dev);
- /* netdev and vf state will be freed out of device_release() */
-}
-
static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct netdevsim *ns = netdev_priv(dev);
@@ -299,8 +246,6 @@ nsim_set_features(struct net_device *dev, netdev_features_t features)
}
static const struct net_device_ops nsim_netdev_ops = {
- .ndo_init = nsim_init,
- .ndo_uninit = nsim_uninit,
.ndo_start_xmit = nsim_start_xmit,
.ndo_set_rx_mode = nsim_set_rx_mode,
.ndo_set_mac_address = eth_mac_addr,
@@ -318,7 +263,6 @@ static const struct net_device_ops nsim_netdev_ops = {
.ndo_setup_tc = nsim_setup_tc,
.ndo_set_features = nsim_set_features,
.ndo_bpf = nsim_bpf,
- .ndo_get_port_parent_id = nsim_get_port_parent_id,
};
static void nsim_setup(struct net_device *dev)
@@ -326,10 +270,6 @@ static void nsim_setup(struct net_device *dev)
ether_setup(dev);
eth_hw_addr_random(dev);
- dev->netdev_ops = &nsim_netdev_ops;
- dev->needs_free_netdev = true;
- dev->priv_destructor = nsim_free;
-
dev->tx_queue_len = 0;
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
@@ -344,50 +284,70 @@ static void nsim_setup(struct net_device *dev)
dev->max_mtu = ETH_MAX_MTU;
}
-static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
-{
- if (tb[IFLA_ADDRESS]) {
- if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
- return -EINVAL;
- if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
- return -EADDRNOTAVAIL;
- }
- return 0;
-}
-
-static int nsim_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+struct netdevsim *
+nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
{
- struct netdevsim *ns = netdev_priv(dev);
+ struct net_device *dev;
+ struct netdevsim *ns;
int err;
- ns->netdev = dev;
- ns->nsim_bus_dev = nsim_bus_dev_new_with_ns(ns);
- if (IS_ERR(ns->nsim_bus_dev))
- return PTR_ERR(ns->nsim_bus_dev);
+ dev = alloc_netdev(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+ ns = netdev_priv(dev);
+ ns->netdev = dev;
+ ns->nsim_dev = nsim_dev;
+ ns->nsim_dev_port = nsim_dev_port;
+ ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
+ dev->netdev_ops = &nsim_netdev_ops;
- ns->nsim_dev = dev_get_drvdata(&ns->nsim_bus_dev->dev);
+ rtnl_lock();
+ err = nsim_bpf_init(ns);
+ if (err)
+ goto err_free_netdev;
+
+ nsim_ipsec_init(ns);
err = register_netdevice(dev);
if (err)
- goto err_dev_del;
- return 0;
+ goto err_ipsec_teardown;
+ rtnl_unlock();
-err_dev_del:
- nsim_bus_dev_del(ns->nsim_bus_dev);
- return err;
+ return ns;
+
+err_ipsec_teardown:
+ nsim_ipsec_teardown(ns);
+ nsim_bpf_uninit(ns);
+ rtnl_unlock();
+err_free_netdev:
+ free_netdev(dev);
+ return ERR_PTR(err);
+}
+
+void nsim_destroy(struct netdevsim *ns)
+{
+ struct net_device *dev = ns->netdev;
+
+ rtnl_lock();
+ unregister_netdevice(dev);
+ nsim_ipsec_teardown(ns);
+ nsim_bpf_uninit(ns);
+ rtnl_unlock();
+ free_netdev(dev);
+}
+
+static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+{
+ NL_SET_ERR_MSG_MOD(extack, "Please use: echo \"[ID] [PORT_COUNT]\" > /sys/bus/netdevsim/new_device");
+ return -EOPNOTSUPP;
}
static struct rtnl_link_ops nsim_link_ops __read_mostly = {
.kind = DRV_NAME,
- .priv_size = sizeof(struct netdevsim),
- .setup = nsim_setup,
.validate = nsim_validate,
- .newlink = nsim_newlink,
};
static int __init nsim_module_init(void)
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 6b60589cab91..3f398797c2bc 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -51,6 +51,7 @@ struct nsim_ipsec {
struct netdevsim {
struct net_device *netdev;
struct nsim_dev *nsim_dev;
+ struct nsim_dev_port *nsim_dev_port;
u64 tx_packets;
u64 tx_bytes;
@@ -58,8 +59,6 @@ struct netdevsim {
struct nsim_bus_dev *nsim_bus_dev;
- struct dentry *ddir;
-
struct bpf_prog *bpf_offloaded;
u32 bpf_offloaded_id;
@@ -75,6 +74,10 @@ struct netdevsim {
struct nsim_ipsec ipsec;
};
+struct netdevsim *
+nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port);
+void nsim_destroy(struct netdevsim *ns);
+
#ifdef CONFIG_BPF_SYSCALL
int nsim_bpf_dev_init(struct nsim_dev *nsim_dev);
void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev);
@@ -136,6 +139,7 @@ struct nsim_dev_port {
struct devlink_port devlink_port;
unsigned int port_index;
struct dentry *ddir;
+ struct netdevsim *ns;
};
struct nsim_dev {
@@ -212,8 +216,5 @@ struct nsim_bus_dev {
struct nsim_vf_config *vfconfigs;
};
-struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count);
-struct nsim_bus_dev *nsim_bus_dev_new_with_ns(struct netdevsim *ns);
-void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
int nsim_bus_init(void);
void nsim_bus_exit(void);