From: Jiri Pirko <j...@mellanox.com> 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 <j...@mellanox.com> --- drivers/net/netdevsim/bpf.c | 13 ++- drivers/net/netdevsim/bus.c | 25 ++-- drivers/net/netdevsim/dev.c | 14 ++- drivers/net/netdevsim/ipsec.c | 3 +- drivers/net/netdevsim/netdev.c | 138 ++++++++--------------- drivers/net/netdevsim/netdevsim.h | 11 +- tools/testing/selftests/net/rtnetlink.sh | 6 +- 7 files changed, 89 insertions(+), 121 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 46108a926890..a8e0b1f60a6f 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -117,6 +117,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) { @@ -152,6 +155,8 @@ static ssize_t new_device_store(struct bus_type *bus, const char *buf, } 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) { @@ -225,7 +230,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; @@ -234,8 +240,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; @@ -255,19 +260,7 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count) 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 43d87c457ad9..7bd33989f484 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -275,7 +275,7 @@ static struct nsim_dev *nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, 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); @@ -307,8 +307,18 @@ static int nsim_dev_port_init(struct nsim_dev *nsim_dev, err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port); 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); return 0; +err_port_debugfs_exit: + nsim_dev_port_debugfs_exit(nsim_dev_port); err_dl_port_unregister: devlink_port_unregister(devlink_port); return err; @@ -320,6 +330,8 @@ static void nsim_dev_port_exit(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port = &nsim_dev->ports[port_index]; struct devlink_port *devlink_port = &nsim_dev_port->devlink_port; + 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); } 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..38ebf846ed49 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 c0a08af5e724..a91e2118dd0e 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); @@ -135,6 +138,7 @@ struct nsim_dev_port { struct devlink_port devlink_port; unsigned int port_index; struct dentry *ddir; + struct netdevsim *ns; }; struct nsim_dev { @@ -206,8 +210,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); diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 311f82bcbe8d..710d73ceb9c3 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -696,7 +696,7 @@ kci_test_ipsec_offload() algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128" srcip=192.168.123.3 dstip=192.168.123.4 - dev=simx1 + dev=netdevsim0p1 sysfsd=/sys/kernel/debug/netdevsim/netdevsim0/ports/0/ sysfsf=$sysfsd/ipsec @@ -708,7 +708,8 @@ kci_test_ipsec_offload() return 1 fi - ip link add $dev type netdevsim + echo "0" > /sys/bus/netdevsim/new_device + sleep 0.2 ip addr add $srcip dev $dev ip link set $dev up if [ ! -d $sysfsd ] ; then @@ -781,7 +782,6 @@ EOF fi # clean up any leftovers - ip link del $dev rmmod netdevsim if [ $ret -ne 0 ]; then -- 2.17.2