Commit e05b2d14 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

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: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 794b2c05
...@@ -612,6 +612,7 @@ void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev) ...@@ -612,6 +612,7 @@ void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev)
int nsim_bpf_init(struct netdevsim *ns) int nsim_bpf_init(struct netdevsim *ns)
{ {
struct dentry *ddir = ns->nsim_dev_port->ddir;
int err; int err;
err = bpf_offload_dev_netdev_register(ns->nsim_dev->bpf_dev, err = bpf_offload_dev_netdev_register(ns->nsim_dev->bpf_dev,
...@@ -619,23 +620,23 @@ int nsim_bpf_init(struct netdevsim *ns) ...@@ -619,23 +620,23 @@ int nsim_bpf_init(struct netdevsim *ns)
if (err) if (err)
return 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_offloaded_id);
ns->bpf_tc_accept = true; 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); &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_tc_non_bound_accept);
ns->bpf_xdpdrv_accept = true; 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_xdpdrv_accept);
ns->bpf_xdpoffload_accept = true; 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_xdpoffload_accept);
ns->bpf_map_accept = true; 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); &ns->bpf_map_accept);
return 0; return 0;
......
...@@ -153,6 +153,9 @@ static struct device_type nsim_bus_dev_type = { ...@@ -153,6 +153,9 @@ static struct device_type nsim_bus_dev_type = {
.release = nsim_bus_dev_release, .release = nsim_bus_dev_release,
}; };
static struct nsim_bus_dev *
nsim_bus_dev_new(unsigned int id, unsigned int port_count);
static ssize_t static ssize_t
new_device_store(struct bus_type *bus, const char *buf, size_t count) 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) ...@@ -188,6 +191,8 @@ new_device_store(struct bus_type *bus, const char *buf, size_t count)
} }
static BUS_ATTR_WO(new_device); static BUS_ATTR_WO(new_device);
static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
static ssize_t static ssize_t
del_device_store(struct bus_type *bus, const char *buf, size_t count) del_device_store(struct bus_type *bus, const char *buf, size_t count)
{ {
...@@ -261,7 +266,8 @@ static struct bus_type nsim_bus = { ...@@ -261,7 +266,8 @@ static struct bus_type nsim_bus = {
.num_vf = nsim_num_vf, .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; struct nsim_bus_dev *nsim_bus_dev;
int err; int err;
...@@ -270,8 +276,7 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count) ...@@ -270,8 +276,7 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count)
if (!nsim_bus_dev) if (!nsim_bus_dev)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
err = ida_alloc_range(&nsim_bus_dev_ids, err = ida_alloc_range(&nsim_bus_dev_ids, id, id, GFP_KERNEL);
id == ~0 ? 0 : id, id, GFP_KERNEL);
if (err < 0) if (err < 0)
goto err_nsim_bus_dev_free; goto err_nsim_bus_dev_free;
nsim_bus_dev->dev.id = err; nsim_bus_dev->dev.id = err;
...@@ -291,19 +296,7 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count) ...@@ -291,19 +296,7 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count)
return ERR_PTR(err); return ERR_PTR(err);
} }
struct nsim_bus_dev *nsim_bus_dev_new_with_ns(struct netdevsim *ns) static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
{
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)
{ {
device_unregister(&nsim_bus_dev->dev); device_unregister(&nsim_bus_dev->dev);
ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id); ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
......
...@@ -278,7 +278,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count) ...@@ -278,7 +278,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
return ERR_PTR(err); 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); struct devlink *devlink = priv_to_devlink(nsim_dev);
...@@ -317,10 +317,19 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, ...@@ -317,10 +317,19 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
if (err) if (err)
goto err_dl_port_unregister; 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); list_add(&nsim_dev_port->list, &nsim_dev->port_list);
return 0; return 0;
err_port_debugfs_exit:
nsim_dev_port_debugfs_exit(nsim_dev_port);
err_dl_port_unregister: err_dl_port_unregister:
devlink_port_unregister(devlink_port); devlink_port_unregister(devlink_port);
err_port_free: err_port_free:
...@@ -333,6 +342,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port) ...@@ -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; struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
list_del(&nsim_dev_port->list); 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); nsim_dev_port_debugfs_exit(nsim_dev_port);
devlink_port_unregister(devlink_port); devlink_port_unregister(devlink_port);
kfree(nsim_dev_port); kfree(nsim_dev_port);
......
...@@ -283,7 +283,8 @@ void nsim_ipsec_init(struct netdevsim *ns) ...@@ -283,7 +283,8 @@ void nsim_ipsec_init(struct netdevsim *ns)
ns->netdev->features |= NSIM_ESP_FEATURES; ns->netdev->features |= NSIM_ESP_FEATURES;
ns->netdev->hw_enc_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); &ipsec_dbg_fops);
} }
......
...@@ -25,59 +25,6 @@ ...@@ -25,59 +25,6 @@
#include "netdevsim.h" #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) static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct netdevsim *ns = netdev_priv(dev); struct netdevsim *ns = netdev_priv(dev);
...@@ -299,8 +246,6 @@ nsim_set_features(struct net_device *dev, netdev_features_t features) ...@@ -299,8 +246,6 @@ nsim_set_features(struct net_device *dev, netdev_features_t features)
} }
static const struct net_device_ops nsim_netdev_ops = { static const struct net_device_ops nsim_netdev_ops = {
.ndo_init = nsim_init,
.ndo_uninit = nsim_uninit,
.ndo_start_xmit = nsim_start_xmit, .ndo_start_xmit = nsim_start_xmit,
.ndo_set_rx_mode = nsim_set_rx_mode, .ndo_set_rx_mode = nsim_set_rx_mode,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = eth_mac_addr,
...@@ -318,7 +263,6 @@ static const struct net_device_ops nsim_netdev_ops = { ...@@ -318,7 +263,6 @@ static const struct net_device_ops nsim_netdev_ops = {
.ndo_setup_tc = nsim_setup_tc, .ndo_setup_tc = nsim_setup_tc,
.ndo_set_features = nsim_set_features, .ndo_set_features = nsim_set_features,
.ndo_bpf = nsim_bpf, .ndo_bpf = nsim_bpf,
.ndo_get_port_parent_id = nsim_get_port_parent_id,
}; };
static void nsim_setup(struct net_device *dev) static void nsim_setup(struct net_device *dev)
...@@ -326,10 +270,6 @@ static void nsim_setup(struct net_device *dev) ...@@ -326,10 +270,6 @@ static void nsim_setup(struct net_device *dev)
ether_setup(dev); ether_setup(dev);
eth_hw_addr_random(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->tx_queue_len = 0;
dev->flags |= IFF_NOARP; dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST; dev->flags &= ~IFF_MULTICAST;
...@@ -344,50 +284,70 @@ static void nsim_setup(struct net_device *dev) ...@@ -344,50 +284,70 @@ static void nsim_setup(struct net_device *dev)
dev->max_mtu = ETH_MAX_MTU; dev->max_mtu = ETH_MAX_MTU;
} }
static int nsim_validate(struct nlattr *tb[], struct nlattr *data[], struct netdevsim *
struct netlink_ext_ack *extack) nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
{
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 *ns = netdev_priv(dev); struct net_device *dev;
struct netdevsim *ns;
int err; int err;
ns->netdev = dev; dev = alloc_netdev(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup);
ns->nsim_bus_dev = nsim_bus_dev_new_with_ns(ns); if (!dev)
if (IS_ERR(ns->nsim_bus_dev)) return ERR_PTR(-ENOMEM);
return PTR_ERR(ns->nsim_bus_dev);
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); 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); err = register_netdevice(dev);
if (err) if (err)
goto err_dev_del; goto err_ipsec_teardown;
return 0; rtnl_unlock();
err_dev_del: return ns;
nsim_bus_dev_del(ns->nsim_bus_dev);
return err; 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 = { static struct rtnl_link_ops nsim_link_ops __read_mostly = {
.kind = DRV_NAME, .kind = DRV_NAME,
.priv_size = sizeof(struct netdevsim),
.setup = nsim_setup,
.validate = nsim_validate, .validate = nsim_validate,
.newlink = nsim_newlink,
}; };
static int __init nsim_module_init(void) static int __init nsim_module_init(void)
......
...@@ -51,6 +51,7 @@ struct nsim_ipsec { ...@@ -51,6 +51,7 @@ struct nsim_ipsec {
struct netdevsim { struct netdevsim {
struct net_device *netdev; struct net_device *netdev;
struct nsim_dev *nsim_dev; struct nsim_dev *nsim_dev;
struct nsim_dev_port *nsim_dev_port;
u64 tx_packets; u64 tx_packets;
u64 tx_bytes; u64 tx_bytes;
...@@ -58,8 +59,6 @@ struct netdevsim { ...@@ -58,8 +59,6 @@ struct netdevsim {
struct nsim_bus_dev *nsim_bus_dev; struct nsim_bus_dev *nsim_bus_dev;
struct dentry *ddir;
struct bpf_prog *bpf_offloaded; struct bpf_prog *bpf_offloaded;
u32 bpf_offloaded_id; u32 bpf_offloaded_id;
...@@ -75,6 +74,10 @@ struct netdevsim { ...@@ -75,6 +74,10 @@ struct netdevsim {
struct nsim_ipsec ipsec; 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 #ifdef CONFIG_BPF_SYSCALL
int nsim_bpf_dev_init(struct nsim_dev *nsim_dev); int nsim_bpf_dev_init(struct nsim_dev *nsim_dev);
void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev); void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev);
...@@ -136,6 +139,7 @@ struct nsim_dev_port { ...@@ -136,6 +139,7 @@ struct nsim_dev_port {
struct devlink_port devlink_port; struct devlink_port devlink_port;
unsigned int port_index; unsigned int port_index;
struct dentry *ddir; struct dentry *ddir;
struct netdevsim *ns;
}; };
struct nsim_dev { struct nsim_dev {
...@@ -212,8 +216,5 @@ struct nsim_bus_dev { ...@@ -212,8 +216,5 @@ struct nsim_bus_dev {
struct nsim_vf_config *vfconfigs; 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); int nsim_bus_init(void);
void nsim_bus_exit(void); void nsim_bus_exit(void);
This diff is collapsed.
...@@ -696,9 +696,9 @@ kci_test_ipsec_offload() ...@@ -696,9 +696,9 @@ kci_test_ipsec_offload()
algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128" algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128"
srcip=192.168.123.3 srcip=192.168.123.3
dstip=192.168.123.4 dstip=192.168.123.4
dev=simx1
sysfsd=/sys/kernel/debug/netdevsim/netdevsim0/ports/0/ sysfsd=/sys/kernel/debug/netdevsim/netdevsim0/ports/0/
sysfsf=$sysfsd/ipsec sysfsf=$sysfsd/ipsec
sysfsnet=/sys/bus/netdevsim/devices/netdevsim0/net/
# setup netdevsim since dummydev doesn't have offload support # setup netdevsim since dummydev doesn't have offload support
modprobe netdevsim modprobe netdevsim
...@@ -708,7 +708,11 @@ kci_test_ipsec_offload() ...@@ -708,7 +708,11 @@ kci_test_ipsec_offload()
return 1 return 1
fi fi
ip link add $dev type netdevsim echo "0" > /sys/bus/netdevsim/new_device
while [ ! -d $sysfsnet ] ; do :; done
udevadm settle
dev=`ls $sysfsnet`
ip addr add $srcip dev $dev ip addr add $srcip dev $dev
ip link set $dev up ip link set $dev up
if [ ! -d $sysfsd ] ; then if [ ! -d $sysfsd ] ; then
...@@ -781,7 +785,6 @@ EOF ...@@ -781,7 +785,6 @@ EOF
fi fi
# clean up any leftovers # clean up any leftovers
ip link del $dev
rmmod netdevsim rmmod netdevsim
if [ $ret -ne 0 ]; then if [ $ret -ne 0 ]; then
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment