NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/40605
The following reply was made to PR kern/40605; it has been noted by GNATS.
From: Michael Stapelberg <michael+netbsd%stapelberg.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/40605
Date: Tue, 7 Apr 2009 01:14:44 +0200
Hi,
after some more debugging I found out that the bug is in in_delayed_cksum() in
sys/netinet/ip_output.c.
In the beginning of the function (right after using ip = mtod(â?¦)), the
ip6_hdr's
ip6_vfc field is set to 96, which is the correct value. Afterwards, that is
before
returning, the field is set to some seemingly random value (probably related to
the checksum).
This is probably triggered by re(4) as it is a card which does not support
hardware checksumming.
The triggering code for in_delayed_csum is very likely this one:
if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
if (IN_NEED_CHECKSUM(ifp,
m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4))) {
in_delayed_cksum(m);
}
m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
}
I'm asking myself if M_CSUM_TCPv4 or M_CSUM_UDPv4 should be set on IP-packets
containing IPv6 packets. Is this bug more fundamental?
By applying the following patch, the bug is worked around:
--- a/ip_output.c
+++ b/ip_output.c
@@ -1067,6 +1067,13 @@ in_delayed_cksum(struct mbuf *m)
u_int16_t csum, offset;
ip = mtod(m, struct ip *);
+
+ /* XXX: FIXME: Don't touch IPv6-in-IPv4 packets as long as the checksum
+ * flag is wrongly set for them. This overwrites the version field of a
+ * packet if we don't return here. */
+ if (ip->ip_p == IPPROTO_IPV6)
+ return;
+
offset = ip->ip_hl << 2;
csum = in4_cksum(m, 0, offset, ntohs(ip->ip_len) - offset);
if (csum == 0 && (m->m_pkthdr.csum_flags & M_CSUM_UDPv4) != 0)
Best regards,
Michael
Home |
Main Index |
Thread Index |
Old Index