[RFC V2 PATCH 12/25] net/netpolicy: NET device hotplug
From: <hidden>
Date: 2016-08-04 19:19:44
Also in:
lkml
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
From: Kan Liang <redacted> Support NET device up/down/namechange in the NET policy code. Signed-off-by: Kan Liang <redacted> --- net/core/netpolicy.c | 66 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 8 deletions(-)
diff --git a/net/core/netpolicy.c b/net/core/netpolicy.c
index 8336106..2a04fcf 100644
--- a/net/core/netpolicy.c
+++ b/net/core/netpolicy.c@@ -684,6 +684,9 @@ static const struct file_operations proc_net_policy_operations = { static int netpolicy_proc_dev_init(struct net *net, struct net_device *dev) { + if (dev->proc_dev) + proc_remove(dev->proc_dev); + dev->proc_dev = proc_net_mkdir(net, dev->name, net->proc_netpolicy); if (!dev->proc_dev) return -ENOMEM;
@@ -750,6 +753,19 @@ void uninit_netpolicy(struct net_device *dev) spin_unlock(&dev->np_lock); } +static void netpolicy_dev_init(struct net *net, + struct net_device *dev) +{ + if (!init_netpolicy(dev)) { +#ifdef CONFIG_PROC_FS + if (netpolicy_proc_dev_init(net, dev)) + uninit_netpolicy(dev); + else +#endif /* CONFIG_PROC_FS */ + pr_info("NETPOLICY: Init net policy for %s\n", dev->name); + } +} + static int __net_init netpolicy_net_init(struct net *net) { struct net_device *dev, *aux;
@@ -762,14 +778,7 @@ static int __net_init netpolicy_net_init(struct net *net) #endif /* CONFIG_PROC_FS */ for_each_netdev_safe(net, dev, aux) { - if (!init_netpolicy(dev)) { -#ifdef CONFIG_PROC_FS - if (netpolicy_proc_dev_init(net, dev)) - uninit_netpolicy(dev); - else -#endif /* CONFIG_PROC_FS */ - pr_info("NETPOLICY: Init net policy for %s\n", dev->name); - } + netpolicy_dev_init(net, dev); } return 0;
@@ -791,17 +800,58 @@ static struct pernet_operations netpolicy_net_ops = { .exit = netpolicy_net_exit, }; +static int netpolicy_notify(struct notifier_block *this, + unsigned long event, + void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + + switch (event) { + case NETDEV_CHANGENAME: +#ifdef CONFIG_PROC_FS + if (dev->proc_dev) { + proc_remove(dev->proc_dev); + if ((netpolicy_proc_dev_init(dev_net(dev), dev) < 0) && + dev->proc_dev) { + proc_remove(dev->proc_dev); + dev->proc_dev = NULL; + } + } +#endif + break; + case NETDEV_UP: + netpolicy_dev_init(dev_net(dev), dev); + break; + case NETDEV_GOING_DOWN: + uninit_netpolicy(dev); +#ifdef CONFIG_PROC_FS + proc_remove(dev->proc_dev); + dev->proc_dev = NULL; +#endif + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block netpolicy_dev_notf = { + .notifier_call = netpolicy_notify, +}; + static int __init netpolicy_init(void) { int ret; ret = register_pernet_subsys(&netpolicy_net_ops); + if (!ret) + register_netdevice_notifier(&netpolicy_dev_notf); return ret; } static void __exit netpolicy_exit(void) { + unregister_netdevice_notifier(&netpolicy_dev_notf); unregister_pernet_subsys(&netpolicy_net_ops); }
--
2.5.5