Author: bz
Date: Fri Nov 15 21:40:40 2019
New Revision: 354748
URL: https://svnweb.freebsd.org/changeset/base/354748

Log:
  netinet6: Remove PULLDOWN_TESTs.
  
  Remove the KAME introduced PULLDOWN_TESTs which did not even
  have a compile-time option in sys/conf to turn them on for a
  custom kernel build. They made the code a lot harder to read
  or more complicated in a few cases.
  
  Convert the IP6_EXTHDR_CHECK() calls into FreeBSD looking code.
  Rather than throwing the packet away if it would not fit the
  KAME mbuf expectations, convert the macros to m_pullup() calls.
  Do not do any extra manual conditional checks upfront as to
  whether the m_len would suffice (*), simply let m_pullup() do
  its work (incl. an early check).
  
  Remove extra m_pullup() calls where earlier in the function or
  the only caller has already done the pullup.
  
  Discussed with:       rwatson (*)
  Reviewed by:  ae
  MFC after:    8 weeks
  Sponsored by: Netflix
  Differential Revision:        https://reviews.freebsd.org/D22334

Modified:
  head/sys/netinet6/dest6.c
  head/sys/netinet6/frag6.c
  head/sys/netinet6/icmp6.c
  head/sys/netinet6/ip6_input.c
  head/sys/netinet6/ip6_mroute.c
  head/sys/netinet6/mld6.c
  head/sys/netinet6/nd6_nbr.c
  head/sys/netinet6/nd6_rtr.c
  head/sys/netinet6/route6.c
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet6/dest6.c
==============================================================================
--- head/sys/netinet6/dest6.c   Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/dest6.c   Fri Nov 15 21:40:40 2019        (r354748)
@@ -72,25 +72,23 @@ dest6_input(struct mbuf **mp, int *offp, int proto)
        m = *mp;
        off = *offp;
 
-       /* validation of the length of the header */
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, sizeof(*dstopts), IPPROTO_DONE);
+       /* Validation of the length of the header. */
+       m = m_pullup(m, off + sizeof(*dstopts));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = m;
+               return (IPPROTO_DONE);
+       }
        dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
-#else
-       IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, sizeof(*dstopts));
-       if (dstopts == NULL)
-               return IPPROTO_DONE;
-#endif
        dstoptlen = (dstopts->ip6d_len + 1) << 3;
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, dstoptlen, IPPROTO_DONE);
+       m = m_pullup(m, off + dstoptlen);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = m;
+               return (IPPROTO_DONE);
+       }
        dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
-#else
-       IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, dstoptlen);
-       if (dstopts == NULL)
-               return IPPROTO_DONE;
-#endif
        off += dstoptlen;
        dstoptlen -= sizeof(struct ip6_dest);
        opt = (u_int8_t *)dstopts + sizeof(struct ip6_dest);

Modified: head/sys/netinet6/frag6.c
==============================================================================
--- head/sys/netinet6/frag6.c   Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/frag6.c   Fri Nov 15 21:40:40 2019        (r354748)
@@ -218,30 +218,22 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGBUCKETSIZE, 
  * Remove the IPv6 fragmentation header from the mbuf.
  */
 int
-ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
+ip6_deletefraghdr(struct mbuf *m, int offset, int wait __unused)
 {
        struct ip6_hdr *ip6;
-       struct mbuf *t;
 
-       /* Delete frag6 header. */
-       if (m->m_len >= offset + sizeof(struct ip6_frag)) {
+       KASSERT(m->m_len >= offset + sizeof(struct ip6_frag),
+           ("%s: ext headers not contigous in mbuf %p m_len %d >= "
+           "offset %d + %zu\n", __func__, m, m->m_len, offset,
+           sizeof(struct ip6_frag)));
 
-               /* This is the only possible case with !PULLDOWN_TEST. */
-               ip6 = mtod(m, struct ip6_hdr *);
-               bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag),
-                   offset);
-               m->m_data += sizeof(struct ip6_frag);
-               m->m_len -= sizeof(struct ip6_frag);
-       } else {
-
-               /* This comes with no copy if the boundary is on cluster. */
-               if ((t = m_split(m, offset, wait)) == NULL)
-                       return (ENOMEM);
-               m_adj(t, sizeof(struct ip6_frag));
-               m_cat(m, t);
-       }
-
+       /* Delete frag6 header. */
+       ip6 = mtod(m, struct ip6_hdr *);
+       bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag), offset);
+       m->m_data += sizeof(struct ip6_frag);
+       m->m_len -= sizeof(struct ip6_frag);
        m->m_flags |= M_FRAGMENTED;
+
        return (0);
 }
 
@@ -397,15 +389,13 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 
        M_ASSERTPKTHDR(m);
 
-       ip6 = mtod(m, struct ip6_hdr *);
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE);
-       ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset);
-#else
-       IP6_EXTHDR_GET(ip6f, struct ip6_frag *, m, offset, sizeof(*ip6f));
-       if (ip6f == NULL)
+       m = m_pullup(m, offset + sizeof(struct ip6_frag));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = NULL;
                return (IPPROTO_DONE);
-#endif
+       }
+       ip6 = mtod(m, struct ip6_hdr *);
 
        dstifp = NULL;
        /* Find the destination interface of the packet. */
@@ -429,6 +419,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
         * sizeof(struct ip6_frag) == 8
         * sizeof(struct ip6_hdr) = 40
         */
+       ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset);
        if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) &&
            (((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
                icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
@@ -833,15 +824,7 @@ postinsert:
        V_ip6qb[bucket].count--;
        atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag);
 
-       if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0) {
-#ifdef MAC
-               mac_ip6q_destroy(q6);
-#endif
-               free(q6, M_FRAG6);
-               atomic_subtract_int(&V_frag6_nfragpackets, 1);
-
-               goto dropfrag;
-       }
+       ip6_deletefraghdr(m, offset, M_NOWAIT);
 
        /* Set nxt(-hdr field value) to the original value. */
        m_copyback(m, ip6_get_prevhdr(m, offset), sizeof(uint8_t),

Modified: head/sys/netinet6/icmp6.c
==============================================================================
--- head/sys/netinet6/icmp6.c   Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/icmp6.c   Fri Nov 15 21:40:40 2019        (r354748)
@@ -232,16 +232,13 @@ icmp6_error2(struct mbuf *m, int type, int code, int p
        if (ifp == NULL)
                return;
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), );
-#else
        if (m->m_len < sizeof(struct ip6_hdr)) {
                m = m_pullup(m, sizeof(struct ip6_hdr));
-               if (m == NULL)
+               if (m == NULL) {
+                       IP6STAT_INC(ip6s_exthdrtoolong);
                        return;
+               }
        }
-#endif
-
        ip6 = mtod(m, struct ip6_hdr *);
 
        if (in6_setscope(&ip6->ip6_src, ifp, NULL) != 0)
@@ -276,15 +273,13 @@ icmp6_error(struct mbuf *m, int type, int code, int pa
        }
 #endif
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), );
-#else
        if (m->m_len < sizeof(struct ip6_hdr)) {
                m = m_pullup(m, sizeof(struct ip6_hdr));
-               if (m == NULL)
+               if (m == NULL) {
+                       IP6STAT_INC(ip6s_exthdrtoolong);
                        return;
+               }
        }
-#endif
        oip6 = mtod(m, struct ip6_hdr *);
 
        /*
@@ -322,17 +317,14 @@ icmp6_error(struct mbuf *m, int type, int code, int pa
        if (off >= 0 && nxt == IPPROTO_ICMPV6) {
                struct icmp6_hdr *icp;
 
-#ifndef PULLDOWN_TEST
-               IP6_EXTHDR_CHECK(m, 0, off + sizeof(struct icmp6_hdr), );
-               icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
-#else
-               IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off,
-                       sizeof(*icp));
-               if (icp == NULL) {
-                       ICMP6STAT_INC(icp6s_tooshort);
+               m = m_pullup(m, off + sizeof(struct icmp6_hdr));
+               if (m == NULL) {
+                       IP6STAT_INC(ip6s_exthdrtoolong);
                        return;
                }
-#endif
+               oip6 = mtod(m, struct ip6_hdr *);
+               icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
+
                if (icp->icmp6_type < ICMP6_ECHO_REQUEST ||
                    icp->icmp6_type == ND_REDIRECT) {
                        /*
@@ -349,8 +341,6 @@ icmp6_error(struct mbuf *m, int type, int code, int pa
                /* non-ICMPv6 - send the error */
        }
 
-       oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */
-
        /* Finally, do rate limitation check. */
        if (icmp6_ratelimit(&oip6->ip6_src, type, code)) {
                ICMP6STAT_INC(icp6s_toofreq);
@@ -411,10 +401,12 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
        m = *mp;
        off = *offp;
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE);
-       /* m might change if M_LOOP.  So, call mtod after this */
-#endif
+       m = m_pullup(m, off + sizeof(struct icmp6_hdr));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = m;
+               return (IPPROTO_DONE);
+       }
 
        /*
         * Locate icmp6 structure in mbuf, and check
@@ -445,17 +437,8 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
        }
 
        /* Calculate the checksum. */
-#ifndef PULLDOWN_TEST
        icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
-       if (icmp6 == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
-               return IPPROTO_DONE;
-       }
-#endif
        code = icmp6->icmp6_code;
-
        if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) {
                nd6log((LOG_ERR,
                    "ICMP6 checksum error(%d|%x) %s\n",
@@ -583,8 +566,12 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
                        n->m_pkthdr.len = n0len + (noff - off);
                        n->m_next = n0;
                } else {
-                       IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off,
-                           sizeof(*nicmp6));
+                       n = m_pullup(n, off + sizeof(*nicmp6));
+                       if (n == NULL) {
+                               IP6STAT_INC(ip6s_exthdrtoolong);
+                               break;
+                       }
+                       nicmp6 = (struct icmp6_hdr *)(mtod(n, caddr_t) + off);
                        noff = off;
                }
                if (n) {
@@ -648,10 +635,12 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
                if (pr == NULL)
                        pr = curthread->td_ucred->cr_prison;
                if (mode == FQDN) {
-#ifndef PULLDOWN_TEST
-                       IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo),
-                           IPPROTO_DONE);
-#endif
+                       m = m_pullup(m, off + sizeof(struct icmp6_nodeinfo));
+                       if (m == NULL) {
+                               IP6STAT_INC(ip6s_exthdrtoolong);
+                               *mp = m;
+                               return (IPPROTO_DONE);
+                       }
                        n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
                        if (n)
                                n = ni6_input(n, off, pr);
@@ -736,7 +725,12 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
                if (icmp6len < sizeof(struct nd_router_solicit))
                        goto badlen;
                if (send_sendso_input_hook != NULL) {
-                       IP6_EXTHDR_CHECK(m, off, icmp6len, IPPROTO_DONE);
+                       m = m_pullup(m, off + icmp6len);
+                       if (m == NULL) {
+                               IP6STAT_INC(ip6s_exthdrtoolong);
+                               *mp = NULL;
+                               return (IPPROTO_DONE);
+                       }
                        error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
                        if (error == 0) {
                                m = NULL;
@@ -896,18 +890,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp
                ICMP6STAT_INC(icp6s_tooshort);
                goto freeit;
        }
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off,
-           sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr), -1);
-       icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
-#else
-       IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
-           sizeof(*icmp6) + sizeof(struct ip6_hdr));
-       if (icmp6 == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
+
+       m = m_pullup(m, off + sizeof(*icmp6) + sizeof(struct ip6_hdr));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = m;
                return (-1);
        }
-#endif
+       icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
        eip6 = (struct ip6_hdr *)(icmp6 + 1);
 
        /* Detect the upper level protocol */
@@ -931,19 +921,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp
                        case IPPROTO_HOPOPTS:
                        case IPPROTO_DSTOPTS:
                        case IPPROTO_AH:
-#ifndef PULLDOWN_TEST
-                               IP6_EXTHDR_CHECK(m, 0,
-                                   eoff + sizeof(struct ip6_ext), -1);
-                               eh = (struct ip6_ext *)(mtod(m, caddr_t) + 
eoff);
-#else
-                               IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
-                                   eoff, sizeof(*eh));
-                               if (eh == NULL) {
-                                       ICMP6STAT_INC(icp6s_tooshort);
+                               m = m_pullup(m, eoff + sizeof(struct ip6_ext));
+                               if (m == NULL) {
+                                       IP6STAT_INC(ip6s_exthdrtoolong);
+                                       *mp = m;
                                        return (-1);
                                }
-#endif
-
+                               eh = (struct ip6_ext *)
+                                   (mtod(m, caddr_t) + eoff);
                                if (nxt == IPPROTO_AH)
                                        eoff += (eh->ip6e_len + 2) << 2;
                                else
@@ -959,18 +944,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp
                                 * information that depends on the final
                                 * destination (e.g. path MTU).
                                 */
-#ifndef PULLDOWN_TEST
-                               IP6_EXTHDR_CHECK(m, 0, eoff + sizeof(*rth), -1);
-                               rth = (struct ip6_rthdr *)
-                                   (mtod(m, caddr_t) + eoff);
-#else
-                               IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
-                                   eoff, sizeof(*rth));
-                               if (rth == NULL) {
-                                       ICMP6STAT_INC(icp6s_tooshort);
+                               m = m_pullup(m, eoff + sizeof(*rth));
+                               if (m == NULL) {
+                                       IP6STAT_INC(ip6s_exthdrtoolong);
+                                       *mp = m;
                                        return (-1);
                                }
-#endif
+                               rth = (struct ip6_rthdr *)
+                                   (mtod(m, caddr_t) + eoff);
                                rthlen = (rth->ip6r_len + 1) << 3;
                                /*
                                 * XXX: currently there is no
@@ -984,19 +965,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp
                                    rth->ip6r_type == IPV6_RTHDR_TYPE_0) {
                                        int hops;
 
-#ifndef PULLDOWN_TEST
-                                       IP6_EXTHDR_CHECK(m, 0, eoff + rthlen, 
-1);
-                                       rth0 = (struct ip6_rthdr0 *)
-                                           (mtod(m, caddr_t) + eoff);
-#else
-                                       IP6_EXTHDR_GET(rth0,
-                                           struct ip6_rthdr0 *, m,
-                                           eoff, rthlen);
-                                       if (rth0 == NULL) {
-                                               ICMP6STAT_INC(icp6s_tooshort);
+                                       m = m_pullup(m, eoff + rthlen);
+                                       if (m == NULL) {
+                                               IP6STAT_INC(ip6s_exthdrtoolong);
+                                               *mp = m;
                                                return (-1);
                                        }
-#endif
+                                       rth0 = (struct ip6_rthdr0 *)
+                                           (mtod(m, caddr_t) + eoff);
                                        /* just ignore a bogus header */
                                        if ((rth0->ip6r0_len % 2) == 0 &&
                                            (hops = rth0->ip6r0_len/2))
@@ -1006,19 +982,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp
                                nxt = rth->ip6r_nxt;
                                break;
                        case IPPROTO_FRAGMENT:
-#ifndef PULLDOWN_TEST
-                               IP6_EXTHDR_CHECK(m, 0, eoff +
-                                   sizeof(struct ip6_frag), -1);
-                               fh = (struct ip6_frag *)(mtod(m, caddr_t) +
-                                   eoff);
-#else
-                               IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
-                                   eoff, sizeof(*fh));
-                               if (fh == NULL) {
-                                       ICMP6STAT_INC(icp6s_tooshort);
+                               m = m_pullup(m, eoff + sizeof(struct ip6_frag));
+                               if (m == NULL) {
+                                       IP6STAT_INC(ip6s_exthdrtoolong);
+                                       *mp = m;
                                        return (-1);
                                }
-#endif
+                               fh = (struct ip6_frag *)(mtod(m, caddr_t) +
+                                   eoff);
                                /*
                                 * Data after a fragment header is meaningless
                                 * unless it is the first fragment, but
@@ -1044,16 +1015,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp
                        }
                }
          notify:
-#ifndef PULLDOWN_TEST
                icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
-#else
-               IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
-                   sizeof(*icmp6) + sizeof(struct ip6_hdr));
-               if (icmp6 == NULL) {
-                       ICMP6STAT_INC(icp6s_tooshort);
-                       return (-1);
-               }
-#endif
 
                /*
                 * retrieve parameters from the inner IPv6 header, and convert
@@ -1198,15 +1160,7 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
        struct in6_ifaddr *ia6 = NULL;
 
        ip6 = mtod(m, struct ip6_hdr *);
-#ifndef PULLDOWN_TEST
        ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off);
-#else
-       IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6));
-       if (ni6 == NULL) {
-               /* m is already reclaimed */
-               return (NULL);
-       }
-#endif
 
        /*
         * Validate IPv6 source address.
@@ -1303,7 +1257,6 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
                         *
                         * We do not do proxy at this moment.
                         */
-                       /* m_pulldown instead of copy? */
                        m_copydata(m, off + sizeof(struct icmp6_nodeinfo),
                            subjlen, (caddr_t)&in6_subj);
                        if (in6_setscope(&in6_subj, m->m_pkthdr.rcvif, NULL))
@@ -1342,10 +1295,16 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
                        mtx_unlock(&pr->pr_mtx);
                        if (!n || n->m_next || n->m_len == 0)
                                goto bad;
-                       IP6_EXTHDR_GET(subj, char *, m,
-                           off + sizeof(struct icmp6_nodeinfo), subjlen);
-                       if (subj == NULL)
+                       m = m_pullup(m, off + sizeof(struct icmp6_nodeinfo) +
+                           subjlen);
+                       if (m == NULL) {
+                               IP6STAT_INC(ip6s_exthdrtoolong);
                                goto bad;
+                       }
+                       /* ip6 possibly invalid but not used after. */
+                       ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off);
+                       subj = (char *)(mtod(m, caddr_t) + off +
+                           sizeof(struct icmp6_nodeinfo));
                        if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *),
                            n->m_len)) {
                                goto bad;
@@ -1903,16 +1862,8 @@ icmp6_rip6_input(struct mbuf **mp, int off)
 
        NET_EPOCH_ASSERT();
 
-#ifndef PULLDOWN_TEST
-       /* this is assumed to be safe. */
+       /* This is assumed to be safe; icmp6_input() does a pullup. */
        icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
-       if (icmp6 == NULL) {
-               /* m is already reclaimed */
-               return (IPPROTO_DONE);
-       }
-#endif
 
        /*
         * XXX: the address may have embedded scope zone ID, which should be
@@ -2229,9 +2180,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
        struct ifnet *ifp;
        struct ip6_hdr *ip6;
        struct nd_redirect *nd_rd;
-       struct in6_addr src6;
-       struct in6_addr redtgt6;
-       struct in6_addr reddst6;
+       struct in6_addr src6, redtgt6, reddst6;
        union nd_opts ndopts;
        char ip6buf[INET6_ADDRSTRLEN];
        char *lladdr;
@@ -2252,16 +2201,13 @@ icmp6_redirect_input(struct mbuf *m, int off)
 
        ip6 = mtod(m, struct ip6_hdr *);
        icmp6len = ntohs(ip6->ip6_plen);
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, icmp6len,);
-       nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len);
-       if (nd_rd == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
+       m = m_pullup(m, off + icmp6len);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
                return;
        }
-#endif
+       ip6 = mtod(m, struct ip6_hdr *);
+       nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
 
        ifp = m->m_pkthdr.rcvif;
        redtgt6 = nd_rd->nd_rd_target;

Modified: head/sys/netinet6/ip6_input.c
==============================================================================
--- head/sys/netinet6/ip6_input.c       Fri Nov 15 21:19:06 2019        
(r354747)
+++ head/sys/netinet6/ip6_input.c       Fri Nov 15 21:40:40 2019        
(r354748)
@@ -203,9 +203,6 @@ struct rmlock in6_ifaddr_lock;
 RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock");
 
 static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
-#ifdef PULLDOWN_TEST
-static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
-#endif
 
 /*
  * IP6 initialization: fill in IP6 protocol switch table.
@@ -441,17 +438,8 @@ ip6_input_hbh(struct mbuf **mp, uint32_t *plen, uint32
                            (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
                goto out;
        }
-#ifndef PULLDOWN_TEST
        /* ip6_hopopts_input() ensures that mbuf is contiguous */
        hbh = (struct ip6_hbh *)(ip6 + 1);
-#else
-       IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
-               sizeof(struct ip6_hbh));
-       if (hbh == NULL) {
-               IP6STAT_INC(ip6s_tooshort);
-               goto out;
-       }
-#endif
        *nxt = hbh->ip6h_nxt;
 
        /*
@@ -602,7 +590,6 @@ ip6_input(struct mbuf *m)
        in6_ifstat_inc(rcvif, ifs6_in_receive);
        IP6STAT_INC(ip6s_total);
 
-#ifndef PULLDOWN_TEST
        /*
         * L2 bridge code and some other code can return mbuf chain
         * that does not conform to KAME requirement.  too bad.
@@ -624,9 +611,6 @@ ip6_input(struct mbuf *m)
                m_freem(m);
                m = n;
        }
-       IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /* nothing */);
-#endif
-
        if (m->m_len < sizeof(struct ip6_hdr)) {
                if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
                        IP6STAT_INC(ip6s_toosmall);
@@ -985,28 +969,22 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalert
        struct ip6_hbh *hbh;
 
        /* validation of the length of the header */
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1);
+       m = m_pullup(m, off + sizeof(*hbh));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = NULL;
+               return (-1);
+       }
        hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
        hbhlen = (hbh->ip6h_len + 1) << 3;
 
-       IP6_EXTHDR_CHECK(m, off, hbhlen, -1);
-       hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
-#else
-       IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
-               sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
-       if (hbh == NULL) {
-               IP6STAT_INC(ip6s_tooshort);
-               return -1;
+       m = m_pullup(m, off + hbhlen);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = NULL;
+               return (-1);
        }
-       hbhlen = (hbh->ip6h_len + 1) << 3;
-       IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
-               hbhlen);
-       if (hbh == NULL) {
-               IP6STAT_INC(ip6s_tooshort);
-               return -1;
-       }
-#endif
+       hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
        off += hbhlen;
        hbhlen -= sizeof(struct ip6_hbh);
        if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
@@ -1198,10 +1176,9 @@ ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int of
  * Create the "control" list for this pcb.
  * These functions will not modify mbuf chain at all.
  *
- * With KAME mbuf chain restriction:
  * The routine will be called from upper layer handlers like tcp6_input().
  * Thus the routine assumes that the caller (tcp6_input) have already
- * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
+ * called m_pullup() and all the extension headers are located in the
  * very first mbuf on the mbuf chain.
  *
  * ip6_savecontrol_v4 will handle those options that are possible to be
@@ -1436,29 +1413,10 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                 */
                if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
                        struct ip6_hbh *hbh;
-                       int hbhlen = 0;
-#ifdef PULLDOWN_TEST
-                       struct mbuf *ext;
-#endif
+                       int hbhlen;
 
-#ifndef PULLDOWN_TEST
                        hbh = (struct ip6_hbh *)(ip6 + 1);
                        hbhlen = (hbh->ip6h_len + 1) << 3;
-#else
-                       ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
-                           ip6->ip6_nxt);
-                       if (ext == NULL) {
-                               IP6STAT_INC(ip6s_tooshort);
-                               return;
-                       }
-                       hbh = mtod(ext, struct ip6_hbh *);
-                       hbhlen = (hbh->ip6h_len + 1) << 3;
-                       if (hbhlen != ext->m_len) {
-                               m_freem(ext);
-                               IP6STAT_INC(ip6s_tooshort);
-                               return;
-                       }
-#endif
 
                        /*
                         * XXX: We copy the whole header even if a
@@ -1472,9 +1430,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                            IPPROTO_IPV6);
                        if (*mp)
                                mp = &(*mp)->m_next;
-#ifdef PULLDOWN_TEST
-                       m_freem(ext);
-#endif
                }
        }
 
@@ -1491,9 +1446,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                while (1) {     /* is explicit loop prevention necessary? */
                        struct ip6_ext *ip6e = NULL;
                        int elen;
-#ifdef PULLDOWN_TEST
-                       struct mbuf *ext = NULL;
-#endif
 
                        /*
                         * if it is not an extension header, don't try to
@@ -1509,7 +1461,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                                goto loopend;
                        }
 
-#ifndef PULLDOWN_TEST
                        if (off + sizeof(*ip6e) > m->m_len)
                                goto loopend;
                        ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off);
@@ -1519,23 +1470,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                                elen = (ip6e->ip6e_len + 1) << 3;
                        if (off + elen > m->m_len)
                                goto loopend;
-#else
-                       ext = ip6_pullexthdr(m, off, nxt);
-                       if (ext == NULL) {
-                               IP6STAT_INC(ip6s_tooshort);
-                               return;
-                       }
-                       ip6e = mtod(ext, struct ip6_ext *);
-                       if (nxt == IPPROTO_AH)
-                               elen = (ip6e->ip6e_len + 2) << 2;
-                       else
-                               elen = (ip6e->ip6e_len + 1) << 3;
-                       if (elen != ext->m_len) {
-                               m_freem(ext);
-                               IP6STAT_INC(ip6s_tooshort);
-                               return;
-                       }
-#endif
 
                        switch (nxt) {
                        case IPPROTO_DSTOPTS:
@@ -1570,9 +1504,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                                 * the code just in case (nxt overwritten or
                                 * other cases).
                                 */
-#ifdef PULLDOWN_TEST
-                               m_freem(ext);
-#endif
                                goto loopend;
 
                        }
@@ -1581,10 +1512,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, str
                        off += elen;
                        nxt = ip6e->ip6e_nxt;
                        ip6e = NULL;
-#ifdef PULLDOWN_TEST
-                       m_freem(ext);
-                       ext = NULL;
-#endif
                }
          loopend:
                ;
@@ -1669,49 +1596,6 @@ ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6
        } else
                sorwakeup(so);
 }
-
-#ifdef PULLDOWN_TEST
-/*
- * pull single extension header from mbuf chain.  returns single mbuf that
- * contains the result, or NULL on error.
- */
-static struct mbuf *
-ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
-{
-       struct ip6_ext ip6e;
-       size_t elen;
-       struct mbuf *n;
-
-#ifdef DIAGNOSTIC
-       switch (nxt) {
-       case IPPROTO_DSTOPTS:
-       case IPPROTO_ROUTING:
-       case IPPROTO_HOPOPTS:
-       case IPPROTO_AH: /* is it possible? */
-               break;
-       default:
-               printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
-       }
-#endif
-
-       m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
-       if (nxt == IPPROTO_AH)
-               elen = (ip6e.ip6e_len + 2) << 2;
-       else
-               elen = (ip6e.ip6e_len + 1) << 3;
-
-       if (elen > MLEN)
-               n = m_getcl(M_NOWAIT, MT_DATA, 0);
-       else
-               n = m_get(M_NOWAIT, MT_DATA);
-       if (n == NULL)
-               return NULL;
-
-       m_copydata(m, off, elen, mtod(n, caddr_t));
-       n->m_len = elen;
-       return n;
-}
-#endif
 
 /*
  * Get pointer to the previous header followed by the header

Modified: head/sys/netinet6/ip6_mroute.c
==============================================================================
--- head/sys/netinet6/ip6_mroute.c      Fri Nov 15 21:19:06 2019        
(r354747)
+++ head/sys/netinet6/ip6_mroute.c      Fri Nov 15 21:40:40 2019        
(r354748)
@@ -1745,20 +1745,13 @@ pim6_input(struct mbuf *m, int off, int proto, void *a
         * Make sure that the IP6 and PIM headers in contiguous memory, and
         * possibly the PIM REGISTER header
         */
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, minlen, IPPROTO_DONE);
-       /* adjust pointer */
-       ip6 = mtod(m, struct ip6_hdr *);
-
-       /* adjust mbuf to point to the PIM header */
-       pim = (struct pim *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(pim, struct pim *, m, off, minlen);
-       if (pim == NULL) {
-               PIM6STAT_INC(pim6s_rcv_tooshort);
+       m = m_pullup(m, off + minlen);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
                return (IPPROTO_DONE);
        }
-#endif
+       ip6 = mtod(m, struct ip6_hdr *);
+       pim = (struct pim *)((caddr_t)ip6 + off);
 
 #define PIM6_CHECKSUM
 #ifdef PIM6_CHECKSUM

Modified: head/sys/netinet6/mld6.c
==============================================================================
--- head/sys/netinet6/mld6.c    Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/mld6.c    Fri Nov 15 21:40:40 2019        (r354748)
@@ -1261,6 +1261,11 @@ mld_input(struct mbuf *m, int off, int icmp6len)
        ifp = m->m_pkthdr.rcvif;
 
        /* Pullup to appropriate size. */
+       m = m_pullup(m, off + sizeof(*mld));
+       if (m == NULL) {
+               ICMP6STAT_INC(icp6s_badlen);
+               return (IPPROTO_DONE);
+       }
        mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
        if (mld->mld_type == MLD_LISTENER_QUERY &&
            icmp6len >= sizeof(struct mldv2_query)) {
@@ -1268,12 +1273,13 @@ mld_input(struct mbuf *m, int off, int icmp6len)
        } else {
                mldlen = sizeof(struct mld_hdr);
        }
-       IP6_EXTHDR_GET(mld, struct mld_hdr *, m, off, mldlen);
-       if (mld == NULL) {
+       m = m_pullup(m, off + mldlen);
+       if (m == NULL) {
                ICMP6STAT_INC(icp6s_badlen);
                return (IPPROTO_DONE);
        }
        ip6 = mtod(m, struct ip6_hdr *);
+       mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
 
        /*
         * Userland needs to see all of this traffic for implementing

Modified: head/sys/netinet6/nd6_nbr.c
==============================================================================
--- head/sys/netinet6/nd6_nbr.c Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/nd6_nbr.c Fri Nov 15 21:40:40 2019        (r354748)
@@ -148,17 +148,13 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
                goto bads;
        }
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, icmp6len,);
-       nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
-       if (nd_ns == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
+       m = m_pullup(m, off + icmp6len);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
                return;
        }
-#endif
-       ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
+       ip6 = mtod(m, struct ip6_hdr *);
+       nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
 
        saddr6 = ip6->ip6_src;
        daddr6 = ip6->ip6_dst;
@@ -656,16 +652,13 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
                goto bad;
        }
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, icmp6len,);
-       nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
-       if (nd_na == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
+       m = m_pullup(m, off + icmp6len);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
                return;
        }
-#endif
+       ip6 = mtod(m, struct ip6_hdr *);
+       nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
 
        flags = nd_na->nd_na_flags_reserved;
        is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/nd6_rtr.c Fri Nov 15 21:40:40 2019        (r354748)
@@ -202,16 +202,13 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
        if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
                goto freeit;
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, icmp6len,);
-       nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len);
-       if (nd_rs == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
+       m = m_pullup(m, off + icmp6len);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
                return;
        }
-#endif
+       ip6 = mtod(m, struct ip6_hdr *);
+       nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
 
        icmp6len -= sizeof(*nd_rs);
        nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
@@ -403,16 +400,13 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
                goto bad;
        }
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, icmp6len,);
-       nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len);
-       if (nd_ra == NULL) {
-               ICMP6STAT_INC(icp6s_tooshort);
+       m = m_pullup(m, off + icmp6len);
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
                return;
        }
-#endif
+       ip6 = mtod(m, struct ip6_hdr *);
+       nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
 
        icmp6len -= sizeof(*nd_ra);
        nd6_option_init(nd_ra + 1, icmp6len, &ndopts);

Modified: head/sys/netinet6/route6.c
==============================================================================
--- head/sys/netinet6/route6.c  Fri Nov 15 21:19:06 2019        (r354747)
+++ head/sys/netinet6/route6.c  Fri Nov 15 21:40:40 2019        (r354748)
@@ -83,18 +83,14 @@ route6_input(struct mbuf **mp, int *offp, int proto)
        }
 #endif
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE);
+       m = m_pullup(m, off + sizeof(*rh));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = NULL;
+               return (IPPROTO_DONE);
+       }
        ip6 = mtod(m, struct ip6_hdr *);
        rh = (struct ip6_rthdr *)((caddr_t)ip6 + off);
-#else
-       ip6 = mtod(m, struct ip6_hdr *);
-       IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh));
-       if (rh == NULL) {
-               IP6STAT_INC(ip6s_tooshort);
-               return IPPROTO_DONE;
-       }
-#endif
 
        /*
         * While this switch may look gratuitous, leave it in

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c     Fri Nov 15 21:19:06 2019        
(r354747)
+++ head/sys/netinet6/udp6_usrreq.c     Fri Nov 15 21:40:40 2019        
(r354748)
@@ -223,16 +223,14 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
 
        ifp = m->m_pkthdr.rcvif;
 
-#ifndef PULLDOWN_TEST
-       IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
-       ip6 = mtod(m, struct ip6_hdr *);
-       uh = (struct udphdr *)((caddr_t)ip6 + off);
-#else
-       IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(*uh));
-       if (!uh)
+       m = m_pullup(m, off + sizeof(struct udphdr));
+       if (m == NULL) {
+               IP6STAT_INC(ip6s_exthdrtoolong);
+               *mp = NULL;
                return (IPPROTO_DONE);
+       }
        ip6 = mtod(m, struct ip6_hdr *);
-#endif
+       uh = (struct udphdr *)((caddr_t)ip6 + off);
 
        UDPSTAT_INC(udps_ipackets);
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to