LCOV - code coverage report
Current view: top level - app/test - test_cksum.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 47 78 60.3 %
Date: 2024-12-01 18:57:19 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 25 46 54.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2021 6WIND S.A.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <string.h>
       6                 :            : #include <stdio.h>
       7                 :            : #include <stdlib.h>
       8                 :            : #include <stdint.h>
       9                 :            : 
      10                 :            : #include <rte_net.h>
      11                 :            : #include <rte_mbuf.h>
      12                 :            : #include <rte_ip.h>
      13                 :            : 
      14                 :            : #include "test.h"
      15                 :            : 
      16                 :            : #define MEMPOOL_CACHE_SIZE      0
      17                 :            : #define MBUF_DATA_SIZE          256
      18                 :            : #define NB_MBUF                 128
      19                 :            : 
      20                 :            : /*
      21                 :            :  * Test L3/L4 checksum API.
      22                 :            :  */
      23                 :            : 
      24                 :            : #define GOTO_FAIL(str, ...) do {                                        \
      25                 :            :                 printf("cksum test FAILED (l.%d): <" str ">\n",               \
      26                 :            :                        __LINE__,  ##__VA_ARGS__);                       \
      27                 :            :                 goto fail;                                              \
      28                 :            :         } while (0)
      29                 :            : 
      30                 :            : /* generated in scapy with Ether()/IP()/TCP())) */
      31                 :            : static const char test_cksum_ipv4_tcp[] = {
      32                 :            :         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
      33                 :            :         0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
      34                 :            :         0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
      35                 :            :         0x7c, 0xcd, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00,
      36                 :            :         0x00, 0x01, 0x00, 0x14, 0x00, 0x50, 0x00, 0x00,
      37                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
      38                 :            :         0x20, 0x00, 0x91, 0x7c, 0x00, 0x00,
      39                 :            : 
      40                 :            : };
      41                 :            : 
      42                 :            : /* generated in scapy with Ether()/IPv6()/TCP()) */
      43                 :            : static const char test_cksum_ipv6_tcp[] = {
      44                 :            :         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
      45                 :            :         0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00,
      46                 :            :         0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00,
      47                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      48                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
      49                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      50                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14,
      51                 :            :         0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      52                 :            :         0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0x8f, 0x7d,
      53                 :            :         0x00, 0x00,
      54                 :            : };
      55                 :            : 
      56                 :            : /* generated in scapy with Ether()/IP()/UDP()/Raw('x')) */
      57                 :            : static const char test_cksum_ipv4_udp[] = {
      58                 :            :         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
      59                 :            :         0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
      60                 :            :         0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11,
      61                 :            :         0x7c, 0xcd, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00,
      62                 :            :         0x00, 0x01, 0x00, 0x35, 0x00, 0x35, 0x00, 0x09,
      63                 :            :         0x89, 0x6f, 0x78,
      64                 :            : };
      65                 :            : 
      66                 :            : /* generated in scapy with Ether()/IPv6()/UDP()/Raw('x')) */
      67                 :            : static const char test_cksum_ipv6_udp[] = {
      68                 :            :         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
      69                 :            :         0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60, 0x00,
      70                 :            :         0x00, 0x00, 0x00, 0x09, 0x11, 0x40, 0x00, 0x00,
      71                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      72                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
      73                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      74                 :            :         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x35,
      75                 :            :         0x00, 0x35, 0x00, 0x09, 0x87, 0x70, 0x78,
      76                 :            : };
      77                 :            : 
      78                 :            : /* generated in scapy with Ether()/IP(options='\x00')/UDP()/Raw('x')) */
      79                 :            : static const char test_cksum_ipv4_opts_udp[] = {
      80                 :            :         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
      81                 :            :         0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x46, 0x00,
      82                 :            :         0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11,
      83                 :            :         0x7b, 0xc9, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00,
      84                 :            :         0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35,
      85                 :            :         0x00, 0x35, 0x00, 0x09, 0x89, 0x6f, 0x78,
      86                 :            : };
      87                 :            : 
      88                 :            : /* test l3/l4 checksum api */
      89                 :            : static int
      90                 :          5 : test_l4_cksum(struct rte_mempool *pktmbuf_pool, const char *pktdata, size_t len)
      91                 :            : {
      92                 :            :         struct rte_net_hdr_lens hdr_lens;
      93                 :            :         struct rte_mbuf *m = NULL;
      94                 :            :         uint32_t packet_type;
      95                 :            :         uint16_t prev_cksum;
      96                 :            :         void *l3_hdr;
      97                 :            :         void *l4_hdr;
      98                 :            :         uint32_t l3;
      99                 :            :         uint32_t l4;
     100                 :            :         char *data;
     101                 :            : 
     102                 :          5 :         m = rte_pktmbuf_alloc(pktmbuf_pool);
     103         [ -  + ]:          5 :         if (m == NULL)
     104                 :          0 :                 GOTO_FAIL("Cannot allocate mbuf");
     105                 :            : 
     106                 :          5 :         data = rte_pktmbuf_append(m, len);
     107         [ -  + ]:          5 :         if (data == NULL)
     108                 :          0 :                 GOTO_FAIL("Cannot append data");
     109                 :            : 
     110                 :            :         memcpy(data, pktdata, len);
     111                 :            : 
     112                 :          5 :         packet_type = rte_net_get_ptype(m, &hdr_lens, RTE_PTYPE_ALL_MASK);
     113                 :          5 :         l3 = packet_type & RTE_PTYPE_L3_MASK;
     114                 :          5 :         l4 = packet_type & RTE_PTYPE_L4_MASK;
     115                 :            : 
     116                 :          5 :         l3_hdr = rte_pktmbuf_mtod_offset(m, void *, hdr_lens.l2_len);
     117                 :          5 :         l4_hdr = rte_pktmbuf_mtod_offset(m, void *,
     118                 :            :                                          hdr_lens.l2_len + hdr_lens.l3_len);
     119                 :            : 
     120         [ +  + ]:          5 :         if (l3 == RTE_PTYPE_L3_IPV4 || l3 == RTE_PTYPE_L3_IPV4_EXT) {
     121                 :            :                 struct rte_ipv4_hdr *ip = l3_hdr;
     122                 :            : 
     123                 :            :                 /* verify IPv4 checksum */
     124         [ -  + ]:          3 :                 if (rte_ipv4_cksum(l3_hdr) != 0)
     125                 :          0 :                         GOTO_FAIL("invalid IPv4 checksum verification");
     126                 :            : 
     127                 :            :                 /* verify bad IPv4 checksum */
     128         [ -  + ]:          3 :                 ip->hdr_checksum++;
     129         [ -  + ]:          3 :                 if (rte_ipv4_cksum(l3_hdr) == 0)
     130                 :          0 :                         GOTO_FAIL("invalid IPv4 bad checksum verification");
     131                 :            :                 ip->hdr_checksum--;
     132                 :            : 
     133                 :            :                 /* recalculate IPv4 checksum */
     134                 :            :                 prev_cksum = ip->hdr_checksum;
     135         [ -  + ]:          3 :                 ip->hdr_checksum = 0;
     136                 :          3 :                 ip->hdr_checksum = rte_ipv4_cksum(ip);
     137         [ -  + ]:          3 :                 if (ip->hdr_checksum != prev_cksum)
     138                 :          0 :                         GOTO_FAIL("invalid IPv4 checksum calculation");
     139                 :            : 
     140                 :            :                 /* verify L4 checksum */
     141                 :            :                 if (rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr) != 0)
     142                 :          0 :                         GOTO_FAIL("invalid L4 checksum verification");
     143                 :            : 
     144         [ +  + ]:          3 :                 if (l4 == RTE_PTYPE_L4_TCP) {
     145                 :            :                         struct rte_tcp_hdr *tcp = l4_hdr;
     146                 :            : 
     147                 :            :                         /* verify bad TCP checksum */
     148                 :          1 :                         tcp->cksum++;
     149                 :            :                         if (rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
     150                 :          0 :                                 GOTO_FAIL("invalid bad TCP checksum verification");
     151                 :            :                         tcp->cksum--;
     152                 :            : 
     153                 :            :                         /* recalculate TCP checksum */
     154                 :            :                         prev_cksum = tcp->cksum;
     155                 :          1 :                         tcp->cksum = 0;
     156                 :          1 :                         tcp->cksum = rte_ipv4_udptcp_cksum(l3_hdr, l4_hdr);
     157         [ -  + ]:          1 :                         if (tcp->cksum != prev_cksum)
     158                 :          0 :                                 GOTO_FAIL("invalid TCP checksum calculation");
     159                 :            : 
     160         [ +  - ]:          2 :                 } else if (l4 == RTE_PTYPE_L4_UDP) {
     161                 :            :                         struct rte_udp_hdr *udp = l4_hdr;
     162                 :            : 
     163                 :            :                         /* verify bad UDP checksum */
     164                 :          2 :                         udp->dgram_cksum++;
     165                 :            :                         if (rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
     166                 :          0 :                                 GOTO_FAIL("invalid bad UDP checksum verification");
     167                 :            :                         udp->dgram_cksum--;
     168                 :            : 
     169                 :            :                         /* recalculate UDP checksum */
     170                 :            :                         prev_cksum = udp->dgram_cksum;
     171                 :          2 :                         udp->dgram_cksum = 0;
     172                 :          2 :                         udp->dgram_cksum = rte_ipv4_udptcp_cksum(l3_hdr,
     173                 :            :                                                                  l4_hdr);
     174         [ -  + ]:          2 :                         if (udp->dgram_cksum != prev_cksum)
     175                 :          0 :                                 GOTO_FAIL("invalid TCP checksum calculation");
     176                 :            :                 }
     177         [ +  + ]:          2 :         } else if (l3 == RTE_PTYPE_L3_IPV6 || l3 == RTE_PTYPE_L3_IPV6_EXT) {
     178                 :            :                 if (rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr) != 0)
     179                 :          0 :                         GOTO_FAIL("invalid L4 checksum verification");
     180                 :            : 
     181         [ -  + ]:          1 :                 if (l4 == RTE_PTYPE_L4_TCP) {
     182                 :            :                         struct rte_tcp_hdr *tcp = l4_hdr;
     183                 :            : 
     184                 :            :                         /* verify bad TCP checksum */
     185                 :          0 :                         tcp->cksum++;
     186                 :            :                         if (rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
     187                 :          0 :                                 GOTO_FAIL("invalid bad TCP checksum verification");
     188                 :            :                         tcp->cksum--;
     189                 :            : 
     190                 :            :                         /* recalculate TCP checksum */
     191                 :            :                         prev_cksum = tcp->cksum;
     192                 :          0 :                         tcp->cksum = 0;
     193                 :          0 :                         tcp->cksum = rte_ipv6_udptcp_cksum(l3_hdr, l4_hdr);
     194         [ #  # ]:          0 :                         if (tcp->cksum != prev_cksum)
     195                 :          0 :                                 GOTO_FAIL("invalid TCP checksum calculation");
     196                 :            : 
     197         [ +  - ]:          1 :                 } else if (l4 == RTE_PTYPE_L4_UDP) {
     198                 :            :                         struct rte_udp_hdr *udp = l4_hdr;
     199                 :            : 
     200                 :            :                         /* verify bad UDP checksum */
     201                 :          1 :                         udp->dgram_cksum++;
     202                 :            :                         if (rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
     203                 :          0 :                                 GOTO_FAIL("invalid bad UDP checksum verification");
     204                 :            :                         udp->dgram_cksum--;
     205                 :            : 
     206                 :            :                         /* recalculate UDP checksum */
     207                 :            :                         prev_cksum = udp->dgram_cksum;
     208                 :          1 :                         udp->dgram_cksum = 0;
     209                 :          1 :                         udp->dgram_cksum = rte_ipv6_udptcp_cksum(l3_hdr,
     210                 :            :                                                                  l4_hdr);
     211         [ -  + ]:          1 :                         if (udp->dgram_cksum != prev_cksum)
     212                 :          0 :                                 GOTO_FAIL("invalid TCP checksum calculation");
     213                 :            :                 }
     214                 :            :         }
     215                 :            : 
     216                 :          5 :         rte_pktmbuf_free(m);
     217                 :            : 
     218                 :          5 :         return 0;
     219                 :            : 
     220                 :          0 : fail:
     221                 :          0 :         rte_pktmbuf_free(m);
     222                 :            : 
     223                 :          0 :         return -1;
     224                 :            : }
     225                 :            : 
     226                 :            : static int
     227                 :          1 : test_cksum(void)
     228                 :            : {
     229                 :            :         struct rte_mempool *pktmbuf_pool = NULL;
     230                 :            : 
     231                 :            :         /* create pktmbuf pool if it does not exist */
     232                 :          1 :         pktmbuf_pool = rte_pktmbuf_pool_create("test_cksum_mbuf_pool",
     233                 :            :                         NB_MBUF, MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
     234                 :            :                         SOCKET_ID_ANY);
     235                 :            : 
     236         [ -  + ]:          1 :         if (pktmbuf_pool == NULL)
     237                 :          0 :                 GOTO_FAIL("cannot allocate mbuf pool");
     238                 :            : 
     239         [ -  + ]:          1 :         if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv4_tcp,
     240                 :            :                           sizeof(test_cksum_ipv4_tcp)) < 0)
     241                 :          0 :                 GOTO_FAIL("checksum error on ipv4_tcp");
     242                 :            : 
     243         [ -  + ]:          1 :         if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv6_tcp,
     244                 :            :                           sizeof(test_cksum_ipv6_tcp)) < 0)
     245                 :          0 :                 GOTO_FAIL("checksum error on ipv6_tcp");
     246                 :            : 
     247         [ -  + ]:          1 :         if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv4_udp,
     248                 :            :                           sizeof(test_cksum_ipv4_udp)) < 0)
     249                 :          0 :                 GOTO_FAIL("checksum error on ipv4_udp");
     250                 :            : 
     251         [ -  + ]:          1 :         if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv6_udp,
     252                 :            :                           sizeof(test_cksum_ipv6_udp)) < 0)
     253                 :          0 :                 GOTO_FAIL("checksum error on ipv6_udp");
     254                 :            : 
     255         [ -  + ]:          1 :         if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv4_opts_udp,
     256                 :            :                           sizeof(test_cksum_ipv4_opts_udp)) < 0)
     257                 :          0 :                 GOTO_FAIL("checksum error on ipv4_opts_udp");
     258                 :            : 
     259                 :          1 :         rte_mempool_free(pktmbuf_pool);
     260                 :            : 
     261                 :          1 :         return 0;
     262                 :            : 
     263                 :          0 : fail:
     264                 :          0 :         rte_mempool_free(pktmbuf_pool);
     265                 :            : 
     266                 :          0 :         return -1;
     267                 :            : }
     268                 :            : #undef GOTO_FAIL
     269                 :            : 
     270                 :        251 : REGISTER_FAST_TEST(cksum_autotest, true, true, test_cksum);

Generated by: LCOV version 1.14