Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
IP6_EXTHDR_GET pass mbuf pointer
To:
tech@openbsd.org
Date:
Thu, 22 May 2025 23:08:06 +0900

Download raw body.

Thread
Hi,

I would like to pass an mbuf pointer instead of an mbuf to
IP6_EXTHDR_GET().  m_pulldown() may free the mbuf and the macro
sets m to NULL.  This is not obvious, it is much cleaner when you
pass a pointer if the value can be modified.

The main reason for this change is that I am slowly converting the
protocol input functions to deal with mbuf pointer instead of mbuf.
m_pullup() and m_pulldown() may modify or free the mbuf, and then
dangling pointers are lying around in the callers.  We had problmes
with that before.

I would prefer to adjust all pointers, which is possible when using
*mp instead of m and setting mp to NULL after free.  Then either a
NULL dereference happens or a double free is ignored.  Both are
much easier to deal with than a use after free.

I have done a similar change with m_freemp(mp) some years ago,
IP6_EXTHDR_GET() is the next interface on my list.

ok?

bluhm

Index: netinet/ip6.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip6.h,v
diff -u -p -r1.21 ip6.h
--- netinet/ip6.h	1 Jan 2025 13:44:22 -0000	1.21
+++ netinet/ip6.h	22 May 2025 06:50:06 -0000
@@ -272,21 +272,21 @@ struct ip6_frag {
  * The pointer to the region will be returned to pointer variable "val",
  * with type "typ".
  */
-#define IP6_EXTHDR_GET(val, typ, m, off, len)				\
+#define IP6_EXTHDR_GET(val, typ, mp, off, len)				\
 do {									\
 	struct mbuf *t;							\
 	int tmp;							\
-	if ((m)->m_len >= (off) + (len))				\
-		(val) = (typ)(mtod((m), caddr_t) + (off));		\
+	if ((*(mp))->m_len >= (off) + (len))				\
+		(val) = (typ)(mtod((*(mp)), caddr_t) + (off));		\
 	else {								\
-		t = m_pulldown((m), (off), (len), &tmp);		\
+		t = m_pulldown((*(mp)), (off), (len), &tmp);		\
 		if (t) {						\
 			if (t->m_len < tmp + (len))			\
 				panic("m_pulldown malfunction");	\
 			(val) = (typ)(mtod(t, caddr_t) + tmp);		\
 		} else {						\
 			(val) = (typ)NULL;				\
-			(m) = NULL;					\
+			(*(mp)) = NULL;					\
 		}							\
 	}								\
 } while (/* CONSTCOND */ 0)
Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
diff -u -p -r1.447 tcp_input.c
--- netinet/tcp_input.c	19 May 2025 02:27:57 -0000	1.447
+++ netinet/tcp_input.c	22 May 2025 06:51:19 -0000
@@ -448,7 +448,7 @@ tcp_input_solocked(struct mbuf **mp, int
 	 * Get IP and TCP header together in first mbuf.
 	 * Note: IP leaves IP header in first mbuf.
 	 */
-	IP6_EXTHDR_GET(th, struct tcphdr *, m, iphlen, sizeof(*th));
+	IP6_EXTHDR_GET(th, struct tcphdr *, mp, iphlen, sizeof(*th));
 	if (!th) {
 		tcpstat_inc(tcps_rcvshort);
 		return IPPROTO_DONE;
@@ -532,7 +532,7 @@ tcp_input_solocked(struct mbuf **mp, int
 	}
 	tlen -= off;
 	if (off > sizeof(struct tcphdr)) {
-		IP6_EXTHDR_GET(th, struct tcphdr *, m, iphlen, off);
+		IP6_EXTHDR_GET(th, struct tcphdr *, mp, iphlen, off);
 		if (!th) {
 			tcpstat_inc(tcps_rcvshort);
 			return IPPROTO_DONE;
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v
diff -u -p -r1.337 udp_usrreq.c
--- netinet/udp_usrreq.c	12 May 2025 17:21:21 -0000	1.337
+++ netinet/udp_usrreq.c	22 May 2025 06:52:01 -0000
@@ -213,7 +213,7 @@ udp_input(struct mbuf **mp, int *offp, i
 
 	udpstat_inc(udps_ipackets);
 
-	IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr));
+	IP6_EXTHDR_GET(uh, struct udphdr *, mp, iphlen, sizeof(struct udphdr));
 	if (!uh) {
 		udpstat_inc(udps_hdrops);
 		return IPPROTO_DONE;
Index: netinet6/dest6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/dest6.c,v
diff -u -p -r1.21 dest6.c
--- netinet6/dest6.c	2 Mar 2025 21:28:32 -0000	1.21
+++ netinet6/dest6.c	22 May 2025 06:53:25 -0000
@@ -57,12 +57,12 @@ dest6_input(struct mbuf **mp, int *offp,
 	u_int8_t *opt;
 
 	/* validation of the length of the header */
-	IP6_EXTHDR_GET(dstopts, struct ip6_dest *, *mp, off, sizeof(*dstopts));
+	IP6_EXTHDR_GET(dstopts, struct ip6_dest *, mp, off, sizeof(*dstopts));
 	if (dstopts == NULL)
 		return IPPROTO_DONE;
 	dstoptlen = (dstopts->ip6d_len + 1) << 3;
 
-	IP6_EXTHDR_GET(dstopts, struct ip6_dest *, *mp, off, dstoptlen);
+	IP6_EXTHDR_GET(dstopts, struct ip6_dest *, mp, off, dstoptlen);
 	if (dstopts == NULL)
 		return IPPROTO_DONE;
 	off += dstoptlen;
Index: netinet6/frag6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/frag6.c,v
diff -u -p -r1.90 frag6.c
--- netinet6/frag6.c	2 Mar 2025 21:28:32 -0000	1.90
+++ netinet6/frag6.c	22 May 2025 07:06:00 -0000
@@ -114,7 +114,7 @@ int
 frag6_input(struct mbuf **mp, int *offp, int proto, int af,
     struct netstack *ns)
 {
-	struct mbuf *m = *mp, *t;
+	struct mbuf *t;
 	struct ip6_hdr *ip6;
 	struct ip6_frag *ip6f;
 	struct ip6q *q6;
@@ -124,14 +124,14 @@ frag6_input(struct mbuf **mp, int *offp,
 	int fragoff, frgpartlen;	/* must be larger than u_int16_t */
 	u_int8_t ecn, ecn0;
 
-	ip6 = mtod(m, struct ip6_hdr *);
-	IP6_EXTHDR_GET(ip6f, struct ip6_frag *, m, offset, sizeof(*ip6f));
+	ip6 = mtod(*mp, struct ip6_hdr *);
+	IP6_EXTHDR_GET(ip6f, struct ip6_frag *, mp, offset, sizeof(*ip6f));
 	if (ip6f == NULL)
 		return IPPROTO_DONE;
 
 	/* jumbo payload can't contain a fragment header */
 	if (ip6->ip6_plen == 0) {
-		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
+		icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 		    offset);
 		return IPPROTO_DONE;
 	}
@@ -144,7 +144,7 @@ frag6_input(struct mbuf **mp, int *offp,
 	 */
 	if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) &&
 	    (((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
-		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
+		icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 		    offsetof(struct ip6_hdr, ip6_plen));
 		return IPPROTO_DONE;
 	}
@@ -169,7 +169,7 @@ frag6_input(struct mbuf **mp, int *offp,
 
 	/* Ignore empty non atomic fragment, do not classify as overlapping. */
 	if (sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) <= offset) {
-		m_freem(m);
+		m_freemp(mp);
 		return IPPROTO_DONE;
 	}
 
@@ -249,14 +249,15 @@ frag6_input(struct mbuf **mp, int *offp,
 		/* The 1st fragment has already arrived. */
 		if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
 			mtx_leave(&frag6_mutex);
-			icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
+			icmp6_error(*mp, ICMP6_PARAM_PROB,
+			    ICMP6_PARAMPROB_HEADER,
 			    offset - sizeof(struct ip6_frag) +
 			    offsetof(struct ip6_frag, ip6f_offlg));
 			return (IPPROTO_DONE);
 		}
 	} else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
 		mtx_leave(&frag6_mutex);
-		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
+		icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 			    offset - sizeof(struct ip6_frag) +
 				offsetof(struct ip6_frag, ip6f_offlg));
 		return (IPPROTO_DONE);
@@ -304,7 +305,7 @@ frag6_input(struct mbuf **mp, int *offp,
 	ip6af->ip6af_off = fragoff;
 	ip6af->ip6af_frglen = frgpartlen;
 	ip6af->ip6af_offset = offset;
-	ip6af->ip6af_m = m;
+	ip6af->ip6af_m = *mp;
 
 	if (first_frag) {
 		paf6 = NULL;
@@ -392,7 +393,7 @@ frag6_input(struct mbuf **mp, int *offp,
 	 */
 	ip6af = LIST_FIRST(&q6->ip6q_asfrag);
 	LIST_REMOVE(ip6af, ip6af_list);
-	t = m = ip6af->ip6af_m;
+	t = *mp = ip6af->ip6af_m;
 	while ((af6 = LIST_FIRST(&q6->ip6q_asfrag)) != NULL) {
 		LIST_REMOVE(af6, ip6af_list);
 		while (t->m_next)
@@ -415,7 +416,7 @@ frag6_input(struct mbuf **mp, int *offp,
 		pool_put(&ip6q_pool, q6);
 		goto dropfrag;
 	}
-	ip6 = mtod(m, struct ip6_hdr *);
+	ip6 = mtod(*mp, struct ip6_hdr *);
 	ip6->ip6_plen = htons(next);
 	ip6->ip6_src = q6->ip6q_src;
 	ip6->ip6_dst = q6->ip6q_dst;
@@ -424,7 +425,7 @@ frag6_input(struct mbuf **mp, int *offp,
 	nxt = q6->ip6q_nxt;
 
 	/* Delete frag6 header */
-	if (frag6_deletefraghdr(m, offset) != 0) {
+	if (frag6_deletefraghdr(*mp, offset) != 0) {
 		TAILQ_REMOVE(&frag6_queue, q6, ip6q_queue);
 		frag6_nfrags -= q6->ip6q_nfrag;
 		frag6_nfragpackets--;
@@ -441,16 +442,16 @@ frag6_input(struct mbuf **mp, int *offp,
 
 	pool_put(&ip6q_pool, q6);
 
-	m_calchdrlen(m);
+	m_calchdrlen(*mp);
 
 	/*
 	 * Restore NXT to the original.
 	 */
 	{
-		int prvnxt = ip6_get_prevhdr(m, offset);
+		int prvnxt = ip6_get_prevhdr(*mp, offset);
 		uint8_t *prvnxtp;
 
-		IP6_EXTHDR_GET(prvnxtp, uint8_t *, m, prvnxt,
+		IP6_EXTHDR_GET(prvnxtp, uint8_t *, mp, prvnxt,
 		    sizeof(*prvnxtp));
 		if (prvnxtp == NULL)
 			goto dropfrag;
@@ -462,10 +463,7 @@ frag6_input(struct mbuf **mp, int *offp,
 	/*
 	 * Tell launch routine the next header
 	 */
-
-	*mp = m;
 	*offp = offset;
-
 	return nxt;
 
  flushfrags:
@@ -484,12 +482,12 @@ frag6_input(struct mbuf **mp, int *offp,
 	}
 	ip6stat_add(ip6s_fragdropped, q6->ip6q_nfrag + 1);
 	pool_put(&ip6q_pool, q6);
-	m_freem(m);
+	m_freemp(mp);
 	return IPPROTO_DONE;
 
  dropfrag:
 	ip6stat_inc(ip6s_fragdropped);
-	m_freem(m);
+	m_freemp(mp);
 	return IPPROTO_DONE;
 }
 
Index: netinet6/icmp6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/icmp6.c,v
diff -u -p -r1.264 icmp6.c
--- netinet6/icmp6.c	19 May 2025 07:34:21 -0000	1.264
+++ netinet6/icmp6.c	22 May 2025 07:23:54 -0000
@@ -281,7 +281,7 @@ icmp6_do_error(struct mbuf *m, int type,
 	if (off >= 0 && nxt == IPPROTO_ICMPV6) {
 		struct icmp6_hdr *icp;
 
-		IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off,
+		IP6_EXTHDR_GET(icp, struct icmp6_hdr *, &m, off,
 			sizeof(*icp));
 		if (icp == NULL) {
 			icmp6stat_inc(icp6s_tooshort);
@@ -407,7 +407,7 @@ icmp6_input(struct mbuf **mp, int *offp,
 	/*
 	 * calculate the checksum
 	 */
-	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
+	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, mp, off, sizeof(*icmp6));
 	if (icmp6 == NULL) {
 		icmp6stat_inc(icp6s_tooshort);
 		return IPPROTO_DONE;
@@ -588,7 +588,7 @@ icmp6_input(struct mbuf **mp, int *offp,
 			n->m_next = n0;
 		} else {
 	 deliverecho:
-			IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off,
+			IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, &n, off,
 			    sizeof(*nicmp6));
 			noff = off;
 		}
@@ -762,7 +762,7 @@ icmp6_notify_error(struct mbuf *m, int o
 		icmp6stat_inc(icp6s_tooshort);
 		goto freeit;
 	}
-	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
+	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, &m, off,
 		       sizeof(*icmp6) + sizeof(struct ip6_hdr));
 	if (icmp6 == NULL) {
 		icmp6stat_inc(icp6s_tooshort);
@@ -791,7 +791,7 @@ icmp6_notify_error(struct mbuf *m, int o
 			case IPPROTO_HOPOPTS:
 			case IPPROTO_DSTOPTS:
 			case IPPROTO_AH:
-				IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
+				IP6_EXTHDR_GET(eh, struct ip6_ext *, &m,
 					       eoff, sizeof(*eh));
 				if (eh == NULL) {
 					icmp6stat_inc(icp6s_tooshort);
@@ -813,7 +813,7 @@ icmp6_notify_error(struct mbuf *m, int o
 				 * information that depends on the final
 				 * destination (e.g. path MTU).
 				 */
-				IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
+				IP6_EXTHDR_GET(rth, struct ip6_rthdr *, &m,
 					       eoff, sizeof(*rth));
 				if (rth == NULL) {
 					icmp6stat_inc(icp6s_tooshort);
@@ -833,7 +833,7 @@ icmp6_notify_error(struct mbuf *m, int o
 					int hops;
 
 					IP6_EXTHDR_GET(rth0,
-						       struct ip6_rthdr0 *, m,
+						       struct ip6_rthdr0 *, &m,
 						       eoff, rthlen);
 					if (rth0 == NULL) {
 						icmp6stat_inc(icp6s_tooshort);
@@ -848,7 +848,7 @@ icmp6_notify_error(struct mbuf *m, int o
 				nxt = rth->ip6r_nxt;
 				break;
 			case IPPROTO_FRAGMENT:
-				IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
+				IP6_EXTHDR_GET(fh, struct ip6_frag *, &m,
 					       eoff, sizeof(*fh));
 				if (fh == NULL) {
 					icmp6stat_inc(icp6s_tooshort);
@@ -879,7 +879,7 @@ icmp6_notify_error(struct mbuf *m, int o
 			}
 		}
 	  notify:
-		IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
+		IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, &m, off,
 			       sizeof(*icmp6) + sizeof(struct ip6_hdr));
 		if (icmp6 == NULL) {
 			icmp6stat_inc(icp6s_tooshort);
@@ -1204,7 +1204,7 @@ icmp6_redirect_input(struct mbuf *m, int
 	if (!(ifp->if_xflags & IFXF_AUTOCONF6))
 		goto freeit;
 
-	IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len);
+	IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, &m, off, icmp6len);
 	if (nd_rd == NULL) {
 		icmp6stat_inc(icp6s_tooshort);
 		if_put(ifp);
Index: netinet6/ip6_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
diff -u -p -r1.270 ip6_input.c
--- netinet6/ip6_input.c	19 May 2025 06:38:33 -0000	1.270
+++ netinet6/ip6_input.c	22 May 2025 07:11:35 -0000
@@ -685,7 +685,7 @@ ip6_hbhchcheck(struct mbuf **mp, int *of
 				    (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
 			goto bad;
 		}
-		IP6_EXTHDR_GET(hbh, struct ip6_hbh *, *mp,
+		IP6_EXTHDR_GET(hbh, struct ip6_hbh *, mp,
 		    sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
 		if (hbh == NULL) {
 			ip6stat_inc(ip6s_tooshort);
@@ -814,14 +814,14 @@ ip6_hopopts_input(struct mbuf **mp, int 
 	struct ip6_hbh *hbh;
 
 	/* validation of the length of the header */
-	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, *mp,
+	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, mp,
 		sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
 	if (hbh == NULL) {
 		ip6stat_inc(ip6s_tooshort);
 		return -1;
 	}
 	hbhlen = (hbh->ip6h_len + 1) << 3;
-	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, *mp, sizeof(struct ip6_hdr),
+	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, mp, sizeof(struct ip6_hdr),
 		hbhlen);
 	if (hbh == NULL) {
 		ip6stat_inc(ip6s_tooshort);
Index: netinet6/mld6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/mld6.c,v
diff -u -p -r1.65 mld6.c
--- netinet6/mld6.c	2 Mar 2025 21:28:32 -0000	1.65
+++ netinet6/mld6.c	22 May 2025 07:16:49 -0000
@@ -179,7 +179,7 @@ mld6_input(struct mbuf *m, int off)
 	/* XXX: These are necessary for KAME's link-local hack */
 	struct in6_addr all_nodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
 
-	IP6_EXTHDR_GET(mldh, struct mld_hdr *, m, off, sizeof(*mldh));
+	IP6_EXTHDR_GET(mldh, struct mld_hdr *, &m, off, sizeof(*mldh));
 	if (mldh == NULL) {
 		icmp6stat_inc(icp6s_tooshort);
 		return;
Index: netinet6/nd6_nbr.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_nbr.c,v
diff -u -p -r1.158 nd6_nbr.c
--- netinet6/nd6_nbr.c	19 May 2025 06:42:53 -0000	1.158
+++ netinet6/nd6_nbr.c	22 May 2025 07:13:58 -0000
@@ -117,7 +117,7 @@ nd6_ns_input(struct mbuf *m, int off, in
 	if (ifp == NULL)
 		goto freeit;
 
-	IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
+	IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, &m, off, icmp6len);
 	if (nd_ns == NULL) {
 		icmp6stat_inc(icp6s_tooshort);
 		if_put(ifp);
@@ -540,7 +540,7 @@ nd6_na_input(struct mbuf *m, int off, in
 	if (ip6->ip6_hlim != 255)
 		goto bad;
 
-	IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
+	IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, &m, off, icmp6len);
 	if (nd_na == NULL) {
 		icmp6stat_inc(icp6s_tooshort);
 		if_put(ifp);
Index: netinet6/nd6_rtr.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_rtr.c,v
diff -u -p -r1.173 nd6_rtr.c
--- netinet6/nd6_rtr.c	19 May 2025 06:39:19 -0000	1.173
+++ netinet6/nd6_rtr.c	22 May 2025 07:13:17 -0000
@@ -92,7 +92,7 @@ nd6_rtr_cache(struct mbuf *m, int off, i
 		if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
 			goto freeit;
 
-		IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off,
+		IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, &m, off,
 		    icmp6len);
 		if (nd_rs == NULL) {
 			icmp6stat_inc(icp6s_tooshort);
@@ -109,7 +109,7 @@ nd6_rtr_cache(struct mbuf *m, int off, i
 		if (!IN6_IS_ADDR_LINKLOCAL(&saddr6))
 			goto bad;
 
-		IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off,
+		IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, &m, off,
 		    icmp6len);
 		if (nd_ra == NULL) {
 			icmp6stat_inc(icp6s_tooshort);
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
diff -u -p -r1.190 raw_ip6.c
--- netinet6/raw_ip6.c	11 Mar 2025 15:31:03 -0000	1.190
+++ netinet6/raw_ip6.c	22 May 2025 07:12:47 -0000
@@ -147,7 +147,7 @@ rip6_input(struct mbuf **mp, int *offp, 
 	if (proto == IPPROTO_ICMPV6) {
 		struct icmp6_hdr *icmp6;
 
-		IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, *offp,
+		IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, mp, *offp,
 		    sizeof(*icmp6));
 		if (icmp6 == NULL)
 			return IPPROTO_DONE;
Index: netinet6/route6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/route6.c,v
diff -u -p -r1.23 route6.c
--- netinet6/route6.c	2 Mar 2025 21:28:32 -0000	1.23
+++ netinet6/route6.c	22 May 2025 07:17:18 -0000
@@ -55,12 +55,11 @@ route6_input(struct mbuf **mp, int *offp
     struct netstack *ns)
 {
 	struct ip6_hdr *ip6;
-	struct mbuf *m = *mp;
 	struct ip6_rthdr *rh;
 	int off = *offp, rhlen;
 
-	ip6 = mtod(m, struct ip6_hdr *);
-	IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh));
+	ip6 = mtod(*mp, struct ip6_hdr *);
+	IP6_EXTHDR_GET(rh, struct ip6_rthdr *, mp, off, sizeof(*rh));
 	if (rh == NULL) {
 		ip6stat_inc(ip6s_tooshort);
 		return IPPROTO_DONE;
@@ -80,7 +79,7 @@ route6_input(struct mbuf **mp, int *offp
 			break;	/* Final dst. Just ignore the header. */
 		}
 		ip6stat_inc(ip6s_badoptions);
-		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
+		icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 			    (caddr_t)&rh->ip6r_type - (caddr_t)ip6);
 		return (IPPROTO_DONE);
 	}