crypto-native: 256-bit AES CBC support
[vpp.git] / src / vppinfra / test / ip_csum.c
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright(c) 2021 Cisco Systems, Inc.
3  */
4
5 #include <vppinfra/format.h>
6 #include <vppinfra/test/test.h>
7 #include <vppinfra/vector/ip_csum.h>
8
9 typedef struct
10 {
11   struct
12   {
13     u8 *src;
14     u32 count;
15   } chunk[5];
16   u16 result;
17 } ip_csum_test_t;
18
19 static u8 test1[] = { 0x45, 0x00, 0x00, 0x73, 0x00, 0x00, 0x40,
20                       0x00, 0x40, 0x11, 0x00, 0x00, 0xc0, 0xa8,
21                       0x00, 0x01, 0xc0, 0xa8, 0x00, 0xc7, 0x00 };
22 #define TEST_LEN(x) (ARRAY_LEN (x) - 1)
23
24 static ip_csum_test_t tests[] = { {
25                                     .chunk[0].src = test1,
26                                     .chunk[0].count = TEST_LEN (test1),
27                                     .result = 0x61b8,
28                                   },
29                                   {
30                                     .chunk[0].src = test1,
31                                     .chunk[0].count = 1,
32                                     .chunk[1].src = test1 + 1,
33                                     .chunk[1].count = 2,
34                                     .chunk[2].src = test1 + 3,
35                                     .chunk[2].count = 3,
36                                     .chunk[3].src = test1 + 6,
37                                     .chunk[3].count = 4,
38                                     .chunk[4].src = test1 + 10,
39                                     .chunk[4].count = TEST_LEN (test1) - 10,
40                                     .result = 0x61b8,
41                                   },
42                                   {
43                                     .chunk[0].count = 1,
44                                     .result = 0xff0f,
45                                   },
46                                   {
47                                     .chunk[0].count = 2,
48                                     .result = 0x080f,
49                                   },
50                                   {
51                                     .chunk[0].count = 3,
52                                     .result = 0x0711,
53                                   },
54                                   {
55                                     .chunk[0].count = 4,
56                                     .result = 0x1210,
57                                   },
58                                   {
59                                     .chunk[0].count = 63,
60                                     .result = 0xda01,
61                                   },
62                                   {
63                                     .chunk[0].count = 64,
64                                     .result = 0xe100,
65                                   },
66                                   {
67                                     .chunk[0].count = 65,
68                                     .result = 0xe010,
69                                   },
70                                   {
71                                     .chunk[0].count = 65535,
72                                     .result = 0xfc84,
73                                   },
74                                   {
75                                     .chunk[0].count = 65536,
76                                     .result = 0xffff,
77                                   } };
78
79 static clib_error_t *
80 test_clib_ip_csum (clib_error_t *err)
81 {
82   u8 *buf;
83   buf = test_mem_alloc (65536);
84   for (int i = 0; i < 65536; i++)
85     buf[i] = 0xf0 + ((i * 7) & 0xf);
86
87   for (int i = 0; i < ARRAY_LEN (tests); i++)
88     {
89       clib_ip_csum_t c = {};
90       ip_csum_test_t *t = tests + i;
91       u16 rv;
92
93       for (int j = 0; j < ARRAY_LEN (((ip_csum_test_t *) 0)->chunk); j++)
94         if (t->chunk[j].count > 0)
95           {
96             if (t->chunk[j].src == 0)
97               clib_ip_csum_chunk (&c, buf, t->chunk[j].count);
98             else
99               clib_ip_csum_chunk (&c, t->chunk[j].src, t->chunk[j].count);
100           }
101       rv = clib_ip_csum_fold (&c);
102
103       if (rv != tests[i].result)
104         {
105           err = clib_error_return (err,
106                                    "bad checksum in test case %u (expected "
107                                    "0x%04x, calculated 0x%04x)",
108                                    i, tests[i].result, rv);
109           goto done;
110         }
111     }
112 done:
113   test_mem_free (buf);
114   return err;
115 }
116
117 void __test_perf_fn
118 perftest_ip4_hdr (test_perf_t *tp)
119 {
120   u32 n = tp->n_ops;
121   u8 *data = test_mem_alloc_and_splat (20, n, (void *) &test1);
122   u16 *res = test_mem_alloc (n * sizeof (u16));
123
124   test_perf_event_enable (tp);
125   for (int i = 0; i < n; i++)
126     res[i] = clib_ip_csum (data + i * 20, 20);
127   test_perf_event_disable (tp);
128
129   test_mem_free (data);
130   test_mem_free (res);
131 }
132
133 void __test_perf_fn
134 perftest_tcp_payload (test_perf_t *tp)
135 {
136   u32 n = tp->n_ops;
137   volatile uword *lenp = &tp->arg0;
138   u8 *data = test_mem_alloc_and_splat (20, n, (void *) &test1);
139   u16 *res = test_mem_alloc (n * sizeof (u16));
140
141   test_perf_event_enable (tp);
142   for (int i = 0; i < n; i++)
143     res[i] = clib_ip_csum (data + i * lenp[0], lenp[0]);
144   test_perf_event_disable (tp);
145
146   test_mem_free (data);
147   test_mem_free (res);
148 }
149
150 void __test_perf_fn
151 perftest_byte (test_perf_t *tp)
152 {
153   volatile uword *np = &tp->n_ops;
154   u8 *data = test_mem_alloc_and_fill_inc_u8 (*np, 0, 0);
155   u16 *res = test_mem_alloc (sizeof (u16));
156
157   test_perf_event_enable (tp);
158   res[0] = clib_ip_csum (data, np[0]);
159   test_perf_event_disable (tp);
160
161   test_mem_free (data);
162   test_mem_free (res);
163 }
164
165 REGISTER_TEST (clib_ip_csum) = {
166   .name = "clib_ip_csum",
167   .fn = test_clib_ip_csum,
168   .perf_tests = PERF_TESTS (
169     { .name = "fixed size (per IPv4 Header)",
170       .n_ops = 1024,
171       .fn = perftest_ip4_hdr },
172     { .name = "fixed size (per 1460 byte block)",
173       .n_ops = 16,
174       .arg0 = 1460,
175       .fn = perftest_tcp_payload },
176     { .name = "variable size (per byte)", .n_ops = 16384, .fn = perftest_byte }
177
178     ),
179 };