aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/addrconf.c63
1 files changed, 34 insertions, 29 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6a48bb88f46d..27b35ddeeabf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -102,7 +102,15 @@
102 102
103#ifdef CONFIG_SYSCTL 103#ifdef CONFIG_SYSCTL
104static void addrconf_sysctl_register(struct inet6_dev *idev); 104static void addrconf_sysctl_register(struct inet6_dev *idev);
105static void addrconf_sysctl_unregister(struct ipv6_devconf *p); 105static void addrconf_sysctl_unregister(struct inet6_dev *idev);
106#else
107static inline void addrconf_sysctl_register(struct inet6_dev *idev)
108{
109}
110
111static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
112{
113}
106#endif 114#endif
107 115
108#ifdef CONFIG_IPV6_PRIVACY 116#ifdef CONFIG_IPV6_PRIVACY
@@ -392,13 +400,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
392 400
393 ipv6_mc_init_dev(ndev); 401 ipv6_mc_init_dev(ndev);
394 ndev->tstamp = jiffies; 402 ndev->tstamp = jiffies;
395#ifdef CONFIG_SYSCTL
396 neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6,
397 NET_IPV6_NEIGH, "ipv6",
398 &ndisc_ifinfo_sysctl_change,
399 NULL);
400 addrconf_sysctl_register(ndev); 403 addrconf_sysctl_register(ndev);
401#endif
402 /* protected by rtnl_lock */ 404 /* protected by rtnl_lock */
403 rcu_assign_pointer(dev->ip6_ptr, ndev); 405 rcu_assign_pointer(dev->ip6_ptr, ndev);
404 406
@@ -2391,15 +2393,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2391 case NETDEV_CHANGENAME: 2393 case NETDEV_CHANGENAME:
2392 if (idev) { 2394 if (idev) {
2393 snmp6_unregister_dev(idev); 2395 snmp6_unregister_dev(idev);
2394#ifdef CONFIG_SYSCTL 2396 addrconf_sysctl_unregister(idev);
2395 addrconf_sysctl_unregister(&idev->cnf);
2396 neigh_sysctl_unregister(idev->nd_parms);
2397 neigh_sysctl_register(dev, idev->nd_parms,
2398 NET_IPV6, NET_IPV6_NEIGH, "ipv6",
2399 &ndisc_ifinfo_sysctl_change,
2400 NULL);
2401 addrconf_sysctl_register(idev); 2397 addrconf_sysctl_register(idev);
2402#endif
2403 err = snmp6_register_dev(idev); 2398 err = snmp6_register_dev(idev);
2404 if (err) 2399 if (err)
2405 return notifier_from_errno(err); 2400 return notifier_from_errno(err);
@@ -2523,10 +2518,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2523 /* Shot the device (if unregistered) */ 2518 /* Shot the device (if unregistered) */
2524 2519
2525 if (how == 1) { 2520 if (how == 1) {
2526#ifdef CONFIG_SYSCTL 2521 addrconf_sysctl_unregister(idev);
2527 addrconf_sysctl_unregister(&idev->cnf);
2528 neigh_sysctl_unregister(idev->nd_parms);
2529#endif
2530 neigh_parms_release(&nd_tbl, idev->nd_parms); 2522 neigh_parms_release(&nd_tbl, idev->nd_parms);
2531 neigh_ifdown(&nd_tbl, dev); 2523 neigh_ifdown(&nd_tbl, dev);
2532 in6_dev_put(idev); 2524 in6_dev_put(idev);
@@ -4106,21 +4098,34 @@ out:
4106 return; 4098 return;
4107} 4099}
4108 4100
4101static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
4102{
4103 struct addrconf_sysctl_table *t;
4104
4105 if (p->sysctl == NULL)
4106 return;
4107
4108 t = p->sysctl;
4109 p->sysctl = NULL;
4110 unregister_sysctl_table(t->sysctl_header);
4111 kfree(t->dev_name);
4112 kfree(t);
4113}
4114
4109static void addrconf_sysctl_register(struct inet6_dev *idev) 4115static void addrconf_sysctl_register(struct inet6_dev *idev)
4110{ 4116{
4117 neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6,
4118 NET_IPV6_NEIGH, "ipv6",
4119 &ndisc_ifinfo_sysctl_change,
4120 NULL);
4111 __addrconf_sysctl_register(idev->dev->name, idev->dev->ifindex, 4121 __addrconf_sysctl_register(idev->dev->name, idev->dev->ifindex,
4112 idev, &idev->cnf); 4122 idev, &idev->cnf);
4113} 4123}
4114 4124
4115static void addrconf_sysctl_unregister(struct ipv6_devconf *p) 4125static void addrconf_sysctl_unregister(struct inet6_dev *idev)
4116{ 4126{
4117 if (p->sysctl) { 4127 __addrconf_sysctl_unregister(&idev->cnf);
4118 struct addrconf_sysctl_table *t = p->sysctl; 4128 neigh_sysctl_unregister(idev->nd_parms);
4119 p->sysctl = NULL;
4120 unregister_sysctl_table(t->sysctl_header);
4121 kfree(t->dev_name);
4122 kfree(t);
4123 }
4124} 4129}
4125 4130
4126 4131
@@ -4232,8 +4237,8 @@ void addrconf_cleanup(void)
4232 unregister_netdevice_notifier(&ipv6_dev_notf); 4237 unregister_netdevice_notifier(&ipv6_dev_notf);
4233 4238
4234#ifdef CONFIG_SYSCTL 4239#ifdef CONFIG_SYSCTL
4235 addrconf_sysctl_unregister(&ipv6_devconf_dflt); 4240 __addrconf_sysctl_unregister(&ipv6_devconf_dflt);
4236 addrconf_sysctl_unregister(&ipv6_devconf); 4241 __addrconf_sysctl_unregister(&ipv6_devconf);
4237#endif 4242#endif
4238 4243
4239 rtnl_lock(); 4244 rtnl_lock();