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 : 252 : REGISTER_FAST_TEST(cksum_autotest, true, true, test_cksum);
|