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) {
in_delayed_cksum(m);
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