DPDK usage discussions
 help / color / mirror / Atom feed
From: "N. Benes" <nbenes@eso.org>
To: users@dpdk.org
Subject: [dpdk-users] Bug in IPv4 header checksum computation?
Date: Thu, 21 Mar 2019 15:03:00 +0000	[thread overview]
Message-ID: <abd6263a-2d7a-cf1b-1193-7af41af510a5@eso.org> (raw)

Hi,

the function for calculating the IPv4 header checksum avoids returning 0
with an additional complement. This is similar to the algorithm for UDP
checksums (where 0 is reserved for "no checksum"), but I could not find
a reference that the same shall also be done for IPv4.

I'm wondering whether I just failed to find the correct reference or if
it is a bug in DPDK?

https://git.dpdk.org/dpdk/tree/lib/librte_net/rte_ip.h#n251
https://git.dpdk.org/dpdk-stable/tree/lib/librte_net/rte_ip.h#n313
> static inline uint16_t
> rte_ipv4_cksum(const struct ipv4_hdr *ipv4_hdr)
> {
> 	uint16_t cksum;
> 	cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct ipv4_hdr));
> 	return (cksum == 0xffff) ? cksum : ~cksum;
> }

In /UDP/, a checksum value 0x0000 means that no checksum was calculated
by the sender and that the receiver cannot check anything. The checksum
is computed from the one's complement sum of 16-bit words, followed by a
one's complement. If the resulting value is 0, it is inverted again.
Therefore, a one's complement 16-bit sum "0xffff" is not inverted, while
all other values are (e.g. "return (sum == 0xffff) ? sum : ~sum"):

https://tools.ietf.org/html/rfc768
> Checksum is the 16-bit one's complement of the one's complement sum of a
> pseudo header of information from the IP header, the UDP header, and the
> data,  padded  with zero octets  at the end (if  necessary)  to  make  a
> multiple of two octets....
> 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).

The above function 'rte_ipv4_cksum()' is supposed to compute the
checksum of the /IPv4/ header and -- like checksums for UDP -- does not
return 0 by doing an additional inversion.

However, the IPv4 header checksum is specified as:

https://tools.ietf.org/rfc/rfc791
>     The checksum algorithm is:
> 
>       The checksum field is the 16 bit one's complement of the one's
>       complement sum of all 16 bit words in the header.  For purposes of
>       computing the checksum, the value of the checksum field is zero.

There are no mentioning to an additional inversion, if the resulting
checksum was 0.

Also Wireshark shows an IPv4 header checksum error for packets with
checksum 0. I understand this as indication that IPv4 is not supposed to
allow for ignoring header checksums.

Example to generate a PCAP with 0x0000 IPv4 header checksum and
(correct) UDP payload with 0 checksum:

text2pcap -n -e 0800 ipcks.txt ipcks.pcapng
> 0000 45 00 00 20 12 34 00 00   10 11 00 00 0a 00 00 01
> 0010 0a 00 00 02 01 00 00 16   00 0c 00 00 00 00 00 00


Cheers!

             reply	other threads:[~2019-03-21 15:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-21 15:03 N. Benes [this message]
2019-03-22  9:30 ` N. Benes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=abd6263a-2d7a-cf1b-1193-7af41af510a5@eso.org \
    --to=nbenes@eso.org \
    --cc=users@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).