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

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. */

Best regards,
Tiwei Bie

_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to