API Reference Manual 1.51.0
Loading...
Searching...
No Matches
test/performance/odp_ipsec.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2018 Linaro Limited
3 * Copyright (c) 2022 Marvell
4 * Copyright (c) 2022 Nokia
5 */
6
15#ifndef _GNU_SOURCE
16#define _GNU_SOURCE
17#endif /* _GNU_SOURCE */
18
19#include <stdlib.h>
20#include <string.h>
21#include <getopt.h>
22#include <unistd.h>
23#include <stdio.h>
24#include <sys/time.h>
25#include <sys/resource.h>
26
27#include <odp_api.h>
28#include <odp/helper/odph_api.h>
29#include <inttypes.h>
30
34#define POOL_NUM_PKT 4096
35
36#define MAX_DEQUEUE_BURST 16
37
38static uint8_t test_salt[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
39
40static uint8_t test_key16[16] = { 0x01, 0x02, 0x03, 0x04, 0x05,
41 0x06, 0x07, 0x08, 0x09, 0x0a,
42 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
43 0x10,
44};
45
46static uint8_t test_key20[20] = { 0x01, 0x02, 0x03, 0x04, 0x05,
47 0x06, 0x07, 0x08, 0x09, 0x0a,
48 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
49 0x10, 0x11, 0x12, 0x13, 0x14,
50};
51
52static uint8_t test_key24[24] = { 0x01, 0x02, 0x03, 0x04, 0x05,
53 0x06, 0x07, 0x08, 0x09, 0x0a,
54 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
55 0x10, 0x11, 0x12, 0x13, 0x14,
56 0x15, 0x16, 0x17, 0x18
57};
58
59static uint8_t test_key32[32] = { 0x01, 0x02, 0x03, 0x04, 0x05,
60 0x06, 0x07, 0x08, 0x09, 0x0a,
61 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
62 0x10, 0x11, 0x12, 0x13, 0x14,
63 0x15, 0x16, 0x17, 0x18, 0x19,
64 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
65 0x1f, 0x20,
66};
67
68static uint8_t test_key64[64] = { 0x01, 0x02, 0x03, 0x04, 0x05,
69 0x06, 0x07, 0x08, 0x09, 0x0a,
70 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
71 0x10, 0x11, 0x12, 0x13, 0x14,
72 0x15, 0x16, 0x17, 0x18, 0x19,
73 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
74 0x1f, 0x20, 0x21, 0x22, 0x23,
75 0x24, 0x25, 0x26, 0x27, 0x28,
76 0x29, 0x2a, 0x4b, 0x2c, 0x2d,
77 0x2e, 0x2f, 0x30, 0x31, 0x32,
78 0x33, 0x34, 0x55, 0x36, 0x37,
79 0x38, 0x39, 0x5a, 0x3b, 0x3c,
80 0x3d, 0x3e, 0x5f, 0x40,
81};
82
87typedef struct {
88 const char *name;
90} ipsec_alg_config_t;
91
95typedef struct {
100 int debug_packets;
101
108 int in_flight;
109
115 int packet_count;
116
121 unsigned int payload_length;
122
128 ipsec_alg_config_t *alg_config;
129
134 int schedule;
135
136 /*
137 * Poll completion queue for crypto completion events.
138 * Specified through -p argument.
139 */
140 int poll;
141
142 /*
143 * Use tunnel instead of transport mode.
144 * Specified through -t argument.
145 */
146 int tunnel;
147
148 /*
149 * Use AH transformation.
150 * Specified through -u argument.
151 */
152 int ah;
153
154 /*
155 * Burst size.
156 * Prepare and submit as many packets for IPsec processing in each
157 * iteration of the loop.
158 */
159 int burst_size;
160
161 /*
162 * Use vector packet completion from IPsec APIs.
163 * Specified through -v or --vector argument.
164 */
165 uint32_t vec_pkt_size;
166} ipsec_args_t;
167
168/*
169 * Helper structure that holds averages for test of one algorithm
170 * for given payload size.
171 */
172typedef struct {
176 double elapsed;
177
183 double rusage_self;
184
190 double rusage_thread;
191} ipsec_run_result_t;
192
196typedef struct {
197 struct timeval tv;
198 struct rusage ru_self;
199 struct rusage ru_thread;
200} time_record_t;
201
205static unsigned int global_payloads[] = {
206 64,
207 256,
208 1024,
209 8192,
210 16384
211};
212
214static unsigned int global_num_payloads;
215
219static ipsec_alg_config_t algs_config[] = {
220 {
221 .name = "3des-cbc-null",
222 .crypto = {
224 .cipher_key = {
225 .data = test_key24,
226 .length = sizeof(test_key24)
227 },
228 .auth_alg = ODP_AUTH_ALG_NULL
229 },
230 },
231 {
232 .name = "3des-cbc-hmac-md5-96",
233 .crypto = {
234 .cipher_alg = ODP_CIPHER_ALG_3DES_CBC,
235 .cipher_key = {
236 .data = test_key24,
237 .length = sizeof(test_key24)
238 },
239 .auth_alg = ODP_AUTH_ALG_MD5_HMAC,
240 .auth_key = {
241 .data = test_key16,
242 .length = sizeof(test_key16)
243 },
244 },
245 },
246 {
247 .name = "null-hmac-md5-96",
248 .crypto = {
249 .cipher_alg = ODP_CIPHER_ALG_NULL,
250 .auth_alg = ODP_AUTH_ALG_MD5_HMAC,
251 .auth_key = {
252 .data = test_key16,
253 .length = sizeof(test_key16)
254 },
255 },
256 },
257 {
258 .name = "aes-cbc-null",
259 .crypto = {
260 .cipher_alg = ODP_CIPHER_ALG_AES_CBC,
261 .cipher_key = {
262 .data = test_key16,
263 .length = sizeof(test_key16)
264 },
265 .auth_alg = ODP_AUTH_ALG_NULL
266 },
267 },
268 {
269 .name = "aes-cbc-hmac-sha1-96",
270 .crypto = {
271 .cipher_alg = ODP_CIPHER_ALG_AES_CBC,
272 .cipher_key = {
273 .data = test_key16,
274 .length = sizeof(test_key16)
275 },
276 .auth_alg = ODP_AUTH_ALG_SHA1_HMAC,
277 .auth_key = {
278 .data = test_key20,
279 .length = sizeof(test_key20)
280 },
281 },
282 },
283 {
284 .name = "aes-ctr-null",
285 .crypto = {
286 .cipher_alg = ODP_CIPHER_ALG_AES_CTR,
287 .cipher_key = {
288 .data = test_key16,
289 .length = sizeof(test_key16)
290 },
291 .cipher_key_extra = {
292 .data = test_salt,
293 .length = 4,
294 },
295 .auth_alg = ODP_AUTH_ALG_NULL
296 },
297 },
298 {
299 .name = "aes-ctr-hmac-sha1-96",
300 .crypto = {
301 .cipher_alg = ODP_CIPHER_ALG_AES_CTR,
302 .cipher_key = {
303 .data = test_key16,
304 .length = sizeof(test_key16)
305 },
306 .cipher_key_extra = {
307 .data = test_salt,
308 .length = 4,
309 },
310 .auth_alg = ODP_AUTH_ALG_SHA1_HMAC,
311 .auth_key = {
312 .data = test_key20,
313 .length = sizeof(test_key20)
314 },
315 },
316 },
317 {
318 .name = "null-hmac-sha1-96",
319 .crypto = {
320 .cipher_alg = ODP_CIPHER_ALG_NULL,
321 .auth_alg = ODP_AUTH_ALG_SHA1_HMAC,
322 .auth_key = {
323 .data = test_key20,
324 .length = sizeof(test_key20)
325 },
326 },
327 },
328 {
329 .name = "null-hmac-sha256-128",
330 .crypto = {
331 .cipher_alg = ODP_CIPHER_ALG_NULL,
332 .auth_alg = ODP_AUTH_ALG_SHA256_HMAC,
333 .auth_key = {
334 .data = test_key32,
335 .length = sizeof(test_key32)
336 },
337 },
338 },
339 {
340 .name = "null-hmac-sha512-256",
341 .crypto = {
342 .cipher_alg = ODP_CIPHER_ALG_NULL,
343 .auth_alg = ODP_AUTH_ALG_SHA512_HMAC,
344 .auth_key = {
345 .data = test_key64,
346 .length = sizeof(test_key64)
347 },
348 },
349 },
350 {
351 .name = "null-aes-gmac",
352 .crypto = {
353 .cipher_alg = ODP_CIPHER_ALG_NULL,
354 .auth_alg = ODP_AUTH_ALG_AES_GMAC,
355 .auth_key = {
356 .data = test_key16,
357 .length = sizeof(test_key16)
358 },
359 .auth_key_extra = {
360 .data = test_salt,
361 .length = 4,
362 },
363 },
364 },
365 {
366 .name = "aes-gcm",
367 .crypto = {
368 .cipher_alg = ODP_CIPHER_ALG_AES_GCM,
369 .cipher_key = {
370 .data = test_key16,
371 .length = sizeof(test_key16)
372 },
373 .cipher_key_extra = {
374 .data = test_salt,
375 .length = 4,
376 },
377 .auth_alg = ODP_AUTH_ALG_AES_GCM,
378 },
379 },
380 {
381 .name = "aes-ccm",
382 .crypto = {
383 .cipher_alg = ODP_CIPHER_ALG_AES_CCM,
384 .cipher_key = {
385 .data = test_key16,
386 .length = sizeof(test_key16)
387 },
388 .cipher_key_extra = {
389 .data = test_salt,
390 .length = 3,
391 },
392 .auth_alg = ODP_AUTH_ALG_AES_CCM,
393 },
394 },
395 {
396 .name = "chacha20-poly1305",
397 .crypto = {
399 .cipher_key = {
400 .data = test_key32,
401 .length = sizeof(test_key32)
402 },
403 .cipher_key_extra = {
404 .data = test_salt,
405 .length = 4,
406 },
408 },
409 },
410};
411
416static ipsec_alg_config_t *
417find_config_by_name(const char *name)
418{
419 unsigned int i;
420 ipsec_alg_config_t *ret = NULL;
421
422 for (i = 0; i < ODPH_ARRAY_SIZE(algs_config); i++) {
423 if (strcmp(algs_config[i].name, name) == 0) {
424 ret = algs_config + i;
425 break;
426 }
427 }
428 return ret;
429}
430
435static void
436print_config_names(const char *prefix)
437{
438 unsigned int i;
439
440 for (i = 0; i < ODPH_ARRAY_SIZE(algs_config); i++)
441 printf("%s %s\n", prefix, algs_config[i].name);
442}
443
447static void
448fill_time_record(time_record_t *rec)
449{
450 gettimeofday(&rec->tv, NULL);
451 getrusage(RUSAGE_SELF, &rec->ru_self);
452 getrusage(RUSAGE_THREAD, &rec->ru_thread);
453}
454
459static unsigned long long
460get_rusage_diff(struct rusage *start, struct rusage *end)
461{
462 unsigned long long rusage_diff;
463 unsigned long long rusage_start;
464 unsigned long long rusage_end;
465
466 rusage_start = (start->ru_utime.tv_sec * 1000000) +
467 (start->ru_utime.tv_usec);
468 rusage_start += (start->ru_stime.tv_sec * 1000000) +
469 (start->ru_stime.tv_usec);
470
471 rusage_end = (end->ru_utime.tv_sec * 1000000) +
472 (end->ru_utime.tv_usec);
473 rusage_end += (end->ru_stime.tv_sec * 1000000) +
474 (end->ru_stime.tv_usec);
475
476 rusage_diff = rusage_end - rusage_start;
477
478 return rusage_diff;
479}
480
485static unsigned long long
486get_rusage_self_diff(time_record_t *start, time_record_t *end)
487{
488 return get_rusage_diff(&start->ru_self, &end->ru_self);
489}
490
495static unsigned long long
496get_rusage_thread_diff(time_record_t *start, time_record_t *end)
497{
498 return get_rusage_diff(&start->ru_thread, &end->ru_thread);
499}
500
504static unsigned long long
505get_elapsed_usec(time_record_t *start, time_record_t *end)
506{
507 unsigned long long s;
508 unsigned long long e;
509
510 s = (start->tv.tv_sec * 1000000) + (start->tv.tv_usec);
511 e = (end->tv.tv_sec * 1000000) + (end->tv.tv_usec);
512
513 return e - s;
514}
515
519static void
520print_result_header(void)
521{
522 printf("\n%30.30s %15s %15s %15s %15s %15s %15s\n",
523 "algorithm", "avg over #", "payload (bytes)", "elapsed (us)",
524 "rusg self (us)", "rusg thrd (us)", "throughput (Kb)");
525}
526
530static void
531print_result(ipsec_args_t *cargs,
532 unsigned int payload_length,
533 ipsec_alg_config_t *config,
534 ipsec_run_result_t *result)
535{
536 unsigned int throughput;
537
538 throughput = (1000000.0 / result->elapsed) * payload_length / 1024;
539 printf("%30.30s %15d %15d %15.3f %15.3f %15.3f %15d\n",
540 config->name, cargs->packet_count, payload_length,
541 result->elapsed, result->rusage_self, result->rusage_thread,
542 throughput);
543}
544
545#define IPV4ADDR(a, b, c, d) odp_cpu_to_be_32((a << 24) | \
546 (b << 16) | \
547 (c << 8) | \
548 (d << 0))
549
553static odp_ipsec_sa_t
554create_sa_from_config(ipsec_alg_config_t *config,
555 ipsec_args_t *cargs)
556{
558 odp_queue_t out_queue;
559
561 memcpy(&param.crypto, &config->crypto,
563
564 param.proto = ODP_IPSEC_ESP;
566
567 if (cargs->tunnel) {
568 uint32_t src = IPV4ADDR(10, 0, 111, 2);
569 uint32_t dst = IPV4ADDR(10, 0, 222, 2);
571
572 memset(&tunnel, 0, sizeof(tunnel));
574 tunnel.ipv4.src_addr = &src;
575 tunnel.ipv4.dst_addr = &dst;
576 tunnel.ipv4.ttl = 64;
577
579 param.outbound.tunnel = tunnel;
580 } else {
582 }
583
584 if (cargs->schedule || cargs->poll) {
585 out_queue = odp_queue_lookup("ipsec-out");
586 if (out_queue == ODP_QUEUE_INVALID) {
587 ODPH_ERR("ipsec-out queue not found\n");
589 }
590 param.dest_queue = out_queue;
591 } else {
593 }
594
595 return odp_ipsec_sa_create(&param);
596}
597
598static uint8_t test_data[] = {
599 /* IP */
600 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
601 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02,
602 0xc0, 0xa8, 0xde, 0x02,
603
604 /* ICMP */
605 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00
606};
607
608static inline void debug_packets(int debug, odp_packet_t *pkt, int num_pkts)
609{
610 if (odp_likely(!debug))
611 return;
612 for (int i = 0; i < num_pkts; i++)
613 odp_packet_print_data(pkt[i], 0, odp_packet_len(pkt[i]));
614}
615
616static int
617make_packet_multi(odp_pool_t pkt_pool, unsigned int payload_length,
618 odp_packet_t pkt[], int num)
619{
620 int i, ret;
621
622 ret = odp_packet_alloc_multi(pkt_pool, payload_length, pkt, num);
623 if (ret != num) {
624 ODPH_ERR("Could not allocate buffer\n");
625 if (ret > 0)
626 odp_packet_free_sp(pkt, ret);
627 return -1;
628 }
629
630 for (i = 0; i < num; i++) {
631 odp_packet_copy_from_mem(pkt[i], 0, sizeof(test_data), test_data);
632 odp_packet_l3_offset_set(pkt[i], 0);
633
634 uint8_t *mem = odp_packet_data(pkt[i]);
635 ((odph_ipv4hdr_t *)mem)->tot_len = odp_cpu_to_be_16(payload_length);
636 memset(mem + sizeof(test_data), 1, payload_length - sizeof(test_data));
637 }
638
639 return 0;
640}
641
642static inline void check_ipsec_result(odp_packet_t ipsec_pkt)
643{
645
646 if (odp_unlikely(odp_ipsec_result(&result, ipsec_pkt)))
647 ODPH_ERR("odp_ipsec_result() failed\n");
648 else if (odp_unlikely(result.status.error.all))
649 ODPH_ERR("IPsec processing error: %" PRIu32 "\n",
650 result.status.error.all);
651}
652
657static int
658run_measure_one(ipsec_args_t *cargs,
660 unsigned int payload_length,
661 time_record_t *start,
662 time_record_t *end)
663{
664 int in_flight, pkts_allowed, num_out, num_pkts, rc = 0;
665 const int max_in_flight = cargs->in_flight;
666 const int burst_size = cargs->burst_size;
667 const int packet_count = cargs->packet_count;
668 const int debug = cargs->debug_packets;
670 odp_pool_t pkt_pool;
671
672 pkt_pool = odp_pool_lookup("packet_pool");
673 if (pkt_pool == ODP_POOL_INVALID) {
674 ODPH_ERR("pkt_pool not found\n");
675 return -1;
676 }
677
678 if (payload_length < sizeof(test_data))
679 return -1;
680
681 int packets_sent = 0;
682 int packets_received = 0;
683
684 /* Initialize parameters block */
685 memset(&param, 0, sizeof(param));
686 param.num_sa = 1;
687 param.num_opt = 0;
688 param.sa = &sa;
689
690 fill_time_record(start);
691
692 while ((packets_sent < packet_count) ||
693 (packets_received < packet_count)) {
694 num_pkts = packet_count - packets_sent;
695
696 /* Enqueue up to burst size */
697 num_pkts = num_pkts > burst_size ? burst_size : num_pkts;
698
699 /* Enqueue up to (max in flight - current in flight) */
700 in_flight = packets_sent - packets_received;
701 pkts_allowed = max_in_flight - in_flight;
702
703 /* Enqueue either a burst of packets or skip */
704 num_pkts = num_pkts > pkts_allowed ? 0 : num_pkts;
705
706 if (odp_likely(num_pkts)) {
707 odp_packet_t out_pkt[num_pkts];
708 odp_packet_t pkt[num_pkts];
709 int i;
710
711 if (odp_unlikely(make_packet_multi(pkt_pool,
712 payload_length,
713 pkt,
714 num_pkts)))
715 return -1;
716
717 debug_packets(debug, pkt, num_pkts);
718 num_out = num_pkts;
719
720 rc = odp_ipsec_out(pkt, num_pkts,
721 out_pkt, &num_out,
722 &param);
723 if (odp_unlikely(rc <= 0)) {
724 ODPH_ERR("Failed odp_ipsec_out: rc = %d\n", rc);
725 odp_packet_free_sp(pkt, num_pkts);
726 break;
727 }
728
729 for (i = 0; i < num_out; i++)
730 check_ipsec_result(out_pkt[i]);
731
732 packets_sent += rc;
733 packets_received += num_out;
734 debug_packets(debug, out_pkt, num_out);
735
736 if (odp_unlikely(rc != num_pkts))
737 odp_packet_free_sp(&pkt[rc], num_pkts - rc);
738 odp_packet_free_sp(out_pkt, num_out);
739 }
740 }
741
742 fill_time_record(end);
743
744 return rc < 0 ? rc : 0;
745}
746
747static uint32_t dequeue_burst(odp_queue_t polled_queue,
748 odp_event_t *events,
749 int max_burst)
750{
751 int num = 0;
752
753 if (polled_queue != ODP_QUEUE_INVALID) {
754 int rc = odp_queue_deq_multi(polled_queue,
755 events,
756 max_burst);
757 num = odp_likely(rc >= 0) ? rc : 0;
758 } else {
759 num = odp_schedule_multi(NULL,
761 events,
762 max_burst);
763 }
764 return num;
765}
766
767static inline uint32_t vec_pkt_handle(int debug, odp_event_t ev)
768{
770 uint32_t vec_size = odp_packet_vector_size(vec);
771 odp_packet_t *pkt_tbl;
772 uint32_t j;
773
774 odp_packet_vector_tbl(vec, &pkt_tbl);
775
776 for (j = 0; j < vec_size; j++)
777 check_ipsec_result(pkt_tbl[j]);
778
779 debug_packets(debug, pkt_tbl, vec_size);
780
781 odp_packet_free_sp(pkt_tbl, vec_size);
783
784 return vec_size;
785}
786
787static int
788run_measure_one_async(ipsec_args_t *cargs,
790 unsigned int payload_length,
791 time_record_t *start,
792 time_record_t *end)
793{
794 int in_flight, packets_allowed, num_pkts, rc = 0;
795 const int max_in_flight = cargs->in_flight;
796 const int burst_size = cargs->burst_size;
797 const int packet_count = cargs->packet_count;
798 const int debug = cargs->debug_packets;
800 odp_pool_t pkt_pool;
801 odp_queue_t polled_queue = ODP_QUEUE_INVALID;
802
803 pkt_pool = odp_pool_lookup("packet_pool");
804 if (pkt_pool == ODP_POOL_INVALID) {
805 ODPH_ERR("pkt_pool not found\n");
806 return -1;
807 }
808
809 if (cargs->poll) {
810 polled_queue = odp_queue_lookup("ipsec-out");
811 if (polled_queue == ODP_QUEUE_INVALID) {
812 ODPH_ERR("ipsec-out queue not found\n");
813 return -1;
814 }
815 }
816
817 if (payload_length < sizeof(test_data))
818 return -1;
819
820 int packets_sent = 0;
821 int packets_received = 0;
822
823 /* Initialize parameters block */
824 memset(&param, 0, sizeof(param));
825 param.num_sa = 1;
826 param.num_opt = 0;
827 param.sa = &sa;
828
829 fill_time_record(start);
830
831 while ((packets_sent < packet_count) ||
832 (packets_received < packet_count)) {
833
834 num_pkts = packet_count - packets_sent;
835
836 /* Enqueue up to burst size */
837 num_pkts = num_pkts > burst_size ? burst_size : num_pkts;
838
839 /* Enqueue up to (max in flight - current in flight) */
840 in_flight = packets_sent - packets_received;
841 packets_allowed = max_in_flight - in_flight;
842
843 if (num_pkts > 0 && num_pkts <= packets_allowed) {
844 odp_packet_t pkt[num_pkts];
845
846 if (odp_unlikely(make_packet_multi(pkt_pool,
847 payload_length,
848 pkt,
849 num_pkts)))
850 return -1;
851
852 debug_packets(debug, pkt, num_pkts);
853
854 rc = odp_ipsec_out_enq(pkt, num_pkts, &param);
855 if (odp_unlikely(rc <= 0)) {
856 ODPH_ERR("Failed odp_ipsec_out_enq: rc = %d\n",
857 rc);
858 odp_packet_free_sp(pkt, num_pkts);
859 break;
860 }
861
862 if (odp_unlikely(rc != num_pkts))
863 odp_packet_free_sp(&pkt[rc], num_pkts - rc);
864
865 packets_sent += rc;
866 } else {
867 odp_packet_t pkt_out[max_in_flight];
868 int i = 0;
869
870 /*
871 * Dequeue packets until we can enqueue the next burst
872 * or until we have received all remaining packets
873 * when there are no more packets to be sent.
874 */
875 while (num_pkts > packets_allowed ||
876 (num_pkts == 0 && packets_received < packet_count)) {
877 odp_event_t events[MAX_DEQUEUE_BURST];
878 uint32_t num;
879
880 num = dequeue_burst(polled_queue, events, MAX_DEQUEUE_BURST);
881
882 for (uint32_t n = 0; n < num; n++) {
883 if (odp_event_type(events[n]) == ODP_EVENT_PACKET_VECTOR) {
884 uint32_t vec_size;
885
886 vec_size = vec_pkt_handle(debug, events[n]);
887 packets_received += vec_size - 1;
888 packets_allowed += vec_size - 1;
889 } else {
890 pkt_out[i] = odp_ipsec_packet_from_event(events[n]);
891 check_ipsec_result(pkt_out[i]);
892 i++;
893 }
894
895 }
896 packets_received += num;
897 packets_allowed += num;
898 }
899 debug_packets(debug, pkt_out, i);
900
901 if (i > 0)
902 odp_packet_free_sp(pkt_out, i);
903 }
904 }
905
906 fill_time_record(end);
907
908 return rc < 0 ? rc : 0;
909}
910
915static int
916run_measure_one_config(ipsec_args_t *cargs,
917 ipsec_alg_config_t *config)
918{
919 unsigned int num_payloads = global_num_payloads;
920 unsigned int *payloads = global_payloads;
923 unsigned int i;
924 int rc = 0;
925
926 if (odp_ipsec_capability(&capa) < 0) {
927 ODPH_ERR("IPSEC capability call failed.\n");
928 return -1;
929 }
930
931 if (cargs->ah && (ODP_SUPPORT_NO == capa.proto_ah)) {
932 ODPH_ERR("IPSEC AH protocol not supported.\n");
933 return -1;
934 }
935
936 rc = odph_ipsec_alg_check(&capa, config->crypto.cipher_alg,
937 config->crypto.cipher_key.length,
938 config->crypto.auth_alg,
939 config->crypto.auth_key.length);
940
941 if (rc) {
942 printf(" => %s skipped\n\n", config->name);
943 return 0;
944 }
945
946 sa = create_sa_from_config(config, cargs);
947 if (sa == ODP_IPSEC_SA_INVALID) {
948 ODPH_ERR("IPsec SA create failed.\n");
949 return -1;
950 }
951
952 print_result_header();
953 if (cargs->payload_length) {
954 num_payloads = 1;
955 payloads = &cargs->payload_length;
956 }
957
958 for (i = 0; i < num_payloads; i++) {
959 double count;
960 ipsec_run_result_t result;
961 time_record_t start, end;
962
963 if (cargs->schedule || cargs->poll)
964 rc = run_measure_one_async(cargs, sa,
965 payloads[i],
966 &start, &end);
967 else
968 rc = run_measure_one(cargs, sa,
969 payloads[i],
970 &start, &end);
971 if (rc)
972 break;
973
974 count = get_elapsed_usec(&start, &end);
975 result.elapsed = count / cargs->packet_count;
976
977 count = get_rusage_self_diff(&start, &end);
978 result.rusage_self = count / cargs->packet_count;
979
980 count = get_rusage_thread_diff(&start, &end);
981 result.rusage_thread = count / cargs->packet_count;
982
983 print_result(cargs, payloads[i],
984 config, &result);
985 }
986
988 if (cargs->schedule || cargs->poll) {
989 odp_queue_t out_queue = odp_queue_lookup("ipsec-out");
990 odp_ipsec_status_t status;
991
992 while (1) {
993 odp_event_t event;
994
995 if (cargs->poll)
996 event = odp_queue_deq(out_queue);
997 else
998 event = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
999
1000 if (event != ODP_EVENT_INVALID &&
1001 odp_event_type(event) == ODP_EVENT_IPSEC_STATUS &&
1002 odp_ipsec_status(&status, event) == ODP_IPSEC_OK &&
1003 status.id == ODP_IPSEC_STATUS_SA_DISABLE &&
1004 status.sa == sa)
1005 break;
1006 }
1007 }
1009
1010 return rc;
1011}
1012
1013typedef struct thr_arg {
1014 ipsec_args_t ipsec_args;
1015 ipsec_alg_config_t *ipsec_alg_config;
1016} thr_arg_t;
1017
1018static int run_thr_func(void *arg)
1019{
1020 thr_arg_t *thr_args = (thr_arg_t *)arg;
1021
1022 run_measure_one_config(&thr_args->ipsec_args,
1023 thr_args->ipsec_alg_config);
1024 return 0;
1025}
1026
1030static void usage(char *progname)
1031{
1032 printf("\n"
1033 "Usage: %s OPTIONS\n"
1034 " E.g. %s -i 100000\n"
1035 "\n"
1036 "OpenDataPlane crypto speed measure.\n"
1037 "Optional OPTIONS\n"
1038 " -a, --algorithm <name> Specify algorithm name (default all)\n"
1039 " Supported values are:\n",
1040 progname, progname);
1041
1042 print_config_names(" ");
1043 printf(" -d, --debug Enable dump of processed packets.\n"
1044 " -f, --flight <number> Max number of packet processed in parallel (default 1)\n"
1045 " -c, --count <number> Number of packets (default 10000)\n"
1046 " -b, --burst <number> Number of packets in one IPsec API submission (default 1)\n"
1047 " -v, --vector <number> Enable vector packet completion from IPsec APIs with specified vector size.\n"
1048 " -l, --payload Payload length.\n"
1049 " -s, --schedule Use scheduler for completion events.\n"
1050 " -p, --poll Poll completion queue for completion events.\n"
1051 " -t, --tunnel Use tunnel-mode IPsec transformation.\n"
1052 " -u, --ah Use AH transformation instead of ESP.\n"
1053 " -h, --help Display help and exit.\n"
1054 "\n");
1055}
1056
1057static void parse_args(int argc, char *argv[], ipsec_args_t *cargs)
1058{
1059 int opt;
1060 static const struct option longopts[] = {
1061 {"algorithm", optional_argument, NULL, 'a'},
1062 {"debug", no_argument, NULL, 'd'},
1063 {"flight", optional_argument, NULL, 'f'},
1064 {"help", no_argument, NULL, 'h'},
1065 {"count", optional_argument, NULL, 'c'},
1066 {"burst", optional_argument, NULL, 'b'},
1067 {"vector", optional_argument, NULL, 'v'},
1068 {"payload", optional_argument, NULL, 'l'},
1069 {"sessions", optional_argument, NULL, 'm'},
1070 {"poll", no_argument, NULL, 'p'},
1071 {"schedule", no_argument, NULL, 's'},
1072 {"tunnel", no_argument, NULL, 't'},
1073 {"ah", no_argument, NULL, 'u'},
1074 {NULL, 0, NULL, 0}
1075 };
1076
1077 static const char *shortopts = "+a:b:c:df:hm:nl:sptuv:";
1078
1079 cargs->in_flight = 1;
1080 cargs->debug_packets = 0;
1081 cargs->packet_count = 10000;
1082 cargs->burst_size = 1;
1083 cargs->vec_pkt_size = 0;
1084 cargs->payload_length = 0;
1085 cargs->alg_config = NULL;
1086 cargs->schedule = 0;
1087 cargs->ah = 0;
1088
1089 while (1) {
1090 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
1091
1092 if (opt == -1)
1093 break; /* No more options */
1094
1095 switch (opt) {
1096 case 'a':
1097 cargs->alg_config = find_config_by_name(optarg);
1098 if (!cargs->alg_config) {
1099 printf("cannot test crypto '%s' configuration\n",
1100 optarg);
1101 usage(argv[0]);
1102 exit(-1);
1103 }
1104 break;
1105 case 'd':
1106 cargs->debug_packets = 1;
1107 break;
1108 case 'c':
1109 cargs->packet_count = atoi(optarg);
1110 break;
1111 case 'b':
1112 if (optarg == NULL)
1113 cargs->burst_size = 32;
1114 else
1115 cargs->burst_size = atoi(optarg);
1116 if (cargs->burst_size > POOL_NUM_PKT) {
1117 printf("Invalid burst size (max allowed: %d)\n", POOL_NUM_PKT);
1118 exit(-1);
1119 }
1120 break;
1121 case 'v':
1122 if (optarg == NULL)
1123 cargs->vec_pkt_size = 32;
1124 else
1125 cargs->vec_pkt_size = atoi(optarg);
1126 break;
1127 case 'f':
1128 cargs->in_flight = atoi(optarg);
1129 break;
1130 case 'h':
1131 usage(argv[0]);
1132 exit(EXIT_SUCCESS);
1133 break;
1134 case 'l':
1135 cargs->payload_length = atoi(optarg);
1136 break;
1137 case 's':
1138 cargs->schedule = 1;
1139 break;
1140 case 'p':
1141 cargs->poll = 1;
1142 break;
1143 case 't':
1144 cargs->tunnel = 1;
1145 break;
1146 case 'u':
1147 cargs->ah = 1;
1148 break;
1149 default:
1150 break;
1151 }
1152 }
1153
1154 if (cargs->in_flight < cargs->burst_size) {
1155 printf("-f (flight) must be greater than or equal to -b (burst)\n");
1156 exit(-1);
1157 }
1158
1159 optind = 1; /* reset 'extern optind' from the getopt lib */
1160
1161 if (cargs->schedule && cargs->poll) {
1162 printf("-s (schedule) and -p (poll) options are not compatible\n");
1163 usage(argv[0]);
1164 exit(-1);
1165 }
1166}
1167
1168int main(int argc, char *argv[])
1169{
1170 odp_pool_t vec_pool = ODP_POOL_INVALID;
1171 ipsec_args_t cargs;
1172 odp_pool_t pool;
1173 odp_queue_param_t qparam;
1174 odp_pool_param_t param;
1175 odp_queue_t out_queue = ODP_QUEUE_INVALID;
1176 thr_arg_t thr_arg;
1177 odp_cpumask_t cpumask;
1178 char cpumaskstr[ODP_CPUMASK_STR_SIZE];
1179 int num_workers = 1;
1180 odph_helper_options_t helper_options;
1181 odph_thread_t thread_tbl[num_workers];
1182 odph_thread_common_param_t thr_common;
1183 odph_thread_param_t thr_param;
1184 odp_instance_t instance;
1185 odp_init_t init_param;
1186 odp_ipsec_capability_t ipsec_capa;
1188 odp_ipsec_config_t config;
1189 uint32_t max_seg_len;
1190 unsigned int i;
1191
1192 /* Let helper collect its own arguments (e.g. --odph_proc) */
1193 argc = odph_parse_options(argc, argv);
1194 if (odph_options(&helper_options)) {
1195 ODPH_ERR("Reading ODP helper options failed.\n");
1196 exit(EXIT_FAILURE);
1197 }
1198
1199 odp_init_param_init(&init_param);
1200 init_param.mem_model = helper_options.mem_model;
1201
1202 memset(&cargs, 0, sizeof(cargs));
1203
1204 /* Parse and store the application arguments */
1205 parse_args(argc, argv, &cargs);
1206
1207 /* Init ODP before calling anything else */
1208 if (odp_init_global(&instance, &init_param, NULL)) {
1209 ODPH_ERR("ODP global init failed.\n");
1210 exit(EXIT_FAILURE);
1211 }
1212
1213 /* Init this thread */
1214 if (odp_init_local(instance, ODP_THREAD_WORKER)) {
1215 ODPH_ERR("ODP local init failed.\n");
1216 exit(EXIT_FAILURE);
1217 }
1218
1220
1221 if (odp_pool_capability(&capa)) {
1222 ODPH_ERR("Pool capability request failed.\n");
1223 exit(EXIT_FAILURE);
1224 }
1225
1226 max_seg_len = capa.pkt.max_seg_len;
1227
1228 for (i = 0; i < ODPH_ARRAY_SIZE(global_payloads); i++) {
1229 if (global_payloads[i] > max_seg_len)
1230 break;
1231 }
1232
1233 global_num_payloads = i;
1234
1235 /* Create packet pool */
1236 odp_pool_param_init(&param);
1237 param.pkt.seg_len = max_seg_len;
1238 param.pkt.len = max_seg_len;
1239 param.pkt.num = POOL_NUM_PKT;
1240 param.type = ODP_POOL_PACKET;
1241 pool = odp_pool_create("packet_pool", &param);
1242
1243 if (pool == ODP_POOL_INVALID) {
1244 ODPH_ERR("packet pool create failed.\n");
1245 exit(EXIT_FAILURE);
1246 }
1247 odp_pool_print(pool);
1248
1249 if (odp_ipsec_capability(&ipsec_capa) < 0) {
1250 ODPH_ERR("IPSEC capability call failed.\n");
1251 exit(EXIT_FAILURE);
1252 }
1253
1254 if (cargs.schedule && !ipsec_capa.queue_type_sched) {
1255 ODPH_ERR("Scheduled type destination queue not supported.\n");
1256 exit(EXIT_FAILURE);
1257 }
1258
1259 if (cargs.poll && !ipsec_capa.queue_type_plain) {
1260 ODPH_ERR("Plain type destination queue not supported.\n");
1261 exit(EXIT_FAILURE);
1262 }
1263
1264 if (cargs.vec_pkt_size) {
1265 if (capa.vector.max_pools < 1) {
1266 ODPH_ERR("Vector packet pool not available");
1267 exit(EXIT_FAILURE);
1268 }
1269
1270 if (!ipsec_capa.vector.supported) {
1271 ODPH_ERR("Vector packet completion not supported by IPsec.\n");
1272 exit(EXIT_FAILURE);
1273 }
1274
1275 if (capa.vector.max_size < cargs.vec_pkt_size) {
1276 ODPH_ERR("Vector size larger than max size supported by vector pool.\n");
1277 exit(EXIT_FAILURE);
1278 }
1279
1280 if (!cargs.schedule && !cargs.poll) {
1281 ODPH_ERR("Vector packet is not supported with sync APIs.\n");
1282 exit(EXIT_FAILURE);
1283 }
1284
1285 /* Create vector pool */
1286 odp_pool_param_init(&param);
1287 param.vector.num = POOL_NUM_PKT;
1288 param.vector.max_size = cargs.vec_pkt_size;
1289 param.type = ODP_POOL_VECTOR;
1290 vec_pool = odp_pool_create("vector_pool", &param);
1291
1292 if (vec_pool == ODP_POOL_INVALID) {
1293 ODPH_ERR("Vector packet pool create failed.\n");
1294 exit(EXIT_FAILURE);
1295 }
1296
1297 odp_pool_print(vec_pool);
1298 }
1299
1300 odp_ipsec_config_init(&config);
1301 config.max_num_sa = 2;
1302 config.inbound.chksums.all_chksum = 0;
1303 config.outbound.all_chksum = 0;
1304
1305 if (vec_pool != ODP_POOL_INVALID) {
1306 config.vector.enable = true;
1307 config.vector.pool = vec_pool;
1308 config.vector.max_size = cargs.vec_pkt_size;
1309 config.vector.max_tmo_ns = ipsec_capa.vector.max_tmo_ns;
1310 }
1311
1312 odp_queue_param_init(&qparam);
1313 if (cargs.schedule) {
1314 odp_schedule_config(NULL);
1315 qparam.type = ODP_QUEUE_TYPE_SCHED;
1319 out_queue = odp_queue_create("ipsec-out", &qparam);
1320 } else if (cargs.poll) {
1321 qparam.type = ODP_QUEUE_TYPE_PLAIN;
1322 out_queue = odp_queue_create("ipsec-out", &qparam);
1323 }
1324 if (cargs.schedule || cargs.poll) {
1325 if (out_queue == ODP_QUEUE_INVALID) {
1326 ODPH_ERR("ipsec-out queue create failed.\n");
1327 exit(EXIT_FAILURE);
1328 }
1331 config.inbound.default_queue = out_queue;
1332 } else {
1336 }
1337 if (odp_ipsec_config(&config)) {
1338 ODPH_ERR("odp_ipsec_config() failed\n");
1339 exit(EXIT_FAILURE);
1340 }
1341
1342 if (cargs.schedule) {
1343 printf("Run in async scheduled mode\n");
1344
1345 thr_arg.ipsec_args = cargs;
1346 thr_arg.ipsec_alg_config = cargs.alg_config;
1347 num_workers = odp_cpumask_default_worker(&cpumask,
1348 num_workers);
1349 (void)odp_cpumask_to_str(&cpumask, cpumaskstr,
1350 sizeof(cpumaskstr));
1351 printf("num worker threads: %i\n",
1352 num_workers);
1353 printf("first CPU: %i\n",
1354 odp_cpumask_first(&cpumask));
1355 printf("cpu mask: %s\n",
1356 cpumaskstr);
1357 } else if (cargs.poll) {
1358 printf("Run in async poll mode\n");
1359 } else {
1360 printf("Run in sync mode\n");
1361 }
1362
1363 if (cargs.alg_config) {
1364 odph_thread_common_param_init(&thr_common);
1365 thr_common.instance = instance;
1366 thr_common.cpumask = &cpumask;
1367 thr_common.share_param = 1;
1368
1369 if (cargs.schedule) {
1370 odph_thread_param_init(&thr_param);
1371 thr_param.start = run_thr_func;
1372 thr_param.arg = &thr_arg;
1373 thr_param.thr_type = ODP_THREAD_WORKER;
1374
1375 memset(thread_tbl, 0, sizeof(thread_tbl));
1376 odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
1377
1378 odph_thread_join(thread_tbl, num_workers);
1379 } else {
1380 run_measure_one_config(&cargs, cargs.alg_config);
1381 }
1382 } else {
1383 for (i = 0; i < ODPH_ARRAY_SIZE(algs_config); i++) {
1384 if (cargs.ah &&
1385 algs_config[i].crypto.cipher_alg !=
1387 continue;
1388 run_measure_one_config(&cargs, algs_config + i);
1389 }
1390 }
1391
1392 if (cargs.schedule || cargs.poll)
1393 odp_queue_destroy(out_queue);
1394
1395 if (cargs.vec_pkt_size) {
1396 if (odp_pool_destroy(vec_pool)) {
1397 ODPH_ERR("Error: vector pool destroy\n");
1398 exit(EXIT_FAILURE);
1399 }
1400 }
1401
1402 if (odp_pool_destroy(pool)) {
1403 ODPH_ERR("Error: pool destroy\n");
1404 exit(EXIT_FAILURE);
1405 }
1406
1407 if (odp_term_local()) {
1408 ODPH_ERR("Error: term local\n");
1409 exit(EXIT_FAILURE);
1410 }
1411
1412 if (odp_term_global(instance)) {
1413 ODPH_ERR("Error: term global\n");
1414 exit(EXIT_FAILURE);
1415 }
1416
1417 return 0;
1418}
1419
#define odp_unlikely(x)
Branch unlikely taken.
Definition spec/hints.h:64
odp_u16be_t odp_cpu_to_be_16(uint16_t cpu16)
Convert cpu native uint16_t to 16bit big endian.
#define odp_likely(x)
Branch likely taken.
Definition spec/hints.h:59
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
@ ODP_CIPHER_ALG_AES_CCM
AES-CCM.
@ ODP_CIPHER_ALG_AES_CTR
AES with counter mode.
@ ODP_CIPHER_ALG_CHACHA20_POLY1305
ChaCha20-Poly1305.
@ ODP_CIPHER_ALG_AES_CBC
AES with cipher block chaining.
@ ODP_CIPHER_ALG_AES_GCM
AES-GCM.
@ ODP_CIPHER_ALG_3DES_CBC
Triple DES with cipher block chaining.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_AUTH_ALG_CHACHA20_POLY1305
ChaCha20-Poly1305 AEAD.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
@ ODP_AUTH_ALG_MD5_HMAC
HMAC-MD5.
@ ODP_AUTH_ALG_SHA512_HMAC
HMAC-SHA-512.
@ ODP_AUTH_ALG_SHA1_HMAC
HMAC-SHA-1.
@ ODP_AUTH_ALG_SHA256_HMAC
HMAC-SHA-256.
@ ODP_AUTH_ALG_AES_GMAC
AES-GMAC.
@ ODP_AUTH_ALG_AES_GCM
AES-GCM.
@ ODP_AUTH_ALG_AES_CCM
AES-CCM.
odp_event_type_t odp_event_type(odp_event_t event)
Event type of an event.
#define ODP_EVENT_INVALID
Invalid event.
void odp_init_param_init(odp_init_t *param)
Initialize the odp_init_t to default values for all fields.
int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
Thread local ODP initialization.
int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params)
Global ODP initialization.
int odp_term_local(void)
Thread local ODP termination.
int odp_term_global(odp_instance_t instance)
Global ODP termination.
uint64_t odp_instance_t
ODP instance ID.
odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev)
Convert IPSEC processed packet event to packet handle.
#define ODP_IPSEC_OK
IPSEC operation status has no errors.
int odp_ipsec_capability(odp_ipsec_capability_t *capa)
Query IPSEC capabilities.
int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in, odp_packet_t pkt_out[], int *num_out, const odp_ipsec_out_param_t *param)
Outbound synchronous IPSEC operation.
void odp_ipsec_config_init(odp_ipsec_config_t *config)
Initialize IPSEC configuration options.
void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param)
Initialize IPSEC SA parameters.
int odp_ipsec_config(const odp_ipsec_config_t *config)
Global IPSEC configuration.
int odp_ipsec_sa_disable(odp_ipsec_sa_t sa)
Disable IPSEC SA.
int odp_ipsec_out_enq(const odp_packet_t pkt[], int num, const odp_ipsec_out_param_t *param)
Outbound asynchronous IPSEC operation.
int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event)
Get IPSEC status information from an ODP_EVENT_IPSEC_STATUS event.
#define ODP_IPSEC_SA_INVALID
Invalid IPSEC SA.
odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
Create IPSEC SA.
int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa)
Destroy IPSEC SA.
int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet)
Get IPSEC operation results from an IPSEC processed packet.
@ ODP_IPSEC_OP_MODE_SYNC
Synchronous IPSEC operation.
@ ODP_IPSEC_OP_MODE_ASYNC
Asynchronous IPSEC operation.
@ ODP_IPSEC_STATUS_SA_DISABLE
Response to SA disable command.
@ ODP_IPSEC_ESP
ESP protocol.
@ ODP_IPSEC_TUNNEL_IPV4
Outer header is IPv4.
@ ODP_IPSEC_MODE_TRANSPORT
IPSEC transport mode.
@ ODP_IPSEC_MODE_TUNNEL
IPSEC tunnel mode.
@ ODP_IPSEC_DIR_OUTBOUND
Outbound IPSEC SA.
void odp_packet_print_data(odp_packet_t pkt, uint32_t offset, uint32_t len)
Print packet data.
int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
Set layer 3 start offset.
odp_packet_vector_t odp_packet_vector_from_event(odp_event_t ev)
Get packet vector handle from event.
void * odp_packet_data(odp_packet_t pkt)
Packet data pointer.
uint32_t odp_packet_len(odp_packet_t pkt)
Packet data length.
void odp_packet_vector_free(odp_packet_vector_t pktv)
Free packet vector.
int odp_packet_copy_from_mem(odp_packet_t pkt, uint32_t offset, uint32_t len, const void *src)
Copy data from memory to packet.
uint32_t odp_packet_vector_tbl(odp_packet_vector_t pktv, odp_packet_t **pkt_tbl)
Get packet vector table.
int odp_packet_alloc_multi(odp_pool_t pool, uint32_t len, odp_packet_t pkt[], int num)
Allocate multiple packets from a packet pool.
void odp_packet_free_sp(const odp_packet_t pkt[], int num)
Free multiple packets to the same pool.
uint32_t odp_packet_vector_size(odp_packet_vector_t pktv)
Number of packets in a vector.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
int odp_pool_capability(odp_pool_capability_t *capa)
Query pool capabilities.
void odp_pool_param_init(odp_pool_param_t *param)
Initialize pool params.
int odp_pool_destroy(odp_pool_t pool)
Destroy a pool previously created by odp_pool_create()
void odp_pool_print(odp_pool_t pool)
Print pool info.
odp_pool_t odp_pool_lookup(const char *name)
Find a pool by name.
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_VECTOR
Vector event pool.
@ ODP_POOL_PACKET
Packet pool.
odp_queue_t odp_queue_lookup(const char *name)
Find a queue by name.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid queue.
odp_event_t odp_queue_deq(odp_queue_t queue)
Dequeue an event from a queue.
odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
Queue create.
int odp_queue_destroy(odp_queue_t queue)
Destroy ODP queue.
int odp_queue_deq_multi(odp_queue_t queue, odp_event_t events[], int num)
Dequeue multiple events from a queue.
@ ODP_QUEUE_TYPE_SCHED
Scheduled queue.
@ ODP_QUEUE_TYPE_PLAIN
Plain queue.
#define ODP_SCHED_SYNC_PARALLEL
Parallel scheduled queues.
int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], int num)
Schedule multiple events.
#define ODP_SCHED_NO_WAIT
Do not wait.
int odp_schedule_default_prio(void)
Default scheduling priority level.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
#define ODP_SCHED_GROUP_ALL
Group of all threads.
@ ODP_SUPPORT_NO
Feature is not supported.
void odp_sys_info_print(void)
Print system info.
@ ODP_THREAD_WORKER
Worker thread.
The OpenDataPlane API.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
odp_pktin_vector_capability_t vector
Support for returning completion packets as vectors.
odp_bool_t queue_type_sched
Scheduled queue support.
odp_bool_t queue_type_plain
Plain queue support.
odp_support_t proto_ah
IP Authenticated Header (ODP_IPSEC_AH) support.
IPSEC configuration options.
odp_pktin_vector_config_t vector
Packet vector configuration for async and inline operations.
odp_ipsec_op_mode_t outbound_mode
Outbound IPSEC operation mode.
odp_ipsec_inbound_config_t inbound
IPSEC inbound processing configuration.
uint32_t max_num_sa
Maximum number of IPSEC SAs that application will use simultaneously.
odp_ipsec_outbound_config_t outbound
IPSEC outbound processing configuration.
odp_ipsec_op_mode_t inbound_mode
Inbound IPSEC operation mode.
IPSEC crypto parameters.
odp_cipher_alg_t cipher_alg
Cipher algorithm.
uint32_t all
All error bits.
odp_queue_t default_queue
Default destination queue for IPSEC events.
odp_proto_chksums_t chksums
Flags to control IPSEC payload data checks up to the selected parse level.
uint8_t ttl
IPv4 Time To Live.
void * src_addr
IPv4 source address (NETWORK ENDIAN)
void * dst_addr
IPv4 destination address (NETWORK ENDIAN)
odp_ipsec_error_t error
IPSEC errors.
IPSEC outbound operation parameters.
int num_opt
Number of outbound operation options.
const odp_ipsec_sa_t * sa
Pointer to an array of IPSEC SAs.
uint32_t all_chksum
All bits of the bit field structure.
IPSEC operation result for a packet.
odp_ipsec_op_status_t status
IPSEC operation status.
IPSEC Security Association (SA) parameters.
odp_ipsec_crypto_param_t crypto
Parameters for crypto and authentication algorithms.
odp_queue_t dest_queue
Destination queue for IPSEC events.
odp_ipsec_mode_t mode
IPSEC protocol mode: transport or tunnel.
struct odp_ipsec_sa_param_t::@52::@55 outbound
Outbound specific parameters.
odp_ipsec_dir_t dir
IPSEC SA direction: inbound or outbound.
odp_ipsec_tunnel_param_t tunnel
Parameters for tunnel mode.
odp_ipsec_protocol_t proto
IPSEC protocol: ESP or AH.
IPSEC status content.
odp_ipsec_sa_t sa
IPSEC SA that was target of the operation.
odp_ipsec_status_id_t id
IPSEC status ID.
IPSEC tunnel parameters.
odp_ipsec_tunnel_type_t type
Tunnel type: IPv4 or IPv6.
odp_ipsec_ipv4_param_t ipv4
IPv4 header parameters.
uint64_t max_tmo_ns
Maximum timeout in nanoseconds for the producer to wait for the vector of packets.
odp_support_t supported
Packet input vector availability.
odp_bool_t enable
Enable packet input vector.
uint32_t max_size
Maximum number of packets in a vector.
uint64_t max_tmo_ns
Maximum time to wait for packets.
struct odp_pool_capability_t::@134 pkt
Packet pool capabilities
uint32_t max_size
Maximum buffer data size in bytes.
struct odp_pool_capability_t::@136 vector
Vector pool capabilities.
uint32_t max_pools
Maximum number of pools of any type (odp_pool_type_t)
uint32_t max_seg_len
Maximum packet segment data length in bytes.
uint32_t num
Number of buffers in the pool.
struct odp_pool_param_t::@139 pkt
Parameters for packet pools.
odp_pool_type_t type
Pool type.
uint32_t len
Minimum length of 'num' packets.
uint32_t max_size
Maximum number of handles (such as odp_packet_t) in a vector.
uint32_t seg_len
Minimum number of packet data bytes that can be stored in the first segment of a newly allocated pack...
struct odp_pool_param_t::@141 vector
Parameters for vector pools.
ODP Queue parameters.
odp_schedule_param_t sched
Scheduler parameters.
odp_queue_type_t type
Queue type.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
odp_schedule_sync_t sync
Synchronization method.
uint32_t all_chksum
All checksum bits.