mirror of https://gitee.com/openkylin/linux.git
net: introduce dev_net notifier register/unregister variants
Introduce dev_net variants of netdev notifier register/unregister functions and allow per-net notifier to follow the netdevice into the namespace it is moved to. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1f637703d8
commit
93642e14bd
|
@ -939,6 +939,11 @@ struct netdev_name_node {
|
||||||
int netdev_name_node_alt_create(struct net_device *dev, const char *name);
|
int netdev_name_node_alt_create(struct net_device *dev, const char *name);
|
||||||
int netdev_name_node_alt_destroy(struct net_device *dev, const char *name);
|
int netdev_name_node_alt_destroy(struct net_device *dev, const char *name);
|
||||||
|
|
||||||
|
struct netdev_net_notifier {
|
||||||
|
struct list_head list;
|
||||||
|
struct notifier_block *nb;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure defines the management hooks for network devices.
|
* This structure defines the management hooks for network devices.
|
||||||
* The following hooks can be defined; unless noted otherwise, they are
|
* The following hooks can be defined; unless noted otherwise, they are
|
||||||
|
@ -1793,6 +1798,10 @@ enum netdev_priv_flags {
|
||||||
*
|
*
|
||||||
* @wol_enabled: Wake-on-LAN is enabled
|
* @wol_enabled: Wake-on-LAN is enabled
|
||||||
*
|
*
|
||||||
|
* @net_notifier_list: List of per-net netdev notifier block
|
||||||
|
* that follow this device when it is moved
|
||||||
|
* to another network namespace.
|
||||||
|
*
|
||||||
* FIXME: cleanup struct net_device such that network protocol info
|
* FIXME: cleanup struct net_device such that network protocol info
|
||||||
* moves out.
|
* moves out.
|
||||||
*/
|
*/
|
||||||
|
@ -2085,6 +2094,8 @@ struct net_device {
|
||||||
struct lock_class_key addr_list_lock_key;
|
struct lock_class_key addr_list_lock_key;
|
||||||
bool proto_down;
|
bool proto_down;
|
||||||
unsigned wol_enabled:1;
|
unsigned wol_enabled:1;
|
||||||
|
|
||||||
|
struct list_head net_notifier_list;
|
||||||
};
|
};
|
||||||
#define to_net_dev(d) container_of(d, struct net_device, dev)
|
#define to_net_dev(d) container_of(d, struct net_device, dev)
|
||||||
|
|
||||||
|
@ -2529,6 +2540,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb);
|
||||||
int register_netdevice_notifier_net(struct net *net, struct notifier_block *nb);
|
int register_netdevice_notifier_net(struct net *net, struct notifier_block *nb);
|
||||||
int unregister_netdevice_notifier_net(struct net *net,
|
int unregister_netdevice_notifier_net(struct net *net,
|
||||||
struct notifier_block *nb);
|
struct notifier_block *nb);
|
||||||
|
int register_netdevice_notifier_dev_net(struct net_device *dev,
|
||||||
|
struct notifier_block *nb,
|
||||||
|
struct netdev_net_notifier *nn);
|
||||||
|
int unregister_netdevice_notifier_dev_net(struct net_device *dev,
|
||||||
|
struct notifier_block *nb,
|
||||||
|
struct netdev_net_notifier *nn);
|
||||||
|
|
||||||
struct netdev_notifier_info {
|
struct netdev_notifier_info {
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
|
@ -1874,6 +1874,48 @@ int unregister_netdevice_notifier_net(struct net *net,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(unregister_netdevice_notifier_net);
|
EXPORT_SYMBOL(unregister_netdevice_notifier_net);
|
||||||
|
|
||||||
|
int register_netdevice_notifier_dev_net(struct net_device *dev,
|
||||||
|
struct notifier_block *nb,
|
||||||
|
struct netdev_net_notifier *nn)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
|
err = __register_netdevice_notifier_net(dev_net(dev), nb, false);
|
||||||
|
if (!err) {
|
||||||
|
nn->nb = nb;
|
||||||
|
list_add(&nn->list, &dev->net_notifier_list);
|
||||||
|
}
|
||||||
|
rtnl_unlock();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(register_netdevice_notifier_dev_net);
|
||||||
|
|
||||||
|
int unregister_netdevice_notifier_dev_net(struct net_device *dev,
|
||||||
|
struct notifier_block *nb,
|
||||||
|
struct netdev_net_notifier *nn)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
|
list_del(&nn->list);
|
||||||
|
err = __unregister_netdevice_notifier_net(dev_net(dev), nb);
|
||||||
|
rtnl_unlock();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(unregister_netdevice_notifier_dev_net);
|
||||||
|
|
||||||
|
static void move_netdevice_notifiers_dev_net(struct net_device *dev,
|
||||||
|
struct net *net)
|
||||||
|
{
|
||||||
|
struct netdev_net_notifier *nn;
|
||||||
|
|
||||||
|
list_for_each_entry(nn, &dev->net_notifier_list, list) {
|
||||||
|
__unregister_netdevice_notifier_net(dev_net(dev), nn->nb);
|
||||||
|
__register_netdevice_notifier_net(net, nn->nb, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* call_netdevice_notifiers_info - call all network notifier blocks
|
* call_netdevice_notifiers_info - call all network notifier blocks
|
||||||
* @val: value passed unmodified to notifier function
|
* @val: value passed unmodified to notifier function
|
||||||
|
@ -9786,6 +9828,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
|
||||||
INIT_LIST_HEAD(&dev->adj_list.lower);
|
INIT_LIST_HEAD(&dev->adj_list.lower);
|
||||||
INIT_LIST_HEAD(&dev->ptype_all);
|
INIT_LIST_HEAD(&dev->ptype_all);
|
||||||
INIT_LIST_HEAD(&dev->ptype_specific);
|
INIT_LIST_HEAD(&dev->ptype_specific);
|
||||||
|
INIT_LIST_HEAD(&dev->net_notifier_list);
|
||||||
#ifdef CONFIG_NET_SCHED
|
#ifdef CONFIG_NET_SCHED
|
||||||
hash_init(dev->qdisc_hash);
|
hash_init(dev->qdisc_hash);
|
||||||
#endif
|
#endif
|
||||||
|
@ -10049,6 +10092,9 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
||||||
kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE);
|
kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE);
|
||||||
netdev_adjacent_del_links(dev);
|
netdev_adjacent_del_links(dev);
|
||||||
|
|
||||||
|
/* Move per-net netdevice notifiers that are following the netdevice */
|
||||||
|
move_netdevice_notifiers_dev_net(dev, net);
|
||||||
|
|
||||||
/* Actually switch the network namespace */
|
/* Actually switch the network namespace */
|
||||||
dev_net_set(dev, net);
|
dev_net_set(dev, net);
|
||||||
dev->ifindex = new_ifindex;
|
dev->ifindex = new_ifindex;
|
||||||
|
|
Loading…
Reference in New Issue