[ovs-dev] [PATCH 1/3] csum: Fix csum_continue() on big endian with an odd number of bytes.

Daniele Di Proietto diproiettod at vmware.com
Fri Dec 9 02:50:19 UTC 2016


Even though it reads 16 bits at a time, csum_continue() is almost
neutral to endianness (see RFC 1071 1.2 (B), "Byte Order Independence").

Consider a buffer like the following:

00000000: XX YY XX YY XX YY XX YY ZZ

Each couple of bytes is interpreted on little endian as:

*data = 0xYYXX

while on big endian

*data = 0xXXYY

The last byte "ZZ" should be treated as the two bytes "ZZ 00"
little endian:

*data = 0x00ZZ

big endian:

*data = 0xZZ00

which means that the last byte (for odd buffers) should be left shifted
by 8 bits on big endian platforms.

This fixes a couple of connection tracking tests in userspace for big
endian platforms.

I guess RFC1071 4.1 (implementation example of the checksum in C), would
manifest the same problem on big endian.

Reported-at: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=840770
Signed-off-by: Daniele Di Proietto <diproiettod at vmware.com>
---
 lib/csum.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/csum.c b/lib/csum.c
index a0e9967..5951576 100644
--- a/lib/csum.c
+++ b/lib/csum.c
@@ -44,7 +44,11 @@ csum_continue(uint32_t partial, const void *data_, size_t n)
         partial = csum_add16(partial, get_unaligned_be16(data));
     }
     if (n) {
+#ifdef WORDS_BIGENDIAN
+        partial += (*(uint8_t *) data) << 8;
+#else
         partial += *(uint8_t *) data;
+#endif
     }
     return partial;
 }
-- 
2.10.2



More information about the dev mailing list