tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Clear m->m_pkthdr.csum_flags when forwarding packets!

On Sun, May 04, 2008 at 12:33:05PM +0900, Takahiro Kambe wrote:
> Hi,
> In message <>
>       on Tue, 15 Apr 2008 20:32:16 +0900 (JST),
>       Takahiro Kambe <> wrote:
> > Today, NetBSD 4.0_STABLE machine paniced in ip_output() when
> > forwarding IPv4 multicast packet.  The packet was short (36 octets)
> > UDP/IP pakcet.

This is a bug in the multicast forwarding code (it is related to a bug
I have been investigating in ipf, pf, and bridge).  Look at ip_forward()
and ip_flow(): on NetBSD, if you forward a packet using the same mbuf
in which it was received, you must set csum_flags to 0 before handing
that packet to ip_output.

This is because the same flags were used for "hardware checked checksum
on receive" and "hardware should insert checksum on transmit" which, in
my opinion, was a mistake.  The existing M_CSUM_DATA and M_CSUM_NO_PSEUDOHDR
would have been sufficient for receive, leaving M_CSUM_TCPv4 (etc.) for
transmit use.

As it is now, if you receive such a packet and forward it without looking
inside the UDP or TCP layer, you can in fact cause the hardware to stamp
a *good* checksum on a packet which had a *bad* one when received, because
you won't check for M_CSUM_TCPUDP_BAD, but will send the packet into
ip_output() with M_CSUM_TCPv4 or M_CSUM_UDPv4 set, because that's how it
was received.

Anyway, all code forwarding packets on NetBSD must explicitly set
csum_flags to 0 after receive because of this.


Home | Main Index | Thread Index | Old Index