UDP / TCP Checksum errors from tcpdump & NIC Hardware Offloading

If you’ve ever tried to trace a UDP or TCP stream by using the tcpdump tool on Linux then you may have noticed that all, or at least most, packets indicate checksum errors. This is caused because you have checksum offloading on your network card (NIC) and tcpdump reads IP packets from the Linux kernel right before the actual checksum takes place in the NIC’s chipset. That’s why you only see errors in tcpdump and your network traffic works ok.

So, just to prove my point, here is a tcpdump output while monitoring DNS traffic (udp/53)

$ sudo tcpdump -i eth0 -vvv -nn udp dst port 53
 tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
 17:04:48.145904 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 61)
 10.0.0.2.56497 > 10.0.0.1.53: [bad udp cksum 0x8f54 -> 0xb8fc!] 30234+ AAAA? www.twitter.com. (33)
 17:04:48.145925 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 61)
 10.0.0.2.56497 > 10.0.0.1.53: [bad udp cksum 0x224d -> 0x2604!] 30234+ AAAA? www.twitter.com. (33)

After checking active NIC hardware offloading options you can see the obvious

$ sudo ethtool -k eth0 | grep on
 rx-checksumming: on
 tx-checksumming: on
 scatter-gather: on
 generic-segmentation-offload: on
 generic-receive-offload: on
 rx-vlan-offload: on
 tx-vlan-offload: on

After disabling TCO (tcp offloading) for TX/RX on the NIC the problem is gone

$ sudo ethtool -K eth0 tx off rx off

$ sudo tcpdump -i eth0 -vvv -nn udp dst port 53
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
17:06:09.355411 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 57)
10.0.0.2.18964 > 10.0.0.1.53: [udp sum ok] 292+ AAAA? twitter.com. (29)
17:06:09.355431 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 57)
10.0.0.2.18964 > 10.0.0.1.53: [udp sum ok] 292+ AAAA? twitter.com. (29)

 

For the sake of performance, remember to turn TCO back on after each tcpdump execution. ;-)

If you saved the tcpdump output and later you need to correct the bad checksums then you can do one of the following:

$ sudo tcpreplay -i eth0 -F -w output.cap input.cap

or

$ sudo tcprewrite -i input.cap -o output.cap -C

Edit:
In this excellent article you can see the whole process illustrated as well as the impact of Generic Segmentation Offloading during packet capture.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close