From: Alexander Bluhm Subject: Re: Unlock IPV6CTL_DAD_COUNT case of ip6_sysctl() To: Vitaliy Makkoveev Cc: tech@openbsd.org Date: Thu, 24 Jul 2025 00:02:31 +0200 On Thu, Jul 24, 2025 at 12:41:18AM +0300, Vitaliy Makkoveev wrote: > `ip6_dad_count' is local to nd6_dad_start() and used only to initialize > `dad_count' of the addresses to run DAD on. However, we do non-null > check before, so use cached value. Unused in ramdisk. OK bluhm@ > Index: sys/netinet6/in6_proto.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/in6_proto.c,v > retrieving revision 1.139 > diff -u -p -r1.139 in6_proto.c > --- sys/netinet6/in6_proto.c 23 Jul 2025 20:53:55 -0000 1.139 > +++ sys/netinet6/in6_proto.c 23 Jul 2025 21:35:35 -0000 > @@ -358,7 +358,7 @@ int ip6_maxfragpackets = 200; /* [a] */ > int ip6_maxfrags = 200; > int ip6_log_interval = 5; /* [a] */ > int ip6_hdrnestlimit = 10; /* [a] appropriate? */ > -int ip6_dad_count = 1; /* DupAddrDetectionTransmits */ > +int ip6_dad_count = 1; /* [a] DupAddrDetectionTransmits */ > int ip6_dad_pending; /* number of currently running DADs */ > int ip6_auto_flowlabel = 1; > int ip6_use_deprecated = 1; /* allow deprecated addr (RFC2462 5.5.4) */ > Index: sys/netinet6/ip6_input.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/ip6_input.c,v > retrieving revision 1.283 > diff -u -p -r1.283 ip6_input.c > --- sys/netinet6/ip6_input.c 23 Jul 2025 20:53:55 -0000 1.283 > +++ sys/netinet6/ip6_input.c 23 Jul 2025 21:35:35 -0000 > @@ -1450,10 +1450,10 @@ const struct sysctl_bounded_args ipv6ctl > { IPV6CTL_MAXFRAGPACKETS, &ip6_maxfragpackets, 0, 1000 }, > { IPV6CTL_LOG_INTERVAL, &ip6_log_interval, 0, INT_MAX }, > { IPV6CTL_HDRNESTLIMIT, &ip6_hdrnestlimit, 0, 100 }, > + { IPV6CTL_DAD_COUNT, &ip6_dad_count, 0, 10 }, > }; > > const struct sysctl_bounded_args ipv6ctl_vars[] = { > - { IPV6CTL_DAD_COUNT, &ip6_dad_count, 0, 10 }, > { IPV6CTL_AUTO_FLOWLABEL, &ip6_auto_flowlabel, 0, 1 }, > { IPV6CTL_DEFMCASTHLIM, &ip6_defmcasthlim, 0, 255 }, > { IPV6CTL_USE_DEPRECATED, &ip6_use_deprecated, 0, 1 }, > @@ -1573,6 +1573,7 @@ ip6_sysctl(int *name, u_int namelen, voi > case IPV6CTL_MAXFRAGPACKETS: > case IPV6CTL_LOG_INTERVAL: > case IPV6CTL_HDRNESTLIMIT: > + case IPV6CTL_DAD_COUNT: > return (sysctl_bounded_arr( > ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked), > name, namelen, oldp, oldlenp, newp, newlen)); > Index: sys/netinet6/nd6_nbr.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v > retrieving revision 1.161 > diff -u -p -r1.161 nd6_nbr.c > --- sys/netinet6/nd6_nbr.c 8 Jul 2025 00:47:41 -0000 1.161 > +++ sys/netinet6/nd6_nbr.c 23 Jul 2025 21:35:35 -0000 > @@ -1021,6 +1021,7 @@ nd6_dad_start(struct ifaddr *ifa) > struct in6_ifaddr *ia6 = ifatoia6(ifa); > struct dadq *dp; > char addr[INET6_ADDRSTRLEN]; > + int ip6_dad_count_local = atomic_load_int(&ip6_dad_count); > > NET_ASSERT_LOCKED(); > > @@ -1031,7 +1032,7 @@ nd6_dad_start(struct ifaddr *ifa) > * - the interface address is anycast > */ > KASSERT(ia6->ia6_flags & IN6_IFF_TENTATIVE); > - if ((ia6->ia6_flags & IN6_IFF_ANYCAST) || (!ip6_dad_count)) { > + if ((ia6->ia6_flags & IN6_IFF_ANYCAST) || ip6_dad_count_local == 0) { > ia6->ia6_flags &= ~IN6_IFF_TENTATIVE; > > rtm_addr(RTM_CHGADDRATTR, ifa); > @@ -1062,7 +1063,7 @@ nd6_dad_start(struct ifaddr *ifa) > * (re)initialization. > */ > dp->dad_ifa = ifaref(ifa); > - dp->dad_count = ip6_dad_count; > + dp->dad_count = ip6_dad_count_local; > dp->dad_ns_icount = dp->dad_na_icount = 0; > dp->dad_ns_ocount = dp->dad_ns_tcount = 0; > nd6_dad_ns_output(dp, ifa);