summaryrefslogtreecommitdiffstats
path: root/VNFs
diff options
context:
space:
mode:
authorXavier Simonart <xavier.simonart@intel.com>2019-05-28 20:24:00 +0200
committerPatrice Buriez <patrice.buriez@intel.com>2019-06-11 11:58:49 +0000
commit0d8616af8418480595a2c53e1dc7c3b809962a28 (patch)
tree7cd7b4a16d9265e8dc3016293f4c29ab8e3ddd98 /VNFs
parentc477a3fa2d36e10c6004f2c20fe89acdc0a51917 (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.c12
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) {