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 ---