Page MenuHomeFreeBSD

dhclient: improve UDP checksum handling
ClosedPublic

Authored by tuexen on Sep 5 2025, 1:04 PM.
Tags
None
Referenced Files
F131541646: D52394.diff
Thu, Oct 9, 2:30 AM
F131520293: D52394.diff
Wed, Oct 8, 9:29 PM
Unknown Object (File)
Wed, Oct 1, 10:27 AM
Unknown Object (File)
Fri, Sep 26, 6:33 PM
Unknown Object (File)
Fri, Sep 26, 2:36 PM
Unknown Object (File)
Tue, Sep 23, 2:38 AM
Unknown Object (File)
Mon, Sep 22, 3:56 AM
Unknown Object (File)
Mon, Sep 22, 2:41 AM
Subscribers

Details

Summary

Improve the UDP checksum handling:

  • When sending UDP packets,
    • compute the checksum in the correct order. This only has an impact if the length of the payload is odd.
    • don't send packet with a checksum of zero, use 0xffff instead as required.
  • When receiving UDP packets,
    • don't do any computations when the checksum is zero.
    • compute the checksum in the correct order. This only has an impact if the length of the payload is odd.
    • when computing the checksum, store the pseudo header checksum
    • if the checksum is computed as zero, use 0xffff instead.
    • also accept packets, when the checksum in the packet is the pseudo header checksum.

The past point fixes a problem when the DHCP client runs in a VM, the DHCP server runs on the host serving the VM and the network interface supports transmit checksum offloading. Since dhclient doesn't use UDP sockets but bpf devices to read the packets, the checksum will be incorrect and only contain the checksum of the pseudo header.

This was reported in PR 263229.
Tested by danilo@.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

tuexen requested review of this revision.Sep 5 2025, 1:04 PM
sbin/dhclient/packet.c
232

It seems odd to just accept UDP packets if the checksum is 0, but probably OK, since the FreeBSD's UDP implementation does it too.

243

Receiving a UDP packet that contains the correct checksum of the pseudo header is a good indication that the sender on the local host used checksum offloading. The perfect indication would be the mbuf flag CSUM_UDP. Is it somehow possible to pass this flag to this point?

If not, I guess this deserves a comment. Something like:

A packet containing the correct checksum of the pseudo header probably comes from the local host that only prepared the checksum for checksum offloading.
sbin/dhclient/packet.c
243

I agree that this deserves a comment.

tuexen marked 2 inline comments as done.

Add a comment describing that in addition to packet with the correct checksum, also packet with the correct pseudo header checksum are accepted. This was suggested by Timo and Mark.

sbin/dhclient/packet.c
232

It seems odd to just accept UDP packets if the checksum is 0, but probably OK, since the FreeBSD's UDP implementation does it too.

That is required by RFC 768:

If the computed  checksum  is zero,  it is transmitted  as all ones (the
equivalent  in one's complement  arithmetic).   An all zero  transmitted
checksum  value means that the transmitter  generated  no checksum  (for
debugging or for higher level protocols that don't care).

Please note that the old code

  • also accepts packet with a checksum of zero, but only after computing the checksum and then ignoring the result.
  • missing the special case of a computed checksum of zero in the send path.

Fun fact: RFC 8200 forbids the usage of a zero checksum for UDP/IPv6. But the code here is for UDP/IPv4 only.

243

Receiving a UDP packet that contains the correct checksum of the pseudo header is a good indication that the sender on the local host used checksum offloading. The perfect indication would be the mbuf flag CSUM_UDP. Is it somehow possible to pass this flag to this point?

Not without changing the bpf interface. When libpacp provides a packet to its user, the user gets a pointer to byte sequence of the actual packet and a struct pcap_pkthdr, which contains a timestamp, the length of the packet and the captured length of the packet. So there is no way to provide any other information.
Please not the something like CSUM_UDP would be BSD specific and libpcap is a library which runs on a variety of platforms.

If not, I guess this deserves a comment. Something like:

A packet containing the correct checksum of the pseudo header probably comes from the local host that only prepared the checksum for checksum offloading.

I added a comment.

markj added inline comments.
sbin/dhclient/packet.c
247
This revision is now accepted and ready to land.Tue, Sep 9, 11:40 PM
This revision was automatically updated to reflect the committed changes.