mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 08:31:37 +00:00
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:
parent
794b2c05ca
commit
e05b2d141f
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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 @@
|
|||||||
|
|
||||||
#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)
|
||||||
|
@ -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);
|
||||||
|
@ -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...")
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user