forked from mirrors/linux
		
	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
					
				
					 8 changed files with 238 additions and 197 deletions
				
			
		| 
						 | 
					@ -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 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count)
 | 
				
			||||||
	return ERR_PTR(err);
 | 
						return ERR_PTR(err);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct nsim_bus_dev *nsim_bus_dev_new_with_ns(struct netdevsim *ns)
 | 
					static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct nsim_bus_dev *nsim_bus_dev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dev_hold(ns->netdev);
 | 
					 | 
				
			||||||
	rtnl_unlock();
 | 
					 | 
				
			||||||
	nsim_bus_dev = nsim_bus_dev_new(~0, 0);
 | 
					 | 
				
			||||||
	rtnl_lock();
 | 
					 | 
				
			||||||
	dev_put(ns->netdev);
 | 
					 | 
				
			||||||
	return nsim_bus_dev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	device_unregister(&nsim_bus_dev->dev);
 | 
						device_unregister(&nsim_bus_dev->dev);
 | 
				
			||||||
	ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
 | 
						ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -278,7 +278,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
 | 
				
			||||||
	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 a new issue