aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c334
1 files changed, 152 insertions, 182 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1fd0a3d775d2..de7a194a64ab 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -481,9 +481,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
481 struct net_device *dev; 481 struct net_device *dev;
482 struct inet6_dev *idev; 482 struct inet6_dev *idev;
483 483
484 read_lock(&dev_base_lock); 484 rcu_read_lock();
485 for_each_netdev(net, dev) { 485 for_each_netdev_rcu(net, dev) {
486 rcu_read_lock();
487 idev = __in6_dev_get(dev); 486 idev = __in6_dev_get(dev);
488 if (idev) { 487 if (idev) {
489 int changed = (!idev->cnf.forwarding) ^ (!newf); 488 int changed = (!idev->cnf.forwarding) ^ (!newf);
@@ -491,9 +490,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
491 if (changed) 490 if (changed)
492 dev_forward_change(idev); 491 dev_forward_change(idev);
493 } 492 }
494 rcu_read_unlock();
495 } 493 }
496 read_unlock(&dev_base_lock); 494 rcu_read_unlock();
497} 495}
498 496
499static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) 497static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
@@ -1137,10 +1135,9 @@ int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
1137 hiscore->rule = -1; 1135 hiscore->rule = -1;
1138 hiscore->ifa = NULL; 1136 hiscore->ifa = NULL;
1139 1137
1140 read_lock(&dev_base_lock);
1141 rcu_read_lock(); 1138 rcu_read_lock();
1142 1139
1143 for_each_netdev(net, dev) { 1140 for_each_netdev_rcu(net, dev) {
1144 struct inet6_dev *idev; 1141 struct inet6_dev *idev;
1145 1142
1146 /* Candidate Source Address (section 4) 1143 /* Candidate Source Address (section 4)
@@ -1235,7 +1232,6 @@ try_nextdev:
1235 read_unlock_bh(&idev->lock); 1232 read_unlock_bh(&idev->lock);
1236 } 1233 }
1237 rcu_read_unlock(); 1234 rcu_read_unlock();
1238 read_unlock(&dev_base_lock);
1239 1235
1240 if (!hiscore->ifa) 1236 if (!hiscore->ifa)
1241 return -EADDRNOTAVAIL; 1237 return -EADDRNOTAVAIL;
@@ -3485,85 +3481,114 @@ enum addr_type_t
3485 ANYCAST_ADDR, 3481 ANYCAST_ADDR,
3486}; 3482};
3487 3483
3484/* called with rcu_read_lock() */
3485static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3486 struct netlink_callback *cb, enum addr_type_t type,
3487 int s_ip_idx, int *p_ip_idx)
3488{
3489 struct inet6_ifaddr *ifa;
3490 struct ifmcaddr6 *ifmca;
3491 struct ifacaddr6 *ifaca;
3492 int err = 1;
3493 int ip_idx = *p_ip_idx;
3494
3495 read_lock_bh(&idev->lock);
3496 switch (type) {
3497 case UNICAST_ADDR:
3498 /* unicast address incl. temp addr */
3499 for (ifa = idev->addr_list; ifa;
3500 ifa = ifa->if_next, ip_idx++) {
3501 if (ip_idx < s_ip_idx)
3502 continue;
3503 err = inet6_fill_ifaddr(skb, ifa,
3504 NETLINK_CB(cb->skb).pid,
3505 cb->nlh->nlmsg_seq,
3506 RTM_NEWADDR,
3507 NLM_F_MULTI);
3508 if (err <= 0)
3509 break;
3510 }
3511 break;
3512 case MULTICAST_ADDR:
3513 /* multicast address */
3514 for (ifmca = idev->mc_list; ifmca;
3515 ifmca = ifmca->next, ip_idx++) {
3516 if (ip_idx < s_ip_idx)
3517 continue;
3518 err = inet6_fill_ifmcaddr(skb, ifmca,
3519 NETLINK_CB(cb->skb).pid,
3520 cb->nlh->nlmsg_seq,
3521 RTM_GETMULTICAST,
3522 NLM_F_MULTI);
3523 if (err <= 0)
3524 break;
3525 }
3526 break;
3527 case ANYCAST_ADDR:
3528 /* anycast address */
3529 for (ifaca = idev->ac_list; ifaca;
3530 ifaca = ifaca->aca_next, ip_idx++) {
3531 if (ip_idx < s_ip_idx)
3532 continue;
3533 err = inet6_fill_ifacaddr(skb, ifaca,
3534 NETLINK_CB(cb->skb).pid,
3535 cb->nlh->nlmsg_seq,
3536 RTM_GETANYCAST,
3537 NLM_F_MULTI);
3538 if (err <= 0)
3539 break;
3540 }
3541 break;
3542 default:
3543 break;
3544 }
3545 read_unlock_bh(&idev->lock);
3546 *p_ip_idx = ip_idx;
3547 return err;
3548}
3549
3488static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, 3550static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
3489 enum addr_type_t type) 3551 enum addr_type_t type)
3490{ 3552{
3553 struct net *net = sock_net(skb->sk);
3554 int h, s_h;
3491 int idx, ip_idx; 3555 int idx, ip_idx;
3492 int s_idx, s_ip_idx; 3556 int s_idx, s_ip_idx;
3493 int err = 1;
3494 struct net_device *dev; 3557 struct net_device *dev;
3495 struct inet6_dev *idev = NULL; 3558 struct inet6_dev *idev;
3496 struct inet6_ifaddr *ifa; 3559 struct hlist_head *head;
3497 struct ifmcaddr6 *ifmca; 3560 struct hlist_node *node;
3498 struct ifacaddr6 *ifaca;
3499 struct net *net = sock_net(skb->sk);
3500 3561
3501 s_idx = cb->args[0]; 3562 s_h = cb->args[0];
3502 s_ip_idx = ip_idx = cb->args[1]; 3563 s_idx = idx = cb->args[1];
3564 s_ip_idx = ip_idx = cb->args[2];
3503 3565
3504 idx = 0; 3566 rcu_read_lock();
3505 for_each_netdev(net, dev) { 3567 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3506 if (idx < s_idx) 3568 idx = 0;
3507 goto cont; 3569 head = &net->dev_index_head[h];
3508 if (idx > s_idx) 3570 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3509 s_ip_idx = 0; 3571 if (idx < s_idx)
3510 ip_idx = 0; 3572 goto cont;
3511 if ((idev = in6_dev_get(dev)) == NULL) 3573 if (idx > s_idx)
3512 goto cont; 3574 s_ip_idx = 0;
3513 read_lock_bh(&idev->lock); 3575 ip_idx = 0;
3514 switch (type) { 3576 if ((idev = __in6_dev_get(dev)) == NULL)
3515 case UNICAST_ADDR: 3577 goto cont;
3516 /* unicast address incl. temp addr */ 3578
3517 for (ifa = idev->addr_list; ifa; 3579 if (in6_dump_addrs(idev, skb, cb, type,
3518 ifa = ifa->if_next, ip_idx++) { 3580 s_ip_idx, &ip_idx) <= 0)
3519 if (ip_idx < s_ip_idx) 3581 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: 3582cont:
3563 idx++; 3583 idx++;
3584 }
3564 } 3585 }
3565 cb->args[0] = idx; 3586done:
3566 cb->args[1] = ip_idx; 3587 rcu_read_unlock();
3588 cb->args[0] = h;
3589 cb->args[1] = idx;
3590 cb->args[2] = ip_idx;
3591
3567 return skb->len; 3592 return skb->len;
3568} 3593}
3569 3594
@@ -3708,6 +3733,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3708#endif 3733#endif
3709 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; 3734 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
3710 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; 3735 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
3736 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
3711} 3737}
3712 3738
3713static inline size_t inet6_if_nlmsg_size(void) 3739static inline size_t inet6_if_nlmsg_size(void)
@@ -3826,28 +3852,39 @@ nla_put_failure:
3826static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3852static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3827{ 3853{
3828 struct net *net = sock_net(skb->sk); 3854 struct net *net = sock_net(skb->sk);
3829 int idx, err; 3855 int h, s_h;
3830 int s_idx = cb->args[0]; 3856 int idx = 0, s_idx;
3831 struct net_device *dev; 3857 struct net_device *dev;
3832 struct inet6_dev *idev; 3858 struct inet6_dev *idev;
3859 struct hlist_head *head;
3860 struct hlist_node *node;
3833 3861
3834 read_lock(&dev_base_lock); 3862 s_h = cb->args[0];
3835 idx = 0; 3863 s_idx = cb->args[1];
3836 for_each_netdev(net, dev) { 3864
3837 if (idx < s_idx) 3865 rcu_read_lock();
3838 goto cont; 3866 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3839 if ((idev = in6_dev_get(dev)) == NULL) 3867 idx = 0;
3840 goto cont; 3868 head = &net->dev_index_head[h];
3841 err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, 3869 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3842 cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); 3870 if (idx < s_idx)
3843 in6_dev_put(idev); 3871 goto cont;
3844 if (err <= 0) 3872 idev = __in6_dev_get(dev);
3845 break; 3873 if (!idev)
3874 goto cont;
3875 if (inet6_fill_ifinfo(skb, idev,
3876 NETLINK_CB(cb->skb).pid,
3877 cb->nlh->nlmsg_seq,
3878 RTM_NEWLINK, NLM_F_MULTI) <= 0)
3879 goto out;
3846cont: 3880cont:
3847 idx++; 3881 idx++;
3882 }
3848 } 3883 }
3849 read_unlock(&dev_base_lock); 3884out:
3850 cb->args[0] = idx; 3885 rcu_read_unlock();
3886 cb->args[1] = idx;
3887 cb->args[0] = h;
3851 3888
3852 return skb->len; 3889 return skb->len;
3853} 3890}
@@ -4000,41 +4037,6 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
4000 return ret; 4037 return ret;
4001} 4038}
4002 4039
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) 4040static void dev_disable_change(struct inet6_dev *idev)
4039{ 4041{
4040 if (!idev || !idev->dev) 4042 if (!idev || !idev->dev)
@@ -4051,9 +4053,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
4051 struct net_device *dev; 4053 struct net_device *dev;
4052 struct inet6_dev *idev; 4054 struct inet6_dev *idev;
4053 4055
4054 read_lock(&dev_base_lock); 4056 rcu_read_lock();
4055 for_each_netdev(net, dev) { 4057 for_each_netdev_rcu(net, dev) {
4056 rcu_read_lock();
4057 idev = __in6_dev_get(dev); 4058 idev = __in6_dev_get(dev);
4058 if (idev) { 4059 if (idev) {
4059 int changed = (!idev->cnf.disable_ipv6) ^ (!newf); 4060 int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
@@ -4061,9 +4062,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
4061 if (changed) 4062 if (changed)
4062 dev_disable_change(idev); 4063 dev_disable_change(idev);
4063 } 4064 }
4064 rcu_read_unlock();
4065 } 4065 }
4066 read_unlock(&dev_base_lock); 4066 rcu_read_unlock();
4067} 4067}
4068 4068
4069static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) 4069static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
@@ -4113,16 +4113,13 @@ static struct addrconf_sysctl_table
4113 .sysctl_header = NULL, 4113 .sysctl_header = NULL,
4114 .addrconf_vars = { 4114 .addrconf_vars = {
4115 { 4115 {
4116 .ctl_name = NET_IPV6_FORWARDING,
4117 .procname = "forwarding", 4116 .procname = "forwarding",
4118 .data = &ipv6_devconf.forwarding, 4117 .data = &ipv6_devconf.forwarding,
4119 .maxlen = sizeof(int), 4118 .maxlen = sizeof(int),
4120 .mode = 0644, 4119 .mode = 0644,
4121 .proc_handler = addrconf_sysctl_forward, 4120 .proc_handler = addrconf_sysctl_forward,
4122 .strategy = addrconf_sysctl_forward_strategy,
4123 }, 4121 },
4124 { 4122 {
4125 .ctl_name = NET_IPV6_HOP_LIMIT,
4126 .procname = "hop_limit", 4123 .procname = "hop_limit",
4127 .data = &ipv6_devconf.hop_limit, 4124 .data = &ipv6_devconf.hop_limit,
4128 .maxlen = sizeof(int), 4125 .maxlen = sizeof(int),
@@ -4130,7 +4127,6 @@ static struct addrconf_sysctl_table
4130 .proc_handler = proc_dointvec, 4127 .proc_handler = proc_dointvec,
4131 }, 4128 },
4132 { 4129 {
4133 .ctl_name = NET_IPV6_MTU,
4134 .procname = "mtu", 4130 .procname = "mtu",
4135 .data = &ipv6_devconf.mtu6, 4131 .data = &ipv6_devconf.mtu6,
4136 .maxlen = sizeof(int), 4132 .maxlen = sizeof(int),
@@ -4138,7 +4134,6 @@ static struct addrconf_sysctl_table
4138 .proc_handler = proc_dointvec, 4134 .proc_handler = proc_dointvec,
4139 }, 4135 },
4140 { 4136 {
4141 .ctl_name = NET_IPV6_ACCEPT_RA,
4142 .procname = "accept_ra", 4137 .procname = "accept_ra",
4143 .data = &ipv6_devconf.accept_ra, 4138 .data = &ipv6_devconf.accept_ra,
4144 .maxlen = sizeof(int), 4139 .maxlen = sizeof(int),
@@ -4146,7 +4141,6 @@ static struct addrconf_sysctl_table
4146 .proc_handler = proc_dointvec, 4141 .proc_handler = proc_dointvec,
4147 }, 4142 },
4148 { 4143 {
4149 .ctl_name = NET_IPV6_ACCEPT_REDIRECTS,
4150 .procname = "accept_redirects", 4144 .procname = "accept_redirects",
4151 .data = &ipv6_devconf.accept_redirects, 4145 .data = &ipv6_devconf.accept_redirects,
4152 .maxlen = sizeof(int), 4146 .maxlen = sizeof(int),
@@ -4154,7 +4148,6 @@ static struct addrconf_sysctl_table
4154 .proc_handler = proc_dointvec, 4148 .proc_handler = proc_dointvec,
4155 }, 4149 },
4156 { 4150 {
4157 .ctl_name = NET_IPV6_AUTOCONF,
4158 .procname = "autoconf", 4151 .procname = "autoconf",
4159 .data = &ipv6_devconf.autoconf, 4152 .data = &ipv6_devconf.autoconf,
4160 .maxlen = sizeof(int), 4153 .maxlen = sizeof(int),
@@ -4162,7 +4155,6 @@ static struct addrconf_sysctl_table
4162 .proc_handler = proc_dointvec, 4155 .proc_handler = proc_dointvec,
4163 }, 4156 },
4164 { 4157 {
4165 .ctl_name = NET_IPV6_DAD_TRANSMITS,
4166 .procname = "dad_transmits", 4158 .procname = "dad_transmits",
4167 .data = &ipv6_devconf.dad_transmits, 4159 .data = &ipv6_devconf.dad_transmits,
4168 .maxlen = sizeof(int), 4160 .maxlen = sizeof(int),
@@ -4170,7 +4162,6 @@ static struct addrconf_sysctl_table
4170 .proc_handler = proc_dointvec, 4162 .proc_handler = proc_dointvec,
4171 }, 4163 },
4172 { 4164 {
4173 .ctl_name = NET_IPV6_RTR_SOLICITS,
4174 .procname = "router_solicitations", 4165 .procname = "router_solicitations",
4175 .data = &ipv6_devconf.rtr_solicits, 4166 .data = &ipv6_devconf.rtr_solicits,
4176 .maxlen = sizeof(int), 4167 .maxlen = sizeof(int),
@@ -4178,25 +4169,20 @@ static struct addrconf_sysctl_table
4178 .proc_handler = proc_dointvec, 4169 .proc_handler = proc_dointvec,
4179 }, 4170 },
4180 { 4171 {
4181 .ctl_name = NET_IPV6_RTR_SOLICIT_INTERVAL,
4182 .procname = "router_solicitation_interval", 4172 .procname = "router_solicitation_interval",
4183 .data = &ipv6_devconf.rtr_solicit_interval, 4173 .data = &ipv6_devconf.rtr_solicit_interval,
4184 .maxlen = sizeof(int), 4174 .maxlen = sizeof(int),
4185 .mode = 0644, 4175 .mode = 0644,
4186 .proc_handler = proc_dointvec_jiffies, 4176 .proc_handler = proc_dointvec_jiffies,
4187 .strategy = sysctl_jiffies,
4188 }, 4177 },
4189 { 4178 {
4190 .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY,
4191 .procname = "router_solicitation_delay", 4179 .procname = "router_solicitation_delay",
4192 .data = &ipv6_devconf.rtr_solicit_delay, 4180 .data = &ipv6_devconf.rtr_solicit_delay,
4193 .maxlen = sizeof(int), 4181 .maxlen = sizeof(int),
4194 .mode = 0644, 4182 .mode = 0644,
4195 .proc_handler = proc_dointvec_jiffies, 4183 .proc_handler = proc_dointvec_jiffies,
4196 .strategy = sysctl_jiffies,
4197 }, 4184 },
4198 { 4185 {
4199 .ctl_name = NET_IPV6_FORCE_MLD_VERSION,
4200 .procname = "force_mld_version", 4186 .procname = "force_mld_version",
4201 .data = &ipv6_devconf.force_mld_version, 4187 .data = &ipv6_devconf.force_mld_version,
4202 .maxlen = sizeof(int), 4188 .maxlen = sizeof(int),
@@ -4205,7 +4191,6 @@ static struct addrconf_sysctl_table
4205 }, 4191 },
4206#ifdef CONFIG_IPV6_PRIVACY 4192#ifdef CONFIG_IPV6_PRIVACY
4207 { 4193 {
4208 .ctl_name = NET_IPV6_USE_TEMPADDR,
4209 .procname = "use_tempaddr", 4194 .procname = "use_tempaddr",
4210 .data = &ipv6_devconf.use_tempaddr, 4195 .data = &ipv6_devconf.use_tempaddr,
4211 .maxlen = sizeof(int), 4196 .maxlen = sizeof(int),
@@ -4213,7 +4198,6 @@ static struct addrconf_sysctl_table
4213 .proc_handler = proc_dointvec, 4198 .proc_handler = proc_dointvec,
4214 }, 4199 },
4215 { 4200 {
4216 .ctl_name = NET_IPV6_TEMP_VALID_LFT,
4217 .procname = "temp_valid_lft", 4201 .procname = "temp_valid_lft",
4218 .data = &ipv6_devconf.temp_valid_lft, 4202 .data = &ipv6_devconf.temp_valid_lft,
4219 .maxlen = sizeof(int), 4203 .maxlen = sizeof(int),
@@ -4221,7 +4205,6 @@ static struct addrconf_sysctl_table
4221 .proc_handler = proc_dointvec, 4205 .proc_handler = proc_dointvec,
4222 }, 4206 },
4223 { 4207 {
4224 .ctl_name = NET_IPV6_TEMP_PREFERED_LFT,
4225 .procname = "temp_prefered_lft", 4208 .procname = "temp_prefered_lft",
4226 .data = &ipv6_devconf.temp_prefered_lft, 4209 .data = &ipv6_devconf.temp_prefered_lft,
4227 .maxlen = sizeof(int), 4210 .maxlen = sizeof(int),
@@ -4229,7 +4212,6 @@ static struct addrconf_sysctl_table
4229 .proc_handler = proc_dointvec, 4212 .proc_handler = proc_dointvec,
4230 }, 4213 },
4231 { 4214 {
4232 .ctl_name = NET_IPV6_REGEN_MAX_RETRY,
4233 .procname = "regen_max_retry", 4215 .procname = "regen_max_retry",
4234 .data = &ipv6_devconf.regen_max_retry, 4216 .data = &ipv6_devconf.regen_max_retry,
4235 .maxlen = sizeof(int), 4217 .maxlen = sizeof(int),
@@ -4237,7 +4219,6 @@ static struct addrconf_sysctl_table
4237 .proc_handler = proc_dointvec, 4219 .proc_handler = proc_dointvec,
4238 }, 4220 },
4239 { 4221 {
4240 .ctl_name = NET_IPV6_MAX_DESYNC_FACTOR,
4241 .procname = "max_desync_factor", 4222 .procname = "max_desync_factor",
4242 .data = &ipv6_devconf.max_desync_factor, 4223 .data = &ipv6_devconf.max_desync_factor,
4243 .maxlen = sizeof(int), 4224 .maxlen = sizeof(int),
@@ -4246,7 +4227,6 @@ static struct addrconf_sysctl_table
4246 }, 4227 },
4247#endif 4228#endif
4248 { 4229 {
4249 .ctl_name = NET_IPV6_MAX_ADDRESSES,
4250 .procname = "max_addresses", 4230 .procname = "max_addresses",
4251 .data = &ipv6_devconf.max_addresses, 4231 .data = &ipv6_devconf.max_addresses,
4252 .maxlen = sizeof(int), 4232 .maxlen = sizeof(int),
@@ -4254,7 +4234,6 @@ static struct addrconf_sysctl_table
4254 .proc_handler = proc_dointvec, 4234 .proc_handler = proc_dointvec,
4255 }, 4235 },
4256 { 4236 {
4257 .ctl_name = NET_IPV6_ACCEPT_RA_DEFRTR,
4258 .procname = "accept_ra_defrtr", 4237 .procname = "accept_ra_defrtr",
4259 .data = &ipv6_devconf.accept_ra_defrtr, 4238 .data = &ipv6_devconf.accept_ra_defrtr,
4260 .maxlen = sizeof(int), 4239 .maxlen = sizeof(int),
@@ -4262,7 +4241,6 @@ static struct addrconf_sysctl_table
4262 .proc_handler = proc_dointvec, 4241 .proc_handler = proc_dointvec,
4263 }, 4242 },
4264 { 4243 {
4265 .ctl_name = NET_IPV6_ACCEPT_RA_PINFO,
4266 .procname = "accept_ra_pinfo", 4244 .procname = "accept_ra_pinfo",
4267 .data = &ipv6_devconf.accept_ra_pinfo, 4245 .data = &ipv6_devconf.accept_ra_pinfo,
4268 .maxlen = sizeof(int), 4246 .maxlen = sizeof(int),
@@ -4271,7 +4249,6 @@ static struct addrconf_sysctl_table
4271 }, 4249 },
4272#ifdef CONFIG_IPV6_ROUTER_PREF 4250#ifdef CONFIG_IPV6_ROUTER_PREF
4273 { 4251 {
4274 .ctl_name = NET_IPV6_ACCEPT_RA_RTR_PREF,
4275 .procname = "accept_ra_rtr_pref", 4252 .procname = "accept_ra_rtr_pref",
4276 .data = &ipv6_devconf.accept_ra_rtr_pref, 4253 .data = &ipv6_devconf.accept_ra_rtr_pref,
4277 .maxlen = sizeof(int), 4254 .maxlen = sizeof(int),
@@ -4279,17 +4256,14 @@ static struct addrconf_sysctl_table
4279 .proc_handler = proc_dointvec, 4256 .proc_handler = proc_dointvec,
4280 }, 4257 },
4281 { 4258 {
4282 .ctl_name = NET_IPV6_RTR_PROBE_INTERVAL,
4283 .procname = "router_probe_interval", 4259 .procname = "router_probe_interval",
4284 .data = &ipv6_devconf.rtr_probe_interval, 4260 .data = &ipv6_devconf.rtr_probe_interval,
4285 .maxlen = sizeof(int), 4261 .maxlen = sizeof(int),
4286 .mode = 0644, 4262 .mode = 0644,
4287 .proc_handler = proc_dointvec_jiffies, 4263 .proc_handler = proc_dointvec_jiffies,
4288 .strategy = sysctl_jiffies,
4289 }, 4264 },
4290#ifdef CONFIG_IPV6_ROUTE_INFO 4265#ifdef CONFIG_IPV6_ROUTE_INFO
4291 { 4266 {
4292 .ctl_name = NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,
4293 .procname = "accept_ra_rt_info_max_plen", 4267 .procname = "accept_ra_rt_info_max_plen",
4294 .data = &ipv6_devconf.accept_ra_rt_info_max_plen, 4268 .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
4295 .maxlen = sizeof(int), 4269 .maxlen = sizeof(int),
@@ -4299,7 +4273,6 @@ static struct addrconf_sysctl_table
4299#endif 4273#endif
4300#endif 4274#endif
4301 { 4275 {
4302 .ctl_name = NET_IPV6_PROXY_NDP,
4303 .procname = "proxy_ndp", 4276 .procname = "proxy_ndp",
4304 .data = &ipv6_devconf.proxy_ndp, 4277 .data = &ipv6_devconf.proxy_ndp,
4305 .maxlen = sizeof(int), 4278 .maxlen = sizeof(int),
@@ -4307,7 +4280,6 @@ static struct addrconf_sysctl_table
4307 .proc_handler = proc_dointvec, 4280 .proc_handler = proc_dointvec,
4308 }, 4281 },
4309 { 4282 {
4310 .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
4311 .procname = "accept_source_route", 4283 .procname = "accept_source_route",
4312 .data = &ipv6_devconf.accept_source_route, 4284 .data = &ipv6_devconf.accept_source_route,
4313 .maxlen = sizeof(int), 4285 .maxlen = sizeof(int),
@@ -4316,7 +4288,6 @@ static struct addrconf_sysctl_table
4316 }, 4288 },
4317#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 4289#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
4318 { 4290 {
4319 .ctl_name = CTL_UNNUMBERED,
4320 .procname = "optimistic_dad", 4291 .procname = "optimistic_dad",
4321 .data = &ipv6_devconf.optimistic_dad, 4292 .data = &ipv6_devconf.optimistic_dad,
4322 .maxlen = sizeof(int), 4293 .maxlen = sizeof(int),
@@ -4327,7 +4298,6 @@ static struct addrconf_sysctl_table
4327#endif 4298#endif
4328#ifdef CONFIG_IPV6_MROUTE 4299#ifdef CONFIG_IPV6_MROUTE
4329 { 4300 {
4330 .ctl_name = CTL_UNNUMBERED,
4331 .procname = "mc_forwarding", 4301 .procname = "mc_forwarding",
4332 .data = &ipv6_devconf.mc_forwarding, 4302 .data = &ipv6_devconf.mc_forwarding,
4333 .maxlen = sizeof(int), 4303 .maxlen = sizeof(int),
@@ -4336,16 +4306,13 @@ static struct addrconf_sysctl_table
4336 }, 4306 },
4337#endif 4307#endif
4338 { 4308 {
4339 .ctl_name = CTL_UNNUMBERED,
4340 .procname = "disable_ipv6", 4309 .procname = "disable_ipv6",
4341 .data = &ipv6_devconf.disable_ipv6, 4310 .data = &ipv6_devconf.disable_ipv6,
4342 .maxlen = sizeof(int), 4311 .maxlen = sizeof(int),
4343 .mode = 0644, 4312 .mode = 0644,
4344 .proc_handler = addrconf_sysctl_disable, 4313 .proc_handler = addrconf_sysctl_disable,
4345 .strategy = sysctl_intvec,
4346 }, 4314 },
4347 { 4315 {
4348 .ctl_name = CTL_UNNUMBERED,
4349 .procname = "accept_dad", 4316 .procname = "accept_dad",
4350 .data = &ipv6_devconf.accept_dad, 4317 .data = &ipv6_devconf.accept_dad,
4351 .maxlen = sizeof(int), 4318 .maxlen = sizeof(int),
@@ -4353,13 +4320,20 @@ static struct addrconf_sysctl_table
4353 .proc_handler = proc_dointvec, 4320 .proc_handler = proc_dointvec,
4354 }, 4321 },
4355 { 4322 {
4356 .ctl_name = 0, /* sentinel */ 4323 .procname = "force_tllao",
4324 .data = &ipv6_devconf.force_tllao,
4325 .maxlen = sizeof(int),
4326 .mode = 0644,
4327 .proc_handler = proc_dointvec
4328 },
4329 {
4330 /* sentinel */
4357 } 4331 }
4358 }, 4332 },
4359}; 4333};
4360 4334
4361static int __addrconf_sysctl_register(struct net *net, char *dev_name, 4335static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4362 int ctl_name, struct inet6_dev *idev, struct ipv6_devconf *p) 4336 struct inet6_dev *idev, struct ipv6_devconf *p)
4363{ 4337{
4364 int i; 4338 int i;
4365 struct addrconf_sysctl_table *t; 4339 struct addrconf_sysctl_table *t;
@@ -4367,9 +4341,9 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4367#define ADDRCONF_CTL_PATH_DEV 3 4341#define ADDRCONF_CTL_PATH_DEV 3
4368 4342
4369 struct ctl_path addrconf_ctl_path[] = { 4343 struct ctl_path addrconf_ctl_path[] = {
4370 { .procname = "net", .ctl_name = CTL_NET, }, 4344 { .procname = "net", },
4371 { .procname = "ipv6", .ctl_name = NET_IPV6, }, 4345 { .procname = "ipv6", },
4372 { .procname = "conf", .ctl_name = NET_IPV6_CONF, }, 4346 { .procname = "conf", },
4373 { /* to be set */ }, 4347 { /* to be set */ },
4374 { }, 4348 { },
4375 }; 4349 };
@@ -4395,7 +4369,6 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4395 goto free; 4369 goto free;
4396 4370
4397 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name; 4371 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name;
4398 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].ctl_name = ctl_name;
4399 4372
4400 t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path, 4373 t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path,
4401 t->addrconf_vars); 4374 t->addrconf_vars);
@@ -4431,10 +4404,9 @@ static void addrconf_sysctl_register(struct inet6_dev *idev)
4431{ 4404{
4432 neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6, 4405 neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6,
4433 NET_IPV6_NEIGH, "ipv6", 4406 NET_IPV6_NEIGH, "ipv6",
4434 &ndisc_ifinfo_sysctl_change, 4407 &ndisc_ifinfo_sysctl_change);
4435 ndisc_ifinfo_sysctl_strategy);
4436 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, 4408 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
4437 idev->dev->ifindex, idev, &idev->cnf); 4409 idev, &idev->cnf);
4438} 4410}
4439 4411
4440static void addrconf_sysctl_unregister(struct inet6_dev *idev) 4412static void addrconf_sysctl_unregister(struct inet6_dev *idev)
@@ -4455,7 +4427,7 @@ static int addrconf_init_net(struct net *net)
4455 all = &ipv6_devconf; 4427 all = &ipv6_devconf;
4456 dflt = &ipv6_devconf_dflt; 4428 dflt = &ipv6_devconf_dflt;
4457 4429
4458 if (net != &init_net) { 4430 if (!net_eq(net, &init_net)) {
4459 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL); 4431 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
4460 if (all == NULL) 4432 if (all == NULL)
4461 goto err_alloc_all; 4433 goto err_alloc_all;
@@ -4473,13 +4445,11 @@ static int addrconf_init_net(struct net *net)
4473 net->ipv6.devconf_dflt = dflt; 4445 net->ipv6.devconf_dflt = dflt;
4474 4446
4475#ifdef CONFIG_SYSCTL 4447#ifdef CONFIG_SYSCTL
4476 err = __addrconf_sysctl_register(net, "all", NET_PROTO_CONF_ALL, 4448 err = __addrconf_sysctl_register(net, "all", NULL, all);
4477 NULL, all);
4478 if (err < 0) 4449 if (err < 0)
4479 goto err_reg_all; 4450 goto err_reg_all;
4480 4451
4481 err = __addrconf_sysctl_register(net, "default", NET_PROTO_CONF_DEFAULT, 4452 err = __addrconf_sysctl_register(net, "default", NULL, dflt);
4482 NULL, dflt);
4483 if (err < 0) 4453 if (err < 0)
4484 goto err_reg_dflt; 4454 goto err_reg_dflt;
4485#endif 4455#endif
@@ -4503,7 +4473,7 @@ static void addrconf_exit_net(struct net *net)
4503 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt); 4473 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
4504 __addrconf_sysctl_unregister(net->ipv6.devconf_all); 4474 __addrconf_sysctl_unregister(net->ipv6.devconf_all);
4505#endif 4475#endif
4506 if (net != &init_net) { 4476 if (!net_eq(net, &init_net)) {
4507 kfree(net->ipv6.devconf_dflt); 4477 kfree(net->ipv6.devconf_dflt);
4508 kfree(net->ipv6.devconf_all); 4478 kfree(net->ipv6.devconf_all);
4509 } 4479 }