diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 334 |
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 | ||
499 | static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) | 497 | static 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() */ | ||
3485 | static 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 | |||
3488 | static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | 3550 | static 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; | ||
3562 | cont: | 3582 | cont: |
3563 | idx++; | 3583 | idx++; |
3584 | } | ||
3564 | } | 3585 | } |
3565 | cb->args[0] = idx; | 3586 | done: |
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 | ||
3713 | static inline size_t inet6_if_nlmsg_size(void) | 3739 | static inline size_t inet6_if_nlmsg_size(void) |
@@ -3826,28 +3852,39 @@ nla_put_failure: | |||
3826 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 3852 | static 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; | ||
3846 | cont: | 3880 | cont: |
3847 | idx++; | 3881 | idx++; |
3882 | } | ||
3848 | } | 3883 | } |
3849 | read_unlock(&dev_base_lock); | 3884 | out: |
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 | ||
4003 | static 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 | |||
4038 | static void dev_disable_change(struct inet6_dev *idev) | 4040 | static 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 | ||
4069 | static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) | 4069 | static 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 | ||
4361 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, | 4335 | static 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 | ||
4440 | static void addrconf_sysctl_unregister(struct inet6_dev *idev) | 4412 | static 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 | } |