addrconf.c (690e179059e7e89040d1cd564e39761567a8d5dc) | addrconf.c (3e0b8f529c10037ae0b369fc892e524eae5a5485) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * IPv6 Address [auto]configuration 4 * Linux INET6 implementation 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> --- 321 unchanged lines hidden (view full) --- 330 if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay)) 331 in6_ifa_put(ifp); 332} 333 334static int snmp6_alloc_dev(struct inet6_dev *idev) 335{ 336 int i; 337 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * IPv6 Address [auto]configuration 4 * Linux INET6 implementation 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> --- 321 unchanged lines hidden (view full) --- 330 if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay)) 331 in6_ifa_put(ifp); 332} 333 334static int snmp6_alloc_dev(struct inet6_dev *idev) 335{ 336 int i; 337 |
338 idev->stats.ipv6 = alloc_percpu(struct ipstats_mib); | 338 idev->stats.ipv6 = alloc_percpu_gfp(struct ipstats_mib, GFP_KERNEL_ACCOUNT); |
339 if (!idev->stats.ipv6) 340 goto err_ip; 341 342 for_each_possible_cpu(i) { 343 struct ipstats_mib *addrconf_stats; 344 addrconf_stats = per_cpu_ptr(idev->stats.ipv6, i); 345 u64_stats_init(&addrconf_stats->syncp); 346 } 347 348 349 idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device), 350 GFP_KERNEL); 351 if (!idev->stats.icmpv6dev) 352 goto err_icmp; 353 idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device), | 339 if (!idev->stats.ipv6) 340 goto err_ip; 341 342 for_each_possible_cpu(i) { 343 struct ipstats_mib *addrconf_stats; 344 addrconf_stats = per_cpu_ptr(idev->stats.ipv6, i); 345 u64_stats_init(&addrconf_stats->syncp); 346 } 347 348 349 idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device), 350 GFP_KERNEL); 351 if (!idev->stats.icmpv6dev) 352 goto err_icmp; 353 idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device), |
354 GFP_KERNEL); | 354 GFP_KERNEL_ACCOUNT); |
355 if (!idev->stats.icmpv6msgdev) 356 goto err_icmpmsg; 357 358 return 0; 359 360err_icmpmsg: 361 kfree(idev->stats.icmpv6dev); 362err_icmp: --- 7 unchanged lines hidden (view full) --- 370 struct inet6_dev *ndev; 371 int err = -ENOMEM; 372 373 ASSERT_RTNL(); 374 375 if (dev->mtu < IPV6_MIN_MTU && dev != blackhole_netdev) 376 return ERR_PTR(-EINVAL); 377 | 355 if (!idev->stats.icmpv6msgdev) 356 goto err_icmpmsg; 357 358 return 0; 359 360err_icmpmsg: 361 kfree(idev->stats.icmpv6dev); 362err_icmp: --- 7 unchanged lines hidden (view full) --- 370 struct inet6_dev *ndev; 371 int err = -ENOMEM; 372 373 ASSERT_RTNL(); 374 375 if (dev->mtu < IPV6_MIN_MTU && dev != blackhole_netdev) 376 return ERR_PTR(-EINVAL); 377 |
378 ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL); | 378 ndev = kzalloc(sizeof(*ndev), GFP_KERNEL_ACCOUNT); |
379 if (!ndev) 380 return ERR_PTR(err); 381 382 rwlock_init(&ndev->lock); 383 ndev->dev = dev; 384 INIT_LIST_HEAD(&ndev->addr_list); 385 timer_setup(&ndev->rs_timer, addrconf_rs_timer, 0); 386 memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf)); --- 405 unchanged lines hidden (view full) --- 792 return skb->len; 793} 794 795#ifdef CONFIG_SYSCTL 796static void dev_forward_change(struct inet6_dev *idev) 797{ 798 struct net_device *dev; 799 struct inet6_ifaddr *ifa; | 379 if (!ndev) 380 return ERR_PTR(err); 381 382 rwlock_init(&ndev->lock); 383 ndev->dev = dev; 384 INIT_LIST_HEAD(&ndev->addr_list); 385 timer_setup(&ndev->rs_timer, addrconf_rs_timer, 0); 386 memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf)); --- 405 unchanged lines hidden (view full) --- 792 return skb->len; 793} 794 795#ifdef CONFIG_SYSCTL 796static void dev_forward_change(struct inet6_dev *idev) 797{ 798 struct net_device *dev; 799 struct inet6_ifaddr *ifa; |
800 LIST_HEAD(tmp_addr_list); |
|
800 801 if (!idev) 802 return; 803 dev = idev->dev; 804 if (idev->cnf.forwarding) 805 dev_disable_lro(dev); 806 if (dev->flags & IFF_MULTICAST) { 807 if (idev->cnf.forwarding) { 808 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); 809 ipv6_dev_mc_inc(dev, &in6addr_interfacelocal_allrouters); 810 ipv6_dev_mc_inc(dev, &in6addr_sitelocal_allrouters); 811 } else { 812 ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters); 813 ipv6_dev_mc_dec(dev, &in6addr_interfacelocal_allrouters); 814 ipv6_dev_mc_dec(dev, &in6addr_sitelocal_allrouters); 815 } 816 } 817 | 801 802 if (!idev) 803 return; 804 dev = idev->dev; 805 if (idev->cnf.forwarding) 806 dev_disable_lro(dev); 807 if (dev->flags & IFF_MULTICAST) { 808 if (idev->cnf.forwarding) { 809 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); 810 ipv6_dev_mc_inc(dev, &in6addr_interfacelocal_allrouters); 811 ipv6_dev_mc_inc(dev, &in6addr_sitelocal_allrouters); 812 } else { 813 ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters); 814 ipv6_dev_mc_dec(dev, &in6addr_interfacelocal_allrouters); 815 ipv6_dev_mc_dec(dev, &in6addr_sitelocal_allrouters); 816 } 817 } 818 |
819 read_lock_bh(&idev->lock); |
|
818 list_for_each_entry(ifa, &idev->addr_list, if_list) { 819 if (ifa->flags&IFA_F_TENTATIVE) 820 continue; | 820 list_for_each_entry(ifa, &idev->addr_list, if_list) { 821 if (ifa->flags&IFA_F_TENTATIVE) 822 continue; |
823 list_add_tail(&ifa->if_list_aux, &tmp_addr_list); 824 } 825 read_unlock_bh(&idev->lock); 826 827 while (!list_empty(&tmp_addr_list)) { 828 ifa = list_first_entry(&tmp_addr_list, 829 struct inet6_ifaddr, if_list_aux); 830 list_del(&ifa->if_list_aux); |
|
821 if (idev->cnf.forwarding) 822 addrconf_join_anycast(ifa); 823 else 824 addrconf_leave_anycast(ifa); 825 } | 831 if (idev->cnf.forwarding) 832 addrconf_join_anycast(ifa); 833 else 834 addrconf_leave_anycast(ifa); 835 } |
836 |
|
826 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF, 827 NETCONFA_FORWARDING, 828 dev->ifindex, &idev->cnf); 829} 830 831 832static void addrconf_forward_change(struct net *net, __s32 newf) 833{ --- 2889 unchanged lines hidden (view full) --- 3723 (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); 3724} 3725 3726static int addrconf_ifdown(struct net_device *dev, bool unregister) 3727{ 3728 unsigned long event = unregister ? NETDEV_UNREGISTER : NETDEV_DOWN; 3729 struct net *net = dev_net(dev); 3730 struct inet6_dev *idev; | 837 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF, 838 NETCONFA_FORWARDING, 839 dev->ifindex, &idev->cnf); 840} 841 842 843static void addrconf_forward_change(struct net *net, __s32 newf) 844{ --- 2889 unchanged lines hidden (view full) --- 3734 (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); 3735} 3736 3737static int addrconf_ifdown(struct net_device *dev, bool unregister) 3738{ 3739 unsigned long event = unregister ? NETDEV_UNREGISTER : NETDEV_DOWN; 3740 struct net *net = dev_net(dev); 3741 struct inet6_dev *idev; |
3731 struct inet6_ifaddr *ifa, *tmp; | 3742 struct inet6_ifaddr *ifa; 3743 LIST_HEAD(tmp_addr_list); |
3732 bool keep_addr = false; 3733 bool was_ready; 3734 int state, i; 3735 3736 ASSERT_RTNL(); 3737 3738 rt6_disable_ip(dev, event); 3739 --- 75 unchanged lines hidden (view full) --- 3815 in6_ifa_put(ifa->ifpub); 3816 ifa->ifpub = NULL; 3817 } 3818 spin_unlock_bh(&ifa->lock); 3819 in6_ifa_put(ifa); 3820 write_lock_bh(&idev->lock); 3821 } 3822 | 3744 bool keep_addr = false; 3745 bool was_ready; 3746 int state, i; 3747 3748 ASSERT_RTNL(); 3749 3750 rt6_disable_ip(dev, event); 3751 --- 75 unchanged lines hidden (view full) --- 3827 in6_ifa_put(ifa->ifpub); 3828 ifa->ifpub = NULL; 3829 } 3830 spin_unlock_bh(&ifa->lock); 3831 in6_ifa_put(ifa); 3832 write_lock_bh(&idev->lock); 3833 } 3834 |
3823 list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { | 3835 list_for_each_entry(ifa, &idev->addr_list, if_list) 3836 list_add_tail(&ifa->if_list_aux, &tmp_addr_list); 3837 write_unlock_bh(&idev->lock); 3838 3839 while (!list_empty(&tmp_addr_list)) { |
3824 struct fib6_info *rt = NULL; 3825 bool keep; 3826 | 3840 struct fib6_info *rt = NULL; 3841 bool keep; 3842 |
3843 ifa = list_first_entry(&tmp_addr_list, 3844 struct inet6_ifaddr, if_list_aux); 3845 list_del(&ifa->if_list_aux); 3846 |
|
3827 addrconf_del_dad_work(ifa); 3828 3829 keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) && 3830 !addr_is_local(&ifa->addr); 3831 | 3847 addrconf_del_dad_work(ifa); 3848 3849 keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) && 3850 !addr_is_local(&ifa->addr); 3851 |
3832 write_unlock_bh(&idev->lock); | |
3833 spin_lock_bh(&ifa->lock); 3834 3835 if (keep) { 3836 /* set state to skip the notifier below */ 3837 state = INET6_IFADDR_STATE_DEAD; 3838 ifa->state = INET6_IFADDR_STATE_PREDAD; 3839 if (!(ifa->flags & IFA_F_NODAD)) 3840 ifa->flags |= IFA_F_TENTATIVE; --- 14 unchanged lines hidden (view full) --- 3855 __ipv6_ifa_notify(RTM_DELADDR, ifa); 3856 inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); 3857 } else { 3858 if (idev->cnf.forwarding) 3859 addrconf_leave_anycast(ifa); 3860 addrconf_leave_solict(ifa->idev, &ifa->addr); 3861 } 3862 | 3852 spin_lock_bh(&ifa->lock); 3853 3854 if (keep) { 3855 /* set state to skip the notifier below */ 3856 state = INET6_IFADDR_STATE_DEAD; 3857 ifa->state = INET6_IFADDR_STATE_PREDAD; 3858 if (!(ifa->flags & IFA_F_NODAD)) 3859 ifa->flags |= IFA_F_TENTATIVE; --- 14 unchanged lines hidden (view full) --- 3874 __ipv6_ifa_notify(RTM_DELADDR, ifa); 3875 inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); 3876 } else { 3877 if (idev->cnf.forwarding) 3878 addrconf_leave_anycast(ifa); 3879 addrconf_leave_solict(ifa->idev, &ifa->addr); 3880 } 3881 |
3863 write_lock_bh(&idev->lock); | |
3864 if (!keep) { | 3882 if (!keep) { |
3883 write_lock_bh(&idev->lock); |
|
3865 list_del_rcu(&ifa->if_list); | 3884 list_del_rcu(&ifa->if_list); |
3885 write_unlock_bh(&idev->lock); |
|
3866 in6_ifa_put(ifa); 3867 } 3868 } 3869 | 3886 in6_ifa_put(ifa); 3887 } 3888 } 3889 |
3870 write_unlock_bh(&idev->lock); 3871 | |
3872 /* Step 5: Discard anycast and multicast list */ 3873 if (unregister) { 3874 ipv6_ac_destroy_dev(idev); 3875 ipv6_mc_destroy_dev(idev); 3876 } else if (was_ready) { 3877 ipv6_mc_down(idev); 3878 } 3879 --- 87 unchanged lines hidden (view full) --- 3967{ 3968 struct inet6_dev *idev = ifp->idev; 3969 struct net_device *dev = idev->dev; 3970 bool bump_id, notify = false; 3971 struct net *net; 3972 3973 addrconf_join_solict(dev, &ifp->addr); 3974 | 3890 /* Step 5: Discard anycast and multicast list */ 3891 if (unregister) { 3892 ipv6_ac_destroy_dev(idev); 3893 ipv6_mc_destroy_dev(idev); 3894 } else if (was_ready) { 3895 ipv6_mc_down(idev); 3896 } 3897 --- 87 unchanged lines hidden (view full) --- 3985{ 3986 struct inet6_dev *idev = ifp->idev; 3987 struct net_device *dev = idev->dev; 3988 bool bump_id, notify = false; 3989 struct net *net; 3990 3991 addrconf_join_solict(dev, &ifp->addr); 3992 |
3975 prandom_seed((__force u32) ifp->addr.s6_addr32[3]); 3976 | |
3977 read_lock_bh(&idev->lock); 3978 spin_lock(&ifp->lock); 3979 if (ifp->state == INET6_IFADDR_STATE_DEAD) 3980 goto out; 3981 3982 net = dev_net(dev); 3983 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 3984 (net->ipv6.devconf_all->accept_dad < 1 && --- 211 unchanged lines hidden (view full) --- 4196 router advertisements, start sending router solicitations. 4197 */ 4198 4199 read_lock_bh(&ifp->idev->lock); 4200 send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp); 4201 send_rs = send_mld && 4202 ipv6_accept_ra(ifp->idev) && 4203 ifp->idev->cnf.rtr_solicits != 0 && | 3993 read_lock_bh(&idev->lock); 3994 spin_lock(&ifp->lock); 3995 if (ifp->state == INET6_IFADDR_STATE_DEAD) 3996 goto out; 3997 3998 net = dev_net(dev); 3999 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 4000 (net->ipv6.devconf_all->accept_dad < 1 && --- 211 unchanged lines hidden (view full) --- 4212 router advertisements, start sending router solicitations. 4213 */ 4214 4215 read_lock_bh(&ifp->idev->lock); 4216 send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp); 4217 send_rs = send_mld && 4218 ipv6_accept_ra(ifp->idev) && 4219 ifp->idev->cnf.rtr_solicits != 0 && |
4204 (dev->flags&IFF_LOOPBACK) == 0; | 4220 (dev->flags & IFF_LOOPBACK) == 0 && 4221 (dev->type != ARPHRD_TUNNEL); |
4205 read_unlock_bh(&ifp->idev->lock); 4206 4207 /* While dad is in progress mld report's source address is in6_addrany. 4208 * Resend with proper ll now. 4209 */ 4210 if (send_mld) 4211 ipv6_mc_dad_complete(ifp->idev); 4212 --- 1351 unchanged lines hidden (view full) --- 5564 array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode; 5565 array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy; 5566 array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass; 5567 array[DEVCONF_RPL_SEG_ENABLED] = cnf->rpl_seg_enabled; 5568 array[DEVCONF_IOAM6_ENABLED] = cnf->ioam6_enabled; 5569 array[DEVCONF_IOAM6_ID] = cnf->ioam6_id; 5570 array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; 5571 array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; | 4222 read_unlock_bh(&ifp->idev->lock); 4223 4224 /* While dad is in progress mld report's source address is in6_addrany. 4225 * Resend with proper ll now. 4226 */ 4227 if (send_mld) 4228 ipv6_mc_dad_complete(ifp->idev); 4229 --- 1351 unchanged lines hidden (view full) --- 5581 array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode; 5582 array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy; 5583 array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass; 5584 array[DEVCONF_RPL_SEG_ENABLED] = cnf->rpl_seg_enabled; 5585 array[DEVCONF_IOAM6_ENABLED] = cnf->ioam6_enabled; 5586 array[DEVCONF_IOAM6_ID] = cnf->ioam6_id; 5587 array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; 5588 array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; |
5589 array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na; |
|
5572} 5573 5574static inline size_t inet6_ifla6_size(void) 5575{ 5576 return nla_total_size(4) /* IFLA_INET6_FLAGS */ 5577 + nla_total_size(sizeof(struct ifla_cacheinfo)) 5578 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ 5579 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ --- 1435 unchanged lines hidden (view full) --- 7015 .data = &ipv6_devconf.ndisc_evict_nocarrier, 7016 .maxlen = sizeof(u8), 7017 .mode = 0644, 7018 .proc_handler = proc_dou8vec_minmax, 7019 .extra1 = (void *)SYSCTL_ZERO, 7020 .extra2 = (void *)SYSCTL_ONE, 7021 }, 7022 { | 5590} 5591 5592static inline size_t inet6_ifla6_size(void) 5593{ 5594 return nla_total_size(4) /* IFLA_INET6_FLAGS */ 5595 + nla_total_size(sizeof(struct ifla_cacheinfo)) 5596 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ 5597 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ --- 1435 unchanged lines hidden (view full) --- 7033 .data = &ipv6_devconf.ndisc_evict_nocarrier, 7034 .maxlen = sizeof(u8), 7035 .mode = 0644, 7036 .proc_handler = proc_dou8vec_minmax, 7037 .extra1 = (void *)SYSCTL_ZERO, 7038 .extra2 = (void *)SYSCTL_ONE, 7039 }, 7040 { |
7041 .procname = "accept_untracked_na", 7042 .data = &ipv6_devconf.accept_untracked_na, 7043 .maxlen = sizeof(int), 7044 .mode = 0644, 7045 .proc_handler = proc_dointvec_minmax, 7046 .extra1 = (void *)SYSCTL_ZERO, 7047 .extra2 = (void *)SYSCTL_ONE, 7048 }, 7049 { |
|
7023 /* sentinel */ 7024 } 7025}; 7026 7027static int __addrconf_sysctl_register(struct net *net, char *dev_name, 7028 struct inet6_dev *idev, struct ipv6_devconf *p) 7029{ 7030 int i, ifindex; 7031 struct ctl_table *table; 7032 char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; 7033 | 7050 /* sentinel */ 7051 } 7052}; 7053 7054static int __addrconf_sysctl_register(struct net *net, char *dev_name, 7055 struct inet6_dev *idev, struct ipv6_devconf *p) 7056{ 7057 int i, ifindex; 7058 struct ctl_table *table; 7059 char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; 7060 |
7034 table = kmemdup(addrconf_sysctl, sizeof(addrconf_sysctl), GFP_KERNEL); | 7061 table = kmemdup(addrconf_sysctl, sizeof(addrconf_sysctl), GFP_KERNEL_ACCOUNT); |
7035 if (!table) 7036 goto out; 7037 7038 for (i = 0; table[i].data; i++) { 7039 table[i].data += (char *)p - (char *)&ipv6_devconf; 7040 /* If one of these is already set, then it is not safe to 7041 * overwrite either of them: this makes proc_dointvec_minmax 7042 * usable. --- 309 unchanged lines hidden --- | 7062 if (!table) 7063 goto out; 7064 7065 for (i = 0; table[i].data; i++) { 7066 table[i].data += (char *)p - (char *)&ipv6_devconf; 7067 /* If one of these is already set, then it is not safe to 7068 * overwrite either of them: this makes proc_dointvec_minmax 7069 * usable. --- 309 unchanged lines hidden --- |