RX checksum offloading problem
Michael Tuexen
Michael.Tuexen at lurchi.franken.de
Fri May 2 10:22:32 UTC 2014
Dear all,
during testing I found that FreeBSD head (on a raspberry pi) accepts SCTP packet
with bad checksums. After debugging this I figured out that this is a problem with
the csum_flags defined in mbuf.h.
The SCTP code on its input path checks for CSUM_SCTP_VALID, which is defined in mbuf.h:
#define CSUM_SCTP_VALID CSUM_L4_VALID
This makes sense: If CSUM_SCTP_VALID is set in csum_flags, the packet is considered
to have a correct checksum.
For UDP and TCP some drivers calculate the UDP/TCP checksum and set CSUM_DATA_VALID in
csum_flags to indicate that the UDP/TCP should consider csum_data to figure out if
the packet has a correct checksum. The problem is that CSUM_DATA_VALID is defined as
#define CSUM_DATA_VALID CSUM_L4_VALID
In this case the semantic is not that the packet has a valid checksum, but the csum_data
field contains information.
Now the following happens (on the raspberry pi the driver used is
dev/usb/net/if_smsc.c
1. A packet is received and if it is not too short, the checksum computed
is stored in csum_data and the flag CSUM_DATA_VALID is set. This happens
for all IP packets, not only for UDP and TCP packets.
2. In case of SCTP packets, the SCTP interprets CSUM_DATA_VALID as CSUM_SCTP_VALID
and accepts the packet. So no SCTP checksum check ever happened.
Alternatives to fix this:
1. Change all drivers to set CSUM_DATA_VALID only in case of UDP or TCP packets, since
it only makes sense in these cases.
2. Map CSUM_DATA_VALID to some other generic value in mbuf.h. However, CSUM_L4_CALC,
which would make perfect sense in my view, is already used for CSUM_PSEUDO_HDR. Therefore
we would have to define a new generic value.
So what is the best way to fix this?
Best regards
Michael
More information about the freebsd-net
mailing list