udp checksum implementation error in FreeBSD 7.2?

Rick Macklem rmacklem at uoguelph.ca
Tue Jun 28 14:24:38 UTC 2011


Benoit Panizzon wrote:
> Hi
> 
> We are running a DHCP Server on a FreeBSD 7.2-RELEASE-p4 box.
> 
> This works for most of our customers, except ones with some kind of
> SonicWall
> Firewalls. We have analyzed the problem with the sonicwall tech
> support:
> 
> We found the problem being in the sonicwall setting a UDP checksum of
> 0x0000
> for DHCP Requests.
> 
> According to the RFC this is a valid value and tells the receiving UDP
> stack
> not to check the checksum:
> 
> http://www.faqs.org/rfcs/rfc768.html
> 
> If the value is different from 0x0000 the receiving UDP stack can
> perform a
> checksum check and if this fails, silently drop that packet.
> 
> What we observe is:
> 
> DHCP Request with UDP checksum set => Packet reaches DHCP Daemon and
> is being
> answered.
> DHCP Request with UDP checksum 0x0000 => ICMP Port Unreachable from
> FreeBSD.
> 
> Can someone confirm this non RFC conform behaviour and knows how to
> fix it?
> 
Well, I took a quick look at the sources (which are in sys/netinet/udp_usrreq.c
in a function called udp_input() at about line#300) and it only does the
checksum if it is non-zero. It looks like:
   if (uh->uh_sum) {
      ....do checksum 
(If you don't have kernel sources handy, you can find them here:
  http://svn.freebsd.org/viewvc/base/releng/7.2)

So, I have no idea why the packet without the checksum doesn't make it
through, but it doesn't appear to be because the checksum field is set to 0.
In fact, if you do "netstat -s", you should see the count for UDP packets
with no checksum increase as it receives them.
If this count isn't increaing when the request with checksum == 0x0000 is
being sent to the FreeBSD box, it isn't getting as far as the udp checksum
calculation. (The code fails a UDP packet with a 0 destination port#, for
example.) Or maybe your network hardware is trying to do the checksum and
then dropping the packet? Look at "ifconfig -a" and if RXCSUM is enabled,
you could try disabling it with "-rxcsum" on the ifconfig command line.

Otherwise, all I can suggest is good old fashioned printf()s in the
udp_input() function to try and figure out why the packet is being dropped?
(Oh, this assumes you've already looked at the packet via wireshark or
tcpdump to make sure that the UDP packet looks ok otherwise when it has
the checksum == 0x0000.)
> As I understand, setting net.inet.udp.checksum to zero would not fix
> the
> problem, as this is only for packet generation.
> 
Yes, the code shouldn't ever try and calculate a UDP checksum when it's
0 in the packet.

Maybe others have better suggestions, rick


More information about the freebsd-net mailing list