From: Vitaliy Makkoveev Subject: Unlock IPV6CTL_MCAST_PMTU case of ip6_sysctl() To: Alexander Bluhm , tech@openbsd.org Date: Fri, 25 Jul 2025 23:40:22 +0300 Cache `ip6_mcast_pmtu' value and pass it to phyint_send6(). Not used in ramdisk. Index: sys/netinet6/in6_proto.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_proto.c,v retrieving revision 1.145 diff -u -p -r1.145 in6_proto.c --- sys/netinet6/in6_proto.c 25 Jul 2025 20:04:47 -0000 1.145 +++ sys/netinet6/in6_proto.c 25 Jul 2025 20:37:05 -0000 @@ -362,7 +362,7 @@ int ip6_dad_count = 1; /* [a] DupAddrDet int ip6_dad_pending; /* number of currently running DADs */ int ip6_auto_flowlabel = 1; /* [a] */ int ip6_use_deprecated = 1; /* [a] allow deprecated addr (RFC2462 5.5.4) */ -int ip6_mcast_pmtu = 0; /* enable pMTU discovery for multicast? */ +int ip6_mcast_pmtu = 0; /* [a] enable pMTU discovery for multicast? */ int ip6_neighborgcthresh = 2048; /* Threshold # of NDP entries for GC */ int ip6_maxdynroutes = 4096; /* Max # of routes created via redirect */ time_t ip6_log_time = (time_t)0L; Index: sys/netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.290 diff -u -p -r1.290 ip6_input.c --- sys/netinet6/ip6_input.c 25 Jul 2025 20:04:47 -0000 1.290 +++ sys/netinet6/ip6_input.c 25 Jul 2025 20:37:05 -0000 @@ -1457,10 +1457,10 @@ const struct sysctl_bounded_args ipv6ctl { IPV6CTL_USE_DEPRECATED, &ip6_use_deprecated, 0, 1 }, { IPV6CTL_MAXFRAGS, &ip6_maxfrags, 0, 1000 }, { IPV6CTL_MFORWARDING, &ip6_mforwarding, 0, 1 }, + { IPV6CTL_MCAST_PMTU, &ip6_mcast_pmtu, 0, 1 }, }; const struct sysctl_bounded_args ipv6ctl_vars[] = { - { IPV6CTL_MCAST_PMTU, &ip6_mcast_pmtu, 0, 1 }, { IPV6CTL_NEIGHBORGCTHRESH, &ip6_neighborgcthresh, -1, 5 * 2048 }, { IPV6CTL_MAXDYNROUTES, &ip6_maxdynroutes, -1, 5 * 4096 }, }; @@ -1577,6 +1577,7 @@ ip6_sysctl(int *name, u_int namelen, voi case IPV6CTL_USE_DEPRECATED: case IPV6CTL_MAXFRAGS: case IPV6CTL_MFORWARDING: + case IPV6CTL_MCAST_PMTU: return (sysctl_bounded_arr( ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked), name, namelen, oldp, oldlenp, newp, newlen)); Index: sys/netinet6/ip6_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.152 diff -u -p -r1.152 ip6_mroute.c --- sys/netinet6/ip6_mroute.c 24 Jul 2025 21:35:53 -0000 1.152 +++ sys/netinet6/ip6_mroute.c 25 Jul 2025 20:37:05 -0000 @@ -125,7 +125,7 @@ int mcast6_debug = 1; #endif int ip6_mdq(struct mbuf *, struct ifnet *, struct rtentry *, int); -void phyint_send6(struct ifnet *, struct ip6_hdr *, struct mbuf *, int); +void phyint_send6(struct ifnet *, struct ip6_hdr *, struct mbuf *, int, int); /* * Globals. All but ip6_mrouter, ip6_mrtproto and mrt6stat could be static, @@ -1078,7 +1078,7 @@ ip6_mdq(struct mbuf *m, struct ifnet *if struct mif6 *m6, *mifp = (struct mif6 *)ifp->if_mcast6; struct mf6c *mf6c = (struct mf6c *)rt->rt_llinfo; struct ifnet *ifn; - int plen = m->m_pkthdr.len; + int plen = m->m_pkthdr.len, ip6_mcast_pmtu_local; if (mifp == NULL || mf6c == NULL) { rtfree(rt); @@ -1111,6 +1111,8 @@ ip6_mdq(struct mbuf *m, struct ifnet *if * For each mif, forward a copy of the packet if there are group * members downstream on the interface. */ + ip6_mcast_pmtu_local = atomic_load_int(&ip6_mcast_pmtu); + do { /* Don't consider non multicast routes. */ if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != @@ -1160,7 +1162,7 @@ ip6_mdq(struct mbuf *m, struct ifnet *if m6->m6_pkt_out++; m6->m6_bytes_out += plen; - phyint_send6(ifn, ip6, m, flags); + phyint_send6(ifn, ip6, m, flags, ip6_mcast_pmtu_local); if_put(ifn); } while ((rt = rtable_iterate(rt)) != NULL); @@ -1168,7 +1170,8 @@ ip6_mdq(struct mbuf *m, struct ifnet *if } void -phyint_send6(struct ifnet *ifp, struct ip6_hdr *ip6, struct mbuf *m, int flags) +phyint_send6(struct ifnet *ifp, struct ip6_hdr *ip6, struct mbuf *m, + int flags, int mcast_pmtu) { struct mbuf *mb_copy; struct sockaddr_in6 *dst6, sin6; @@ -1228,7 +1231,7 @@ phyint_send6(struct ifnet *ifp, struct i dst6->sin6_addr = ip6->ip6_dst; error = ifp->if_output(ifp, mb_copy, sin6tosa(dst6), NULL); } else { - if (ip6_mcast_pmtu) + if (mcast_pmtu) icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); else {