[Bug 202788] 'proto' should be used to get protocol number instead of ip6->ip6_nxt in udp6_input()

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Mon Aug 31 10:01:28 UTC 2015


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202788

            Bug ID: 202788
           Summary: 'proto' should be used to get protocol number instead
                    of ip6->ip6_nxt in udp6_input()
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs at FreeBSD.org
          Reporter: btw at mail.ustc.edu.cn

The 'proto' parameter should be used to get the protocol number (UDP or
UDPLITE), instead of ip6->ip6_nxt in udp6_input().

Because ip6->ip6_nxt may be the protocol number of extension header,
such as:

If a UDP packet is an "atomic" fragment, frag6_input() will return
directly, and ip6->ip6_nxt will be IPPROTO_FRAGMENT (if the first
extension header is the fragment header) instead of IPPROTO_UDP or
IPPROTO_UDPLITE:

int
frag6_input(struct mbuf **mp, int *offp, int proto)
{
    ......

    /*
     * RFC 6946: Handle "atomic" fragments (offset and m bit set to 0)
     * upfront, unrelated to any reassembly.  Just skip the fragment header.
     */
    if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
        /* XXX-BZ we want dedicated counters for this. */
        IP6STAT_INC(ip6s_reassembled);
        in6_ifstat_inc(dstifp, ifs6_reass_ok);
        *offp = offset;
        return (ip6f->ip6f_nxt);
    }


And this is the patch to fix this bug:

diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 98790a8..da72f00 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -207,7 +207,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
     struct sockaddr_in6 fromsa;
     struct m_tag *fwd_tag;
     uint16_t uh_sum;
-    uint8_t nxt;
+    uint8_t nxt = proto;

     ifp = m->m_pkthdr.rcvif;
     ip6 = mtod(m, struct ip6_hdr *);
@@ -233,7 +233,6 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
     plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
     ulen = ntohs((u_short)uh->uh_ulen);

-    nxt = ip6->ip6_nxt;
     cscov_partial = (nxt == IPPROTO_UDPLITE) ? 1 : 0;
     if (nxt == IPPROTO_UDPLITE) {
         /* Zero means checksum over the complete packet. */

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list