netdevsim: move netdev creation/destruction to dev probe
authorJiri Pirko <jiri@mellanox.com>
Thu, 25 Apr 2019 13:59:55 +0000 (15:59 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Apr 2019 05:52:03 +0000 (01:52 -0400)
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>
drivers/net/netdevsim/bpf.c
drivers/net/netdevsim/bus.c
drivers/net/netdevsim/dev.c
drivers/net/netdevsim/ipsec.c
drivers/net/netdevsim/netdev.c
drivers/net/netdevsim/netdevsim.h
tools/testing/selftests/bpf/test_offload.py
tools/testing/selftests/net/rtnetlink.sh

index 89980b223adc543013ec4437776c5d619b3cfa0c..2b74425822ab118b4fc723fcbaa3d91385c33e2b 100644 (file)
@@ -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;
index 549c399f29da8914cdfde5c6e643e76fdb2009ea..ae482347b67b93feec487792ef54a7368c0ee4e6 100644 (file)
@@ -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);
index 2fa1b20613701eaa4b5baa4d85e86d24b57f7a56..b509b941d5cab39fc55a29dca7ddf16208a5ddb1 100644 (file)
@@ -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);
index 76e11d889bb6eab360cf629d7945235a07ee23a9..e27fc1a4516dfaa1ad87819b9b7b0cc7f5adde47 100644 (file)
@@ -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);
 }
 
index 99169fe521f2859e9ac53ccead4b6c8fb17f115b..040c390d0c0110f4efcbca18f03da9056e2cb051 100644 (file)
 
 #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)
index 6b60589cab912cc81827b721f07d79824ba6563b..3f398797c2bc7855f6ae05baee28b25507463500 100644 (file)
@@ -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);
index 5f2e4f9e70e47c5f0a53ae5e335913360903b00e..425f9ed27c3b1b9de7e733358c3035b595dbef21 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/python3
 
 # Copyright (C) 2017 Netronome Systems, Inc.
+# Copyright (c) 2019 Mellanox Technologies. All rights reserved
 #
 # This software is licensed under the GNU General License Version 2,
 # June 1991 as shown in the file COPYING in the top-level directory of this
 
 from datetime import datetime
 import argparse
+import errno
 import json
 import os
 import pprint
 import random
+import re
 import string
 import struct
 import subprocess
@@ -323,42 +326,112 @@ class DebugfsDir:
 
         return dfs
 
-class NetdevSim:
+class NetdevSimDev:
     """
-    Class for netdevsim netdevice and its attributes.
+    Class for netdevsim bus device and its attributes.
     """
 
-    def __init__(self, link=None):
-        self.link = link
+    def __init__(self, port_count=1):
+        addr = 0
+        while True:
+            try:
+                with open("/sys/bus/netdevsim/new_device", "w") as f:
+                    f.write("%u %u" % (addr, port_count))
+            except OSError as e:
+                if e.errno == errno.ENOSPC:
+                    addr += 1
+                    continue
+                raise e
+            break
+        self.addr = addr
+
+        # As probe of netdevsim device might happen from a workqueue,
+        # so wait here until all netdevs appear.
+        self.wait_for_netdevs(port_count)
+
+        ret, out = cmd("udevadm settle", fail=False)
+        if ret:
+            raise Exception("udevadm settle failed")
+        ifnames = self.get_ifnames()
 
-        self.dev = self._netdevsim_create()
         devs.append(self)
+        self.dfs_dir = "/sys/kernel/debug/netdevsim/netdevsim%u/" % addr
+
+        self.nsims = []
+        for port_index in range(port_count):
+            self.nsims.append(NetdevSim(self, port_index, ifnames[port_index]))
+
+    def get_ifnames(self):
+        ifnames = []
+        listdir = os.listdir("/sys/bus/netdevsim/devices/netdevsim%u/net/" % self.addr)
+        for ifname in listdir:
+            ifnames.append(ifname)
+        ifnames.sort()
+        return ifnames
+
+    def wait_for_netdevs(self, port_count):
+        timeout = 5
+        timeout_start = time.time()
+
+        while True:
+            try:
+                ifnames = self.get_ifnames()
+            except FileNotFoundError as e:
+                ifnames = []
+            if len(ifnames) == port_count:
+                break
+            if time.time() < timeout_start + timeout:
+                continue
+            raise Exception("netdevices did not appear within timeout")
 
-        self.ns = ""
+    def dfs_num_bound_progs(self):
+        path = os.path.join(self.dfs_dir, "bpf_bound_progs")
+        _, progs = cmd('ls %s' % (path))
+        return len(progs.split())
 
-        self.dfs_dir = '/sys/kernel/debug/netdevsim/netdevsim0/ports/0/'
-        self.dev_dir = self.dfs_dir + '/dev/'
-        self.dfs_refresh()
+    def dfs_get_bound_progs(self, expected):
+        progs = DebugfsDir(os.path.join(self.dfs_dir, "bpf_bound_progs"))
+        if expected is not None:
+            if len(progs) != expected:
+                fail(True, "%d BPF programs bound, expected %d" %
+                     (len(progs), expected))
+        return progs
 
-    def __getitem__(self, key):
-        return self.dev[key]
+    def remove(self):
+        with open("/sys/bus/netdevsim/del_device", "w") as f:
+            f.write("%u" % self.addr)
+        devs.remove(self)
+
+    def remove_nsim(self, nsim):
+        self.nsims.remove(nsim)
+        with open("/sys/bus/netdevsim/devices/netdevsim%u/del_port" % self.addr ,"w") as f:
+            f.write("%u" % nsim.port_index)
+
+class NetdevSim:
+    """
+    Class for netdevsim netdevice and its attributes.
+    """
 
-    def _netdevsim_create(self):
-        link = "" if self.link is None else "link " + self.link.dev['ifname']
-        _, old  = ip("link show")
-        ip("link add sim%d {link} type netdevsim".format(link=link))
-        _, new  = ip("link show")
+    def __init__(self, nsimdev, port_index, ifname):
+        # In case udev renamed the netdev to according to new schema,
+        # check if the name matches the port_index.
+        nsimnamere = re.compile("eni\d+np(\d+)")
+        match = nsimnamere.match(ifname)
+        if match and int(match.groups()[0]) != port_index + 1:
+            raise Exception("netdevice name mismatches the expected one")
 
-        for dev in new:
-            f = filter(lambda x: x["ifname"] == dev["ifname"], old)
-            if len(list(f)) == 0:
-                return dev
+        self.nsimdev = nsimdev
+        self.port_index = port_index
+        self.ns = ""
+        self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
+        self.dfs_refresh()
+        _, [self.dev] = ip("link show dev %s" % ifname)
 
-        raise Exception("failed to create netdevsim device")
+    def __getitem__(self, key):
+        return self.dev[key]
 
     def remove(self):
-        devs.remove(self)
-        ip("link del dev %s" % (self.dev["ifname"]), ns=self.ns)
+        self.nsimdev.remove_nsim(self)
 
     def dfs_refresh(self):
         self.dfs = DebugfsDir(self.dfs_dir)
@@ -369,22 +442,9 @@ class NetdevSim:
         _, data = cmd('cat %s' % (path))
         return data.strip()
 
-    def dfs_num_bound_progs(self):
-        path = os.path.join(self.dev_dir, "bpf_bound_progs")
-        _, progs = cmd('ls %s' % (path))
-        return len(progs.split())
-
-    def dfs_get_bound_progs(self, expected):
-        progs = DebugfsDir(os.path.join(self.dev_dir, "bpf_bound_progs"))
-        if expected is not None:
-            if len(progs) != expected:
-                fail(True, "%d BPF programs bound, expected %d" %
-                     (len(progs), expected))
-        return progs
-
     def wait_for_flush(self, bound=0, total=0, n_retry=20):
         for i in range(n_retry):
-            nbound = self.dfs_num_bound_progs()
+            nbound = self.nsimdev.dfs_num_bound_progs()
             nprogs = len(bpftool_prog_list())
             if nbound == bound and nprogs == total:
                 return
@@ -614,7 +674,7 @@ def test_spurios_extack(sim, obj, skip_hw, needle):
                             include_stderr=True)
     check_no_extack(res, needle)
 
-def test_multi_prog(sim, obj, modename, modeid):
+def test_multi_prog(simdev, sim, obj, modename, modeid):
     start_test("Test multi-attachment XDP - %s + offload..." %
                (modename or "default", ))
     sim.set_xdp(obj, "offload")
@@ -670,11 +730,12 @@ def test_multi_prog(sim, obj, modename, modeid):
     check_multi_basic(two_xdps)
 
     start_test("Test multi-attachment XDP - device remove...")
-    sim.remove()
+    simdev.remove()
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.set_ethtool_tc_offloads(True)
-    return sim
+    return [simdev, sim]
 
 # Parse command line
 parser = argparse.ArgumentParser()
@@ -731,12 +792,14 @@ try:
     bytecode = bpf_bytecode("1,6 0 0 4294967295,")
 
     start_test("Test destruction of generic XDP...")
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.set_xdp(obj, "generic")
-    sim.remove()
+    simdev.remove()
     bpftool_prog_list_wait(expected=0)
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.tc_add_ingress()
 
     start_test("Test TC non-offloaded...")
@@ -746,7 +809,7 @@ try:
     start_test("Test TC non-offloaded isn't getting bound...")
     ret, _ = sim.cls_bpf_add_filter(obj, fail=False)
     fail(ret != 0, "Software TC filter did not load")
-    sim.dfs_get_bound_progs(expected=0)
+    simdev.dfs_get_bound_progs(expected=0)
 
     sim.tc_flush_filters()
 
@@ -763,7 +826,7 @@ try:
     start_test("Test TC offload by default...")
     ret, _ = sim.cls_bpf_add_filter(obj, fail=False)
     fail(ret != 0, "Software TC filter did not load")
-    sim.dfs_get_bound_progs(expected=0)
+    simdev.dfs_get_bound_progs(expected=0)
     ingress = sim.tc_show_ingress(expected=1)
     fltr = ingress[0]
     fail(not fltr["in_hw"], "Filter not offloaded by default")
@@ -773,7 +836,7 @@ try:
     start_test("Test TC cBPF bytcode tries offload by default...")
     ret, _ = sim.cls_bpf_add_filter(bytecode, fail=False)
     fail(ret != 0, "Software TC filter did not load")
-    sim.dfs_get_bound_progs(expected=0)
+    simdev.dfs_get_bound_progs(expected=0)
     ingress = sim.tc_show_ingress(expected=1)
     fltr = ingress[0]
     fail(not fltr["in_hw"], "Bytecode not offloaded by default")
@@ -841,7 +904,7 @@ try:
     check_verifier_log(err, "[netdevsim] Hello from netdevsim!")
 
     start_test("Test TC offload basics...")
-    dfs = sim.dfs_get_bound_progs(expected=1)
+    dfs = simdev.dfs_get_bound_progs(expected=1)
     progs = bpftool_prog_list(expected=1)
     ingress = sim.tc_show_ingress(expected=1)
 
@@ -876,18 +939,20 @@ try:
 
     start_test("Test destroying device gets rid of TC filters...")
     sim.cls_bpf_add_filter(obj, skip_sw=True)
-    sim.remove()
+    simdev.remove()
     bpftool_prog_list_wait(expected=0)
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.set_ethtool_tc_offloads(True)
 
     start_test("Test destroying device gets rid of XDP...")
     sim.set_xdp(obj, "offload")
-    sim.remove()
+    simdev.remove()
     bpftool_prog_list_wait(expected=0)
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.set_ethtool_tc_offloads(True)
 
     start_test("Test XDP prog reporting...")
@@ -973,7 +1038,7 @@ try:
     check_verifier_log(err, "[netdevsim] Hello from netdevsim!")
 
     start_test("Test XDP offload is device bound...")
-    dfs = sim.dfs_get_bound_progs(expected=1)
+    dfs = simdev.dfs_get_bound_progs(expected=1)
     dprog = dfs[0]
 
     fail(prog["id"] != link_xdp["id"], "Program IDs don't match")
@@ -992,7 +1057,8 @@ try:
     bpftool_prog_list_wait(expected=0)
 
     start_test("Test attempt to use a program for a wrong device...")
-    sim2 = NetdevSim()
+    simdev2 = NetdevSimDev()
+    sim2, = simdev2.nsims
     sim2.set_xdp(obj, "offload")
     pin_file, pinned = pin_prog("/sys/fs/bpf/tmp")
 
@@ -1000,7 +1066,7 @@ try:
                               fail=False, include_stderr=True)
     fail(ret == 0, "Pinned program loaded for a different device accepted")
     check_extack_nsim(err, "program bound to different dev.", args)
-    sim2.remove()
+    simdev2.remove()
     ret, _, err = sim.set_xdp(pinned, "offload",
                               fail=False, include_stderr=True)
     fail(ret == 0, "Pinned program loaded for a removed device accepted")
@@ -1008,9 +1074,9 @@ try:
     rm(pin_file)
     bpftool_prog_list_wait(expected=0)
 
-    sim = test_multi_prog(sim, obj, "", 1)
-    sim = test_multi_prog(sim, obj, "drv", 1)
-    sim = test_multi_prog(sim, obj, "generic", 2)
+    simdev, sim = test_multi_prog(simdev, sim, obj, "", 1)
+    simdev, sim = test_multi_prog(simdev, sim, obj, "drv", 1)
+    simdev, sim = test_multi_prog(simdev, sim, obj, "generic", 2)
 
     start_test("Test mixing of TC and XDP...")
     sim.tc_add_ingress()
@@ -1063,9 +1129,9 @@ try:
                (sim['ifname'], obj)
     tc_proc = cmd(cmd_line, background=True, fail=False)
     # Wait for the verifier to start
-    while sim.dfs_num_bound_progs() <= 2:
+    while simdev.dfs_num_bound_progs() <= 2:
         pass
-    sim.remove()
+    simdev.remove()
     end = time.time()
     ret, _ = cmd_result(tc_proc, fail=False)
     time_diff = end - start
@@ -1080,7 +1146,8 @@ try:
     clean_up()
     bpftool_prog_list_wait(expected=0)
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     map_obj = bpf_obj("sample_map_ret0.o")
     start_test("Test loading program with maps...")
     sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON
@@ -1102,7 +1169,7 @@ try:
 
     prog_file, _ = pin_prog("/sys/fs/bpf/tmp_prog")
     map_file, _ = pin_map("/sys/fs/bpf/tmp_map", idx=1, expected=2)
-    sim.remove()
+    simdev.remove()
 
     start_test("Test bpftool bound info reporting (removed dev)...")
     check_dev_info_removed(prog_file=prog_file, map_file=map_file)
@@ -1111,7 +1178,8 @@ try:
     clean_up()
     bpftool_prog_list_wait(expected=0)
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
 
     start_test("Test map update (no flags)...")
     sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON
@@ -1192,27 +1260,29 @@ try:
     start_test("Test map remove...")
     sim.unset_xdp("offload")
     bpftool_map_list_wait(expected=0)
-    sim.remove()
+    simdev.remove()
 
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON
-    sim.remove()
+    simdev.remove()
     bpftool_map_list_wait(expected=0)
 
     start_test("Test map creation fail path...")
-    sim = NetdevSim()
+    simdev = NetdevSimDev()
+    sim, = simdev.nsims
     sim.dfs["bpf_map_accept"] = "N"
     ret, _ = sim.set_xdp(map_obj, "offload", JSON=False, fail=False)
     fail(ret == 0,
          "netdevsim didn't refuse to create a map with offload disabled")
 
-    sim.remove()
+    simdev.remove()
 
     start_test("Test multi-dev ASIC program reuse...")
-    simA = NetdevSim()
-    simB1 = NetdevSim()
-    simB2 = NetdevSim(link=simB1)
-    simB3 = NetdevSim(link=simB1)
+    simdevA = NetdevSimDev()
+    simA, = simdevA.nsims
+    simdevB = NetdevSimDev(3)
+    simB1, simB2, simB3 = simdevB.nsims
     sims = (simA, simB1, simB2, simB3)
     simB = (simB1, simB2, simB3)
 
@@ -1224,13 +1294,13 @@ try:
     progB = bpf_pinned("/sys/fs/bpf/nsimB")
 
     simA.set_xdp(progA, "offload", JSON=False)
-    for d in simB:
+    for d in simdevB.nsims:
         d.set_xdp(progB, "offload", JSON=False)
 
     start_test("Test multi-dev ASIC cross-dev replace...")
     ret, _ = simA.set_xdp(progB, "offload", force=True, JSON=False, fail=False)
     fail(ret == 0, "cross-ASIC program allowed")
-    for d in simB:
+    for d in simdevB.nsims:
         ret, _ = d.set_xdp(progA, "offload", force=True, JSON=False, fail=False)
         fail(ret == 0, "cross-ASIC program allowed")
 
@@ -1242,7 +1312,7 @@ try:
                                fail=False, include_stderr=True)
     fail(ret == 0, "cross-ASIC program allowed")
     check_extack_nsim(err, "program bound to different dev.", args)
-    for d in simB:
+    for d in simdevB.nsims:
         ret, _, err = d.set_xdp(progA, "offload", force=True, JSON=False,
                                 fail=False, include_stderr=True)
         fail(ret == 0, "cross-ASIC program allowed")
@@ -1279,7 +1349,7 @@ try:
     start_test("Test multi-dev ASIC cross-dev destruction...")
     bpftool_prog_list_wait(expected=2)
 
-    simA.remove()
+    simdevA.remove()
     bpftool_prog_list_wait(expected=1)
 
     ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
@@ -1297,6 +1367,7 @@ try:
     fail(ifnameB != simB3['ifname'], "program not bound to remaining device")
 
     simB3.remove()
+    simdevB.remove()
     bpftool_prog_list_wait(expected=0)
 
     start_test("Test multi-dev ASIC cross-dev destruction - orphaned...")
index 311f82bcbe8d072323e3757b8c8105153ddce7c9..b25c9fe019d28211abcd282384ec9cda0945436d 100755 (executable)
@@ -696,9 +696,9 @@ kci_test_ipsec_offload()
        algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128"
        srcip=192.168.123.3
        dstip=192.168.123.4
-       dev=simx1
        sysfsd=/sys/kernel/debug/netdevsim/netdevsim0/ports/0/
        sysfsf=$sysfsd/ipsec
+       sysfsnet=/sys/bus/netdevsim/devices/netdevsim0/net/
 
        # setup netdevsim since dummydev doesn't have offload support
        modprobe netdevsim
@@ -708,7 +708,11 @@ kci_test_ipsec_offload()
                return 1
        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 link set $dev up
        if [ ! -d $sysfsd ] ; then
@@ -781,7 +785,6 @@ EOF
        fi
 
        # clean up any leftovers
-       ip link del $dev
        rmmod netdevsim
 
        if [ $ret -ne 0 ]; then