diff options
-rw-r--r-- | net/ipv6/addrconf.c | 63 |
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 |
104 | static void addrconf_sysctl_register(struct inet6_dev *idev); | 104 | static void addrconf_sysctl_register(struct inet6_dev *idev); |
105 | static void addrconf_sysctl_unregister(struct ipv6_devconf *p); | 105 | static void addrconf_sysctl_unregister(struct inet6_dev *idev); |
106 | #else | ||
107 | static inline void addrconf_sysctl_register(struct inet6_dev *idev) | ||
108 | { | ||
109 | } | ||
110 | |||
111 | static 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 | ||
4101 | static 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 | |||
4109 | static void addrconf_sysctl_register(struct inet6_dev *idev) | 4115 | static 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 | ||
4115 | static void addrconf_sysctl_unregister(struct ipv6_devconf *p) | 4125 | static 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(); |