From: Alexander Bluhm Subject: Re: Unlock IPV6CTL_MFORWARDING case of ip6_sysctl() To: Vitaliy Makkoveev Cc: tech@openbsd.org Date: Fri, 25 Jul 2025 14:14:18 +0200 On Fri, Jul 25, 2025 at 01:25:52PM +0300, Vitaliy Makkoveev wrote: > ip6_input_if() and ip6_output() belongs to different paths. Nothing > wrong to reload `ip6_mforwarding' while the interface was changed in > ip6_output(). "&& (flags & IPV6_FORWARDING) == 0" prevents us from re-evaluating ip6_mforwarding in ip6_output(). OK bluhm@ > Index: sys/netinet6/in6_proto.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/in6_proto.c,v > diff -u -p -r1.144 in6_proto.c > --- sys/netinet6/in6_proto.c 24 Jul 2025 22:57:24 -0000 1.144 > +++ sys/netinet6/in6_proto.c 25 Jul 2025 09:09:23 -0000 > @@ -349,7 +349,7 @@ const struct domain inet6domain = { > * Internet configuration info > */ > int ip6_forwarding = 0; /* [a] no forwarding unless sysctl to enable */ > -int ip6_mforwarding = 0; /* no multicast forwarding unless ... */ > +int ip6_mforwarding = 0; /* [a] 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] */ > Index: sys/netinet6/ip6_input.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/ip6_input.c,v > diff -u -p -r1.289 ip6_input.c > --- sys/netinet6/ip6_input.c 24 Jul 2025 22:57:24 -0000 1.289 > +++ sys/netinet6/ip6_input.c 25 Jul 2025 09:09:23 -0000 > @@ -477,7 +477,8 @@ ip6_input_if(struct mbuf **mp, int *offp > ours = 1; > > #ifdef MROUTING > - if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain]) { > + if (atomic_load_int(&ip6_mforwarding) && > + ip6_mrouter[ifp->if_rdomain]) { > int error; > > nxt = ip6_hbhchcheck(&m, offp, &ours, flags); > @@ -1455,10 +1456,10 @@ const struct sysctl_bounded_args ipv6ctl > { 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 }, > }; > > const struct sysctl_bounded_args ipv6ctl_vars[] = { > - { IPV6CTL_MFORWARDING, &ip6_mforwarding, 0, 1 }, > { IPV6CTL_MCAST_PMTU, &ip6_mcast_pmtu, 0, 1 }, > { IPV6CTL_NEIGHBORGCTHRESH, &ip6_neighborgcthresh, -1, 5 * 2048 }, > { IPV6CTL_MAXDYNROUTES, &ip6_maxdynroutes, -1, 5 * 4096 }, > @@ -1575,6 +1576,7 @@ ip6_sysctl(int *name, u_int namelen, voi > case IPV6CTL_DEFMCASTHLIM: > case IPV6CTL_USE_DEPRECATED: > case IPV6CTL_MAXFRAGS: > + case IPV6CTL_MFORWARDING: > 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 > diff -u -p -r1.302 ip6_output.c > --- sys/netinet6/ip6_output.c 24 Jul 2025 19:49:08 -0000 1.302 > +++ sys/netinet6/ip6_output.c 25 Jul 2025 09:09:23 -0000 > @@ -529,7 +529,8 @@ reroute: > * above, will be forwarded by the ip6_input() routine, > * if necessary. > */ > - if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain] && > + if (atomic_load_int(&ip6_mforwarding) && > + ip6_mrouter[ifp->if_rdomain] && > (flags & IPV6_FORWARDING) == 0) { > if (ip6_mforward(ip6, ifp, m, flags) != 0) { > m_freem(m);