X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=VNFs%2FDPPD-PROX%2Fprox_cksum.c;h=add52f2b4845366594f44d30ba73d47cb7083f0c;hb=ccae9496c217020455acfe337aaf2b2f0c5644d8;hp=9a05097ecbe82ee2791c39a65ef4727c6d3e7f7c;hpb=f608601d06f2da7dcb52f0a0da6caebd12412ad1;p=samplevnf.git diff --git a/VNFs/DPPD-PROX/prox_cksum.c b/VNFs/DPPD-PROX/prox_cksum.c index 9a05097e..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 */ -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,20 +84,20 @@ 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 & IPV4_CKSUM); + prox_ip_cksum(mbuf, pip, l2_len, l3_len, cksum_offload & DEV_TX_OFFLOAD_IPV4_CKSUM); uint32_t l4_len = rte_bswap16(pip->total_length) - l3_len; if (pip->next_proto_id == IPPROTO_UDP) { struct udp_hdr *udp = (struct udp_hdr *)(((uint8_t*)pip) + l3_len); #ifndef SOFT_CRC - if (cksum_offload & UDP_CKSUM) { + if (cksum_offload & DEV_TX_OFFLOAD_UDP_CKSUM) { mbuf->ol_flags |= PKT_TX_UDP_CKSUM; prox_write_udp_pseudo_hdr(udp, l4_len, pip->src_addr, pip->dst_addr); } else @@ -96,7 +106,7 @@ void prox_ip_udp_cksum(struct rte_mbuf *mbuf, struct ipv4_hdr *pip, uint16_t l2_ } else if (pip->next_proto_id == IPPROTO_TCP) { struct tcp_hdr *tcp = (struct tcp_hdr *)(((uint8_t*)pip) + l3_len); #ifndef SOFT_CRC - if (cksum_offload & UDP_CKSUM) { + if (cksum_offload & DEV_TX_OFFLOAD_TCP_CKSUM) { prox_write_tcp_pseudo_hdr(tcp, l4_len, pip->src_addr, pip->dst_addr); mbuf->ol_flags |= PKT_TX_UDP_CKSUM; } else @@ -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);