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>
This commit is contained in:
Jiri Pirko 2019-04-25 15:59:55 +02:00 committed by David S. Miller
parent 794b2c05ca
commit e05b2d141f
8 changed files with 238 additions and 197 deletions

View File

@ -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)
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;

View File

@ -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)
} }
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 = {
.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)
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 @@ err_nsim_bus_dev_free:
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);

View File

@ -278,7 +278,7 @@ err_devlink_free:
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,
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)
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);

View File

@ -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);
} }

View File

@ -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)
} }
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 = {
.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)
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)
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]) { struct net_device *dev;
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) struct netdevsim *ns;
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);
int err; int err;
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->netdev = dev;
ns->nsim_bus_dev = nsim_bus_dev_new_with_ns(ns); ns->nsim_dev = nsim_dev;
if (IS_ERR(ns->nsim_bus_dev)) ns->nsim_dev_port = nsim_dev_port;
return PTR_ERR(ns->nsim_bus_dev); 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)

View File

@ -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 {
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 {
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 {
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 {
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);

View File

@ -1,6 +1,7 @@
#!/usr/bin/python3 #!/usr/bin/python3
# Copyright (C) 2017 Netronome Systems, Inc. # 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, # 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 # June 1991 as shown in the file COPYING in the top-level directory of this
@ -15,10 +16,12 @@
from datetime import datetime from datetime import datetime
import argparse import argparse
import errno
import json import json
import os import os
import pprint import pprint
import random import random
import re
import string import string
import struct import struct
import subprocess import subprocess
@ -323,42 +326,112 @@ class DebugfsDir:
return dfs return dfs
class NetdevSimDev:
"""
Class for netdevsim bus device and its attributes.
"""
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()
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")
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())
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 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 NetdevSim:
""" """
Class for netdevsim netdevice and its attributes. Class for netdevsim netdevice and its attributes.
""" """
def __init__(self, link=None): def __init__(self, nsimdev, port_index, ifname):
self.link = link # In case udev renamed the netdev to according to new schema,
# check if the name matches the port_index.
self.dev = self._netdevsim_create() nsimnamere = re.compile("eni\d+np(\d+)")
devs.append(self) match = nsimnamere.match(ifname)
if match and int(match.groups()[0]) != port_index + 1:
raise Exception("netdevice name mismatches the expected one")
self.nsimdev = nsimdev
self.port_index = port_index
self.ns = "" self.ns = ""
self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
self.dfs_dir = '/sys/kernel/debug/netdevsim/netdevsim0/ports/0/'
self.dev_dir = self.dfs_dir + '/dev/'
self.dfs_refresh() self.dfs_refresh()
_, [self.dev] = ip("link show dev %s" % ifname)
def __getitem__(self, key): def __getitem__(self, key):
return self.dev[key] return self.dev[key]
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")
for dev in new:
f = filter(lambda x: x["ifname"] == dev["ifname"], old)
if len(list(f)) == 0:
return dev
raise Exception("failed to create netdevsim device")
def remove(self): def remove(self):
devs.remove(self) self.nsimdev.remove_nsim(self)
ip("link del dev %s" % (self.dev["ifname"]), ns=self.ns)
def dfs_refresh(self): def dfs_refresh(self):
self.dfs = DebugfsDir(self.dfs_dir) self.dfs = DebugfsDir(self.dfs_dir)
@ -369,22 +442,9 @@ class NetdevSim:
_, data = cmd('cat %s' % (path)) _, data = cmd('cat %s' % (path))
return data.strip() 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): def wait_for_flush(self, bound=0, total=0, n_retry=20):
for i in range(n_retry): for i in range(n_retry):
nbound = self.dfs_num_bound_progs() nbound = self.nsimdev.dfs_num_bound_progs()
nprogs = len(bpftool_prog_list()) nprogs = len(bpftool_prog_list())
if nbound == bound and nprogs == total: if nbound == bound and nprogs == total:
return return
@ -614,7 +674,7 @@ def test_spurios_extack(sim, obj, skip_hw, needle):
include_stderr=True) include_stderr=True)
check_no_extack(res, needle) 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..." % start_test("Test multi-attachment XDP - %s + offload..." %
(modename or "default", )) (modename or "default", ))
sim.set_xdp(obj, "offload") sim.set_xdp(obj, "offload")
@ -670,11 +730,12 @@ def test_multi_prog(sim, obj, modename, modeid):
check_multi_basic(two_xdps) check_multi_basic(two_xdps)
start_test("Test multi-attachment XDP - device remove...") 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) sim.set_ethtool_tc_offloads(True)
return sim return [simdev, sim]
# Parse command line # Parse command line
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -731,12 +792,14 @@ try:
bytecode = bpf_bytecode("1,6 0 0 4294967295,") bytecode = bpf_bytecode("1,6 0 0 4294967295,")
start_test("Test destruction of generic XDP...") start_test("Test destruction of generic XDP...")
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
sim.set_xdp(obj, "generic") sim.set_xdp(obj, "generic")
sim.remove() simdev.remove()
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
sim.tc_add_ingress() sim.tc_add_ingress()
start_test("Test TC non-offloaded...") start_test("Test TC non-offloaded...")
@ -746,7 +809,7 @@ try:
start_test("Test TC non-offloaded isn't getting bound...") start_test("Test TC non-offloaded isn't getting bound...")
ret, _ = sim.cls_bpf_add_filter(obj, fail=False) ret, _ = sim.cls_bpf_add_filter(obj, fail=False)
fail(ret != 0, "Software TC filter did not load") 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() sim.tc_flush_filters()
@ -763,7 +826,7 @@ try:
start_test("Test TC offload by default...") start_test("Test TC offload by default...")
ret, _ = sim.cls_bpf_add_filter(obj, fail=False) ret, _ = sim.cls_bpf_add_filter(obj, fail=False)
fail(ret != 0, "Software TC filter did not load") 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) ingress = sim.tc_show_ingress(expected=1)
fltr = ingress[0] fltr = ingress[0]
fail(not fltr["in_hw"], "Filter not offloaded by default") 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...") start_test("Test TC cBPF bytcode tries offload by default...")
ret, _ = sim.cls_bpf_add_filter(bytecode, fail=False) ret, _ = sim.cls_bpf_add_filter(bytecode, fail=False)
fail(ret != 0, "Software TC filter did not load") 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) ingress = sim.tc_show_ingress(expected=1)
fltr = ingress[0] fltr = ingress[0]
fail(not fltr["in_hw"], "Bytecode not offloaded by default") fail(not fltr["in_hw"], "Bytecode not offloaded by default")
@ -841,7 +904,7 @@ try:
check_verifier_log(err, "[netdevsim] Hello from netdevsim!") check_verifier_log(err, "[netdevsim] Hello from netdevsim!")
start_test("Test TC offload basics...") 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) progs = bpftool_prog_list(expected=1)
ingress = sim.tc_show_ingress(expected=1) ingress = sim.tc_show_ingress(expected=1)
@ -876,18 +939,20 @@ try:
start_test("Test destroying device gets rid of TC filters...") start_test("Test destroying device gets rid of TC filters...")
sim.cls_bpf_add_filter(obj, skip_sw=True) sim.cls_bpf_add_filter(obj, skip_sw=True)
sim.remove() simdev.remove()
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
sim.set_ethtool_tc_offloads(True) sim.set_ethtool_tc_offloads(True)
start_test("Test destroying device gets rid of XDP...") start_test("Test destroying device gets rid of XDP...")
sim.set_xdp(obj, "offload") sim.set_xdp(obj, "offload")
sim.remove() simdev.remove()
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
sim.set_ethtool_tc_offloads(True) sim.set_ethtool_tc_offloads(True)
start_test("Test XDP prog reporting...") start_test("Test XDP prog reporting...")
@ -973,7 +1038,7 @@ try:
check_verifier_log(err, "[netdevsim] Hello from netdevsim!") check_verifier_log(err, "[netdevsim] Hello from netdevsim!")
start_test("Test XDP offload is device bound...") 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] dprog = dfs[0]
fail(prog["id"] != link_xdp["id"], "Program IDs don't match") fail(prog["id"] != link_xdp["id"], "Program IDs don't match")
@ -992,7 +1057,8 @@ try:
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
start_test("Test attempt to use a program for a wrong device...") start_test("Test attempt to use a program for a wrong device...")
sim2 = NetdevSim() simdev2 = NetdevSimDev()
sim2, = simdev2.nsims
sim2.set_xdp(obj, "offload") sim2.set_xdp(obj, "offload")
pin_file, pinned = pin_prog("/sys/fs/bpf/tmp") pin_file, pinned = pin_prog("/sys/fs/bpf/tmp")
@ -1000,7 +1066,7 @@ try:
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "Pinned program loaded for a different device accepted") fail(ret == 0, "Pinned program loaded for a different device accepted")
check_extack_nsim(err, "program bound to different dev.", args) check_extack_nsim(err, "program bound to different dev.", args)
sim2.remove() simdev2.remove()
ret, _, err = sim.set_xdp(pinned, "offload", ret, _, err = sim.set_xdp(pinned, "offload",
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "Pinned program loaded for a removed device accepted") fail(ret == 0, "Pinned program loaded for a removed device accepted")
@ -1008,9 +1074,9 @@ try:
rm(pin_file) rm(pin_file)
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
sim = test_multi_prog(sim, obj, "", 1) simdev, sim = test_multi_prog(simdev, sim, obj, "", 1)
sim = test_multi_prog(sim, obj, "drv", 1) simdev, sim = test_multi_prog(simdev, sim, obj, "drv", 1)
sim = test_multi_prog(sim, obj, "generic", 2) simdev, sim = test_multi_prog(simdev, sim, obj, "generic", 2)
start_test("Test mixing of TC and XDP...") start_test("Test mixing of TC and XDP...")
sim.tc_add_ingress() sim.tc_add_ingress()
@ -1063,9 +1129,9 @@ try:
(sim['ifname'], obj) (sim['ifname'], obj)
tc_proc = cmd(cmd_line, background=True, fail=False) tc_proc = cmd(cmd_line, background=True, fail=False)
# Wait for the verifier to start # Wait for the verifier to start
while sim.dfs_num_bound_progs() <= 2: while simdev.dfs_num_bound_progs() <= 2:
pass pass
sim.remove() simdev.remove()
end = time.time() end = time.time()
ret, _ = cmd_result(tc_proc, fail=False) ret, _ = cmd_result(tc_proc, fail=False)
time_diff = end - start time_diff = end - start
@ -1080,7 +1146,8 @@ try:
clean_up() clean_up()
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
map_obj = bpf_obj("sample_map_ret0.o") map_obj = bpf_obj("sample_map_ret0.o")
start_test("Test loading program with maps...") start_test("Test loading program with maps...")
sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON 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") prog_file, _ = pin_prog("/sys/fs/bpf/tmp_prog")
map_file, _ = pin_map("/sys/fs/bpf/tmp_map", idx=1, expected=2) 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)...") start_test("Test bpftool bound info reporting (removed dev)...")
check_dev_info_removed(prog_file=prog_file, map_file=map_file) check_dev_info_removed(prog_file=prog_file, map_file=map_file)
@ -1111,7 +1178,8 @@ try:
clean_up() clean_up()
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
start_test("Test map update (no flags)...") start_test("Test map update (no flags)...")
sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON
@ -1192,27 +1260,29 @@ try:
start_test("Test map remove...") start_test("Test map remove...")
sim.unset_xdp("offload") sim.unset_xdp("offload")
bpftool_map_list_wait(expected=0) 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.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON
sim.remove() simdev.remove()
bpftool_map_list_wait(expected=0) bpftool_map_list_wait(expected=0)
start_test("Test map creation fail path...") start_test("Test map creation fail path...")
sim = NetdevSim() simdev = NetdevSimDev()
sim, = simdev.nsims
sim.dfs["bpf_map_accept"] = "N" sim.dfs["bpf_map_accept"] = "N"
ret, _ = sim.set_xdp(map_obj, "offload", JSON=False, fail=False) ret, _ = sim.set_xdp(map_obj, "offload", JSON=False, fail=False)
fail(ret == 0, fail(ret == 0,
"netdevsim didn't refuse to create a map with offload disabled") "netdevsim didn't refuse to create a map with offload disabled")
sim.remove() simdev.remove()
start_test("Test multi-dev ASIC program reuse...") start_test("Test multi-dev ASIC program reuse...")
simA = NetdevSim() simdevA = NetdevSimDev()
simB1 = NetdevSim() simA, = simdevA.nsims
simB2 = NetdevSim(link=simB1) simdevB = NetdevSimDev(3)
simB3 = NetdevSim(link=simB1) simB1, simB2, simB3 = simdevB.nsims
sims = (simA, simB1, simB2, simB3) sims = (simA, simB1, simB2, simB3)
simB = (simB1, simB2, simB3) simB = (simB1, simB2, simB3)
@ -1224,13 +1294,13 @@ try:
progB = bpf_pinned("/sys/fs/bpf/nsimB") progB = bpf_pinned("/sys/fs/bpf/nsimB")
simA.set_xdp(progA, "offload", JSON=False) simA.set_xdp(progA, "offload", JSON=False)
for d in simB: for d in simdevB.nsims:
d.set_xdp(progB, "offload", JSON=False) d.set_xdp(progB, "offload", JSON=False)
start_test("Test multi-dev ASIC cross-dev replace...") start_test("Test multi-dev ASIC cross-dev replace...")
ret, _ = simA.set_xdp(progB, "offload", force=True, JSON=False, fail=False) ret, _ = simA.set_xdp(progB, "offload", force=True, JSON=False, fail=False)
fail(ret == 0, "cross-ASIC program allowed") 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) ret, _ = d.set_xdp(progA, "offload", force=True, JSON=False, fail=False)
fail(ret == 0, "cross-ASIC program allowed") fail(ret == 0, "cross-ASIC program allowed")
@ -1242,7 +1312,7 @@ try:
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "cross-ASIC program allowed") fail(ret == 0, "cross-ASIC program allowed")
check_extack_nsim(err, "program bound to different dev.", args) 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, ret, _, err = d.set_xdp(progA, "offload", force=True, JSON=False,
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "cross-ASIC program allowed") fail(ret == 0, "cross-ASIC program allowed")
@ -1279,7 +1349,7 @@ try:
start_test("Test multi-dev ASIC cross-dev destruction...") start_test("Test multi-dev ASIC cross-dev destruction...")
bpftool_prog_list_wait(expected=2) bpftool_prog_list_wait(expected=2)
simA.remove() simdevA.remove()
bpftool_prog_list_wait(expected=1) bpftool_prog_list_wait(expected=1)
ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"] ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
@ -1297,6 +1367,7 @@ try:
fail(ifnameB != simB3['ifname'], "program not bound to remaining device") fail(ifnameB != simB3['ifname'], "program not bound to remaining device")
simB3.remove() simB3.remove()
simdevB.remove()
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
start_test("Test multi-dev ASIC cross-dev destruction - orphaned...") start_test("Test multi-dev ASIC cross-dev destruction - orphaned...")

View File

@ -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()
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
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