API Reference Manual 1.51.0
Loading...
Searching...
No Matches
ipsec_api/odp_ipsec_stream.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2014-2018 Linaro Limited
3 */
4
7/* enable strtok */
8#ifndef _GNU_SOURCE
9#define _GNU_SOURCE
10#endif
11
12#include <stdlib.h>
13#include <string.h>
14
15#include <openssl/des.h>
16#include <openssl/rand.h>
17#include <openssl/hmac.h>
18#include <openssl/opensslv.h>
19
20#include <odp_api.h>
21
22#include <odp/helper/odph_api.h>
23
24#include <odp_ipsec_stream.h>
25
26#define STREAM_MAGIC 0xBABE01234567CAFE
27
28#define LOOP_DEQ_COUNT 32
30/* Ignore warnings about APIs deprecated in OpenSSL 3.0 */
31#if OPENSSL_VERSION_NUMBER >= 0x30000000L
32#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
33#endif
34
38typedef struct ODP_PACKED stream_pkt_hdr_s {
39 odp_u64be_t magic;
40 uint8_t data[];
41} stream_pkt_hdr_t;
42
43static const char *shm_name = "stream_db";
44stream_db_t *stream_db;
45
46void init_stream_db(void)
47{
48 odp_shm_t shm;
49
50 shm = odp_shm_reserve(shm_name,
51 sizeof(stream_db_t),
52 ODP_CACHE_LINE_SIZE,
53 0);
54
55 if (shm == ODP_SHM_INVALID) {
56 ODPH_ERR("Error: shared mem reserve failed.\n");
57 exit(EXIT_FAILURE);
58 }
59
60 stream_db = odp_shm_addr(shm);
61
62 if (stream_db == NULL) {
63 ODPH_ERR("Error: shared mem alloc failed.\n");
64 exit(EXIT_FAILURE);
65 }
66 memset(stream_db, 0, sizeof(*stream_db));
67}
68
69void deinit_stream_db(void)
70{
71 stream_db_entry_t *stream = NULL;
72
73 for (stream = stream_db->list; NULL != stream; stream = stream->next) {
74 free(stream->input.intf);
75 free(stream->output.intf);
76 }
77
78 odp_shm_t shm = odp_shm_lookup(shm_name);
79
80 if (shm == ODP_SHM_INVALID) {
81 ODPH_ERR("Error: shared mem not found.\n");
82 exit(EXIT_FAILURE);
83 }
84
85 if (odp_shm_free(shm)) {
86 ODPH_ERR("Error: shared mem free failed.\n");
87 exit(EXIT_FAILURE);
88 }
89}
90
91int create_stream_db_entry(char *input)
92{
93 int pos = 0;
94 char *local;
95 char *str;
96 char *save;
97 char *token;
98 stream_db_entry_t *entry = &stream_db->array[stream_db->index];
99
100 /* Verify we have a good entry */
101 if (MAX_DB <= stream_db->index)
102 return -1;
103
104 /* Make a local copy */
105 local = malloc(strlen(input) + 1);
106 if (NULL == local)
107 return -1;
108 strcpy(local, input);
109
110 /* Setup for using "strtok_r" to search input string */
111 str = local;
112 save = NULL;
113
114 /* Parse tokens separated by ',' */
115 while (NULL != (token = strtok_r(str, ",", &save))) {
116 str = NULL; /* reset str for subsequent strtok_r calls */
117
118 /* Parse token based on its position */
119 switch (pos) {
120 case 0:
121 parse_ipv4_string(token, &entry->src_ip, NULL);
122 break;
123 case 1:
124 parse_ipv4_string(token, &entry->dst_ip, NULL);
125 break;
126 case 2:
127 entry->input.intf = strdup(token);
128 break;
129 case 3:
130 entry->output.intf = strdup(token);
131 break;
132 case 4:
133 entry->count = atoi(token);
134 break;
135 case 5:
136 entry->length = atoi(token);
137 if (entry->length < sizeof(stream_pkt_hdr_t))
138 entry->length = 0;
139 else
140 entry->length -= sizeof(stream_pkt_hdr_t);
141 break;
142 default:
143 printf("ERROR: extra token \"%s\" at position %d\n",
144 token, pos);
145 break;
146 }
147
148 /* Advance to next position */
149 pos++;
150 }
151
152 /* Verify we parsed exactly the number of tokens we expected */
153 if (6 != pos) {
154 printf("ERROR: \"%s\" contains %d tokens, expected 6\n",
155 input,
156 pos);
157 free(local);
158 return -1;
159 }
160
161 /* Add stream to the list */
162 entry->id = stream_db->index++;
163 entry->next = stream_db->list;
164 stream_db->list = entry;
165
166 free(local);
167 return 0;
168}
169
170static const EVP_MD *get_evp_md(odp_auth_alg_t auth)
171{
172 const EVP_MD *evp_md;
173
174 switch (auth) {
176 evp_md = EVP_md5();
177 break;
179 evp_md = EVP_sha1();
180 break;
182 evp_md = EVP_sha256();
183 break;
184 default:
185 evp_md = NULL;
186 }
187
188 return evp_md;
189}
190
191void resolve_stream_db(void)
192{
193 stream_db_entry_t *stream = NULL;
194
195 /* For each stream look for input and output IPsec entries */
196 for (stream = stream_db->list; NULL != stream; stream = stream->next) {
197 ipsec_cache_entry_t *entry;
198
199 /* Lookup input entry */
200 entry = find_ipsec_cache_entry_in(stream->src_ip,
201 stream->dst_ip,
202 NULL,
203 NULL);
204 stream->input.entry = entry;
205
206 stream->input.pktio = odp_pktio_lookup(stream->input.intf);
207
208 if (entry)
209 stream->evp_md = get_evp_md(entry->ah.alg);
210
211 /* Lookup output entry */
212 entry = find_ipsec_cache_entry_out(stream->src_ip,
213 stream->dst_ip,
214 0);
215 stream->output.entry = entry;
216
217 stream->output.pktio = odp_pktio_lookup(stream->output.intf);
218
219 if (stream->evp_md == NULL && entry)
220 stream->evp_md = get_evp_md(entry->ah.alg);
221 }
222}
223
224odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
225 uint8_t *dmac,
226 odp_pool_t pkt_pool,
227 uint32_t max_len)
228{
229 ipsec_cache_entry_t *entry = NULL;
230 odp_packet_t pkt;
231 uint8_t *base;
232 uint8_t *data;
233 odph_ethhdr_t *eth;
234 odph_ipv4hdr_t *ip;
235 odph_ipv4hdr_t *inner_ip = NULL;
236 odph_ahhdr_t *ah = NULL;
237 odph_esphdr_t *esp = NULL;
238 odph_icmphdr_t *icmp;
239 stream_pkt_hdr_t *test;
240 unsigned i;
241
242 if (stream->input.entry)
243 entry = stream->input.entry;
244 else if (stream->output.entry)
245 entry = stream->output.entry;
246
247 /* Make sure there is enough space for protocol overhead */
248 if ((stream->length + 200) > max_len) {
249 ODPH_ERR("Error: too large test packet\n");
250 return ODP_PACKET_INVALID;
251 }
252
253 /* Get packet */
254 pkt = odp_packet_alloc(pkt_pool, max_len);
255 if (ODP_PACKET_INVALID == pkt) {
256 ODPH_ERR("Error: packet alloc failed\n");
257 return ODP_PACKET_INVALID;
258 }
259 base = odp_packet_data(pkt);
260 data = odp_packet_data(pkt);
261
262 /* Ethernet */
264 eth = (odph_ethhdr_t *)data;
265 data += sizeof(*eth);
266
267 memset((char *)eth->src.addr, (0x80 | stream->id), ODPH_ETHADDR_LEN);
268 memcpy((char *)eth->dst.addr, dmac, ODPH_ETHADDR_LEN);
269 eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
270
271 /* IPv4 */
273 ip = (odph_ipv4hdr_t *)data;
274 data += sizeof(*ip);
275
276 /* Wait until almost finished to fill in mutable fields */
277 memset((char *)ip, 0, sizeof(*ip));
278 ip->ver_ihl = 0x45;
279 ip->id = odp_cpu_to_be_16(stream->id);
280 /* Outer IP header in tunnel mode */
281 if (entry && entry->mode == IPSEC_SA_MODE_TUNNEL &&
282 (entry == stream->input.entry)) {
283 ip->proto = ODPH_IPV4;
284 ip->src_addr = odp_cpu_to_be_32(entry->tun_src_ip);
285 ip->dst_addr = odp_cpu_to_be_32(entry->tun_dst_ip);
286 } else {
287 ip->proto = ODPH_IPPROTO_ICMPV4;
288 ip->src_addr = odp_cpu_to_be_32(stream->src_ip);
289 ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip);
290 }
291
292 /* AH (if specified) */
293 if (entry && (entry == stream->input.entry) &&
294 (ODP_AUTH_ALG_NULL != entry->ah.alg)) {
295 if (entry->ah.alg != ODP_AUTH_ALG_MD5_HMAC &&
296 entry->ah.alg != ODP_AUTH_ALG_SHA1_HMAC &&
297 entry->ah.alg != ODP_AUTH_ALG_SHA256_HMAC)
298 abort();
299
300 ah = (odph_ahhdr_t *)data;
301 data += sizeof(*ah);
302 data += entry->ah.icv_len;
303
304 memset((char *)ah, 0, sizeof(*ah) + entry->ah.icv_len);
305 ah->ah_len = 1 + (entry->ah.icv_len / 4);
306 ah->spi = odp_cpu_to_be_32(entry->ah.spi);
307 ah->seq_no = odp_cpu_to_be_32(stream->input.ah_seq++);
308 }
309
310 /* ESP (if specified) */
311 if (entry && (entry == stream->input.entry) &&
312 (ODP_CIPHER_ALG_NULL != entry->esp.alg)) {
313 if (ODP_CIPHER_ALG_3DES_CBC != entry->esp.alg)
314 abort();
315
316 esp = (odph_esphdr_t *)data;
317 data += sizeof(*esp);
318 data += entry->esp.iv_len;
319
320 esp->spi = odp_cpu_to_be_32(entry->esp.spi);
321 esp->seq_no = odp_cpu_to_be_32(stream->input.esp_seq++);
322 RAND_bytes(esp->iv, 8);
323 }
324
325 /* Inner IP header in tunnel mode */
326 if (entry && (entry == stream->input.entry) &&
327 (entry->mode == IPSEC_SA_MODE_TUNNEL)) {
328 inner_ip = (odph_ipv4hdr_t *)data;
329 memset((char *)inner_ip, 0, sizeof(*inner_ip));
330 inner_ip->ver_ihl = 0x45;
331 inner_ip->tot_len = odp_cpu_to_be_16(sizeof(odph_ipv4hdr_t) +
332 sizeof(odph_icmphdr_t) +
333 sizeof(stream_pkt_hdr_t) +
334 stream->length);
335 inner_ip->proto = ODPH_IPPROTO_ICMPV4;
336 inner_ip->id = odp_cpu_to_be_16(stream->id);
337 inner_ip->ttl = 64;
338 inner_ip->tos = 0;
339 inner_ip->frag_offset = 0;
340 inner_ip->src_addr = odp_cpu_to_be_32(stream->src_ip);
341 inner_ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip);
342 inner_ip->chksum = ~odp_chksum_ones_comp16(inner_ip,
343 sizeof(*inner_ip));
344 data += sizeof(*inner_ip);
345 }
346
347 /* ICMP header so we can see it on wireshark */
348 icmp = (odph_icmphdr_t *)data;
349 data += sizeof(*icmp);
350 icmp->type = ODPH_ICMP_ECHO;
351 icmp->code = 0;
352 icmp->un.echo.id = odp_cpu_to_be_16(0x1234);
353 icmp->un.echo.sequence = odp_cpu_to_be_16(stream->created);
354
355 /* Packet payload of incrementing bytes */
356 test = (stream_pkt_hdr_t *)data;
357 data += sizeof(*test);
358 test->magic = odp_cpu_to_be_64(STREAM_MAGIC);
359 for (i = 0; i < stream->length; i++)
360 *data++ = (uint8_t)i;
361
362 /* Close ICMP */
363 icmp->chksum = 0;
364 icmp->chksum = ~odp_chksum_ones_comp16(icmp, data - (uint8_t *)icmp);
365
366 /* Close ESP if specified */
367 if (esp) {
368 int payload_len = data - (uint8_t *)icmp;
369 uint8_t *encrypt_start = (uint8_t *)icmp;
370
371 if (entry->mode == IPSEC_SA_MODE_TUNNEL) {
372 payload_len = data - (uint8_t *)inner_ip;
373 encrypt_start = (uint8_t *)inner_ip;
374 }
375
376 int encrypt_len;
377 odph_esptrl_t *esp_t;
378 DES_key_schedule ks1, ks2, ks3;
379 uint8_t iv[8];
380
381 memcpy(iv, esp->iv, sizeof(iv));
382
383 encrypt_len = ESP_ENCODE_LEN(payload_len + sizeof(*esp_t),
384 entry->esp.block_len);
385 for (int n = 0; n < encrypt_len - payload_len; n++)
386 *data++ = n + 1;
387
388 esp_t = (odph_esptrl_t *)(data) - 1;
389 esp_t->pad_len = encrypt_len - payload_len - sizeof(*esp_t);
390 esp_t->next_header = ip->proto;
391 ip->proto = ODPH_IPPROTO_ESP;
392
393 DES_set_key((DES_cblock *)&entry->esp.key.data[0], &ks1);
394 DES_set_key((DES_cblock *)&entry->esp.key.data[8], &ks2);
395 DES_set_key((DES_cblock *)&entry->esp.key.data[16], &ks3);
396
397 DES_ede3_cbc_encrypt(encrypt_start,
398 encrypt_start,
399 encrypt_len,
400 &ks1,
401 &ks2,
402 &ks3,
403 (DES_cblock *)iv,
404 1);
405 }
406
407 /* Since ESP can pad we can now fix IP length */
408 ip->tot_len = odp_cpu_to_be_16(data - (uint8_t *)ip);
409
410 /* Close AH if specified */
411 if (ah) {
412 uint8_t hash[EVP_MAX_MD_SIZE];
413 int auth_len = data - (uint8_t *)ip;
414
415 ah->next_header = ip->proto;
416 ip->proto = ODPH_IPPROTO_AH;
417
418 HMAC(stream->evp_md,
419 entry->ah.key.data,
420 entry->ah.key.length,
421 (uint8_t *)ip,
422 auth_len,
423 hash,
424 NULL);
425
426 memcpy(ah->icv, hash, entry->ah.icv_len);
427 }
428
429 /* Correct set packet length offsets */
430 odp_packet_pull_tail(pkt, max_len - (data - base));
431 odp_packet_l2_offset_set(pkt, (uint8_t *)eth - base);
432 odp_packet_l3_offset_set(pkt, (uint8_t *)ip - base);
433 odp_packet_l4_offset_set(pkt, ((uint8_t *)ip - base) + sizeof(*ip));
434
435 /* Now fill in final IP header fields */
436 ip->ttl = 64;
437 ip->tos = 0;
438 ip->frag_offset = 0;
439 ip->chksum = 0;
440 odph_ipv4_csum_update(pkt);
441 return pkt;
442}
443
444odp_bool_t verify_ipv4_packet(stream_db_entry_t *stream,
445 odp_packet_t pkt)
446{
447 ipsec_cache_entry_t *entry = NULL;
448 uint8_t *data;
449 odph_ipv4hdr_t *ip;
450 odph_ahhdr_t *ah = NULL;
451 odph_esphdr_t *esp = NULL;
452 int hdr_len;
453 odph_icmphdr_t *icmp;
454 stream_pkt_hdr_t *test;
455 uint32_t src_ip, dst_ip;
456
457 if (stream->input.entry)
458 entry = stream->input.entry;
459 else if (stream->output.entry)
460 entry = stream->output.entry;
461
462 /* Basic IPv4 verify (add checksum verification) */
463 data = odp_packet_l3_ptr(pkt, NULL);
464 ip = (odph_ipv4hdr_t *)data;
465 data += sizeof(*ip);
466 if (0x45 != ip->ver_ihl)
467 return FALSE;
468
469 src_ip = odp_be_to_cpu_32(ip->src_addr);
470 dst_ip = odp_be_to_cpu_32(ip->dst_addr);
471 if ((stream->src_ip != src_ip) && stream->output.entry &&
472 (stream->output.entry->tun_src_ip != src_ip))
473 return FALSE;
474 if ((stream->dst_ip != dst_ip) && stream->output.entry &&
475 (stream->output.entry->tun_dst_ip != dst_ip))
476 return FALSE;
477
478 if ((stream->src_ip != src_ip) && stream->input.entry &&
479 (stream->input.entry->tun_src_ip != src_ip))
480 return FALSE;
481 if ((stream->dst_ip != dst_ip) && stream->input.entry &&
482 (stream->input.entry->tun_dst_ip != dst_ip))
483 return FALSE;
484
485 /* Find IPsec headers if any and compare against entry */
486 hdr_len = locate_ipsec_headers(ip, &ah, &esp);
487
488 /* Verify if the packet is IPsec encapsulated or is cleartext as
489 * expected
490 */
491 if (((stream->output.entry && (!ah && !esp))) ||
492 (stream->input.entry && (ah || esp)))
493 return FALSE;
494
495 /* Cleartext packet */
496 if (!ah && !esp)
497 goto clear_packet;
498 if (ah) {
499 if (!entry)
500 return FALSE;
501 if (ODP_AUTH_ALG_NULL == entry->ah.alg)
502 return FALSE;
503 if (odp_be_to_cpu_32(ah->spi) != entry->ah.spi)
504 return FALSE;
505 if (ODP_AUTH_ALG_MD5_HMAC != entry->ah.alg &&
506 ODP_AUTH_ALG_SHA1_HMAC != entry->ah.alg &&
507 ODP_AUTH_ALG_SHA256_HMAC != entry->ah.alg)
508 abort();
509 } else {
510 if (entry && (ODP_AUTH_ALG_NULL != entry->ah.alg))
511 return FALSE;
512 }
513 if (esp) {
514 if (!entry)
515 return FALSE;
516 if (ODP_CIPHER_ALG_NULL == entry->esp.alg)
517 return FALSE;
518 if (odp_be_to_cpu_32(esp->spi) != entry->esp.spi)
519 return FALSE;
520 if (ODP_CIPHER_ALG_3DES_CBC != entry->esp.alg)
521 abort();
522 hdr_len += entry->esp.iv_len;
523 } else {
524 if (entry && (ODP_CIPHER_ALG_NULL != entry->esp.alg))
525 return FALSE;
526 }
527 data += hdr_len;
528
529 /* Verify authentication (if present) */
530 if (ah) {
531 uint8_t ip_tos;
532 uint8_t ip_ttl;
533 uint16_t ip_frag_offset;
534 uint8_t icv[entry->ah.icv_len];
535 uint8_t hash[EVP_MAX_MD_SIZE];
536
537 /* Save/clear mutable fields */
538 ip_tos = ip->tos;
539 ip_ttl = ip->ttl;
540 ip_frag_offset = odp_be_to_cpu_16(ip->frag_offset);
541 ip->tos = 0;
542 ip->ttl = 0;
543 ip->frag_offset = 0;
544 ip->chksum = 0;
545 memcpy(icv, ah->icv, entry->ah.icv_len);
546 memset(ah->icv, 0, entry->ah.icv_len);
547
548 /* Calculate HMAC and compare */
549 HMAC(stream->evp_md,
550 entry->ah.key.data,
551 entry->ah.key.length,
552 (uint8_t *)ip,
553 odp_be_to_cpu_16(ip->tot_len),
554 hash,
555 NULL);
556
557 if (0 != memcmp(icv, hash, sizeof(icv)))
558 return FALSE;
559
560 ip->proto = ah->next_header;
561 ip->tos = ip_tos;
562 ip->ttl = ip_ttl;
563 ip->frag_offset = odp_cpu_to_be_16(ip_frag_offset);
564 }
565
566 /* Decipher if present */
567 if (esp) {
568 odph_esptrl_t *esp_t;
569 DES_key_schedule ks1, ks2, ks3;
570 uint8_t iv[8];
571 int encrypt_len = ipv4_data_len(ip) - hdr_len;
572
573 memcpy(iv, esp->iv, sizeof(iv));
574
575 DES_set_key((DES_cblock *)&entry->esp.key.data[0], &ks1);
576 DES_set_key((DES_cblock *)&entry->esp.key.data[8], &ks2);
577 DES_set_key((DES_cblock *)&entry->esp.key.data[16], &ks3);
578
579 DES_ede3_cbc_encrypt((uint8_t *)data,
580 (uint8_t *)data,
581 encrypt_len,
582 &ks1,
583 &ks2,
584 &ks3,
585 (DES_cblock *)iv,
586 0);
587
588 esp_t = (odph_esptrl_t *)(data + encrypt_len) - 1;
589 ip->proto = esp_t->next_header;
590 }
591
592clear_packet:
593 /* Verify IP/ICMP packet */
594 if (entry && (entry->mode == IPSEC_SA_MODE_TUNNEL) && (ah || esp)) {
595 if (ODPH_IPV4 != ip->proto)
596 return FALSE;
597 odph_ipv4hdr_t *inner_ip = (odph_ipv4hdr_t *)data;
598
599 icmp = (odph_icmphdr_t *)(inner_ip + 1);
600 data = (uint8_t *)icmp;
601 } else {
602 if (ODPH_IPPROTO_ICMPV4 != ip->proto)
603 return FALSE;
604 icmp = (odph_icmphdr_t *)data;
605 }
606
607 /* Verify ICMP header */
608 data += sizeof(*icmp);
609 if (ODPH_ICMP_ECHO != icmp->type)
610 return FALSE;
611 if (0x1234 != odp_be_to_cpu_16(icmp->un.echo.id))
612 return FALSE;
613
614 /* Now check our packet */
615 test = (stream_pkt_hdr_t *)data;
616 if (STREAM_MAGIC != odp_be_to_cpu_64(test->magic))
617 return FALSE;
618
619 return TRUE;
620}
621
622int create_stream_db_inputs(void)
623{
624 int created = 0;
625 odp_pool_t pkt_pool;
626 odp_pool_info_t pool_info;
627 stream_db_entry_t *stream = NULL;
628 uint32_t max_len;
629
630 /* Lookup the packet pool */
631 pkt_pool = odp_pool_lookup("packet_pool");
632 if (pkt_pool == ODP_POOL_INVALID) {
633 ODPH_ERR("Error: pkt_pool not found\n");
634 return -1;
635 }
636 if (odp_pool_info(pkt_pool, &pool_info)) {
637 ODPH_ERR("Error: pool info failed\n");
638 return -1;
639 }
640
641 /* Only single segment packets are supported */
642 max_len = pool_info.params.pkt.seg_len;
643
644 /* For each stream create corresponding input packets */
645 for (stream = stream_db->list; NULL != stream; stream = stream->next) {
646 int count;
647 int ret;
648 uint8_t dmac[ODPH_ETHADDR_LEN];
649 odp_pktout_queue_t queue;
650
651 ret = odp_pktio_mac_addr(stream->input.pktio,
652 dmac, sizeof(dmac));
653 if (ret <= 0) {
654 ODPH_ERR("Error: failed during MAC address get for "
655 "%s\n", stream->input.intf);
656 continue;
657 }
658
659 ret = odp_pktout_queue(stream->input.pktio, &queue, 1);
660 if (ret < 1) {
661 ODPH_ERR("Error: failed to get outqueue for %s\n",
662 stream->input.intf);
663 continue;
664 }
665
666 for (count = stream->count; count > 0; count--) {
667 odp_packet_t pkt;
668
669 pkt = create_ipv4_packet(stream, dmac, pkt_pool, max_len);
670 if (ODP_PACKET_INVALID == pkt) {
671 ODPH_ERR("Error: packet buffers exhausted\n");
672 break;
673 }
674 stream->created++;
675 if (odp_pktout_send(queue, &pkt, 1) != 1) {
676 odp_packet_free(pkt);
677 ODPH_ERR("Error: queue enqueue failed\n");
678 break;
679 }
680
681 /* Count this stream when we create first packet */
682 if (1 == stream->created)
683 created++;
684 }
685 }
686 if ((stream_db->index > 0) && created == 0) {
687 ODPH_ERR("Error: failed to create any input streams\n");
688 return -1;
689 }
690
691 return created;
692}
693
694odp_bool_t verify_stream_db_outputs(void)
695{
696 odp_bool_t done = TRUE;
697 stream_db_entry_t *stream = NULL;
698 const char *env;
699
700 env = getenv("ODP_IPSEC_STREAM_VERIFY_MDEQ");
701 /* For each stream look for output packets */
702 for (stream = stream_db->list; NULL != stream; stream = stream->next) {
703 int idx;
704 int count;
705 int ret;
706 odp_queue_t queue;
707 odp_event_t ev_tbl[LOOP_DEQ_COUNT];
708
709 ret = odp_pktin_event_queue(stream->output.pktio, &queue, 1);
710 if (ret < 1) {
711 ODPH_ERR("Error: failed to get inqueue for %s\n",
712 stream->output.intf);
713 continue;
714 }
715
716 for (;;) {
717 if (env) {
718 count = odp_queue_deq_multi(queue,
719 ev_tbl,
720 LOOP_DEQ_COUNT);
721 } else {
722 ev_tbl[0] = odp_queue_deq(queue);
723 count = (ev_tbl[0] != ODP_EVENT_INVALID) ?
724 1 : 0;
725 }
726 if (!count)
727 break;
728 for (idx = 0; idx < count; idx++) {
729 odp_bool_t good;
730 odp_packet_t pkt;
731
732 pkt = odp_packet_from_event(ev_tbl[idx]);
733
734 good = verify_ipv4_packet(stream, pkt);
735 if (good)
736 stream->verified++;
737 odp_packet_free(pkt);
738 }
739 }
740
741 printf("Stream %d %d\n", stream->created, stream->verified);
742
743 if (stream->created != stream->verified)
744 done = FALSE;
745 }
746 return done;
747}
#define ODP_PACKED
Defines type/struct to be packed.
odp_u16be_t odp_cpu_to_be_16(uint16_t cpu16)
Convert cpu native uint16_t to 16bit big endian.
odp_u64be_t odp_cpu_to_be_64(uint64_t cpu64)
Convert cpu native uint64_t to 64bit big endian.
uint16_t odp_be_to_cpu_16(odp_u16be_t be16)
Convert 16bit big endian to cpu native uint16_t.
uint64_t odp_be_to_cpu_64(odp_u64be_t be64)
Convert 64bit big endian to cpu native uint64_t.
odp_u32be_t odp_cpu_to_be_32(uint32_t cpu32)
Convert cpu native uint32_t to 32bit big endian.
uint64_t odp_u64be_t
unsigned 64bit big endian
uint32_t odp_be_to_cpu_32(odp_u32be_t be32)
Convert 32bit big endian to cpu native uint32_t.
odp_auth_alg_t
Crypto API authentication algorithm.
@ ODP_CIPHER_ALG_3DES_CBC
Triple DES with cipher block chaining.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
@ ODP_AUTH_ALG_MD5_HMAC
HMAC-MD5.
@ ODP_AUTH_ALG_SHA1_HMAC
HMAC-SHA-1.
@ ODP_AUTH_ALG_SHA256_HMAC
HMAC-SHA-256.
#define ODP_EVENT_INVALID
Invalid event.
int odp_pktio_mac_addr(odp_pktio_t pktio, void *mac_addr, int size)
Get the default MAC address of a packet IO interface.
odp_pktio_t odp_pktio_lookup(const char *name)
Return a packet IO handle for an already open device.
int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
Direct packet output queues.
int odp_pktin_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
Event queues for packet input.
int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], int num)
Send packets directly to an interface output queue.
int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
Set layer 3 start offset.
void * odp_packet_data(odp_packet_t pkt)
Packet data pointer.
int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
Set layer 4 start offset.
void odp_packet_has_eth_set(odp_packet_t pkt, int val)
Set flag for Ethernet header.
odp_packet_t odp_packet_alloc(odp_pool_t pool, uint32_t len)
Allocate a packet from a packet pool.
int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
Set layer 2 start offset.
void * odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
Layer 3 start pointer.
odp_packet_t odp_packet_from_event(odp_event_t ev)
Get packet handle from event.
void odp_packet_free(odp_packet_t pkt)
Free packet.
#define ODP_PACKET_INVALID
Invalid packet.
void * odp_packet_pull_tail(odp_packet_t pkt, uint32_t len)
Pull in packet tail.
void odp_packet_has_ipv4_set(odp_packet_t pkt, int val)
Set flag for IPv4.
odp_pool_t odp_pool_lookup(const char *name)
Find a pool by name.
int odp_pool_info(odp_pool_t pool, odp_pool_info_t *info)
Retrieve information about a pool.
#define ODP_POOL_INVALID
Invalid pool.
odp_event_t odp_queue_deq(odp_queue_t queue)
Dequeue an event from a queue.
int odp_queue_deq_multi(odp_queue_t queue, odp_event_t events[], int num)
Dequeue multiple events from a queue.
odp_shm_t odp_shm_lookup(const char *name)
Lookup for a block of shared memory.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
#define ODP_SHM_INVALID
Invalid shared memory block.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
bool odp_bool_t
Boolean type.
The OpenDataPlane API.
Pool information struct Used to get information about a pool.
odp_pool_param_t params
Copy of pool parameters.
struct odp_pool_param_t::@139 pkt
Parameters for packet pools.
uint32_t seg_len
Minimum number of packet data bytes that can be stored in the first segment of a newly allocated pack...