Multiple changes for June release
[samplevnf.git] / VNFs / DPPD-PROX / prox_cksum.c
index 10dc3a8..add52f2 100644 (file)
 #include "log.h"
 
 /* compute IP 16 bit checksum */
-void prox_ip_cksum_sw(struct ipv4_hdr *buf)
+/* 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) {
@@ -52,7 +62,7 @@ void prox_ip_cksum_sw(struct ipv4_hdr *buf)
        buf->hdr_checksum = ~((uint16_t)cksum);
 }
 
-static uint16_t calc_pseudo_checksum(uint8_t ipproto, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
+static inline uint16_t calc_pseudo_checksum(uint8_t ipproto, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
 {
        uint32_t csum = 0;
 
@@ -63,7 +73,7 @@ static uint16_t calc_pseudo_checksum(uint8_t ipproto, uint16_t len, uint32_t src
        return csum;
 }
 
-static void prox_write_udp_pseudo_hdr(struct udp_hdr *udp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
+static inline void prox_write_udp_pseudo_hdr(struct udp_hdr *udp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
 {
        /* Note that the csum is not complemented, while the pseaudo
           header checksum is calculated as "... the 16-bit one's
@@ -74,12 +84,12 @@ static void prox_write_udp_pseudo_hdr(struct udp_hdr *udp, uint16_t len, uint32_
        udp->dgram_cksum = calc_pseudo_checksum(IPPROTO_UDP, len, src_ip_addr, dst_ip_addr);
 }
 
-static void prox_write_tcp_pseudo_hdr(struct tcp_hdr *tcp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
+static inline void prox_write_tcp_pseudo_hdr(struct tcp_hdr *tcp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
 {
        tcp->cksum = calc_pseudo_checksum(IPPROTO_TCP, len, src_ip_addr, dst_ip_addr);
 }
 
-void prox_ip_udp_cksum(struct rte_mbuf *mbuf, struct ipv4_hdr *pip, uint16_t l2_len, uint16_t l3_len, int cksum_offload)
+inline void prox_ip_udp_cksum(struct rte_mbuf *mbuf, struct ipv4_hdr *pip, uint16_t l2_len, uint16_t l3_len, int cksum_offload)
 {
        prox_ip_cksum(mbuf, pip, l2_len, l3_len, cksum_offload & DEV_TX_OFFLOAD_IPV4_CKSUM);
 
@@ -105,7 +115,7 @@ void prox_ip_udp_cksum(struct rte_mbuf *mbuf, struct ipv4_hdr *pip, uint16_t l2_
        }
 }
 
-static uint16_t checksum_byte_seq(uint16_t *buf, uint16_t len)
+static inline uint16_t checksum_byte_seq(uint16_t *buf, uint16_t len)
 {
        uint32_t csum = 0;
 
@@ -129,14 +139,14 @@ static uint16_t checksum_byte_seq(uint16_t *buf, uint16_t len)
        return ~csum;
 }
 
-void prox_udp_cksum_sw(struct udp_hdr *udp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
+inline void prox_udp_cksum_sw(struct udp_hdr *udp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
 {
        prox_write_udp_pseudo_hdr(udp, len, src_ip_addr, dst_ip_addr);
        uint16_t csum = checksum_byte_seq((uint16_t *)udp, len);
        udp->dgram_cksum = csum;
 }
 
-void prox_tcp_cksum_sw(struct tcp_hdr *tcp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
+inline void prox_tcp_cksum_sw(struct tcp_hdr *tcp, uint16_t len, uint32_t src_ip_addr, uint32_t dst_ip_addr)
 {
        prox_write_tcp_pseudo_hdr(tcp, len, src_ip_addr, dst_ip_addr);