aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /net/ipv6/addrconf.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c493
1 files changed, 256 insertions, 237 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1fd0a3d775d2..413054f02aab 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -53,6 +53,7 @@
53#include <linux/route.h> 53#include <linux/route.h>
54#include <linux/inetdevice.h> 54#include <linux/inetdevice.h>
55#include <linux/init.h> 55#include <linux/init.h>
56#include <linux/slab.h>
56#ifdef CONFIG_SYSCTL 57#ifdef CONFIG_SYSCTL
57#include <linux/sysctl.h> 58#include <linux/sysctl.h>
58#endif 59#endif
@@ -278,31 +279,31 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
278 279
279static int snmp6_alloc_dev(struct inet6_dev *idev) 280static int snmp6_alloc_dev(struct inet6_dev *idev)
280{ 281{
281 if (snmp_mib_init((void **)idev->stats.ipv6, 282 if (snmp_mib_init((void __percpu **)idev->stats.ipv6,
282 sizeof(struct ipstats_mib)) < 0) 283 sizeof(struct ipstats_mib)) < 0)
283 goto err_ip; 284 goto err_ip;
284 if (snmp_mib_init((void **)idev->stats.icmpv6, 285 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6,
285 sizeof(struct icmpv6_mib)) < 0) 286 sizeof(struct icmpv6_mib)) < 0)
286 goto err_icmp; 287 goto err_icmp;
287 if (snmp_mib_init((void **)idev->stats.icmpv6msg, 288 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg,
288 sizeof(struct icmpv6msg_mib)) < 0) 289 sizeof(struct icmpv6msg_mib)) < 0)
289 goto err_icmpmsg; 290 goto err_icmpmsg;
290 291
291 return 0; 292 return 0;
292 293
293err_icmpmsg: 294err_icmpmsg:
294 snmp_mib_free((void **)idev->stats.icmpv6); 295 snmp_mib_free((void __percpu **)idev->stats.icmpv6);
295err_icmp: 296err_icmp:
296 snmp_mib_free((void **)idev->stats.ipv6); 297 snmp_mib_free((void __percpu **)idev->stats.ipv6);
297err_ip: 298err_ip:
298 return -ENOMEM; 299 return -ENOMEM;
299} 300}
300 301
301static void snmp6_free_dev(struct inet6_dev *idev) 302static void snmp6_free_dev(struct inet6_dev *idev)
302{ 303{
303 snmp_mib_free((void **)idev->stats.icmpv6msg); 304 snmp_mib_free((void __percpu **)idev->stats.icmpv6msg);
304 snmp_mib_free((void **)idev->stats.icmpv6); 305 snmp_mib_free((void __percpu **)idev->stats.icmpv6);
305 snmp_mib_free((void **)idev->stats.ipv6); 306 snmp_mib_free((void __percpu **)idev->stats.ipv6);
306} 307}
307 308
308/* Nobody refers to this device, we may destroy it. */ 309/* Nobody refers to this device, we may destroy it. */
@@ -481,9 +482,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
481 struct net_device *dev; 482 struct net_device *dev;
482 struct inet6_dev *idev; 483 struct inet6_dev *idev;
483 484
484 read_lock(&dev_base_lock); 485 rcu_read_lock();
485 for_each_netdev(net, dev) { 486 for_each_netdev_rcu(net, dev) {
486 rcu_read_lock();
487 idev = __in6_dev_get(dev); 487 idev = __in6_dev_get(dev);
488 if (idev) { 488 if (idev) {
489 int changed = (!idev->cnf.forwarding) ^ (!newf); 489 int changed = (!idev->cnf.forwarding) ^ (!newf);
@@ -491,9 +491,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
491 if (changed) 491 if (changed)
492 dev_forward_change(idev); 492 dev_forward_change(idev);
493 } 493 }
494 rcu_read_unlock();
495 } 494 }
496 read_unlock(&dev_base_lock); 495 rcu_read_unlock();
497} 496}
498 497
499static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) 498static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
@@ -504,8 +503,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
504 if (p == &net->ipv6.devconf_dflt->forwarding) 503 if (p == &net->ipv6.devconf_dflt->forwarding)
505 return 0; 504 return 0;
506 505
507 if (!rtnl_trylock()) 506 if (!rtnl_trylock()) {
507 /* Restore the original values before restarting */
508 *p = old;
508 return restart_syscall(); 509 return restart_syscall();
510 }
509 511
510 if (p == &net->ipv6.devconf_all->forwarding) { 512 if (p == &net->ipv6.devconf_all->forwarding) {
511 __s32 newf = net->ipv6.devconf_all->forwarding; 513 __s32 newf = net->ipv6.devconf_all->forwarding;
@@ -991,8 +993,7 @@ struct ipv6_saddr_dst {
991 993
992static inline int ipv6_saddr_preferred(int type) 994static inline int ipv6_saddr_preferred(int type)
993{ 995{
994 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4| 996 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|IPV6_ADDR_LOOPBACK))
995 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
996 return 1; 997 return 1;
997 return 0; 998 return 0;
998} 999}
@@ -1137,10 +1138,9 @@ int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
1137 hiscore->rule = -1; 1138 hiscore->rule = -1;
1138 hiscore->ifa = NULL; 1139 hiscore->ifa = NULL;
1139 1140
1140 read_lock(&dev_base_lock);
1141 rcu_read_lock(); 1141 rcu_read_lock();
1142 1142
1143 for_each_netdev(net, dev) { 1143 for_each_netdev_rcu(net, dev) {
1144 struct inet6_dev *idev; 1144 struct inet6_dev *idev;
1145 1145
1146 /* Candidate Source Address (section 4) 1146 /* Candidate Source Address (section 4)
@@ -1235,7 +1235,6 @@ try_nextdev:
1235 read_unlock_bh(&idev->lock); 1235 read_unlock_bh(&idev->lock);
1236 } 1236 }
1237 rcu_read_unlock(); 1237 rcu_read_unlock();
1238 read_unlock(&dev_base_lock);
1239 1238
1240 if (!hiscore->ifa) 1239 if (!hiscore->ifa)
1241 return -EADDRNOTAVAIL; 1240 return -EADDRNOTAVAIL;
@@ -1382,6 +1381,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
1382 if (dad_failed) 1381 if (dad_failed)
1383 ifp->flags |= IFA_F_DADFAILED; 1382 ifp->flags |= IFA_F_DADFAILED;
1384 spin_unlock_bh(&ifp->lock); 1383 spin_unlock_bh(&ifp->lock);
1384 if (dad_failed)
1385 ipv6_ifa_notify(0, ifp);
1385 in6_ifa_put(ifp); 1386 in6_ifa_put(ifp);
1386#ifdef CONFIG_IPV6_PRIVACY 1387#ifdef CONFIG_IPV6_PRIVACY
1387 } else if (ifp->flags&IFA_F_TEMPORARY) { 1388 } else if (ifp->flags&IFA_F_TEMPORARY) {
@@ -2617,7 +2618,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
2617static int addrconf_ifdown(struct net_device *dev, int how) 2618static int addrconf_ifdown(struct net_device *dev, int how)
2618{ 2619{
2619 struct inet6_dev *idev; 2620 struct inet6_dev *idev;
2620 struct inet6_ifaddr *ifa, **bifa; 2621 struct inet6_ifaddr *ifa, *keep_list, **bifa;
2621 struct net *net = dev_net(dev); 2622 struct net *net = dev_net(dev);
2622 int i; 2623 int i;
2623 2624
@@ -2650,11 +2651,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2650 2651
2651 write_lock_bh(&addrconf_hash_lock); 2652 write_lock_bh(&addrconf_hash_lock);
2652 while ((ifa = *bifa) != NULL) { 2653 while ((ifa = *bifa) != NULL) {
2653 if (ifa->idev == idev) { 2654 if (ifa->idev == idev &&
2655 (how || !(ifa->flags&IFA_F_PERMANENT) ||
2656 ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2654 *bifa = ifa->lst_next; 2657 *bifa = ifa->lst_next;
2655 ifa->lst_next = NULL; 2658 ifa->lst_next = NULL;
2656 addrconf_del_timer(ifa); 2659 __in6_ifa_put(ifa);
2657 in6_ifa_put(ifa);
2658 continue; 2660 continue;
2659 } 2661 }
2660 bifa = &ifa->lst_next; 2662 bifa = &ifa->lst_next;
@@ -2690,11 +2692,40 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2690 write_lock_bh(&idev->lock); 2692 write_lock_bh(&idev->lock);
2691 } 2693 }
2692#endif 2694#endif
2695 keep_list = NULL;
2696 bifa = &keep_list;
2693 while ((ifa = idev->addr_list) != NULL) { 2697 while ((ifa = idev->addr_list) != NULL) {
2694 idev->addr_list = ifa->if_next; 2698 idev->addr_list = ifa->if_next;
2695 ifa->if_next = NULL; 2699 ifa->if_next = NULL;
2696 ifa->dead = 1; 2700
2697 addrconf_del_timer(ifa); 2701 addrconf_del_timer(ifa);
2702
2703 /* If just doing link down, and address is permanent
2704 and not link-local, then retain it. */
2705 if (how == 0 &&
2706 (ifa->flags&IFA_F_PERMANENT) &&
2707 !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2708
2709 /* Move to holding list */
2710 *bifa = ifa;
2711 bifa = &ifa->if_next;
2712
2713 /* If not doing DAD on this address, just keep it. */
2714 if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
2715 idev->cnf.accept_dad <= 0 ||
2716 (ifa->flags & IFA_F_NODAD))
2717 continue;
2718
2719 /* If it was tentative already, no need to notify */
2720 if (ifa->flags & IFA_F_TENTATIVE)
2721 continue;
2722
2723 /* Flag it for later restoration when link comes up */
2724 ifa->flags |= IFA_F_TENTATIVE;
2725 in6_ifa_hold(ifa);
2726 } else {
2727 ifa->dead = 1;
2728 }
2698 write_unlock_bh(&idev->lock); 2729 write_unlock_bh(&idev->lock);
2699 2730
2700 __ipv6_ifa_notify(RTM_DELADDR, ifa); 2731 __ipv6_ifa_notify(RTM_DELADDR, ifa);
@@ -2703,6 +2734,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2703 2734
2704 write_lock_bh(&idev->lock); 2735 write_lock_bh(&idev->lock);
2705 } 2736 }
2737
2738 idev->addr_list = keep_list;
2739
2706 write_unlock_bh(&idev->lock); 2740 write_unlock_bh(&idev->lock);
2707 2741
2708 /* Step 5: Discard multicast list */ 2742 /* Step 5: Discard multicast list */
@@ -2728,28 +2762,29 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2728static void addrconf_rs_timer(unsigned long data) 2762static void addrconf_rs_timer(unsigned long data)
2729{ 2763{
2730 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; 2764 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
2765 struct inet6_dev *idev = ifp->idev;
2731 2766
2732 if (ifp->idev->cnf.forwarding) 2767 read_lock(&idev->lock);
2768 if (idev->dead || !(idev->if_flags & IF_READY))
2733 goto out; 2769 goto out;
2734 2770
2735 if (ifp->idev->if_flags & IF_RA_RCVD) { 2771 if (idev->cnf.forwarding)
2736 /* 2772 goto out;
2737 * Announcement received after solicitation 2773
2738 * was sent 2774 /* Announcement received after solicitation was sent */
2739 */ 2775 if (idev->if_flags & IF_RA_RCVD)
2740 goto out; 2776 goto out;
2741 }
2742 2777
2743 spin_lock(&ifp->lock); 2778 spin_lock(&ifp->lock);
2744 if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { 2779 if (ifp->probes++ < idev->cnf.rtr_solicits) {
2745 /* The wait after the last probe can be shorter */ 2780 /* The wait after the last probe can be shorter */
2746 addrconf_mod_timer(ifp, AC_RS, 2781 addrconf_mod_timer(ifp, AC_RS,
2747 (ifp->probes == ifp->idev->cnf.rtr_solicits) ? 2782 (ifp->probes == idev->cnf.rtr_solicits) ?
2748 ifp->idev->cnf.rtr_solicit_delay : 2783 idev->cnf.rtr_solicit_delay :
2749 ifp->idev->cnf.rtr_solicit_interval); 2784 idev->cnf.rtr_solicit_interval);
2750 spin_unlock(&ifp->lock); 2785 spin_unlock(&ifp->lock);
2751 2786
2752 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); 2787 ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
2753 } else { 2788 } else {
2754 spin_unlock(&ifp->lock); 2789 spin_unlock(&ifp->lock);
2755 /* 2790 /*
@@ -2757,10 +2792,11 @@ static void addrconf_rs_timer(unsigned long data)
2757 * assumption any longer. 2792 * assumption any longer.
2758 */ 2793 */
2759 printk(KERN_DEBUG "%s: no IPv6 routers present\n", 2794 printk(KERN_DEBUG "%s: no IPv6 routers present\n",
2760 ifp->idev->dev->name); 2795 idev->dev->name);
2761 } 2796 }
2762 2797
2763out: 2798out:
2799 read_unlock(&idev->lock);
2764 in6_ifa_put(ifp); 2800 in6_ifa_put(ifp);
2765} 2801}
2766 2802
@@ -2793,14 +2829,14 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2793 read_lock_bh(&idev->lock); 2829 read_lock_bh(&idev->lock);
2794 if (ifp->dead) 2830 if (ifp->dead)
2795 goto out; 2831 goto out;
2796 spin_lock_bh(&ifp->lock);
2797 2832
2833 spin_lock(&ifp->lock);
2798 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 2834 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
2799 idev->cnf.accept_dad < 1 || 2835 idev->cnf.accept_dad < 1 ||
2800 !(ifp->flags&IFA_F_TENTATIVE) || 2836 !(ifp->flags&IFA_F_TENTATIVE) ||
2801 ifp->flags & IFA_F_NODAD) { 2837 ifp->flags & IFA_F_NODAD) {
2802 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); 2838 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
2803 spin_unlock_bh(&ifp->lock); 2839 spin_unlock(&ifp->lock);
2804 read_unlock_bh(&idev->lock); 2840 read_unlock_bh(&idev->lock);
2805 2841
2806 addrconf_dad_completed(ifp); 2842 addrconf_dad_completed(ifp);
@@ -2808,7 +2844,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2808 } 2844 }
2809 2845
2810 if (!(idev->if_flags & IF_READY)) { 2846 if (!(idev->if_flags & IF_READY)) {
2811 spin_unlock_bh(&ifp->lock); 2847 spin_unlock(&ifp->lock);
2812 read_unlock_bh(&idev->lock); 2848 read_unlock_bh(&idev->lock);
2813 /* 2849 /*
2814 * If the device is not ready: 2850 * If the device is not ready:
@@ -2828,7 +2864,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2828 ip6_ins_rt(ifp->rt); 2864 ip6_ins_rt(ifp->rt);
2829 2865
2830 addrconf_dad_kick(ifp); 2866 addrconf_dad_kick(ifp);
2831 spin_unlock_bh(&ifp->lock); 2867 spin_unlock(&ifp->lock);
2832out: 2868out:
2833 read_unlock_bh(&idev->lock); 2869 read_unlock_bh(&idev->lock);
2834} 2870}
@@ -2839,20 +2875,21 @@ static void addrconf_dad_timer(unsigned long data)
2839 struct inet6_dev *idev = ifp->idev; 2875 struct inet6_dev *idev = ifp->idev;
2840 struct in6_addr mcaddr; 2876 struct in6_addr mcaddr;
2841 2877
2842 read_lock_bh(&idev->lock); 2878 read_lock(&idev->lock);
2843 if (idev->dead) { 2879 if (idev->dead || !(idev->if_flags & IF_READY)) {
2844 read_unlock_bh(&idev->lock); 2880 read_unlock(&idev->lock);
2845 goto out; 2881 goto out;
2846 } 2882 }
2847 spin_lock_bh(&ifp->lock); 2883
2884 spin_lock(&ifp->lock);
2848 if (ifp->probes == 0) { 2885 if (ifp->probes == 0) {
2849 /* 2886 /*
2850 * DAD was successful 2887 * DAD was successful
2851 */ 2888 */
2852 2889
2853 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); 2890 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
2854 spin_unlock_bh(&ifp->lock); 2891 spin_unlock(&ifp->lock);
2855 read_unlock_bh(&idev->lock); 2892 read_unlock(&idev->lock);
2856 2893
2857 addrconf_dad_completed(ifp); 2894 addrconf_dad_completed(ifp);
2858 2895
@@ -2861,8 +2898,8 @@ static void addrconf_dad_timer(unsigned long data)
2861 2898
2862 ifp->probes--; 2899 ifp->probes--;
2863 addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); 2900 addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
2864 spin_unlock_bh(&ifp->lock); 2901 spin_unlock(&ifp->lock);
2865 read_unlock_bh(&idev->lock); 2902 read_unlock(&idev->lock);
2866 2903
2867 /* send a neighbour solicitation for our addr */ 2904 /* send a neighbour solicitation for our addr */
2868 addrconf_addr_solict_mult(&ifp->addr, &mcaddr); 2905 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
@@ -2909,12 +2946,12 @@ static void addrconf_dad_run(struct inet6_dev *idev) {
2909 2946
2910 read_lock_bh(&idev->lock); 2947 read_lock_bh(&idev->lock);
2911 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) { 2948 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
2912 spin_lock_bh(&ifp->lock); 2949 spin_lock(&ifp->lock);
2913 if (!(ifp->flags & IFA_F_TENTATIVE)) { 2950 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2914 spin_unlock_bh(&ifp->lock); 2951 spin_unlock(&ifp->lock);
2915 continue; 2952 continue;
2916 } 2953 }
2917 spin_unlock_bh(&ifp->lock); 2954 spin_unlock(&ifp->lock);
2918 addrconf_dad_kick(ifp); 2955 addrconf_dad_kick(ifp);
2919 } 2956 }
2920 read_unlock_bh(&idev->lock); 2957 read_unlock_bh(&idev->lock);
@@ -3031,14 +3068,14 @@ static const struct file_operations if6_fops = {
3031 .release = seq_release_net, 3068 .release = seq_release_net,
3032}; 3069};
3033 3070
3034static int if6_proc_net_init(struct net *net) 3071static int __net_init if6_proc_net_init(struct net *net)
3035{ 3072{
3036 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops)) 3073 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
3037 return -ENOMEM; 3074 return -ENOMEM;
3038 return 0; 3075 return 0;
3039} 3076}
3040 3077
3041static void if6_proc_net_exit(struct net *net) 3078static void __net_exit if6_proc_net_exit(struct net *net)
3042{ 3079{
3043 proc_net_remove(net, "if_inet6"); 3080 proc_net_remove(net, "if_inet6");
3044} 3081}
@@ -3485,85 +3522,114 @@ enum addr_type_t
3485 ANYCAST_ADDR, 3522 ANYCAST_ADDR,
3486}; 3523};
3487 3524
3525/* called with rcu_read_lock() */
3526static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3527 struct netlink_callback *cb, enum addr_type_t type,
3528 int s_ip_idx, int *p_ip_idx)
3529{
3530 struct inet6_ifaddr *ifa;
3531 struct ifmcaddr6 *ifmca;
3532 struct ifacaddr6 *ifaca;
3533 int err = 1;
3534 int ip_idx = *p_ip_idx;
3535
3536 read_lock_bh(&idev->lock);
3537 switch (type) {
3538 case UNICAST_ADDR:
3539 /* unicast address incl. temp addr */
3540 for (ifa = idev->addr_list; ifa;
3541 ifa = ifa->if_next, ip_idx++) {
3542 if (ip_idx < s_ip_idx)
3543 continue;
3544 err = inet6_fill_ifaddr(skb, ifa,
3545 NETLINK_CB(cb->skb).pid,
3546 cb->nlh->nlmsg_seq,
3547 RTM_NEWADDR,
3548 NLM_F_MULTI);
3549 if (err <= 0)
3550 break;
3551 }
3552 break;
3553 case MULTICAST_ADDR:
3554 /* multicast address */
3555 for (ifmca = idev->mc_list; ifmca;
3556 ifmca = ifmca->next, ip_idx++) {
3557 if (ip_idx < s_ip_idx)
3558 continue;
3559 err = inet6_fill_ifmcaddr(skb, ifmca,
3560 NETLINK_CB(cb->skb).pid,
3561 cb->nlh->nlmsg_seq,
3562 RTM_GETMULTICAST,
3563 NLM_F_MULTI);
3564 if (err <= 0)
3565 break;
3566 }
3567 break;
3568 case ANYCAST_ADDR:
3569 /* anycast address */
3570 for (ifaca = idev->ac_list; ifaca;
3571 ifaca = ifaca->aca_next, ip_idx++) {
3572 if (ip_idx < s_ip_idx)
3573 continue;
3574 err = inet6_fill_ifacaddr(skb, ifaca,
3575 NETLINK_CB(cb->skb).pid,
3576 cb->nlh->nlmsg_seq,
3577 RTM_GETANYCAST,
3578 NLM_F_MULTI);
3579 if (err <= 0)
3580 break;
3581 }
3582 break;
3583 default:
3584 break;
3585 }
3586 read_unlock_bh(&idev->lock);
3587 *p_ip_idx = ip_idx;
3588 return err;
3589}
3590
3488static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, 3591static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
3489 enum addr_type_t type) 3592 enum addr_type_t type)
3490{ 3593{
3594 struct net *net = sock_net(skb->sk);
3595 int h, s_h;
3491 int idx, ip_idx; 3596 int idx, ip_idx;
3492 int s_idx, s_ip_idx; 3597 int s_idx, s_ip_idx;
3493 int err = 1;
3494 struct net_device *dev; 3598 struct net_device *dev;
3495 struct inet6_dev *idev = NULL; 3599 struct inet6_dev *idev;
3496 struct inet6_ifaddr *ifa; 3600 struct hlist_head *head;
3497 struct ifmcaddr6 *ifmca; 3601 struct hlist_node *node;
3498 struct ifacaddr6 *ifaca;
3499 struct net *net = sock_net(skb->sk);
3500 3602
3501 s_idx = cb->args[0]; 3603 s_h = cb->args[0];
3502 s_ip_idx = ip_idx = cb->args[1]; 3604 s_idx = idx = cb->args[1];
3605 s_ip_idx = ip_idx = cb->args[2];
3503 3606
3504 idx = 0; 3607 rcu_read_lock();
3505 for_each_netdev(net, dev) { 3608 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3506 if (idx < s_idx) 3609 idx = 0;
3507 goto cont; 3610 head = &net->dev_index_head[h];
3508 if (idx > s_idx) 3611 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3509 s_ip_idx = 0; 3612 if (idx < s_idx)
3510 ip_idx = 0; 3613 goto cont;
3511 if ((idev = in6_dev_get(dev)) == NULL) 3614 if (h > s_h || idx > s_idx)
3512 goto cont; 3615 s_ip_idx = 0;
3513 read_lock_bh(&idev->lock); 3616 ip_idx = 0;
3514 switch (type) { 3617 if ((idev = __in6_dev_get(dev)) == NULL)
3515 case UNICAST_ADDR: 3618 goto cont;
3516 /* unicast address incl. temp addr */ 3619
3517 for (ifa = idev->addr_list; ifa; 3620 if (in6_dump_addrs(idev, skb, cb, type,
3518 ifa = ifa->if_next, ip_idx++) { 3621 s_ip_idx, &ip_idx) <= 0)
3519 if (ip_idx < s_ip_idx) 3622 goto done;
3520 continue;
3521 err = inet6_fill_ifaddr(skb, ifa,
3522 NETLINK_CB(cb->skb).pid,
3523 cb->nlh->nlmsg_seq,
3524 RTM_NEWADDR,
3525 NLM_F_MULTI);
3526 }
3527 break;
3528 case MULTICAST_ADDR:
3529 /* multicast address */
3530 for (ifmca = idev->mc_list; ifmca;
3531 ifmca = ifmca->next, ip_idx++) {
3532 if (ip_idx < s_ip_idx)
3533 continue;
3534 err = inet6_fill_ifmcaddr(skb, ifmca,
3535 NETLINK_CB(cb->skb).pid,
3536 cb->nlh->nlmsg_seq,
3537 RTM_GETMULTICAST,
3538 NLM_F_MULTI);
3539 }
3540 break;
3541 case ANYCAST_ADDR:
3542 /* anycast address */
3543 for (ifaca = idev->ac_list; ifaca;
3544 ifaca = ifaca->aca_next, ip_idx++) {
3545 if (ip_idx < s_ip_idx)
3546 continue;
3547 err = inet6_fill_ifacaddr(skb, ifaca,
3548 NETLINK_CB(cb->skb).pid,
3549 cb->nlh->nlmsg_seq,
3550 RTM_GETANYCAST,
3551 NLM_F_MULTI);
3552 }
3553 break;
3554 default:
3555 break;
3556 }
3557 read_unlock_bh(&idev->lock);
3558 in6_dev_put(idev);
3559
3560 if (err <= 0)
3561 break;
3562cont: 3623cont:
3563 idx++; 3624 idx++;
3625 }
3564 } 3626 }
3565 cb->args[0] = idx; 3627done:
3566 cb->args[1] = ip_idx; 3628 rcu_read_unlock();
3629 cb->args[0] = h;
3630 cb->args[1] = idx;
3631 cb->args[2] = ip_idx;
3632
3567 return skb->len; 3633 return skb->len;
3568} 3634}
3569 3635
@@ -3708,6 +3774,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3708#endif 3774#endif
3709 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; 3775 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
3710 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; 3776 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
3777 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
3711} 3778}
3712 3779
3713static inline size_t inet6_if_nlmsg_size(void) 3780static inline size_t inet6_if_nlmsg_size(void)
@@ -3726,8 +3793,8 @@ static inline size_t inet6_if_nlmsg_size(void)
3726 ); 3793 );
3727} 3794}
3728 3795
3729static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items, 3796static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
3730 int bytes) 3797 int items, int bytes)
3731{ 3798{
3732 int i; 3799 int i;
3733 int pad = bytes - sizeof(u64) * items; 3800 int pad = bytes - sizeof(u64) * items;
@@ -3746,10 +3813,10 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3746{ 3813{
3747 switch(attrtype) { 3814 switch(attrtype) {
3748 case IFLA_INET6_STATS: 3815 case IFLA_INET6_STATS:
3749 __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); 3816 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3750 break; 3817 break;
3751 case IFLA_INET6_ICMP6STATS: 3818 case IFLA_INET6_ICMP6STATS:
3752 __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); 3819 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3753 break; 3820 break;
3754 } 3821 }
3755} 3822}
@@ -3826,28 +3893,39 @@ nla_put_failure:
3826static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3893static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3827{ 3894{
3828 struct net *net = sock_net(skb->sk); 3895 struct net *net = sock_net(skb->sk);
3829 int idx, err; 3896 int h, s_h;
3830 int s_idx = cb->args[0]; 3897 int idx = 0, s_idx;
3831 struct net_device *dev; 3898 struct net_device *dev;
3832 struct inet6_dev *idev; 3899 struct inet6_dev *idev;
3900 struct hlist_head *head;
3901 struct hlist_node *node;
3833 3902
3834 read_lock(&dev_base_lock); 3903 s_h = cb->args[0];
3835 idx = 0; 3904 s_idx = cb->args[1];
3836 for_each_netdev(net, dev) { 3905
3837 if (idx < s_idx) 3906 rcu_read_lock();
3838 goto cont; 3907 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3839 if ((idev = in6_dev_get(dev)) == NULL) 3908 idx = 0;
3840 goto cont; 3909 head = &net->dev_index_head[h];
3841 err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, 3910 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3842 cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); 3911 if (idx < s_idx)
3843 in6_dev_put(idev); 3912 goto cont;
3844 if (err <= 0) 3913 idev = __in6_dev_get(dev);
3845 break; 3914 if (!idev)
3915 goto cont;
3916 if (inet6_fill_ifinfo(skb, idev,
3917 NETLINK_CB(cb->skb).pid,
3918 cb->nlh->nlmsg_seq,
3919 RTM_NEWLINK, NLM_F_MULTI) <= 0)
3920 goto out;
3846cont: 3921cont:
3847 idx++; 3922 idx++;
3923 }
3848 } 3924 }
3849 read_unlock(&dev_base_lock); 3925out:
3850 cb->args[0] = idx; 3926 rcu_read_unlock();
3927 cb->args[1] = idx;
3928 cb->args[0] = h;
3851 3929
3852 return skb->len; 3930 return skb->len;
3853} 3931}
@@ -3991,50 +4069,18 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
3991{ 4069{
3992 int *valp = ctl->data; 4070 int *valp = ctl->data;
3993 int val = *valp; 4071 int val = *valp;
4072 loff_t pos = *ppos;
3994 int ret; 4073 int ret;
3995 4074
3996 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4075 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
3997 4076
3998 if (write) 4077 if (write)
3999 ret = addrconf_fixup_forwarding(ctl, valp, val); 4078 ret = addrconf_fixup_forwarding(ctl, valp, val);
4079 if (ret)
4080 *ppos = pos;
4000 return ret; 4081 return ret;
4001} 4082}
4002 4083
4003static int addrconf_sysctl_forward_strategy(ctl_table *table,
4004 void __user *oldval,
4005 size_t __user *oldlenp,
4006 void __user *newval, size_t newlen)
4007{
4008 int *valp = table->data;
4009 int val = *valp;
4010 int new;
4011
4012 if (!newval || !newlen)
4013 return 0;
4014 if (newlen != sizeof(int))
4015 return -EINVAL;
4016 if (get_user(new, (int __user *)newval))
4017 return -EFAULT;
4018 if (new == *valp)
4019 return 0;
4020 if (oldval && oldlenp) {
4021 size_t len;
4022 if (get_user(len, oldlenp))
4023 return -EFAULT;
4024 if (len) {
4025 if (len > table->maxlen)
4026 len = table->maxlen;
4027 if (copy_to_user(oldval, valp, len))
4028 return -EFAULT;
4029 if (put_user(len, oldlenp))
4030 return -EFAULT;
4031 }
4032 }
4033
4034 *valp = new;
4035 return addrconf_fixup_forwarding(table, valp, val);
4036}
4037
4038static void dev_disable_change(struct inet6_dev *idev) 4084static void dev_disable_change(struct inet6_dev *idev)
4039{ 4085{
4040 if (!idev || !idev->dev) 4086 if (!idev || !idev->dev)
@@ -4051,9 +4097,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
4051 struct net_device *dev; 4097 struct net_device *dev;
4052 struct inet6_dev *idev; 4098 struct inet6_dev *idev;
4053 4099
4054 read_lock(&dev_base_lock); 4100 rcu_read_lock();
4055 for_each_netdev(net, dev) { 4101 for_each_netdev_rcu(net, dev) {
4056 rcu_read_lock();
4057 idev = __in6_dev_get(dev); 4102 idev = __in6_dev_get(dev);
4058 if (idev) { 4103 if (idev) {
4059 int changed = (!idev->cnf.disable_ipv6) ^ (!newf); 4104 int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
@@ -4061,9 +4106,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
4061 if (changed) 4106 if (changed)
4062 dev_disable_change(idev); 4107 dev_disable_change(idev);
4063 } 4108 }
4064 rcu_read_unlock();
4065 } 4109 }
4066 read_unlock(&dev_base_lock); 4110 rcu_read_unlock();
4067} 4111}
4068 4112
4069static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) 4113static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
@@ -4075,8 +4119,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
4075 if (p == &net->ipv6.devconf_dflt->disable_ipv6) 4119 if (p == &net->ipv6.devconf_dflt->disable_ipv6)
4076 return 0; 4120 return 0;
4077 4121
4078 if (!rtnl_trylock()) 4122 if (!rtnl_trylock()) {
4123 /* Restore the original values before restarting */
4124 *p = old;
4079 return restart_syscall(); 4125 return restart_syscall();
4126 }
4080 4127
4081 if (p == &net->ipv6.devconf_all->disable_ipv6) { 4128 if (p == &net->ipv6.devconf_all->disable_ipv6) {
4082 __s32 newf = net->ipv6.devconf_all->disable_ipv6; 4129 __s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@ -4095,12 +4142,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
4095{ 4142{
4096 int *valp = ctl->data; 4143 int *valp = ctl->data;
4097 int val = *valp; 4144 int val = *valp;
4145 loff_t pos = *ppos;
4098 int ret; 4146 int ret;
4099 4147
4100 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4148 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
4101 4149
4102 if (write) 4150 if (write)
4103 ret = addrconf_disable_ipv6(ctl, valp, val); 4151 ret = addrconf_disable_ipv6(ctl, valp, val);
4152 if (ret)
4153 *ppos = pos;
4104 return ret; 4154 return ret;
4105} 4155}
4106 4156
@@ -4113,16 +4163,13 @@ static struct addrconf_sysctl_table
4113 .sysctl_header = NULL, 4163 .sysctl_header = NULL,
4114 .addrconf_vars = { 4164 .addrconf_vars = {
4115 { 4165 {
4116 .ctl_name = NET_IPV6_FORWARDING,
4117 .procname = "forwarding", 4166 .procname = "forwarding",
4118 .data = &ipv6_devconf.forwarding, 4167 .data = &ipv6_devconf.forwarding,
4119 .maxlen = sizeof(int), 4168 .maxlen = sizeof(int),
4120 .mode = 0644, 4169 .mode = 0644,
4121 .proc_handler = addrconf_sysctl_forward, 4170 .proc_handler = addrconf_sysctl_forward,
4122 .strategy = addrconf_sysctl_forward_strategy,
4123 }, 4171 },
4124 { 4172 {
4125 .ctl_name = NET_IPV6_HOP_LIMIT,
4126 .procname = "hop_limit", 4173 .procname = "hop_limit",
4127 .data = &ipv6_devconf.hop_limit, 4174 .data = &ipv6_devconf.hop_limit,
4128 .maxlen = sizeof(int), 4175 .maxlen = sizeof(int),
@@ -4130,7 +4177,6 @@ static struct addrconf_sysctl_table
4130 .proc_handler = proc_dointvec, 4177 .proc_handler = proc_dointvec,
4131 }, 4178 },
4132 { 4179 {
4133 .ctl_name = NET_IPV6_MTU,
4134 .procname = "mtu", 4180 .procname = "mtu",
4135 .data = &ipv6_devconf.mtu6, 4181 .data = &ipv6_devconf.mtu6,
4136 .maxlen = sizeof(int), 4182 .maxlen = sizeof(int),
@@ -4138,7 +4184,6 @@ static struct addrconf_sysctl_table
4138 .proc_handler = proc_dointvec, 4184 .proc_handler = proc_dointvec,
4139 }, 4185 },
4140 { 4186 {
4141 .ctl_name = NET_IPV6_ACCEPT_RA,
4142 .procname = "accept_ra", 4187 .procname = "accept_ra",
4143 .data = &ipv6_devconf.accept_ra, 4188 .data = &ipv6_devconf.accept_ra,
4144 .maxlen = sizeof(int), 4189 .maxlen = sizeof(int),
@@ -4146,7 +4191,6 @@ static struct addrconf_sysctl_table
4146 .proc_handler = proc_dointvec, 4191 .proc_handler = proc_dointvec,
4147 }, 4192 },
4148 { 4193 {
4149 .ctl_name = NET_IPV6_ACCEPT_REDIRECTS,
4150 .procname = "accept_redirects", 4194 .procname = "accept_redirects",
4151 .data = &ipv6_devconf.accept_redirects, 4195 .data = &ipv6_devconf.accept_redirects,
4152 .maxlen = sizeof(int), 4196 .maxlen = sizeof(int),
@@ -4154,7 +4198,6 @@ static struct addrconf_sysctl_table
4154 .proc_handler = proc_dointvec, 4198 .proc_handler = proc_dointvec,
4155 }, 4199 },
4156 { 4200 {
4157 .ctl_name = NET_IPV6_AUTOCONF,
4158 .procname = "autoconf", 4201 .procname = "autoconf",
4159 .data = &ipv6_devconf.autoconf, 4202 .data = &ipv6_devconf.autoconf,
4160 .maxlen = sizeof(int), 4203 .maxlen = sizeof(int),
@@ -4162,7 +4205,6 @@ static struct addrconf_sysctl_table
4162 .proc_handler = proc_dointvec, 4205 .proc_handler = proc_dointvec,
4163 }, 4206 },
4164 { 4207 {
4165 .ctl_name = NET_IPV6_DAD_TRANSMITS,
4166 .procname = "dad_transmits", 4208 .procname = "dad_transmits",
4167 .data = &ipv6_devconf.dad_transmits, 4209 .data = &ipv6_devconf.dad_transmits,
4168 .maxlen = sizeof(int), 4210 .maxlen = sizeof(int),
@@ -4170,7 +4212,6 @@ static struct addrconf_sysctl_table
4170 .proc_handler = proc_dointvec, 4212 .proc_handler = proc_dointvec,
4171 }, 4213 },
4172 { 4214 {
4173 .ctl_name = NET_IPV6_RTR_SOLICITS,
4174 .procname = "router_solicitations", 4215 .procname = "router_solicitations",
4175 .data = &ipv6_devconf.rtr_solicits, 4216 .data = &ipv6_devconf.rtr_solicits,
4176 .maxlen = sizeof(int), 4217 .maxlen = sizeof(int),
@@ -4178,25 +4219,20 @@ static struct addrconf_sysctl_table
4178 .proc_handler = proc_dointvec, 4219 .proc_handler = proc_dointvec,
4179 }, 4220 },
4180 { 4221 {
4181 .ctl_name = NET_IPV6_RTR_SOLICIT_INTERVAL,
4182 .procname = "router_solicitation_interval", 4222 .procname = "router_solicitation_interval",
4183 .data = &ipv6_devconf.rtr_solicit_interval, 4223 .data = &ipv6_devconf.rtr_solicit_interval,
4184 .maxlen = sizeof(int), 4224 .maxlen = sizeof(int),
4185 .mode = 0644, 4225 .mode = 0644,
4186 .proc_handler = proc_dointvec_jiffies, 4226 .proc_handler = proc_dointvec_jiffies,
4187 .strategy = sysctl_jiffies,
4188 }, 4227 },
4189 { 4228 {
4190 .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY,
4191 .procname = "router_solicitation_delay", 4229 .procname = "router_solicitation_delay",
4192 .data = &ipv6_devconf.rtr_solicit_delay, 4230 .data = &ipv6_devconf.rtr_solicit_delay,
4193 .maxlen = sizeof(int), 4231 .maxlen = sizeof(int),
4194 .mode = 0644, 4232 .mode = 0644,
4195 .proc_handler = proc_dointvec_jiffies, 4233 .proc_handler = proc_dointvec_jiffies,
4196 .strategy = sysctl_jiffies,
4197 }, 4234 },
4198 { 4235 {
4199 .ctl_name = NET_IPV6_FORCE_MLD_VERSION,
4200 .procname = "force_mld_version", 4236 .procname = "force_mld_version",
4201 .data = &ipv6_devconf.force_mld_version, 4237 .data = &ipv6_devconf.force_mld_version,
4202 .maxlen = sizeof(int), 4238 .maxlen = sizeof(int),
@@ -4205,7 +4241,6 @@ static struct addrconf_sysctl_table
4205 }, 4241 },
4206#ifdef CONFIG_IPV6_PRIVACY 4242#ifdef CONFIG_IPV6_PRIVACY
4207 { 4243 {
4208 .ctl_name = NET_IPV6_USE_TEMPADDR,
4209 .procname = "use_tempaddr", 4244 .procname = "use_tempaddr",
4210 .data = &ipv6_devconf.use_tempaddr, 4245 .data = &ipv6_devconf.use_tempaddr,
4211 .maxlen = sizeof(int), 4246 .maxlen = sizeof(int),
@@ -4213,7 +4248,6 @@ static struct addrconf_sysctl_table
4213 .proc_handler = proc_dointvec, 4248 .proc_handler = proc_dointvec,
4214 }, 4249 },
4215 { 4250 {
4216 .ctl_name = NET_IPV6_TEMP_VALID_LFT,
4217 .procname = "temp_valid_lft", 4251 .procname = "temp_valid_lft",
4218 .data = &ipv6_devconf.temp_valid_lft, 4252 .data = &ipv6_devconf.temp_valid_lft,
4219 .maxlen = sizeof(int), 4253 .maxlen = sizeof(int),
@@ -4221,7 +4255,6 @@ static struct addrconf_sysctl_table
4221 .proc_handler = proc_dointvec, 4255 .proc_handler = proc_dointvec,
4222 }, 4256 },
4223 { 4257 {
4224 .ctl_name = NET_IPV6_TEMP_PREFERED_LFT,
4225 .procname = "temp_prefered_lft", 4258 .procname = "temp_prefered_lft",
4226 .data = &ipv6_devconf.temp_prefered_lft, 4259 .data = &ipv6_devconf.temp_prefered_lft,
4227 .maxlen = sizeof(int), 4260 .maxlen = sizeof(int),
@@ -4229,7 +4262,6 @@ static struct addrconf_sysctl_table
4229 .proc_handler = proc_dointvec, 4262 .proc_handler = proc_dointvec,
4230 }, 4263 },
4231 { 4264 {
4232 .ctl_name = NET_IPV6_REGEN_MAX_RETRY,
4233 .procname = "regen_max_retry", 4265 .procname = "regen_max_retry",
4234 .data = &ipv6_devconf.regen_max_retry, 4266 .data = &ipv6_devconf.regen_max_retry,
4235 .maxlen = sizeof(int), 4267 .maxlen = sizeof(int),
@@ -4237,7 +4269,6 @@ static struct addrconf_sysctl_table
4237 .proc_handler = proc_dointvec, 4269 .proc_handler = proc_dointvec,
4238 }, 4270 },
4239 { 4271 {
4240 .ctl_name = NET_IPV6_MAX_DESYNC_FACTOR,
4241 .procname = "max_desync_factor", 4272 .procname = "max_desync_factor",
4242 .data = &ipv6_devconf.max_desync_factor, 4273 .data = &ipv6_devconf.max_desync_factor,
4243 .maxlen = sizeof(int), 4274 .maxlen = sizeof(int),
@@ -4246,7 +4277,6 @@ static struct addrconf_sysctl_table
4246 }, 4277 },
4247#endif 4278#endif
4248 { 4279 {
4249 .ctl_name = NET_IPV6_MAX_ADDRESSES,
4250 .procname = "max_addresses", 4280 .procname = "max_addresses",
4251 .data = &ipv6_devconf.max_addresses, 4281 .data = &ipv6_devconf.max_addresses,
4252 .maxlen = sizeof(int), 4282 .maxlen = sizeof(int),
@@ -4254,7 +4284,6 @@ static struct addrconf_sysctl_table
4254 .proc_handler = proc_dointvec, 4284 .proc_handler = proc_dointvec,
4255 }, 4285 },
4256 { 4286 {
4257 .ctl_name = NET_IPV6_ACCEPT_RA_DEFRTR,
4258 .procname = "accept_ra_defrtr", 4287 .procname = "accept_ra_defrtr",
4259 .data = &ipv6_devconf.accept_ra_defrtr, 4288 .data = &ipv6_devconf.accept_ra_defrtr,
4260 .maxlen = sizeof(int), 4289 .maxlen = sizeof(int),
@@ -4262,7 +4291,6 @@ static struct addrconf_sysctl_table
4262 .proc_handler = proc_dointvec, 4291 .proc_handler = proc_dointvec,
4263 }, 4292 },
4264 { 4293 {
4265 .ctl_name = NET_IPV6_ACCEPT_RA_PINFO,
4266 .procname = "accept_ra_pinfo", 4294 .procname = "accept_ra_pinfo",
4267 .data = &ipv6_devconf.accept_ra_pinfo, 4295 .data = &ipv6_devconf.accept_ra_pinfo,
4268 .maxlen = sizeof(int), 4296 .maxlen = sizeof(int),
@@ -4271,7 +4299,6 @@ static struct addrconf_sysctl_table
4271 }, 4299 },
4272#ifdef CONFIG_IPV6_ROUTER_PREF 4300#ifdef CONFIG_IPV6_ROUTER_PREF
4273 { 4301 {
4274 .ctl_name = NET_IPV6_ACCEPT_RA_RTR_PREF,
4275 .procname = "accept_ra_rtr_pref", 4302 .procname = "accept_ra_rtr_pref",
4276 .data = &ipv6_devconf.accept_ra_rtr_pref, 4303 .data = &ipv6_devconf.accept_ra_rtr_pref,
4277 .maxlen = sizeof(int), 4304 .maxlen = sizeof(int),
@@ -4279,17 +4306,14 @@ static struct addrconf_sysctl_table
4279 .proc_handler = proc_dointvec, 4306 .proc_handler = proc_dointvec,
4280 }, 4307 },
4281 { 4308 {
4282 .ctl_name = NET_IPV6_RTR_PROBE_INTERVAL,
4283 .procname = "router_probe_interval", 4309 .procname = "router_probe_interval",
4284 .data = &ipv6_devconf.rtr_probe_interval, 4310 .data = &ipv6_devconf.rtr_probe_interval,
4285 .maxlen = sizeof(int), 4311 .maxlen = sizeof(int),
4286 .mode = 0644, 4312 .mode = 0644,
4287 .proc_handler = proc_dointvec_jiffies, 4313 .proc_handler = proc_dointvec_jiffies,
4288 .strategy = sysctl_jiffies,
4289 }, 4314 },
4290#ifdef CONFIG_IPV6_ROUTE_INFO 4315#ifdef CONFIG_IPV6_ROUTE_INFO
4291 { 4316 {
4292 .ctl_name = NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,
4293 .procname = "accept_ra_rt_info_max_plen", 4317 .procname = "accept_ra_rt_info_max_plen",
4294 .data = &ipv6_devconf.accept_ra_rt_info_max_plen, 4318 .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
4295 .maxlen = sizeof(int), 4319 .maxlen = sizeof(int),
@@ -4299,7 +4323,6 @@ static struct addrconf_sysctl_table
4299#endif 4323#endif
4300#endif 4324#endif
4301 { 4325 {
4302 .ctl_name = NET_IPV6_PROXY_NDP,
4303 .procname = "proxy_ndp", 4326 .procname = "proxy_ndp",
4304 .data = &ipv6_devconf.proxy_ndp, 4327 .data = &ipv6_devconf.proxy_ndp,
4305 .maxlen = sizeof(int), 4328 .maxlen = sizeof(int),
@@ -4307,7 +4330,6 @@ static struct addrconf_sysctl_table
4307 .proc_handler = proc_dointvec, 4330 .proc_handler = proc_dointvec,
4308 }, 4331 },
4309 { 4332 {
4310 .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
4311 .procname = "accept_source_route", 4333 .procname = "accept_source_route",
4312 .data = &ipv6_devconf.accept_source_route, 4334 .data = &ipv6_devconf.accept_source_route,
4313 .maxlen = sizeof(int), 4335 .maxlen = sizeof(int),
@@ -4316,7 +4338,6 @@ static struct addrconf_sysctl_table
4316 }, 4338 },
4317#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 4339#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
4318 { 4340 {
4319 .ctl_name = CTL_UNNUMBERED,
4320 .procname = "optimistic_dad", 4341 .procname = "optimistic_dad",
4321 .data = &ipv6_devconf.optimistic_dad, 4342 .data = &ipv6_devconf.optimistic_dad,
4322 .maxlen = sizeof(int), 4343 .maxlen = sizeof(int),
@@ -4327,7 +4348,6 @@ static struct addrconf_sysctl_table
4327#endif 4348#endif
4328#ifdef CONFIG_IPV6_MROUTE 4349#ifdef CONFIG_IPV6_MROUTE
4329 { 4350 {
4330 .ctl_name = CTL_UNNUMBERED,
4331 .procname = "mc_forwarding", 4351 .procname = "mc_forwarding",
4332 .data = &ipv6_devconf.mc_forwarding, 4352 .data = &ipv6_devconf.mc_forwarding,
4333 .maxlen = sizeof(int), 4353 .maxlen = sizeof(int),
@@ -4336,16 +4356,13 @@ static struct addrconf_sysctl_table
4336 }, 4356 },
4337#endif 4357#endif
4338 { 4358 {
4339 .ctl_name = CTL_UNNUMBERED,
4340 .procname = "disable_ipv6", 4359 .procname = "disable_ipv6",
4341 .data = &ipv6_devconf.disable_ipv6, 4360 .data = &ipv6_devconf.disable_ipv6,
4342 .maxlen = sizeof(int), 4361 .maxlen = sizeof(int),
4343 .mode = 0644, 4362 .mode = 0644,
4344 .proc_handler = addrconf_sysctl_disable, 4363 .proc_handler = addrconf_sysctl_disable,
4345 .strategy = sysctl_intvec,
4346 }, 4364 },
4347 { 4365 {
4348 .ctl_name = CTL_UNNUMBERED,
4349 .procname = "accept_dad", 4366 .procname = "accept_dad",
4350 .data = &ipv6_devconf.accept_dad, 4367 .data = &ipv6_devconf.accept_dad,
4351 .maxlen = sizeof(int), 4368 .maxlen = sizeof(int),
@@ -4353,13 +4370,20 @@ static struct addrconf_sysctl_table
4353 .proc_handler = proc_dointvec, 4370 .proc_handler = proc_dointvec,
4354 }, 4371 },
4355 { 4372 {
4356 .ctl_name = 0, /* sentinel */ 4373 .procname = "force_tllao",
4374 .data = &ipv6_devconf.force_tllao,
4375 .maxlen = sizeof(int),
4376 .mode = 0644,
4377 .proc_handler = proc_dointvec
4378 },
4379 {
4380 /* sentinel */
4357 } 4381 }
4358 }, 4382 },
4359}; 4383};
4360 4384
4361static int __addrconf_sysctl_register(struct net *net, char *dev_name, 4385static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4362 int ctl_name, struct inet6_dev *idev, struct ipv6_devconf *p) 4386 struct inet6_dev *idev, struct ipv6_devconf *p)
4363{ 4387{
4364 int i; 4388 int i;
4365 struct addrconf_sysctl_table *t; 4389 struct addrconf_sysctl_table *t;
@@ -4367,9 +4391,9 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4367#define ADDRCONF_CTL_PATH_DEV 3 4391#define ADDRCONF_CTL_PATH_DEV 3
4368 4392
4369 struct ctl_path addrconf_ctl_path[] = { 4393 struct ctl_path addrconf_ctl_path[] = {
4370 { .procname = "net", .ctl_name = CTL_NET, }, 4394 { .procname = "net", },
4371 { .procname = "ipv6", .ctl_name = NET_IPV6, }, 4395 { .procname = "ipv6", },
4372 { .procname = "conf", .ctl_name = NET_IPV6_CONF, }, 4396 { .procname = "conf", },
4373 { /* to be set */ }, 4397 { /* to be set */ },
4374 { }, 4398 { },
4375 }; 4399 };
@@ -4395,7 +4419,6 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4395 goto free; 4419 goto free;
4396 4420
4397 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name; 4421 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name;
4398 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].ctl_name = ctl_name;
4399 4422
4400 t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path, 4423 t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path,
4401 t->addrconf_vars); 4424 t->addrconf_vars);
@@ -4429,12 +4452,10 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
4429 4452
4430static void addrconf_sysctl_register(struct inet6_dev *idev) 4453static void addrconf_sysctl_register(struct inet6_dev *idev)
4431{ 4454{
4432 neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6, 4455 neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6",
4433 NET_IPV6_NEIGH, "ipv6", 4456 &ndisc_ifinfo_sysctl_change);
4434 &ndisc_ifinfo_sysctl_change,
4435 ndisc_ifinfo_sysctl_strategy);
4436 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, 4457 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
4437 idev->dev->ifindex, idev, &idev->cnf); 4458 idev, &idev->cnf);
4438} 4459}
4439 4460
4440static void addrconf_sysctl_unregister(struct inet6_dev *idev) 4461static void addrconf_sysctl_unregister(struct inet6_dev *idev)
@@ -4446,7 +4467,7 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
4446 4467
4447#endif 4468#endif
4448 4469
4449static int addrconf_init_net(struct net *net) 4470static int __net_init addrconf_init_net(struct net *net)
4450{ 4471{
4451 int err; 4472 int err;
4452 struct ipv6_devconf *all, *dflt; 4473 struct ipv6_devconf *all, *dflt;
@@ -4455,7 +4476,7 @@ static int addrconf_init_net(struct net *net)
4455 all = &ipv6_devconf; 4476 all = &ipv6_devconf;
4456 dflt = &ipv6_devconf_dflt; 4477 dflt = &ipv6_devconf_dflt;
4457 4478
4458 if (net != &init_net) { 4479 if (!net_eq(net, &init_net)) {
4459 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL); 4480 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
4460 if (all == NULL) 4481 if (all == NULL)
4461 goto err_alloc_all; 4482 goto err_alloc_all;
@@ -4473,13 +4494,11 @@ static int addrconf_init_net(struct net *net)
4473 net->ipv6.devconf_dflt = dflt; 4494 net->ipv6.devconf_dflt = dflt;
4474 4495
4475#ifdef CONFIG_SYSCTL 4496#ifdef CONFIG_SYSCTL
4476 err = __addrconf_sysctl_register(net, "all", NET_PROTO_CONF_ALL, 4497 err = __addrconf_sysctl_register(net, "all", NULL, all);
4477 NULL, all);
4478 if (err < 0) 4498 if (err < 0)
4479 goto err_reg_all; 4499 goto err_reg_all;
4480 4500
4481 err = __addrconf_sysctl_register(net, "default", NET_PROTO_CONF_DEFAULT, 4501 err = __addrconf_sysctl_register(net, "default", NULL, dflt);
4482 NULL, dflt);
4483 if (err < 0) 4502 if (err < 0)
4484 goto err_reg_dflt; 4503 goto err_reg_dflt;
4485#endif 4504#endif
@@ -4497,13 +4516,13 @@ err_alloc_all:
4497 return err; 4516 return err;
4498} 4517}
4499 4518
4500static void addrconf_exit_net(struct net *net) 4519static void __net_exit addrconf_exit_net(struct net *net)
4501{ 4520{
4502#ifdef CONFIG_SYSCTL 4521#ifdef CONFIG_SYSCTL
4503 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt); 4522 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
4504 __addrconf_sysctl_unregister(net->ipv6.devconf_all); 4523 __addrconf_sysctl_unregister(net->ipv6.devconf_all);
4505#endif 4524#endif
4506 if (net != &init_net) { 4525 if (!net_eq(net, &init_net)) {
4507 kfree(net->ipv6.devconf_dflt); 4526 kfree(net->ipv6.devconf_dflt);
4508 kfree(net->ipv6.devconf_all); 4527 kfree(net->ipv6.devconf_all);
4509 } 4528 }