diff options
author | Xavier Simonart <xavier.simonart@intel.com> | 2019-05-28 20:24:00 +0200 |
---|---|---|
committer | Patrice Buriez <patrice.buriez@intel.com> | 2019-06-11 11:58:49 +0000 |
commit | 0d8616af8418480595a2c53e1dc7c3b809962a28 (patch) | |
tree | 7cd7b4a16d9265e8dc3016293f4c29ab8e3ddd98 /VNFs | |
parent | c477a3fa2d36e10c6004f2c20fe89acdc0a51917 (diff) |
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 <xavier.simonart@intel.com>
Signed-off-by: Patrice Buriez <patrice.buriez@intel.com>
Diffstat (limited to 'VNFs')
-rw-r--r-- | VNFs/DPPD-PROX/prox_cksum.c | 12 |
1 files changed, 11 insertions, 1 deletions
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) { |