Download raw body.
IP6_EXTHDR_GET pass mbuf pointer
On Thu, May 22, 2025 at 11:08:06PM +0900, Alexander Bluhm wrote:
> 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?
Would it make sense to actually kill this macro and make it a proper
function? This thing is a monster and it probably makes things slower if
anything.
> 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);
> }
>
--
:wq Claudio
IP6_EXTHDR_GET pass mbuf pointer