From 0d8616af8418480595a2c53e1dc7c3b809962a28 Mon Sep 17 00:00:00 2001 From: Xavier Simonart Date: Tue, 28 May 2019 20:24:00 +0200 Subject: Fix soft checksum calculation Soft CRC was wrong in some cases, such as when compiled with gcc -O2 This might have caused the checksum to be set to 0 in those cases. Change-Id: Idf01df92876bd2a152ad028293b67a31861a0dfc Signed-off-by: Xavier Simonart Signed-off-by: Patrice Buriez --- VNFs/DPPD-PROX/prox_cksum.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/VNFs/DPPD-PROX/prox_cksum.c b/VNFs/DPPD-PROX/prox_cksum.c index 1b9119b0..add52f2b 100644 --- a/VNFs/DPPD-PROX/prox_cksum.c +++ b/VNFs/DPPD-PROX/prox_cksum.c @@ -20,13 +20,23 @@ #include "log.h" /* compute IP 16 bit checksum */ +/* The hdr_checksum field must be set to 0 by the caller. */ inline void prox_ip_cksum_sw(struct ipv4_hdr *buf) { const uint16_t size = sizeof(struct ipv4_hdr); uint32_t cksum = 0; uint32_t nb_dwords; uint32_t tail, mask; - uint32_t *pdwd = (uint32_t *)buf; + /* Defining pdwd as (uint32_t *) causes some optimization issues (gcc -O2). + In prox_ip_cksum(), hdr_checksum is set to 0, as expected by the code below, + but when *pdwd is plain uint32_t, GCC does not see the pointer aliasing on + the IPv4 header, optimizes this hdr_checksum initialization away, and hence + breaks the expectations of the checksum computation loop below. + The following typedef tells GCC that the IPv4 header may be aliased by + pdwd, which prevents GCC from removing the hdr_checksum = 0 assignment. + */ + typedef uint32_t __attribute__((__may_alias__)) uint32_may_alias; + uint32_may_alias *pdwd = (uint32_may_alias *)buf; /* compute 16 bit checksum using hi and low parts of 32 bit integers */ for (nb_dwords = (size >> 2); nb_dwords > 0; --nb_dwords) { -- cgit 1.2.3-korg