Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
Unlock IPV6CTL_MCAST_PMTU case of ip6_sysctl()
To:
Alexander Bluhm <bluhm@openbsd.org>, tech@openbsd.org
Date:
Fri, 25 Jul 2025 23:40:22 +0300

Download raw body.

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