blob: 17a606523f29c14666f8de2a4ce086ffca56580b [file] [log] [blame]
Damjan Marionaa63bc62021-11-08 11:18:30 +00001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
3 */
4
5#include <vppinfra/format.h>
6#include <vppinfra/vector/test/test.h>
7#include <vppinfra/vector/ip_csum.h>
8
9typedef struct
10{
11 struct
12 {
13 u8 *src;
14 u32 count;
15 } chunk[5];
16 u16 result;
17} ip_csum_test_t;
18
19static 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
24static 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
79static clib_error_t *
80test_clib_ip_csum (clib_error_t *err)
81{
82 u8 *buf;
Damjan Marion3323e202021-12-02 11:28:57 +010083 buf = test_mem_alloc (65536);
Damjan Marionaa63bc62021-11-08 11:18:30 +000084 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 }
112done:
Damjan Marion3323e202021-12-02 11:28:57 +0100113 test_mem_free (buf);
Damjan Marionaa63bc62021-11-08 11:18:30 +0000114 return err;
115}
116
Damjan Marion3323e202021-12-02 11:28:57 +0100117void __test_perf_fn
Damjan Mariond5045e62022-04-06 21:16:37 +0200118perftest_ip4_hdr (test_perf_t *tp)
Damjan Marion3323e202021-12-02 11:28:57 +0100119{
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
Damjan Mariond5045e62022-04-06 21:16:37 +0200124 test_perf_event_enable (tp);
Damjan Marion3323e202021-12-02 11:28:57 +0100125 for (int i = 0; i < n; i++)
126 res[i] = clib_ip_csum (data + i * 20, 20);
Damjan Mariond5045e62022-04-06 21:16:37 +0200127 test_perf_event_disable (tp);
Damjan Marion3323e202021-12-02 11:28:57 +0100128
129 test_mem_free (data);
130 test_mem_free (res);
131}
132
133void __test_perf_fn
Damjan Mariond5045e62022-04-06 21:16:37 +0200134perftest_tcp_payload (test_perf_t *tp)
Damjan Marion3323e202021-12-02 11:28:57 +0100135{
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
Damjan Mariond5045e62022-04-06 21:16:37 +0200141 test_perf_event_enable (tp);
Damjan Marion3323e202021-12-02 11:28:57 +0100142 for (int i = 0; i < n; i++)
143 res[i] = clib_ip_csum (data + i * lenp[0], lenp[0]);
Damjan Mariond5045e62022-04-06 21:16:37 +0200144 test_perf_event_disable (tp);
Damjan Marion3323e202021-12-02 11:28:57 +0100145
146 test_mem_free (data);
147 test_mem_free (res);
148}
149
150void __test_perf_fn
Damjan Mariond5045e62022-04-06 21:16:37 +0200151perftest_byte (test_perf_t *tp)
Damjan Marion3323e202021-12-02 11:28:57 +0100152{
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
Damjan Mariond5045e62022-04-06 21:16:37 +0200157 test_perf_event_enable (tp);
Damjan Marion3323e202021-12-02 11:28:57 +0100158 res[0] = clib_ip_csum (data, np[0]);
Damjan Mariond5045e62022-04-06 21:16:37 +0200159 test_perf_event_disable (tp);
Damjan Marion3323e202021-12-02 11:28:57 +0100160
161 test_mem_free (data);
162 test_mem_free (res);
163}
164
Damjan Marionaa63bc62021-11-08 11:18:30 +0000165REGISTER_TEST (clib_ip_csum) = {
166 .name = "clib_ip_csum",
167 .fn = test_clib_ip_csum,
Damjan Marion3323e202021-12-02 11:28:57 +0100168 .perf_tests = PERF_TESTS (
Damjan Mariond5045e62022-04-06 21:16:37 +0200169 { .name = "fixed size (per IPv4 Header)",
Damjan Marion3323e202021-12-02 11:28:57 +0100170 .n_ops = 1024,
171 .fn = perftest_ip4_hdr },
Damjan Mariond5045e62022-04-06 21:16:37 +0200172 { .name = "fixed size (per 1460 byte block)",
Damjan Marion3323e202021-12-02 11:28:57 +0100173 .n_ops = 16,
174 .arg0 = 1460,
175 .fn = perftest_tcp_payload },
Damjan Mariond5045e62022-04-06 21:16:37 +0200176 { .name = "variable size (per byte)", .n_ops = 16384, .fn = perftest_byte }
Damjan Marion3323e202021-12-02 11:28:57 +0100177
178 ),
Damjan Marionaa63bc62021-11-08 11:18:30 +0000179};