diff options
author | Damjan Marion <damarion@cisco.com> | 2021-11-08 11:18:30 +0000 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2021-11-10 23:22:58 +0000 |
commit | aa63bc6cf4b9031c3fc6ae22aecd846cc712bc52 (patch) | |
tree | c007868ca129f5594ac9c5aa460edea4aa63951e /src/vnet | |
parent | 29355644c5eca85b83b183ff887633dbcf86cf35 (diff) |
vppinfra: new vectorized ip checksum functions incl. csum_and_copy
Type: improvement
Change-Id: Id5810b7f4a6d6e4ce16b73c235b50db5d475ebf7
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ip/ip4_input.h | 10 | ||||
-rwxr-xr-x | src/vnet/ip/ip_packet.h | 92 | ||||
-rw-r--r-- | src/vnet/ip/ip_psh_cksum.h | 7 |
3 files changed, 11 insertions, 98 deletions
diff --git a/src/vnet/ip/ip4_input.h b/src/vnet/ip/ip4_input.h index 383ef31758c..53948d60266 100644 --- a/src/vnet/ip/ip4_input.h +++ b/src/vnet/ip/ip4_input.h @@ -42,6 +42,7 @@ #include <vnet/ip/ip.h> #include <vnet/ethernet/ethernet.h> +#include <vppinfra/vector/ip_csum.h> typedef enum { @@ -63,15 +64,16 @@ check_ver_opt_csum (ip4_header_t * ip, u8 * error, int verify_checksum) if ((ip->ip_version_and_header_length & 0xf) != 5) { *error = IP4_ERROR_OPTIONS; - if (verify_checksum && ip_csum (ip, ip4_header_bytes (ip)) != 0) + if (verify_checksum && + clib_ip_csum ((u8 *) ip, ip4_header_bytes (ip)) != 0) *error = IP4_ERROR_BAD_CHECKSUM; } else *error = IP4_ERROR_VERSION; } - else - if (PREDICT_FALSE (verify_checksum && - ip_csum (ip, sizeof (ip4_header_t)) != 0)) + else if (PREDICT_FALSE (verify_checksum && + clib_ip_csum ((u8 *) ip, sizeof (ip4_header_t)) != + 0)) *error = IP4_ERROR_BAD_CHECKSUM; } diff --git a/src/vnet/ip/ip_packet.h b/src/vnet/ip/ip_packet.h index 837b3df8563..04cf9f11d70 100755 --- a/src/vnet/ip/ip_packet.h +++ b/src/vnet/ip/ip_packet.h @@ -149,98 +149,6 @@ STATIC_ASSERT_SIZEOF (ip_ecn_t, 1); extern u8 *format_ip_ecn (u8 * s, va_list * va); -/* IP checksum support. */ - -static_always_inline u16 -ip_csum (void *data, u16 n_left) -{ - u32 sum; -#ifdef CLIB_HAVE_VEC256 - u16x16 v1, v2; - u32x8 zero = { 0 }; - u32x8 sum8 = { 0 }; - u32x4 sum4; -#endif - - /* if there is odd number of bytes, pad by zero and store in sum */ - sum = (n_left & 1) ? ((u8 *) data)[n_left - 1] << 8 : 0; - - /* we deal with words */ - n_left >>= 1; - -#ifdef CLIB_HAVE_VEC256 - while (n_left >= 32) - { - v1 = u16x16_load_unaligned (data); - v2 = u16x16_load_unaligned (data + 32); - -#ifdef CLIB_ARCH_IS_LITTLE_ENDIAN - v1 = u16x16_byte_swap (v1); - v2 = u16x16_byte_swap (v2); -#endif - sum8 += u32x8_from_u16x8 (u16x16_extract_lo (v1)); - sum8 += u32x8_from_u16x8 (u16x16_extract_hi (v1)); - sum8 += u32x8_from_u16x8 (u16x16_extract_lo (v2)); - sum8 += u32x8_from_u16x8 (u16x16_extract_hi (v2)); - n_left -= 32; - data += 64; - } - - if (n_left >= 16) - { - v1 = u16x16_load_unaligned (data); -#ifdef CLIB_ARCH_IS_LITTLE_ENDIAN - v1 = u16x16_byte_swap (v1); -#endif - sum8 += u32x8_from_u16x8 (u16x16_extract_lo (v1)); - sum8 += u32x8_from_u16x8 (u16x16_extract_hi (v1)); - n_left -= 16; - data += 32; - } - - if (n_left) - { - v1 = u16x16_load_unaligned (data); -#ifdef CLIB_ARCH_IS_LITTLE_ENDIAN - v1 = u16x16_byte_swap (v1); -#endif - v1 = u16x16_mask_last (v1, 16 - n_left); - sum8 += u32x8_from_u16x8 (u16x16_extract_lo (v1)); - sum8 += u32x8_from_u16x8 (u16x16_extract_hi (v1)); - } - - sum8 = u32x8_hadd (sum8, zero); - sum4 = u32x8_extract_lo (sum8) + u32x8_extract_hi (sum8); - sum += sum4[0] + sum4[1]; - -#else - /* scalar version */ - while (n_left >= 8) - { - sum += clib_net_to_host_u16 (*((u16 *) data + 0)); - sum += clib_net_to_host_u16 (*((u16 *) data + 1)); - sum += clib_net_to_host_u16 (*((u16 *) data + 2)); - sum += clib_net_to_host_u16 (*((u16 *) data + 3)); - sum += clib_net_to_host_u16 (*((u16 *) data + 4)); - sum += clib_net_to_host_u16 (*((u16 *) data + 5)); - sum += clib_net_to_host_u16 (*((u16 *) data + 6)); - sum += clib_net_to_host_u16 (*((u16 *) data + 7)); - n_left -= 8; - data += 16; - } - while (n_left) - { - sum += clib_net_to_host_u16 (*(u16 *) data); - n_left -= 1; - data += 2; - } -#endif - - sum = (sum & 0xffff) + (sum >> 16); - sum = (sum & 0xffff) + (sum >> 16); - return ~((u16) sum); -} - /* Incremental checksum update. */ typedef uword ip_csum_t; diff --git a/src/vnet/ip/ip_psh_cksum.h b/src/vnet/ip/ip_psh_cksum.h index eaac401f223..8723749865f 100644 --- a/src/vnet/ip/ip_psh_cksum.h +++ b/src/vnet/ip/ip_psh_cksum.h @@ -7,6 +7,7 @@ #define included_ip_psh_cksum_h #include <vnet/ip/ip.h> +#include <vppinfra/vector/ip_csum.h> typedef struct _ip4_psh { @@ -37,7 +38,8 @@ ip4_pseudo_header_cksum (ip4_header_t *ip4) psh.proto = ip4->protocol; psh.l4len = clib_host_to_net_u16 (clib_net_to_host_u16 (ip4->length) - sizeof (ip4_header_t)); - return ~clib_net_to_host_u16 (ip_csum (&psh, sizeof (ip4_psh_t))); + return ~clib_net_to_host_u16 ( + clib_ip_csum ((u8 *) &psh, sizeof (ip4_psh_t))); } static_always_inline u16 @@ -48,7 +50,8 @@ ip6_pseudo_header_cksum (ip6_header_t *ip6) psh.dst = ip6->dst_address; psh.l4len = ip6->payload_length; psh.proto = clib_host_to_net_u32 ((u32) ip6->protocol); - return ~clib_net_to_host_u16 (ip_csum (&psh, sizeof (ip6_psh_t))); + return ~clib_net_to_host_u16 ( + clib_ip_csum ((u8 *) &psh, sizeof (ip6_psh_t))); } #endif /* included_ip_psh_cksum_h */ |