From: Alexander Bluhm Subject: Re: Unlock IPV6CTL_DEFMCASTHLIM case of ip6_sysctl() To: Vitaliy Makkoveev Cc: tech@openbsd.org Date: Thu, 24 Jul 2025 21:36:18 +0200 On Thu, Jul 24, 2025 at 09:42:32PM +0300, Vitaliy Makkoveev wrote: > Only ip6_setmoptions() needs to use cached value. Nothing critical if > the destination interface was changed and ip6_output() will load > `ip6_defmcasthlim' once again to re-initialize `ip6' header. OK bluhm@ > Index: sys/netinet6/in6_proto.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/in6_proto.c,v > retrieving revision 1.141 > diff -u -p -r1.141 in6_proto.c > --- sys/netinet6/in6_proto.c 24 Jul 2025 18:02:19 -0000 1.141 > +++ sys/netinet6/in6_proto.c 24 Jul 2025 18:31:27 -0000 > @@ -352,9 +352,9 @@ int ip6_forwarding = 0; /* [a] no forwar > int ip6_mforwarding = 0; /* no multicast forwarding unless ... */ > int ip6_multipath = 0; /* [a] no using multipath routes unless ... */ > int ip6_sendredirects = 1; /* [a] */ > -int ip6_defhlim = IPV6_DEFHLIM; /* [a] */ > -int ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS; > -int ip6_maxfragpackets = 200; /* [a] */ > +int ip6_defhlim = IPV6_DEFHLIM; /* [a] */ > +int ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS; /* [a] */ > +int ip6_maxfragpackets = 200; /* [a] */ > int ip6_maxfrags = 200; > int ip6_log_interval = 5; /* [a] */ > int ip6_hdrnestlimit = 10; /* [a] appropriate? */ > Index: sys/netinet6/ip6_input.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/ip6_input.c,v > retrieving revision 1.285 > diff -u -p -r1.285 ip6_input.c > --- sys/netinet6/ip6_input.c 24 Jul 2025 18:02:19 -0000 1.285 > +++ sys/netinet6/ip6_input.c 24 Jul 2025 18:31:27 -0000 > @@ -1452,10 +1452,10 @@ const struct sysctl_bounded_args ipv6ctl > { IPV6CTL_HDRNESTLIMIT, &ip6_hdrnestlimit, 0, 100 }, > { IPV6CTL_DAD_COUNT, &ip6_dad_count, 0, 10 }, > { IPV6CTL_AUTO_FLOWLABEL, &ip6_auto_flowlabel, 0, 1 }, > + { IPV6CTL_DEFMCASTHLIM, &ip6_defmcasthlim, 0, 255 }, > }; > > const struct sysctl_bounded_args ipv6ctl_vars[] = { > - { IPV6CTL_DEFMCASTHLIM, &ip6_defmcasthlim, 0, 255 }, > { IPV6CTL_USE_DEPRECATED, &ip6_use_deprecated, 0, 1 }, > { IPV6CTL_MAXFRAGS, &ip6_maxfrags, 0, 1000 }, > { IPV6CTL_MFORWARDING, &ip6_mforwarding, 0, 1 }, > @@ -1575,6 +1575,7 @@ ip6_sysctl(int *name, u_int namelen, voi > case IPV6CTL_HDRNESTLIMIT: > case IPV6CTL_DAD_COUNT: > case IPV6CTL_AUTO_FLOWLABEL: > + case IPV6CTL_DEFMCASTHLIM: > return (sysctl_bounded_arr( > ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked), > name, namelen, oldp, oldlenp, newp, newlen)); > Index: sys/netinet6/ip6_output.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/ip6_output.c,v > retrieving revision 1.301 > diff -u -p -r1.301 ip6_output.c > --- sys/netinet6/ip6_output.c 8 Jul 2025 00:47:41 -0000 1.301 > +++ sys/netinet6/ip6_output.c 24 Jul 2025 18:31:27 -0000 > @@ -420,7 +420,7 @@ reroute: > if (im6o != NULL) > ip6->ip6_hlim = im6o->im6o_hlim; > else > - ip6->ip6_hlim = ip6_defmcasthlim; > + ip6->ip6_hlim = atomic_load_int(&ip6_defmcasthlim); > } > > #ifdef IPSEC > @@ -1879,6 +1879,7 @@ ip6_setmoptions(int optname, struct ip6_ > struct ip6_moptions *im6o = *im6op; > struct in6_multi_mship *imm; > struct proc *p = curproc; /* XXX */ > + int ip6_defmcasthlim_local = atomic_load_int(&ip6_defmcasthlim); > > if (im6o == NULL) { > /* > @@ -1890,7 +1891,7 @@ ip6_setmoptions(int optname, struct ip6_ > return (ENOBUFS); > *im6op = im6o; > im6o->im6o_ifidx = 0; > - im6o->im6o_hlim = ip6_defmcasthlim; > + im6o->im6o_hlim = ip6_defmcasthlim_local; > im6o->im6o_loop = IPV6_DEFAULT_MULTICAST_LOOP; > LIST_INIT(&im6o->im6o_memberships); > } > @@ -1937,7 +1938,7 @@ ip6_setmoptions(int optname, struct ip6_ > if (optval < -1 || optval >= 256) > error = EINVAL; > else if (optval == -1) > - im6o->im6o_hlim = ip6_defmcasthlim; > + im6o->im6o_hlim = ip6_defmcasthlim_local; > else > im6o->im6o_hlim = optval; > break; > @@ -2137,7 +2138,7 @@ ip6_setmoptions(int optname, struct ip6_ > * structure. > */ > if (im6o->im6o_ifidx == 0 && > - im6o->im6o_hlim == ip6_defmcasthlim && > + im6o->im6o_hlim == ip6_defmcasthlim_local && > im6o->im6o_loop == IPV6_DEFAULT_MULTICAST_LOOP && > LIST_EMPTY(&im6o->im6o_memberships)) { > free(*im6op, M_IPMOPTS, sizeof(**im6op)); > @@ -2169,7 +2170,7 @@ ip6_getmoptions(int optname, struct ip6_ > hlim = mtod(m, u_int *); > m->m_len = sizeof(u_int); > if (im6o == NULL) > - *hlim = ip6_defmcasthlim; > + *hlim = atomic_load_int(&ip6_defmcasthlim); > else > *hlim = im6o->im6o_hlim; > return (0); > @@ -2178,7 +2179,7 @@ ip6_getmoptions(int optname, struct ip6_ > loop = mtod(m, u_int *); > m->m_len = sizeof(u_int); > if (im6o == NULL) > - *loop = ip6_defmcasthlim; > + *loop = atomic_load_int(&ip6_defmcasthlim); > else > *loop = im6o->im6o_loop; > return (0);