What's the deal with hardware checksum and net.inet.udp.checksum?

Robert Watson rwatson at FreeBSD.org
Thu Jul 10 21:06:33 UTC 2008

On Thu, 10 Jul 2008, gnn at FreeBSD.org wrote:

> If the sysctl it turned off on the transmitter then the receiving machine 
> sees UDP checksums of 0.

Right.  If you disable UDP checksumming, we don't generate checksums (hardware 
or software) in udp_output():

          * Set up checksum and output datagram.
         if (udp_cksum) {
                 if (inp->inp_flags & INP_ONESBCAST)
                         faddr.s_addr = INADDR_BROADCAST;
                 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, faddr.s_addr,
                     htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP));
                 m->m_pkthdr.csum_flags = CSUM_UDP;
                 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
         } else
                 ui->ui_sum = 0;

You can disable hardware checksums using the -txcsum flag on ifconfig for each 
interface -- once the above-generated mbuf header gets to the IP layer and the 
route out an interface is available, we on-demand generate checksum in 
software if hardware checksums aren't available or are administratively 
disabled.  Vis ip_output():

         m->m_pkthdr.csum_flags |= CSUM_IP;
         sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
         if (sw_csum & CSUM_DELAY_DATA) {
                 sw_csum &= ~CSUM_DELAY_DATA;
         m->m_pkthdr.csum_flags &= ifp->if_hwassist;

It's possible to imagine adding a global sysctl that has slightly different 
policy implications, such as globally disabling hardware checksums, or not 
generating full checksums if the interface doesn't support hardware checksums 
rather than generating them.

Robert N M Watson
Computer Laboratory
University of Cambridge

More information about the freebsd-net mailing list