Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2023 Marvell.
3 : : */
4 : :
5 : : #include <rte_byteorder.h>
6 : : #include <rte_common.h>
7 : : #include <rte_cycles.h>
8 : : #include <rte_ether.h>
9 : : #include <rte_hexdump.h>
10 : : #include <rte_ip.h>
11 : : #include <rte_ip_frag.h>
12 : : #include <rte_mbuf.h>
13 : : #include <rte_mbuf_pool_ops.h>
14 : : #include <rte_os_shim.h>
15 : : #include <rte_random.h>
16 : : #include <rte_udp.h>
17 : :
18 : : #include "test.h"
19 : :
20 : : #define MAX_FLOWS (1024 * 32)
21 : : #define MAX_BKTS MAX_FLOWS
22 : : #define MAX_ENTRIES_PER_BKT 16
23 : : #define MAX_FRAGMENTS RTE_LIBRTE_IP_FRAG_MAX_FRAG
24 : : #define MIN_FRAGMENTS 2
25 : : #define MAX_PKTS (MAX_FLOWS * MAX_FRAGMENTS)
26 : :
27 : : #define MAX_PKT_LEN 2048
28 : : #define MAX_TTL_MS (5 * MS_PER_S)
29 : :
30 : : /* use RFC863 Discard Protocol */
31 : : #define UDP_SRC_PORT 9
32 : : #define UDP_DST_PORT 9
33 : :
34 : : /* use RFC5735 / RFC2544 reserved network test addresses */
35 : : #define IP_SRC_ADDR(x) ((198U << 24) | (18 << 16) | (0 << 8) | (x))
36 : : #define IP_DST_ADDR(x) ((198U << 24) | (18 << 16) | (1 << 15) | (x))
37 : :
38 : : /* 2001:0200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180) */
39 : : static uint8_t ip6_addr[16] = {32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
40 : : #define IP6_VERSION 6
41 : :
42 : : #define IP_DEFTTL 64 /* from RFC 1340. */
43 : :
44 : : static struct rte_ip_frag_tbl *frag_tbl;
45 : : static struct rte_mempool *pkt_pool;
46 : : static struct rte_mbuf *mbufs[MAX_FLOWS][MAX_FRAGMENTS];
47 : : static uint8_t frag_per_flow[MAX_FLOWS];
48 : : static uint32_t flow_cnt;
49 : :
50 : : #define FILL_MODE_LINEAR 0
51 : : #define FILL_MODE_RANDOM 1
52 : : #define FILL_MODE_INTERLEAVED 2
53 : :
54 : : static int
55 : 0 : reassembly_test_setup(void)
56 : : {
57 : 0 : uint64_t max_ttl_cyc = (MAX_TTL_MS * rte_get_timer_hz()) / 1E3;
58 : :
59 : 0 : frag_tbl = rte_ip_frag_table_create(MAX_BKTS, MAX_ENTRIES_PER_BKT,
60 : : MAX_BKTS * MAX_ENTRIES_PER_BKT, max_ttl_cyc,
61 : 0 : rte_socket_id());
62 [ # # ]: 0 : if (frag_tbl == NULL)
63 : : return TEST_FAILED;
64 : :
65 : 0 : rte_mbuf_set_user_mempool_ops("ring_mp_mc");
66 : 0 : pkt_pool = rte_pktmbuf_pool_create(
67 : : "reassembly_perf_pool", MAX_FLOWS * MAX_FRAGMENTS, 0, 0,
68 : 0 : RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
69 [ # # ]: 0 : if (pkt_pool == NULL) {
70 : : printf("[%s] Failed to create pkt pool\n", __func__);
71 : 0 : rte_ip_frag_table_destroy(frag_tbl);
72 : 0 : return TEST_FAILED;
73 : : }
74 : :
75 : : return TEST_SUCCESS;
76 : : }
77 : :
78 : : static void
79 : 0 : reassembly_test_teardown(void)
80 : : {
81 [ # # ]: 0 : if (frag_tbl != NULL)
82 : 0 : rte_ip_frag_table_destroy(frag_tbl);
83 : :
84 : 0 : rte_mempool_free(pkt_pool);
85 : 0 : }
86 : :
87 : : static void
88 : 0 : randomize_array_positions(void **array, uint8_t sz)
89 : : {
90 : : void *tmp;
91 : : int i, j;
92 : :
93 [ # # ]: 0 : if (sz == 2) {
94 : 0 : tmp = array[0];
95 : 0 : array[0] = array[1];
96 : 0 : array[1] = tmp;
97 : : } else {
98 [ # # ]: 0 : for (i = sz - 1; i > 0; i--) {
99 : 0 : j = rte_rand_max(i + 1);
100 : 0 : tmp = array[i];
101 : 0 : array[i] = array[j];
102 : 0 : array[j] = tmp;
103 : : }
104 : : }
105 : 0 : }
106 : :
107 : : static void
108 : 0 : reassembly_print_banner(const char *proto_str)
109 : : {
110 : : printf("+=============================================================="
111 : : "============================================+\n");
112 : : printf("| %-32s| %-3s : %-58d|\n", proto_str, "Flow Count", MAX_FLOWS);
113 : : printf("+================+================+=============+=============+"
114 : : "========================+===================+\n");
115 : : printf("%-17s%-17s%-14s%-14s%-25s%-20s\n", "| Fragment Order",
116 : : "| Fragments/Flow", "| Outstanding", "| Cycles/Flow",
117 : : "| Cycles/Fragment insert", "| Cycles/Reassembly |");
118 : : printf("+================+================+=============+=============+"
119 : : "========================+===================+\n");
120 : 0 : }
121 : :
122 : : static void
123 : 0 : ipv4_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t flow_id,
124 : : uint8_t fill_mode)
125 : : {
126 : : struct rte_ether_hdr *eth_hdr;
127 : : struct rte_ipv4_hdr *ip_hdr;
128 : : struct rte_udp_hdr *udp_hdr;
129 : : uint16_t frag_len;
130 : : uint8_t i;
131 : :
132 : 0 : frag_len = MAX_PKT_LEN / nb_frags;
133 [ # # ]: 0 : if (frag_len % 8)
134 : 0 : frag_len = RTE_ALIGN_MUL_CEIL(frag_len, 8);
135 : :
136 [ # # ]: 0 : for (i = 0; i < nb_frags; i++) {
137 : 0 : struct rte_mbuf *frag = mbuf[i];
138 : : uint16_t frag_offset = 0;
139 : : uint32_t ip_cksum;
140 : : uint16_t pkt_len;
141 : : uint16_t *ptr16;
142 : :
143 : 0 : frag_offset = i * (frag_len / 8);
144 : :
145 [ # # ]: 0 : if (i == nb_frags - 1)
146 : 0 : frag_len = MAX_PKT_LEN - (frag_len * (nb_frags - 1));
147 : : else
148 : 0 : frag_offset |= RTE_IPV4_HDR_MF_FLAG;
149 : :
150 : : rte_pktmbuf_reset_headroom(frag);
151 : 0 : eth_hdr = rte_pktmbuf_mtod(frag, struct rte_ether_hdr *);
152 : 0 : ip_hdr = rte_pktmbuf_mtod_offset(frag, struct rte_ipv4_hdr *,
153 : : sizeof(struct rte_ether_hdr));
154 : 0 : udp_hdr = rte_pktmbuf_mtod_offset(
155 : : frag, struct rte_udp_hdr *,
156 : : sizeof(struct rte_ether_hdr) +
157 : : sizeof(struct rte_ipv4_hdr));
158 : :
159 : 0 : rte_ether_unformat_addr("02:00:00:00:00:01",
160 : : ð_hdr->dst_addr);
161 : 0 : rte_ether_unformat_addr("02:00:00:00:00:00",
162 : : ð_hdr->src_addr);
163 : 0 : eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
164 : :
165 : : pkt_len = frag_len;
166 : : /*
167 : : * Initialize UDP header.
168 : : */
169 [ # # ]: 0 : if (i == 0) {
170 : 0 : udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
171 : 0 : udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
172 [ # # ]: 0 : udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len);
173 : 0 : udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
174 : : }
175 : :
176 : : /*
177 : : * Initialize IP header.
178 : : */
179 : 0 : pkt_len = (uint16_t)(pkt_len + sizeof(struct rte_ipv4_hdr));
180 : 0 : ip_hdr->version_ihl = RTE_IPV4_VHL_DEF;
181 : 0 : ip_hdr->type_of_service = 0;
182 [ # # ]: 0 : ip_hdr->fragment_offset = rte_cpu_to_be_16(frag_offset);
183 : 0 : ip_hdr->time_to_live = IP_DEFTTL;
184 : 0 : ip_hdr->next_proto_id = IPPROTO_UDP;
185 : 0 : ip_hdr->packet_id =
186 [ # # ]: 0 : rte_cpu_to_be_16((flow_id + 1) % UINT16_MAX);
187 [ # # ]: 0 : ip_hdr->total_length = rte_cpu_to_be_16(pkt_len);
188 : : /* Using more than 32K flows will modify the 2nd octet of the IP. */
189 [ # # ]: 0 : ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR(flow_id));
190 [ # # ]: 0 : ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR(flow_id));
191 : :
192 : : /*
193 : : * Compute IP header checksum.
194 : : */
195 : : ptr16 = (unaligned_uint16_t *)ip_hdr;
196 : : ip_cksum = 0;
197 : : ip_cksum += ptr16[0];
198 : 0 : ip_cksum += ptr16[1];
199 : 0 : ip_cksum += ptr16[2];
200 : 0 : ip_cksum += ptr16[3];
201 : 0 : ip_cksum += ptr16[4];
202 : 0 : ip_cksum += ptr16[6];
203 : 0 : ip_cksum += ptr16[7];
204 : 0 : ip_cksum += ptr16[8];
205 : 0 : ip_cksum += ptr16[9];
206 : :
207 : : /*
208 : : * Reduce 32 bit checksum to 16 bits and complement it.
209 : : */
210 : 0 : ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
211 : 0 : (ip_cksum & 0x0000FFFF);
212 [ # # ]: 0 : if (ip_cksum > 65535)
213 : 0 : ip_cksum -= 65535;
214 : 0 : ip_cksum = (~ip_cksum) & 0x0000FFFF;
215 [ # # ]: 0 : if (ip_cksum == 0)
216 : : ip_cksum = 0xFFFF;
217 : 0 : ip_hdr->hdr_checksum = (uint16_t)ip_cksum;
218 : :
219 : 0 : frag->data_len = sizeof(struct rte_ether_hdr) + pkt_len;
220 : 0 : frag->pkt_len = frag->data_len;
221 : 0 : frag->l2_len = sizeof(struct rte_ether_hdr);
222 : 0 : frag->l3_len = sizeof(struct rte_ipv4_hdr);
223 : : }
224 : :
225 [ # # ]: 0 : if (fill_mode == FILL_MODE_RANDOM)
226 : 0 : randomize_array_positions((void **)mbuf, nb_frags);
227 : 0 : }
228 : :
229 : : static uint8_t
230 : : get_rand_frags(uint8_t max_frag)
231 : : {
232 : 0 : uint8_t frags = rte_rand_max(max_frag + 1);
233 : :
234 : 0 : return frags <= 1 ? MIN_FRAGMENTS : frags;
235 : : }
236 : :
237 : : static int
238 : 0 : ipv4_rand_frag_pkt_setup(uint8_t fill_mode, uint8_t max_frag)
239 : : {
240 : : uint8_t nb_frag;
241 : : int i;
242 : :
243 [ # # ]: 0 : for (i = 0; i < MAX_FLOWS; i++) {
244 : 0 : nb_frag = get_rand_frags(max_frag);
245 [ # # # # ]: 0 : if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
246 : : 0)
247 : : return TEST_FAILED;
248 : 0 : ipv4_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
249 : 0 : frag_per_flow[i] = nb_frag;
250 : : }
251 : 0 : flow_cnt = i;
252 : :
253 : 0 : return TEST_SUCCESS;
254 : : }
255 : :
256 : : static int
257 : 0 : ipv4_frag_pkt_setup(uint8_t fill_mode, uint8_t nb_frag)
258 : : {
259 : : int i;
260 : :
261 [ # # ]: 0 : for (i = 0; i < MAX_FLOWS; i++) {
262 [ # # # # ]: 0 : if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
263 : : 0)
264 : : return TEST_FAILED;
265 : 0 : ipv4_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
266 : 0 : frag_per_flow[i] = nb_frag;
267 : : }
268 : 0 : flow_cnt = i;
269 : :
270 : 0 : return TEST_SUCCESS;
271 : : }
272 : :
273 : : static void
274 : 0 : ipv6_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t flow_id,
275 : : uint8_t fill_mode)
276 : : {
277 : : struct ipv6_extension_fragment *frag_hdr;
278 : : struct rte_ether_hdr *eth_hdr;
279 : : struct rte_ipv6_hdr *ip_hdr;
280 : : struct rte_udp_hdr *udp_hdr;
281 : : uint16_t frag_len;
282 : : uint8_t i;
283 : :
284 : 0 : frag_len = MAX_PKT_LEN / nb_frags;
285 [ # # ]: 0 : if (frag_len % 8)
286 : 0 : frag_len = RTE_ALIGN_MUL_CEIL(frag_len, 8);
287 : :
288 [ # # ]: 0 : for (i = 0; i < nb_frags; i++) {
289 : 0 : struct rte_mbuf *frag = mbuf[i];
290 : : uint16_t frag_offset = 0;
291 : : uint16_t pkt_len;
292 : :
293 : 0 : frag_offset = i * (frag_len / 8);
294 : 0 : frag_offset <<= 3;
295 [ # # ]: 0 : if (i == nb_frags - 1) {
296 : 0 : frag_len = MAX_PKT_LEN - (frag_len * (nb_frags - 1));
297 : : frag_offset = RTE_IPV6_SET_FRAG_DATA(frag_offset, 0);
298 : : } else {
299 : 0 : frag_offset = RTE_IPV6_SET_FRAG_DATA(frag_offset, 1);
300 : : }
301 : :
302 : : rte_pktmbuf_reset_headroom(frag);
303 : 0 : eth_hdr = rte_pktmbuf_mtod(frag, struct rte_ether_hdr *);
304 : 0 : ip_hdr = rte_pktmbuf_mtod_offset(frag, struct rte_ipv6_hdr *,
305 : : sizeof(struct rte_ether_hdr));
306 : 0 : udp_hdr = rte_pktmbuf_mtod_offset(
307 : : frag, struct rte_udp_hdr *,
308 : : sizeof(struct rte_ether_hdr) +
309 : : sizeof(struct rte_ipv6_hdr) +
310 : : RTE_IPV6_FRAG_HDR_SIZE);
311 : 0 : frag_hdr = rte_pktmbuf_mtod_offset(
312 : : frag, struct ipv6_extension_fragment *,
313 : : sizeof(struct rte_ether_hdr) +
314 : : sizeof(struct rte_ipv6_hdr));
315 : :
316 : 0 : rte_ether_unformat_addr("02:00:00:00:00:01",
317 : : ð_hdr->dst_addr);
318 : 0 : rte_ether_unformat_addr("02:00:00:00:00:00",
319 : : ð_hdr->src_addr);
320 : 0 : eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
321 : :
322 : : pkt_len = frag_len;
323 : : /*
324 : : * Initialize UDP header.
325 : : */
326 [ # # ]: 0 : if (i == 0) {
327 : 0 : udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
328 : 0 : udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
329 [ # # ]: 0 : udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len);
330 : 0 : udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
331 : : }
332 : :
333 : : /*
334 : : * Initialize IP header.
335 : : */
336 : 0 : pkt_len = (uint16_t)(pkt_len + sizeof(struct rte_ipv6_hdr) +
337 : : RTE_IPV6_FRAG_HDR_SIZE);
338 : 0 : ip_hdr->vtc_flow = rte_cpu_to_be_32(IP6_VERSION << 28);
339 : 0 : ip_hdr->payload_len =
340 [ # # ]: 0 : rte_cpu_to_be_16(pkt_len - sizeof(struct rte_ipv6_hdr));
341 : 0 : ip_hdr->proto = IPPROTO_FRAGMENT;
342 : 0 : ip_hdr->hop_limits = IP_DEFTTL;
343 [ # # ]: 0 : memcpy(ip_hdr->src_addr, ip6_addr, sizeof(ip_hdr->src_addr));
344 : 0 : memcpy(ip_hdr->dst_addr, ip6_addr, sizeof(ip_hdr->dst_addr));
345 : 0 : ip_hdr->src_addr[7] = (flow_id >> 16) & 0xf;
346 : 0 : ip_hdr->src_addr[7] |= 0x10;
347 : 0 : ip_hdr->src_addr[8] = (flow_id >> 8) & 0xff;
348 : 0 : ip_hdr->src_addr[9] = flow_id & 0xff;
349 : :
350 : : ip_hdr->dst_addr[7] = (flow_id >> 16) & 0xf;
351 : 0 : ip_hdr->dst_addr[7] |= 0x20;
352 : 0 : ip_hdr->dst_addr[8] = (flow_id >> 8) & 0xff;
353 : 0 : ip_hdr->dst_addr[9] = flow_id & 0xff;
354 : :
355 : 0 : frag_hdr->next_header = IPPROTO_UDP;
356 : 0 : frag_hdr->reserved = 0;
357 [ # # ]: 0 : frag_hdr->frag_data = rte_cpu_to_be_16(frag_offset);
358 [ # # ]: 0 : frag_hdr->id = rte_cpu_to_be_32(flow_id + 1);
359 : :
360 : 0 : frag->data_len = sizeof(struct rte_ether_hdr) + pkt_len;
361 : 0 : frag->pkt_len = frag->data_len;
362 : 0 : frag->l2_len = sizeof(struct rte_ether_hdr);
363 : 0 : frag->l3_len =
364 : : sizeof(struct rte_ipv6_hdr) + RTE_IPV6_FRAG_HDR_SIZE;
365 : : }
366 : :
367 [ # # ]: 0 : if (fill_mode == FILL_MODE_RANDOM)
368 : 0 : randomize_array_positions((void **)mbuf, nb_frags);
369 : 0 : }
370 : :
371 : : static int
372 : 0 : ipv6_rand_frag_pkt_setup(uint8_t fill_mode, uint8_t max_frag)
373 : : {
374 : : uint8_t nb_frag;
375 : : int i;
376 : :
377 [ # # ]: 0 : for (i = 0; i < MAX_FLOWS; i++) {
378 : 0 : nb_frag = get_rand_frags(max_frag);
379 [ # # # # ]: 0 : if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
380 : : 0)
381 : : return TEST_FAILED;
382 : 0 : ipv6_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
383 : 0 : frag_per_flow[i] = nb_frag;
384 : : }
385 : 0 : flow_cnt = i;
386 : :
387 : 0 : return TEST_SUCCESS;
388 : : }
389 : :
390 : : static int
391 : 0 : ipv6_frag_pkt_setup(uint8_t fill_mode, uint8_t nb_frag)
392 : : {
393 : : int i;
394 : :
395 [ # # ]: 0 : for (i = 0; i < MAX_FLOWS; i++) {
396 [ # # # # ]: 0 : if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
397 : : 0)
398 : : return TEST_FAILED;
399 : 0 : ipv6_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
400 : 0 : frag_per_flow[i] = nb_frag;
401 : : }
402 : 0 : flow_cnt = i;
403 : :
404 : 0 : return TEST_SUCCESS;
405 : : }
406 : :
407 : : static void
408 : : frag_pkt_teardown(void)
409 : : {
410 : : uint32_t i;
411 : :
412 [ # # # # ]: 0 : for (i = 0; i < flow_cnt; i++)
413 : 0 : rte_pktmbuf_free(mbufs[i][0]);
414 : : }
415 : :
416 : : static void
417 : 0 : reassembly_print_stats(int8_t nb_frags, uint8_t fill_order,
418 : : uint32_t outstanding, uint64_t cyc_per_flow,
419 : : uint64_t cyc_per_frag_insert,
420 : : uint64_t cyc_per_reassembly)
421 : : {
422 : : char frag_str[8], order_str[12];
423 : :
424 [ # # ]: 0 : if (nb_frags > 0)
425 : 0 : snprintf(frag_str, sizeof(frag_str), "%d", nb_frags);
426 : : else
427 : : snprintf(frag_str, sizeof(frag_str), "RANDOM");
428 : :
429 [ # # # # ]: 0 : switch (fill_order) {
430 : : case FILL_MODE_LINEAR:
431 : : snprintf(order_str, sizeof(order_str), "LINEAR");
432 : : break;
433 : : case FILL_MODE_RANDOM:
434 : : snprintf(order_str, sizeof(order_str), "RANDOM");
435 : : break;
436 : : case FILL_MODE_INTERLEAVED:
437 : : snprintf(order_str, sizeof(order_str), "INTERLEAVED");
438 : : break;
439 : : default:
440 : : break;
441 : : }
442 : :
443 : : printf("| %-14s | %-14s | %-11d | %-11" PRIu64 " | %-22" PRIu64
444 : : " | %-17" PRIu64 " |\n",
445 : : order_str, frag_str, outstanding, cyc_per_flow,
446 : : cyc_per_frag_insert, cyc_per_reassembly);
447 : : printf("+================+================+=============+=============+"
448 : : "========================+===================+\n");
449 : 0 : }
450 : :
451 : : static void
452 : : join_array(struct rte_mbuf **dest_arr, struct rte_mbuf **src_arr,
453 : : uint8_t offset, uint8_t sz)
454 : : {
455 : : int i, j;
456 : :
457 [ # # # # ]: 0 : for (i = offset, j = 0; j < sz; i++, j++)
458 : 0 : dest_arr[i] = src_arr[j];
459 : : }
460 : :
461 : : static int
462 : 0 : ipv4_reassembly_perf(int8_t nb_frags, uint8_t fill_order)
463 : : {
464 : : struct rte_ip_frag_death_row death_row;
465 : : uint64_t total_reassembled_cyc = 0;
466 : : uint64_t total_empty_cyc = 0;
467 : : uint64_t tstamp, flow_tstamp;
468 : : uint64_t frag_processed = 0;
469 : : uint64_t total_cyc = 0;
470 : : uint32_t i, j;
471 : :
472 [ # # ]: 0 : for (i = 0; i < flow_cnt; i++) {
473 : : struct rte_mbuf *buf_out = NULL;
474 : : uint8_t reassembled = 0;
475 : :
476 : : flow_tstamp = rte_rdtsc_precise();
477 [ # # ]: 0 : for (j = 0; j < frag_per_flow[i]; j++) {
478 : 0 : struct rte_mbuf *buf = mbufs[i][j];
479 : 0 : struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
480 : : buf, struct rte_ipv4_hdr *, buf->l2_len);
481 : :
482 : : tstamp = rte_rdtsc_precise();
483 : 0 : buf_out = rte_ipv4_frag_reassemble_packet(
484 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
485 : :
486 [ # # ]: 0 : if (buf_out == NULL) {
487 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
488 : 0 : frag_processed++;
489 : 0 : continue;
490 : : } else {
491 : : /*Packet out*/
492 : 0 : total_reassembled_cyc +=
493 : 0 : rte_rdtsc_precise() - tstamp;
494 : : reassembled = 1;
495 : : }
496 : : }
497 : 0 : total_cyc += rte_rdtsc_precise() - flow_tstamp;
498 [ # # # # ]: 0 : if (!reassembled || buf_out->nb_segs != frag_per_flow[i])
499 : : return TEST_FAILED;
500 : 0 : memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
501 : 0 : mbufs[i][0] = buf_out;
502 : : }
503 : :
504 : 0 : reassembly_print_stats(nb_frags, fill_order, 0, total_cyc / flow_cnt,
505 : : total_empty_cyc / frag_processed,
506 : : total_reassembled_cyc / flow_cnt);
507 : :
508 : 0 : return TEST_SUCCESS;
509 : : }
510 : :
511 : : static int
512 : 0 : ipv4_outstanding_reassembly_perf(int8_t nb_frags, uint8_t fill_order,
513 : : uint32_t outstanding)
514 : : {
515 : : struct rte_ip_frag_death_row death_row;
516 : : uint64_t total_reassembled_cyc = 0;
517 : : uint64_t total_empty_cyc = 0;
518 : : uint64_t tstamp, flow_tstamp;
519 : : uint64_t frag_processed = 0;
520 : : uint64_t total_cyc = 0;
521 : : uint32_t i, j, k;
522 : :
523 : : k = outstanding;
524 : : /* Insert outstanding fragments */
525 [ # # # # ]: 0 : for (i = 0; k && (i < flow_cnt); i++) {
526 : : struct rte_mbuf *buf_out = NULL;
527 : :
528 : : flow_tstamp = rte_rdtsc_precise();
529 [ # # ]: 0 : for (j = frag_per_flow[i] - 1; j > 0; j--) {
530 : 0 : struct rte_mbuf *buf = mbufs[i][j];
531 : 0 : struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
532 : : buf, struct rte_ipv4_hdr *, buf->l2_len);
533 : :
534 : : tstamp = rte_rdtsc_precise();
535 : 0 : buf_out = rte_ipv4_frag_reassemble_packet(
536 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
537 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
538 : 0 : frag_processed++;
539 [ # # ]: 0 : if (buf_out != NULL)
540 : : return TEST_FAILED;
541 : :
542 : 0 : k--;
543 : : }
544 : 0 : frag_per_flow[i] = 1;
545 : : }
546 : :
547 [ # # ]: 0 : for (i = 0; i < flow_cnt; i++) {
548 : : struct rte_mbuf *buf_out = NULL;
549 : : uint8_t reassembled = 0;
550 : :
551 : : flow_tstamp = rte_rdtsc_precise();
552 [ # # ]: 0 : for (j = 0; j < frag_per_flow[i]; j++) {
553 : 0 : struct rte_mbuf *buf = mbufs[i][j];
554 : 0 : struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
555 : : buf, struct rte_ipv4_hdr *, buf->l2_len);
556 : :
557 : : tstamp = rte_rdtsc_precise();
558 : 0 : buf_out = rte_ipv4_frag_reassemble_packet(
559 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
560 : :
561 [ # # ]: 0 : if (buf_out == NULL) {
562 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
563 : 0 : frag_processed++;
564 : 0 : continue;
565 : : } else {
566 : : /*Packet out*/
567 : 0 : total_reassembled_cyc +=
568 : 0 : rte_rdtsc_precise() - tstamp;
569 : : reassembled = 1;
570 : : }
571 : : }
572 : 0 : total_cyc += rte_rdtsc_precise() - flow_tstamp;
573 [ # # ]: 0 : if (!reassembled)
574 : : return TEST_FAILED;
575 : 0 : memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
576 : 0 : mbufs[i][0] = buf_out;
577 : : }
578 : :
579 : 0 : reassembly_print_stats(nb_frags, fill_order, outstanding,
580 : : total_cyc / flow_cnt,
581 : : total_empty_cyc / frag_processed,
582 : : total_reassembled_cyc / flow_cnt);
583 : :
584 : 0 : return TEST_SUCCESS;
585 : : }
586 : :
587 : : static int
588 : 0 : ipv4_reassembly_interleaved_flows_perf(uint8_t nb_frags)
589 : : {
590 : : struct rte_ip_frag_death_row death_row;
591 : : uint64_t total_reassembled_cyc = 0;
592 : : uint64_t total_empty_cyc = 0;
593 : : uint64_t tstamp, flow_tstamp;
594 : : uint64_t frag_processed = 0;
595 : : uint64_t total_cyc = 0;
596 : : uint32_t i, j;
597 : :
598 [ # # ]: 0 : for (i = 0; i < flow_cnt; i += 4) {
599 : 0 : struct rte_mbuf *buf_out[4] = {NULL};
600 : : uint8_t reassembled = 0;
601 : : uint8_t nb_frags = 0;
602 : : uint8_t prev = 0;
603 : :
604 [ # # ]: 0 : for (j = 0; j < 4; j++)
605 : 0 : nb_frags += frag_per_flow[i + j];
606 : :
607 : 0 : struct rte_mbuf *buf_arr[nb_frags];
608 [ # # ]: 0 : for (j = 0; j < 4; j++) {
609 : 0 : join_array(buf_arr, mbufs[i + j], prev,
610 : 0 : frag_per_flow[i + j]);
611 : 0 : prev += frag_per_flow[i + j];
612 : : }
613 : 0 : randomize_array_positions((void **)buf_arr, nb_frags);
614 : : flow_tstamp = rte_rdtsc_precise();
615 [ # # ]: 0 : for (j = 0; j < nb_frags; j++) {
616 : 0 : struct rte_mbuf *buf = buf_arr[j];
617 : 0 : struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
618 : : buf, struct rte_ipv4_hdr *, buf->l2_len);
619 : :
620 : : tstamp = rte_rdtsc_precise();
621 : 0 : buf_out[reassembled] = rte_ipv4_frag_reassemble_packet(
622 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
623 : :
624 [ # # ]: 0 : if (buf_out[reassembled] == NULL) {
625 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
626 : 0 : frag_processed++;
627 : 0 : continue;
628 : : } else {
629 : : /*Packet out*/
630 : 0 : total_reassembled_cyc +=
631 : 0 : rte_rdtsc_precise() - tstamp;
632 : 0 : reassembled++;
633 : : }
634 : : }
635 : 0 : total_cyc += rte_rdtsc_precise() - flow_tstamp;
636 [ # # ]: 0 : if (reassembled != 4)
637 : 0 : return TEST_FAILED;
638 [ # # ]: 0 : for (j = 0; j < 4; j++) {
639 : 0 : memset(mbufs[i + j], 0,
640 : : sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
641 : 0 : mbufs[i + j][0] = buf_out[j];
642 : : }
643 : : }
644 : :
645 : 0 : reassembly_print_stats(nb_frags, FILL_MODE_INTERLEAVED, 0,
646 : : total_cyc / flow_cnt,
647 : : total_empty_cyc / frag_processed,
648 : : total_reassembled_cyc / flow_cnt);
649 : :
650 : 0 : return TEST_SUCCESS;
651 : : }
652 : :
653 : : static int
654 : 0 : ipv6_reassembly_perf(int8_t nb_frags, uint8_t fill_order)
655 : : {
656 : : struct rte_ip_frag_death_row death_row;
657 : : uint64_t total_reassembled_cyc = 0;
658 : : uint64_t total_empty_cyc = 0;
659 : : uint64_t tstamp, flow_tstamp;
660 : : uint64_t frag_processed = 0;
661 : : uint64_t total_cyc = 0;
662 : : uint32_t i, j;
663 : :
664 [ # # ]: 0 : for (i = 0; i < flow_cnt; i++) {
665 : : struct rte_mbuf *buf_out = NULL;
666 : : uint8_t reassembled = 0;
667 : :
668 : : flow_tstamp = rte_rdtsc_precise();
669 [ # # ]: 0 : for (j = 0; j < frag_per_flow[i]; j++) {
670 : 0 : struct rte_mbuf *buf = mbufs[i][j];
671 : 0 : struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
672 : : buf, struct rte_ipv6_hdr *, buf->l2_len);
673 : 0 : struct ipv6_extension_fragment *frag_hdr =
674 : 0 : rte_pktmbuf_mtod_offset(
675 : : buf, struct ipv6_extension_fragment *,
676 : : buf->l2_len +
677 : : sizeof(struct rte_ipv6_hdr));
678 : :
679 : : tstamp = rte_rdtsc_precise();
680 : 0 : buf_out = rte_ipv6_frag_reassemble_packet(
681 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
682 : : frag_hdr);
683 : :
684 [ # # ]: 0 : if (buf_out == NULL) {
685 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
686 : 0 : frag_processed++;
687 : 0 : continue;
688 : : } else {
689 : : /*Packet out*/
690 : 0 : total_reassembled_cyc +=
691 : 0 : rte_rdtsc_precise() - tstamp;
692 : : reassembled = 1;
693 : : }
694 : : }
695 : 0 : total_cyc += rte_rdtsc_precise() - flow_tstamp;
696 [ # # # # ]: 0 : if (!reassembled || buf_out->nb_segs != frag_per_flow[i])
697 : : return TEST_FAILED;
698 : 0 : memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
699 : 0 : mbufs[i][0] = buf_out;
700 : : }
701 : :
702 : 0 : reassembly_print_stats(nb_frags, fill_order, 0, total_cyc / flow_cnt,
703 : : total_empty_cyc / frag_processed,
704 : : total_reassembled_cyc / flow_cnt);
705 : :
706 : 0 : return TEST_SUCCESS;
707 : : }
708 : :
709 : : static int
710 : 0 : ipv6_outstanding_reassembly_perf(int8_t nb_frags, uint8_t fill_order,
711 : : uint32_t outstanding)
712 : : {
713 : : struct rte_ip_frag_death_row death_row;
714 : : uint64_t total_reassembled_cyc = 0;
715 : : uint64_t total_empty_cyc = 0;
716 : : uint64_t tstamp, flow_tstamp;
717 : : uint64_t frag_processed = 0;
718 : : uint64_t total_cyc = 0;
719 : : uint32_t i, j, k;
720 : :
721 : : k = outstanding;
722 : : /* Insert outstanding fragments */
723 [ # # # # ]: 0 : for (i = 0; k && (i < flow_cnt); i++) {
724 : : struct rte_mbuf *buf_out = NULL;
725 : :
726 : : flow_tstamp = rte_rdtsc_precise();
727 [ # # ]: 0 : for (j = frag_per_flow[i] - 1; j > 0; j--) {
728 : 0 : struct rte_mbuf *buf = mbufs[i][j];
729 : 0 : struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
730 : : buf, struct rte_ipv6_hdr *, buf->l2_len);
731 : 0 : struct ipv6_extension_fragment *frag_hdr =
732 : 0 : rte_pktmbuf_mtod_offset(
733 : : buf, struct ipv6_extension_fragment *,
734 : : buf->l2_len +
735 : : sizeof(struct rte_ipv6_hdr));
736 : :
737 : : tstamp = rte_rdtsc_precise();
738 : 0 : buf_out = rte_ipv6_frag_reassemble_packet(
739 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
740 : : frag_hdr);
741 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
742 : 0 : frag_processed++;
743 : :
744 [ # # ]: 0 : if (buf_out != NULL)
745 : : return TEST_FAILED;
746 : :
747 : 0 : k--;
748 : : }
749 : 0 : frag_per_flow[i] = 1;
750 : : }
751 : :
752 [ # # ]: 0 : for (i = 0; i < flow_cnt; i++) {
753 : : struct rte_mbuf *buf_out = NULL;
754 : : uint8_t reassembled = 0;
755 : :
756 : : flow_tstamp = rte_rdtsc_precise();
757 [ # # ]: 0 : for (j = 0; j < frag_per_flow[i]; j++) {
758 : 0 : struct rte_mbuf *buf = mbufs[i][j];
759 : 0 : struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
760 : : buf, struct rte_ipv6_hdr *, buf->l2_len);
761 : 0 : struct ipv6_extension_fragment *frag_hdr =
762 : 0 : rte_pktmbuf_mtod_offset(
763 : : buf, struct ipv6_extension_fragment *,
764 : : buf->l2_len +
765 : : sizeof(struct rte_ipv6_hdr));
766 : :
767 : : tstamp = rte_rdtsc_precise();
768 : 0 : buf_out = rte_ipv6_frag_reassemble_packet(
769 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
770 : : frag_hdr);
771 : :
772 [ # # ]: 0 : if (buf_out == NULL) {
773 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
774 : 0 : frag_processed++;
775 : 0 : continue;
776 : : } else {
777 : : /*Packet out*/
778 : 0 : total_reassembled_cyc +=
779 : 0 : rte_rdtsc_precise() - tstamp;
780 : : reassembled = 1;
781 : : }
782 : : }
783 : 0 : total_cyc += rte_rdtsc_precise() - flow_tstamp;
784 [ # # ]: 0 : if (!reassembled)
785 : : return TEST_FAILED;
786 : 0 : memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
787 : 0 : mbufs[i][0] = buf_out;
788 : : }
789 : :
790 : 0 : reassembly_print_stats(nb_frags, fill_order, outstanding,
791 : : total_cyc / flow_cnt,
792 : : total_empty_cyc / frag_processed,
793 : : total_reassembled_cyc / flow_cnt);
794 : :
795 : 0 : return TEST_SUCCESS;
796 : : }
797 : :
798 : : static int
799 : 0 : ipv6_reassembly_interleaved_flows_perf(int8_t nb_frags)
800 : : {
801 : : struct rte_ip_frag_death_row death_row;
802 : : uint64_t total_reassembled_cyc = 0;
803 : : uint64_t total_empty_cyc = 0;
804 : : uint64_t tstamp, flow_tstamp;
805 : : uint64_t frag_processed = 0;
806 : : uint64_t total_cyc = 0;
807 : : uint32_t i, j;
808 : :
809 [ # # ]: 0 : for (i = 0; i < flow_cnt; i += 4) {
810 : 0 : struct rte_mbuf *buf_out[4] = {NULL};
811 : : uint8_t reassembled = 0;
812 : : uint8_t nb_frags = 0;
813 : : uint8_t prev = 0;
814 : :
815 [ # # ]: 0 : for (j = 0; j < 4; j++)
816 : 0 : nb_frags += frag_per_flow[i + j];
817 : :
818 : 0 : struct rte_mbuf *buf_arr[nb_frags];
819 [ # # ]: 0 : for (j = 0; j < 4; j++) {
820 : 0 : join_array(buf_arr, mbufs[i + j], prev,
821 : 0 : frag_per_flow[i + j]);
822 : 0 : prev += frag_per_flow[i + j];
823 : : }
824 : 0 : randomize_array_positions((void **)buf_arr, nb_frags);
825 : : flow_tstamp = rte_rdtsc_precise();
826 [ # # ]: 0 : for (j = 0; j < nb_frags; j++) {
827 : 0 : struct rte_mbuf *buf = buf_arr[j];
828 : 0 : struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
829 : : buf, struct rte_ipv6_hdr *, buf->l2_len);
830 : 0 : struct ipv6_extension_fragment *frag_hdr =
831 : 0 : rte_pktmbuf_mtod_offset(
832 : : buf, struct ipv6_extension_fragment *,
833 : : buf->l2_len +
834 : : sizeof(struct rte_ipv6_hdr));
835 : :
836 : : tstamp = rte_rdtsc_precise();
837 : 0 : buf_out[reassembled] = rte_ipv6_frag_reassemble_packet(
838 : : frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
839 : : frag_hdr);
840 : :
841 [ # # ]: 0 : if (buf_out[reassembled] == NULL) {
842 : 0 : total_empty_cyc += rte_rdtsc_precise() - tstamp;
843 : 0 : frag_processed++;
844 : 0 : continue;
845 : : } else {
846 : : /*Packet out*/
847 : 0 : total_reassembled_cyc +=
848 : 0 : rte_rdtsc_precise() - tstamp;
849 : 0 : reassembled++;
850 : : }
851 : : }
852 : 0 : total_cyc += rte_rdtsc_precise() - flow_tstamp;
853 [ # # ]: 0 : if (reassembled != 4)
854 : 0 : return TEST_FAILED;
855 [ # # ]: 0 : for (j = 0; j < 4; j++) {
856 : 0 : memset(mbufs[i + j], 0,
857 : : sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
858 : 0 : mbufs[i + j][0] = buf_out[j];
859 : : }
860 : : }
861 : :
862 : 0 : reassembly_print_stats(nb_frags, FILL_MODE_INTERLEAVED, 0,
863 : : total_cyc / flow_cnt,
864 : : total_empty_cyc / frag_processed,
865 : : total_reassembled_cyc / flow_cnt);
866 : :
867 : 0 : return TEST_SUCCESS;
868 : : }
869 : :
870 : : static int
871 : 0 : ipv4_reassembly_test(int8_t nb_frags, uint8_t fill_order, uint32_t outstanding)
872 : : {
873 : : int rc;
874 : :
875 [ # # ]: 0 : if (nb_frags > 0)
876 : 0 : rc = ipv4_frag_pkt_setup(fill_order, nb_frags);
877 : : else
878 : 0 : rc = ipv4_rand_frag_pkt_setup(fill_order, MAX_FRAGMENTS);
879 : :
880 [ # # ]: 0 : if (rc)
881 : : return rc;
882 : :
883 [ # # ]: 0 : if (outstanding)
884 : 0 : rc = ipv4_outstanding_reassembly_perf(nb_frags, fill_order,
885 : : outstanding);
886 [ # # ]: 0 : else if (fill_order == FILL_MODE_INTERLEAVED)
887 : 0 : rc = ipv4_reassembly_interleaved_flows_perf(nb_frags);
888 : : else
889 : 0 : rc = ipv4_reassembly_perf(nb_frags, fill_order);
890 : :
891 : : frag_pkt_teardown();
892 : :
893 : : return rc;
894 : : }
895 : :
896 : : static int
897 : 0 : ipv6_reassembly_test(int8_t nb_frags, uint8_t fill_order, uint32_t outstanding)
898 : : {
899 : : int rc;
900 : :
901 [ # # ]: 0 : if (nb_frags > 0)
902 : 0 : rc = ipv6_frag_pkt_setup(fill_order, nb_frags);
903 : : else
904 : 0 : rc = ipv6_rand_frag_pkt_setup(fill_order, MAX_FRAGMENTS);
905 : :
906 [ # # ]: 0 : if (rc)
907 : : return rc;
908 : :
909 [ # # ]: 0 : if (outstanding)
910 : 0 : rc = ipv6_outstanding_reassembly_perf(nb_frags, fill_order,
911 : : outstanding);
912 [ # # ]: 0 : else if (fill_order == FILL_MODE_INTERLEAVED)
913 : 0 : rc = ipv6_reassembly_interleaved_flows_perf(nb_frags);
914 : : else
915 : 0 : rc = ipv6_reassembly_perf(nb_frags, fill_order);
916 : :
917 : : frag_pkt_teardown();
918 : :
919 : : return rc;
920 : : }
921 : :
922 : : static int
923 : 0 : test_reassembly_perf(void)
924 : : {
925 : 0 : int8_t nb_fragments[] = {2, 3, MAX_FRAGMENTS, -1 /* Random */};
926 : 0 : uint8_t order_type[] = {FILL_MODE_LINEAR, FILL_MODE_RANDOM};
927 : 0 : uint32_t outstanding[] = {100, 500, 1000, 2000, 3000};
928 : : uint32_t i, j;
929 : : int rc;
930 : :
931 : 0 : rc = reassembly_test_setup();
932 [ # # ]: 0 : if (rc)
933 : : return rc;
934 : :
935 : 0 : reassembly_print_banner("IPV4");
936 : : /* Test variable fragment count and ordering. */
937 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nb_fragments); i++) {
938 [ # # ]: 0 : for (j = 0; j < RTE_DIM(order_type); j++) {
939 : 0 : rc = ipv4_reassembly_test(nb_fragments[i],
940 : 0 : order_type[j], 0);
941 [ # # ]: 0 : if (rc)
942 : 0 : return rc;
943 : : }
944 : : }
945 : :
946 : : /* Test outstanding fragments in the table. */
947 [ # # ]: 0 : for (i = 0; i < RTE_DIM(outstanding); i++) {
948 : 0 : rc = ipv4_reassembly_test(2, 0, outstanding[i]);
949 [ # # ]: 0 : if (rc)
950 : 0 : return rc;
951 : : }
952 [ # # ]: 0 : for (i = 0; i < RTE_DIM(outstanding); i++) {
953 : 0 : rc = ipv4_reassembly_test(MAX_FRAGMENTS, 0, outstanding[i]);
954 [ # # ]: 0 : if (rc)
955 : 0 : return rc;
956 : : }
957 : :
958 : : /* Test interleaved flow reassembly perf */
959 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nb_fragments); i++) {
960 : 0 : rc = ipv4_reassembly_test(nb_fragments[i],
961 : : FILL_MODE_INTERLEAVED, 0);
962 [ # # ]: 0 : if (rc)
963 : 0 : return rc;
964 : : }
965 : : printf("\n");
966 : 0 : reassembly_print_banner("IPV6");
967 : : /* Test variable fragment count and ordering. */
968 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nb_fragments); i++) {
969 [ # # ]: 0 : for (j = 0; j < RTE_DIM(order_type); j++) {
970 : 0 : rc = ipv6_reassembly_test(nb_fragments[i],
971 : 0 : order_type[j], 0);
972 [ # # ]: 0 : if (rc)
973 : 0 : return rc;
974 : : }
975 : : }
976 : :
977 : : /* Test outstanding fragments in the table. */
978 [ # # ]: 0 : for (i = 0; i < RTE_DIM(outstanding); i++) {
979 : 0 : rc = ipv6_reassembly_test(2, 0, outstanding[i]);
980 [ # # ]: 0 : if (rc)
981 : 0 : return rc;
982 : : }
983 : :
984 [ # # ]: 0 : for (i = 0; i < RTE_DIM(outstanding); i++) {
985 : 0 : rc = ipv6_reassembly_test(MAX_FRAGMENTS, 0, outstanding[i]);
986 [ # # ]: 0 : if (rc)
987 : 0 : return rc;
988 : : }
989 : :
990 : : /* Test interleaved flow reassembly perf */
991 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nb_fragments); i++) {
992 : 0 : rc = ipv6_reassembly_test(nb_fragments[i],
993 : : FILL_MODE_INTERLEAVED, 0);
994 [ # # ]: 0 : if (rc)
995 : 0 : return rc;
996 : : }
997 : 0 : reassembly_test_teardown();
998 : :
999 : 0 : return TEST_SUCCESS;
1000 : : }
1001 : :
1002 : 238 : REGISTER_PERF_TEST(reassembly_perf_autotest, test_reassembly_perf);
|