test/security: add ESN and anti-replay for inline IPsec
[dpdk.git] / app / test / test_security_inline_proto.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2022 Marvell.
3  */
4
5
6 #include <stdio.h>
7 #include <inttypes.h>
8
9 #include <rte_ethdev.h>
10 #include <rte_malloc.h>
11 #include <rte_security.h>
12
13 #include "test.h"
14 #include "test_security_inline_proto_vectors.h"
15
16 #ifdef RTE_EXEC_ENV_WINDOWS
17 static int
18 test_inline_ipsec(void)
19 {
20         printf("Inline ipsec not supported on Windows, skipping test\n");
21         return TEST_SKIPPED;
22 }
23
24 #else
25
26 #define NB_ETHPORTS_USED                1
27 #define MEMPOOL_CACHE_SIZE              32
28 #define MAX_PKT_BURST                   32
29 #define RTE_TEST_RX_DESC_DEFAULT        1024
30 #define RTE_TEST_TX_DESC_DEFAULT        1024
31 #define RTE_PORT_ALL            (~(uint16_t)0x0)
32
33 #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
34 #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */
35 #define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */
36
37 #define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */
38 #define TX_HTHRESH 0  /**< Default values of TX host threshold reg. */
39 #define TX_WTHRESH 0  /**< Default values of TX write-back threshold reg. */
40
41 #define MAX_TRAFFIC_BURST               2048
42 #define NB_MBUF                         10240
43
44 #define ENCAP_DECAP_BURST_SZ            33
45 #define APP_REASS_TIMEOUT               10
46
47 extern struct ipsec_test_data pkt_aes_128_gcm;
48 extern struct ipsec_test_data pkt_aes_192_gcm;
49 extern struct ipsec_test_data pkt_aes_256_gcm;
50 extern struct ipsec_test_data pkt_aes_128_gcm_frag;
51 extern struct ipsec_test_data pkt_aes_128_cbc_null;
52 extern struct ipsec_test_data pkt_null_aes_xcbc;
53 extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha384;
54 extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha512;
55
56 static struct rte_mempool *mbufpool;
57 static struct rte_mempool *sess_pool;
58 static struct rte_mempool *sess_priv_pool;
59 /* ethernet addresses of ports */
60 static struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];
61
62 static struct rte_eth_conf port_conf = {
63         .rxmode = {
64                 .mq_mode = RTE_ETH_MQ_RX_NONE,
65                 .split_hdr_size = 0,
66                 .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM |
67                             RTE_ETH_RX_OFFLOAD_SECURITY,
68         },
69         .txmode = {
70                 .mq_mode = RTE_ETH_MQ_TX_NONE,
71                 .offloads = RTE_ETH_TX_OFFLOAD_SECURITY |
72                             RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE,
73         },
74         .lpbk_mode = 1,  /* enable loopback */
75 };
76
77 static struct rte_eth_rxconf rx_conf = {
78         .rx_thresh = {
79                 .pthresh = RX_PTHRESH,
80                 .hthresh = RX_HTHRESH,
81                 .wthresh = RX_WTHRESH,
82         },
83         .rx_free_thresh = 32,
84 };
85
86 static struct rte_eth_txconf tx_conf = {
87         .tx_thresh = {
88                 .pthresh = TX_PTHRESH,
89                 .hthresh = TX_HTHRESH,
90                 .wthresh = TX_WTHRESH,
91         },
92         .tx_free_thresh = 32, /* Use PMD default values */
93         .tx_rs_thresh = 32, /* Use PMD default values */
94 };
95
96 uint16_t port_id;
97
98 static uint64_t link_mbps;
99
100 static int ip_reassembly_dynfield_offset = -1;
101
102 static struct rte_flow *default_flow[RTE_MAX_ETHPORTS];
103
104 /* Create Inline IPsec session */
105 static int
106 create_inline_ipsec_session(struct ipsec_test_data *sa, uint16_t portid,
107                 struct rte_security_session **sess, struct rte_security_ctx **ctx,
108                 uint32_t *ol_flags, const struct ipsec_test_flags *flags,
109                 struct rte_security_session_conf *sess_conf)
110 {
111         uint16_t src_v6[8] = {0x2607, 0xf8b0, 0x400c, 0x0c03, 0x0000, 0x0000,
112                                 0x0000, 0x001a};
113         uint16_t dst_v6[8] = {0x2001, 0x0470, 0xe5bf, 0xdead, 0x4957, 0x2174,
114                                 0xe82c, 0x4887};
115         uint32_t src_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 2));
116         uint32_t dst_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 1));
117         struct rte_security_capability_idx sec_cap_idx;
118         const struct rte_security_capability *sec_cap;
119         enum rte_security_ipsec_sa_direction dir;
120         struct rte_security_ctx *sec_ctx;
121         uint32_t verify;
122
123         sess_conf->action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
124         sess_conf->protocol = RTE_SECURITY_PROTOCOL_IPSEC;
125         sess_conf->ipsec = sa->ipsec_xform;
126
127         dir = sa->ipsec_xform.direction;
128         verify = flags->tunnel_hdr_verify;
129
130         if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && verify) {
131                 if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR)
132                         src_v4 += 1;
133                 else if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR)
134                         dst_v4 += 1;
135         }
136
137         if (sa->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
138                 if (sa->ipsec_xform.tunnel.type ==
139                                 RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
140                         memcpy(&sess_conf->ipsec.tunnel.ipv4.src_ip, &src_v4,
141                                         sizeof(src_v4));
142                         memcpy(&sess_conf->ipsec.tunnel.ipv4.dst_ip, &dst_v4,
143                                         sizeof(dst_v4));
144
145                         if (flags->df == TEST_IPSEC_SET_DF_0_INNER_1)
146                                 sess_conf->ipsec.tunnel.ipv4.df = 0;
147
148                         if (flags->df == TEST_IPSEC_SET_DF_1_INNER_0)
149                                 sess_conf->ipsec.tunnel.ipv4.df = 1;
150
151                         if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
152                                 sess_conf->ipsec.tunnel.ipv4.dscp = 0;
153
154                         if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0)
155                                 sess_conf->ipsec.tunnel.ipv4.dscp =
156                                                 TEST_IPSEC_DSCP_VAL;
157                 } else {
158                         if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
159                                 sess_conf->ipsec.tunnel.ipv6.dscp = 0;
160
161                         if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0)
162                                 sess_conf->ipsec.tunnel.ipv6.dscp =
163                                                 TEST_IPSEC_DSCP_VAL;
164
165                         memcpy(&sess_conf->ipsec.tunnel.ipv6.src_addr, &src_v6,
166                                         sizeof(src_v6));
167                         memcpy(&sess_conf->ipsec.tunnel.ipv6.dst_addr, &dst_v6,
168                                         sizeof(dst_v6));
169                 }
170         }
171
172         /* Save SA as userdata for the security session. When
173          * the packet is received, this userdata will be
174          * retrieved using the metadata from the packet.
175          *
176          * The PMD is expected to set similar metadata for other
177          * operations, like rte_eth_event, which are tied to
178          * security session. In such cases, the userdata could
179          * be obtained to uniquely identify the security
180          * parameters denoted.
181          */
182
183         sess_conf->userdata = (void *) sa;
184
185         sec_ctx = (struct rte_security_ctx *)rte_eth_dev_get_sec_ctx(portid);
186         if (sec_ctx == NULL) {
187                 printf("Ethernet device doesn't support security features.\n");
188                 return TEST_SKIPPED;
189         }
190
191         sec_cap_idx.action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
192         sec_cap_idx.protocol = RTE_SECURITY_PROTOCOL_IPSEC;
193         sec_cap_idx.ipsec.proto = sess_conf->ipsec.proto;
194         sec_cap_idx.ipsec.mode = sess_conf->ipsec.mode;
195         sec_cap_idx.ipsec.direction = sess_conf->ipsec.direction;
196         sec_cap = rte_security_capability_get(sec_ctx, &sec_cap_idx);
197         if (sec_cap == NULL) {
198                 printf("No capabilities registered\n");
199                 return TEST_SKIPPED;
200         }
201
202         if (sa->aead || sa->aes_gmac)
203                 memcpy(&sess_conf->ipsec.salt, sa->salt.data,
204                         RTE_MIN(sizeof(sess_conf->ipsec.salt), sa->salt.len));
205
206         /* Copy cipher session parameters */
207         if (sa->aead) {
208                 rte_memcpy(sess_conf->crypto_xform, &sa->xform.aead,
209                                 sizeof(struct rte_crypto_sym_xform));
210                 sess_conf->crypto_xform->aead.key.data = sa->key.data;
211                 /* Verify crypto capabilities */
212                 if (test_ipsec_crypto_caps_aead_verify(sec_cap,
213                                         sess_conf->crypto_xform) != 0) {
214                         RTE_LOG(INFO, USER1,
215                                 "Crypto capabilities not supported\n");
216                         return TEST_SKIPPED;
217                 }
218         } else {
219                 if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
220                         rte_memcpy(&sess_conf->crypto_xform->cipher,
221                                         &sa->xform.chain.cipher.cipher,
222                                         sizeof(struct rte_crypto_cipher_xform));
223
224                         rte_memcpy(&sess_conf->crypto_xform->next->auth,
225                                         &sa->xform.chain.auth.auth,
226                                         sizeof(struct rte_crypto_auth_xform));
227                         sess_conf->crypto_xform->cipher.key.data =
228                                                         sa->key.data;
229                         sess_conf->crypto_xform->next->auth.key.data =
230                                                         sa->auth_key.data;
231                         /* Verify crypto capabilities */
232                         if (test_ipsec_crypto_caps_cipher_verify(sec_cap,
233                                         sess_conf->crypto_xform) != 0) {
234                                 RTE_LOG(INFO, USER1,
235                                         "Cipher crypto capabilities not supported\n");
236                                 return TEST_SKIPPED;
237                         }
238
239                         if (test_ipsec_crypto_caps_auth_verify(sec_cap,
240                                         sess_conf->crypto_xform->next) != 0) {
241                                 RTE_LOG(INFO, USER1,
242                                         "Auth crypto capabilities not supported\n");
243                                 return TEST_SKIPPED;
244                         }
245                 } else {
246                         rte_memcpy(&sess_conf->crypto_xform->next->cipher,
247                                         &sa->xform.chain.cipher.cipher,
248                                         sizeof(struct rte_crypto_cipher_xform));
249                         rte_memcpy(&sess_conf->crypto_xform->auth,
250                                         &sa->xform.chain.auth.auth,
251                                         sizeof(struct rte_crypto_auth_xform));
252                         sess_conf->crypto_xform->auth.key.data =
253                                                         sa->auth_key.data;
254                         sess_conf->crypto_xform->next->cipher.key.data =
255                                                         sa->key.data;
256
257                         /* Verify crypto capabilities */
258                         if (test_ipsec_crypto_caps_cipher_verify(sec_cap,
259                                         sess_conf->crypto_xform->next) != 0) {
260                                 RTE_LOG(INFO, USER1,
261                                         "Cipher crypto capabilities not supported\n");
262                                 return TEST_SKIPPED;
263                         }
264
265                         if (test_ipsec_crypto_caps_auth_verify(sec_cap,
266                                         sess_conf->crypto_xform) != 0) {
267                                 RTE_LOG(INFO, USER1,
268                                         "Auth crypto capabilities not supported\n");
269                                 return TEST_SKIPPED;
270                         }
271                 }
272         }
273
274         if (test_ipsec_sec_caps_verify(&sess_conf->ipsec, sec_cap, false) != 0)
275                 return TEST_SKIPPED;
276
277         if ((sa->ipsec_xform.direction ==
278                         RTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&
279                         (sa->ipsec_xform.options.iv_gen_disable == 1)) {
280                 /* Set env variable when IV generation is disabled */
281                 char arr[128];
282                 int len = 0, j = 0;
283                 int iv_len = (sa->aead || sa->aes_gmac) ? 8 : 16;
284
285                 for (; j < iv_len; j++)
286                         len += snprintf(arr+len, sizeof(arr) - len,
287                                         "0x%x, ", sa->iv.data[j]);
288                 setenv("ETH_SEC_IV_OVR", arr, 1);
289         }
290
291         *sess = rte_security_session_create(sec_ctx,
292                                 sess_conf, sess_pool, sess_priv_pool);
293         if (*sess == NULL) {
294                 printf("SEC Session init failed.\n");
295                 return TEST_FAILED;
296         }
297
298         *ol_flags = sec_cap->ol_flags;
299         *ctx = sec_ctx;
300
301         return 0;
302 }
303
304 /* Check the link status of all ports in up to 3s, and print them finally */
305 static void
306 check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
307 {
308 #define CHECK_INTERVAL 100 /* 100ms */
309 #define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */
310         uint16_t portid;
311         uint8_t count, all_ports_up, print_flag = 0;
312         struct rte_eth_link link;
313         int ret;
314         char link_status[RTE_ETH_LINK_MAX_STR_LEN];
315
316         printf("Checking link statuses...\n");
317         fflush(stdout);
318         for (count = 0; count <= MAX_CHECK_TIME; count++) {
319                 all_ports_up = 1;
320                 for (portid = 0; portid < port_num; portid++) {
321                         if ((port_mask & (1 << portid)) == 0)
322                                 continue;
323                         memset(&link, 0, sizeof(link));
324                         ret = rte_eth_link_get_nowait(portid, &link);
325                         if (ret < 0) {
326                                 all_ports_up = 0;
327                                 if (print_flag == 1)
328                                         printf("Port %u link get failed: %s\n",
329                                                 portid, rte_strerror(-ret));
330                                 continue;
331                         }
332
333                         /* print link status if flag set */
334                         if (print_flag == 1) {
335                                 if (link.link_status && link_mbps == 0)
336                                         link_mbps = link.link_speed;
337
338                                 rte_eth_link_to_str(link_status,
339                                         sizeof(link_status), &link);
340                                 printf("Port %d %s\n", portid, link_status);
341                                 continue;
342                         }
343                         /* clear all_ports_up flag if any link down */
344                         if (link.link_status == RTE_ETH_LINK_DOWN) {
345                                 all_ports_up = 0;
346                                 break;
347                         }
348                 }
349                 /* after finally printing all link status, get out */
350                 if (print_flag == 1)
351                         break;
352
353                 if (all_ports_up == 0) {
354                         fflush(stdout);
355                         rte_delay_ms(CHECK_INTERVAL);
356                 }
357
358                 /* set the print_flag if all ports up or timeout */
359                 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1))
360                         print_flag = 1;
361         }
362 }
363
364 static void
365 print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr)
366 {
367         char buf[RTE_ETHER_ADDR_FMT_SIZE];
368         rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);
369         printf("%s%s", name, buf);
370 }
371
372 static void
373 copy_buf_to_pkt_segs(const uint8_t *buf, unsigned int len,
374                      struct rte_mbuf *pkt, unsigned int offset)
375 {
376         unsigned int copied = 0;
377         unsigned int copy_len;
378         struct rte_mbuf *seg;
379         void *seg_buf;
380
381         seg = pkt;
382         while (offset >= seg->data_len) {
383                 offset -= seg->data_len;
384                 seg = seg->next;
385         }
386         copy_len = seg->data_len - offset;
387         seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset);
388         while (len > copy_len) {
389                 rte_memcpy(seg_buf, buf + copied, (size_t) copy_len);
390                 len -= copy_len;
391                 copied += copy_len;
392                 seg = seg->next;
393                 seg_buf = rte_pktmbuf_mtod(seg, void *);
394         }
395         rte_memcpy(seg_buf, buf + copied, (size_t) len);
396 }
397
398 static inline struct rte_mbuf *
399 init_packet(struct rte_mempool *mp, const uint8_t *data, unsigned int len)
400 {
401         struct rte_mbuf *pkt;
402
403         pkt = rte_pktmbuf_alloc(mp);
404         if (pkt == NULL)
405                 return NULL;
406         if (((data[0] & 0xF0) >> 4) == IPVERSION) {
407                 rte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN),
408                                 &dummy_ipv4_eth_hdr, RTE_ETHER_HDR_LEN);
409                 pkt->l3_len = sizeof(struct rte_ipv4_hdr);
410         } else {
411                 rte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN),
412                                 &dummy_ipv6_eth_hdr, RTE_ETHER_HDR_LEN);
413                 pkt->l3_len = sizeof(struct rte_ipv6_hdr);
414         }
415         pkt->l2_len = RTE_ETHER_HDR_LEN;
416
417         if (pkt->buf_len > (len + RTE_ETHER_HDR_LEN))
418                 rte_memcpy(rte_pktmbuf_append(pkt, len), data, len);
419         else
420                 copy_buf_to_pkt_segs(data, len, pkt, RTE_ETHER_HDR_LEN);
421         return pkt;
422 }
423
424 static int
425 init_mempools(unsigned int nb_mbuf)
426 {
427         struct rte_security_ctx *sec_ctx;
428         uint16_t nb_sess = 512;
429         uint32_t sess_sz;
430         char s[64];
431
432         if (mbufpool == NULL) {
433                 snprintf(s, sizeof(s), "mbuf_pool");
434                 mbufpool = rte_pktmbuf_pool_create(s, nb_mbuf,
435                                 MEMPOOL_CACHE_SIZE, 0,
436                                 RTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY);
437                 if (mbufpool == NULL) {
438                         printf("Cannot init mbuf pool\n");
439                         return TEST_FAILED;
440                 }
441                 printf("Allocated mbuf pool\n");
442         }
443
444         sec_ctx = rte_eth_dev_get_sec_ctx(port_id);
445         if (sec_ctx == NULL) {
446                 printf("Device does not support Security ctx\n");
447                 return TEST_SKIPPED;
448         }
449         sess_sz = rte_security_session_get_size(sec_ctx);
450         if (sess_pool == NULL) {
451                 snprintf(s, sizeof(s), "sess_pool");
452                 sess_pool = rte_mempool_create(s, nb_sess, sess_sz,
453                                 MEMPOOL_CACHE_SIZE, 0,
454                                 NULL, NULL, NULL, NULL,
455                                 SOCKET_ID_ANY, 0);
456                 if (sess_pool == NULL) {
457                         printf("Cannot init sess pool\n");
458                         return TEST_FAILED;
459                 }
460                 printf("Allocated sess pool\n");
461         }
462         if (sess_priv_pool == NULL) {
463                 snprintf(s, sizeof(s), "sess_priv_pool");
464                 sess_priv_pool = rte_mempool_create(s, nb_sess, sess_sz,
465                                 MEMPOOL_CACHE_SIZE, 0,
466                                 NULL, NULL, NULL, NULL,
467                                 SOCKET_ID_ANY, 0);
468                 if (sess_priv_pool == NULL) {
469                         printf("Cannot init sess_priv pool\n");
470                         return TEST_FAILED;
471                 }
472                 printf("Allocated sess_priv pool\n");
473         }
474
475         return 0;
476 }
477
478 static int
479 create_default_flow(uint16_t portid)
480 {
481         struct rte_flow_action action[2];
482         struct rte_flow_item pattern[2];
483         struct rte_flow_attr attr = {0};
484         struct rte_flow_error err;
485         struct rte_flow *flow;
486         int ret;
487
488         /* Add the default rte_flow to enable SECURITY for all ESP packets */
489
490         pattern[0].type = RTE_FLOW_ITEM_TYPE_ESP;
491         pattern[0].spec = NULL;
492         pattern[0].mask = NULL;
493         pattern[0].last = NULL;
494         pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
495
496         action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
497         action[0].conf = NULL;
498         action[1].type = RTE_FLOW_ACTION_TYPE_END;
499         action[1].conf = NULL;
500
501         attr.ingress = 1;
502
503         ret = rte_flow_validate(portid, &attr, pattern, action, &err);
504         if (ret) {
505                 printf("\nValidate flow failed, ret = %d\n", ret);
506                 return -1;
507         }
508         flow = rte_flow_create(portid, &attr, pattern, action, &err);
509         if (flow == NULL) {
510                 printf("\nDefault flow rule create failed\n");
511                 return -1;
512         }
513
514         default_flow[portid] = flow;
515
516         return 0;
517 }
518
519 static void
520 destroy_default_flow(uint16_t portid)
521 {
522         struct rte_flow_error err;
523         int ret;
524
525         if (!default_flow[portid])
526                 return;
527         ret = rte_flow_destroy(portid, default_flow[portid], &err);
528         if (ret) {
529                 printf("\nDefault flow rule destroy failed\n");
530                 return;
531         }
532         default_flow[portid] = NULL;
533 }
534
535 struct rte_mbuf **tx_pkts_burst;
536 struct rte_mbuf **rx_pkts_burst;
537
538 static int
539 compare_pkt_data(struct rte_mbuf *m, uint8_t *ref, unsigned int tot_len)
540 {
541         unsigned int len;
542         unsigned int nb_segs = m->nb_segs;
543         unsigned int matched = 0;
544         struct rte_mbuf *save = m;
545
546         while (m) {
547                 len = tot_len;
548                 if (len > m->data_len)
549                         len = m->data_len;
550                 if (len != 0) {
551                         if (memcmp(rte_pktmbuf_mtod(m, char *),
552                                         ref + matched, len)) {
553                                 printf("\n====Reassembly case failed: Data Mismatch");
554                                 rte_hexdump(stdout, "Reassembled",
555                                         rte_pktmbuf_mtod(m, char *),
556                                         len);
557                                 rte_hexdump(stdout, "reference",
558                                         ref + matched,
559                                         len);
560                                 return TEST_FAILED;
561                         }
562                 }
563                 tot_len -= len;
564                 matched += len;
565                 m = m->next;
566         }
567
568         if (tot_len) {
569                 printf("\n====Reassembly case failed: Data Missing %u",
570                        tot_len);
571                 printf("\n====nb_segs %u, tot_len %u", nb_segs, tot_len);
572                 rte_pktmbuf_dump(stderr, save, -1);
573                 return TEST_FAILED;
574         }
575         return TEST_SUCCESS;
576 }
577
578 static inline bool
579 is_ip_reassembly_incomplete(struct rte_mbuf *mbuf)
580 {
581         static uint64_t ip_reassembly_dynflag;
582         int ip_reassembly_dynflag_offset;
583
584         if (ip_reassembly_dynflag == 0) {
585                 ip_reassembly_dynflag_offset = rte_mbuf_dynflag_lookup(
586                         RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME, NULL);
587                 if (ip_reassembly_dynflag_offset < 0)
588                         return false;
589                 ip_reassembly_dynflag = RTE_BIT64(ip_reassembly_dynflag_offset);
590         }
591
592         return (mbuf->ol_flags & ip_reassembly_dynflag) != 0;
593 }
594
595 static void
596 free_mbuf(struct rte_mbuf *mbuf)
597 {
598         rte_eth_ip_reassembly_dynfield_t dynfield;
599
600         if (!mbuf)
601                 return;
602
603         if (!is_ip_reassembly_incomplete(mbuf)) {
604                 rte_pktmbuf_free(mbuf);
605         } else {
606                 if (ip_reassembly_dynfield_offset < 0)
607                         return;
608
609                 while (mbuf) {
610                         dynfield = *RTE_MBUF_DYNFIELD(mbuf,
611                                         ip_reassembly_dynfield_offset,
612                                         rte_eth_ip_reassembly_dynfield_t *);
613                         rte_pktmbuf_free(mbuf);
614                         mbuf = dynfield.next_frag;
615                 }
616         }
617 }
618
619
620 static int
621 get_and_verify_incomplete_frags(struct rte_mbuf *mbuf,
622                                 struct reassembly_vector *vector)
623 {
624         rte_eth_ip_reassembly_dynfield_t *dynfield[MAX_PKT_BURST];
625         int j = 0, ret;
626         /**
627          * IP reassembly offload is incomplete, and fragments are listed in
628          * dynfield which can be reassembled in SW.
629          */
630         printf("\nHW IP Reassembly is not complete; attempt SW IP Reassembly,"
631                 "\nMatching with original frags.");
632
633         if (ip_reassembly_dynfield_offset < 0)
634                 return -1;
635
636         printf("\ncomparing frag: %d", j);
637         /* Skip Ethernet header comparison */
638         rte_pktmbuf_adj(mbuf, RTE_ETHER_HDR_LEN);
639         ret = compare_pkt_data(mbuf, vector->frags[j]->data,
640                                 vector->frags[j]->len);
641         if (ret)
642                 return ret;
643         j++;
644         dynfield[j] = RTE_MBUF_DYNFIELD(mbuf, ip_reassembly_dynfield_offset,
645                                         rte_eth_ip_reassembly_dynfield_t *);
646         printf("\ncomparing frag: %d", j);
647         /* Skip Ethernet header comparison */
648         rte_pktmbuf_adj(dynfield[j]->next_frag, RTE_ETHER_HDR_LEN);
649         ret = compare_pkt_data(dynfield[j]->next_frag, vector->frags[j]->data,
650                         vector->frags[j]->len);
651         if (ret)
652                 return ret;
653
654         while ((dynfield[j]->nb_frags > 1) &&
655                         is_ip_reassembly_incomplete(dynfield[j]->next_frag)) {
656                 j++;
657                 dynfield[j] = RTE_MBUF_DYNFIELD(dynfield[j-1]->next_frag,
658                                         ip_reassembly_dynfield_offset,
659                                         rte_eth_ip_reassembly_dynfield_t *);
660                 printf("\ncomparing frag: %d", j);
661                 /* Skip Ethernet header comparison */
662                 rte_pktmbuf_adj(dynfield[j]->next_frag, RTE_ETHER_HDR_LEN);
663                 ret = compare_pkt_data(dynfield[j]->next_frag,
664                                 vector->frags[j]->data, vector->frags[j]->len);
665                 if (ret)
666                         return ret;
667         }
668         return ret;
669 }
670
671 static int
672 test_ipsec_with_reassembly(struct reassembly_vector *vector,
673                 const struct ipsec_test_flags *flags)
674 {
675         struct rte_security_session *out_ses[ENCAP_DECAP_BURST_SZ] = {0};
676         struct rte_security_session *in_ses[ENCAP_DECAP_BURST_SZ] = {0};
677         struct rte_eth_ip_reassembly_params reass_capa = {0};
678         struct rte_security_session_conf sess_conf_out = {0};
679         struct rte_security_session_conf sess_conf_in = {0};
680         unsigned int nb_tx, burst_sz, nb_sent = 0;
681         struct rte_crypto_sym_xform cipher_out = {0};
682         struct rte_crypto_sym_xform auth_out = {0};
683         struct rte_crypto_sym_xform aead_out = {0};
684         struct rte_crypto_sym_xform cipher_in = {0};
685         struct rte_crypto_sym_xform auth_in = {0};
686         struct rte_crypto_sym_xform aead_in = {0};
687         struct ipsec_test_data sa_data;
688         struct rte_security_ctx *ctx;
689         unsigned int i, nb_rx = 0, j;
690         uint32_t ol_flags;
691         int ret = 0;
692
693         burst_sz = vector->burst ? ENCAP_DECAP_BURST_SZ : 1;
694         nb_tx = vector->nb_frags * burst_sz;
695
696         rte_eth_dev_stop(port_id);
697         if (ret != 0) {
698                 printf("rte_eth_dev_stop: err=%s, port=%u\n",
699                                rte_strerror(-ret), port_id);
700                 return ret;
701         }
702         rte_eth_ip_reassembly_capability_get(port_id, &reass_capa);
703         if (reass_capa.max_frags < vector->nb_frags)
704                 return TEST_SKIPPED;
705         if (reass_capa.timeout_ms > APP_REASS_TIMEOUT) {
706                 reass_capa.timeout_ms = APP_REASS_TIMEOUT;
707                 rte_eth_ip_reassembly_conf_set(port_id, &reass_capa);
708         }
709
710         ret = rte_eth_dev_start(port_id);
711         if (ret < 0) {
712                 printf("rte_eth_dev_start: err=%d, port=%d\n",
713                         ret, port_id);
714                 return ret;
715         }
716
717         memset(tx_pkts_burst, 0, sizeof(tx_pkts_burst[0]) * nb_tx);
718         memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_tx);
719
720         for (i = 0; i < nb_tx; i += vector->nb_frags) {
721                 for (j = 0; j < vector->nb_frags; j++) {
722                         tx_pkts_burst[i+j] = init_packet(mbufpool,
723                                                 vector->frags[j]->data,
724                                                 vector->frags[j]->len);
725                         if (tx_pkts_burst[i+j] == NULL) {
726                                 ret = -1;
727                                 printf("\n packed init failed\n");
728                                 goto out;
729                         }
730                 }
731         }
732
733         for (i = 0; i < burst_sz; i++) {
734                 memcpy(&sa_data, vector->sa_data,
735                                 sizeof(struct ipsec_test_data));
736                 /* Update SPI for every new SA */
737                 sa_data.ipsec_xform.spi += i;
738                 sa_data.ipsec_xform.direction =
739                                         RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
740                 if (sa_data.aead) {
741                         sess_conf_out.crypto_xform = &aead_out;
742                 } else {
743                         sess_conf_out.crypto_xform = &cipher_out;
744                         sess_conf_out.crypto_xform->next = &auth_out;
745                 }
746
747                 /* Create Inline IPsec outbound session. */
748                 ret = create_inline_ipsec_session(&sa_data, port_id,
749                                 &out_ses[i], &ctx, &ol_flags, flags,
750                                 &sess_conf_out);
751                 if (ret) {
752                         printf("\nInline outbound session create failed\n");
753                         goto out;
754                 }
755         }
756
757         j = 0;
758         for (i = 0; i < nb_tx; i++) {
759                 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
760                         rte_security_set_pkt_metadata(ctx,
761                                 out_ses[j], tx_pkts_burst[i], NULL);
762                 tx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
763
764                 /* Move to next SA after nb_frags */
765                 if ((i + 1) % vector->nb_frags == 0)
766                         j++;
767         }
768
769         for (i = 0; i < burst_sz; i++) {
770                 memcpy(&sa_data, vector->sa_data,
771                                 sizeof(struct ipsec_test_data));
772                 /* Update SPI for every new SA */
773                 sa_data.ipsec_xform.spi += i;
774                 sa_data.ipsec_xform.direction =
775                                         RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
776
777                 if (sa_data.aead) {
778                         sess_conf_in.crypto_xform = &aead_in;
779                 } else {
780                         sess_conf_in.crypto_xform = &auth_in;
781                         sess_conf_in.crypto_xform->next = &cipher_in;
782                 }
783                 /* Create Inline IPsec inbound session. */
784                 ret = create_inline_ipsec_session(&sa_data, port_id, &in_ses[i],
785                                 &ctx, &ol_flags, flags, &sess_conf_in);
786                 if (ret) {
787                         printf("\nInline inbound session create failed\n");
788                         goto out;
789                 }
790         }
791
792         /* Retrieve reassembly dynfield offset if available */
793         if (ip_reassembly_dynfield_offset < 0 && vector->nb_frags > 1)
794                 ip_reassembly_dynfield_offset = rte_mbuf_dynfield_lookup(
795                                 RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME, NULL);
796
797
798         ret = create_default_flow(port_id);
799         if (ret)
800                 goto out;
801
802         nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_tx);
803         if (nb_sent != nb_tx) {
804                 ret = -1;
805                 printf("\nFailed to tx %u pkts", nb_tx);
806                 goto out;
807         }
808
809         rte_delay_ms(1);
810
811         /* Retry few times before giving up */
812         nb_rx = 0;
813         j = 0;
814         do {
815                 nb_rx += rte_eth_rx_burst(port_id, 0, &rx_pkts_burst[nb_rx],
816                                           nb_tx - nb_rx);
817                 j++;
818                 if (nb_rx >= nb_tx)
819                         break;
820                 rte_delay_ms(1);
821         } while (j < 5 || !nb_rx);
822
823         /* Check for minimum number of Rx packets expected */
824         if ((vector->nb_frags == 1 && nb_rx != nb_tx) ||
825             (vector->nb_frags > 1 && nb_rx < burst_sz)) {
826                 printf("\nreceived less Rx pkts(%u) pkts\n", nb_rx);
827                 ret = TEST_FAILED;
828                 goto out;
829         }
830
831         for (i = 0; i < nb_rx; i++) {
832                 if (vector->nb_frags > 1 &&
833                     is_ip_reassembly_incomplete(rx_pkts_burst[i])) {
834                         ret = get_and_verify_incomplete_frags(rx_pkts_burst[i],
835                                                               vector);
836                         if (ret != TEST_SUCCESS)
837                                 break;
838                         continue;
839                 }
840
841                 if (rx_pkts_burst[i]->ol_flags &
842                     RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED ||
843                     !(rx_pkts_burst[i]->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD)) {
844                         printf("\nsecurity offload failed\n");
845                         ret = TEST_FAILED;
846                         break;
847                 }
848
849                 if (vector->full_pkt->len + RTE_ETHER_HDR_LEN !=
850                                 rx_pkts_burst[i]->pkt_len) {
851                         printf("\nreassembled/decrypted packet length mismatch\n");
852                         ret = TEST_FAILED;
853                         break;
854                 }
855                 rte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN);
856                 ret = compare_pkt_data(rx_pkts_burst[i],
857                                        vector->full_pkt->data,
858                                        vector->full_pkt->len);
859                 if (ret != TEST_SUCCESS)
860                         break;
861         }
862
863 out:
864         destroy_default_flow(port_id);
865
866         /* Clear session data. */
867         for (i = 0; i < burst_sz; i++) {
868                 if (out_ses[i])
869                         rte_security_session_destroy(ctx, out_ses[i]);
870                 if (in_ses[i])
871                         rte_security_session_destroy(ctx, in_ses[i]);
872         }
873
874         for (i = nb_sent; i < nb_tx; i++)
875                 free_mbuf(tx_pkts_burst[i]);
876         for (i = 0; i < nb_rx; i++)
877                 free_mbuf(rx_pkts_burst[i]);
878         return ret;
879 }
880
881 static int
882 test_ipsec_inline_proto_process(struct ipsec_test_data *td,
883                 struct ipsec_test_data *res_d,
884                 int nb_pkts,
885                 bool silent,
886                 const struct ipsec_test_flags *flags)
887 {
888         struct rte_security_session_conf sess_conf = {0};
889         struct rte_crypto_sym_xform cipher = {0};
890         struct rte_crypto_sym_xform auth = {0};
891         struct rte_crypto_sym_xform aead = {0};
892         struct rte_security_session *ses;
893         struct rte_security_ctx *ctx;
894         int nb_rx = 0, nb_sent;
895         uint32_t ol_flags;
896         int i, j = 0, ret;
897
898         memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_pkts);
899
900         if (td->aead) {
901                 sess_conf.crypto_xform = &aead;
902         } else {
903                 if (td->ipsec_xform.direction ==
904                                 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
905                         sess_conf.crypto_xform = &cipher;
906                         sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
907                         sess_conf.crypto_xform->next = &auth;
908                         sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH;
909                 } else {
910                         sess_conf.crypto_xform = &auth;
911                         sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
912                         sess_conf.crypto_xform->next = &cipher;
913                         sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
914                 }
915         }
916
917         /* Create Inline IPsec session. */
918         ret = create_inline_ipsec_session(td, port_id, &ses, &ctx,
919                                           &ol_flags, flags, &sess_conf);
920         if (ret)
921                 return ret;
922
923         if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
924                 ret = create_default_flow(port_id);
925                 if (ret)
926                         goto out;
927         }
928         for (i = 0; i < nb_pkts; i++) {
929                 tx_pkts_burst[i] = init_packet(mbufpool, td->input_text.data,
930                                                 td->input_text.len);
931                 if (tx_pkts_burst[i] == NULL) {
932                         while (i--)
933                                 rte_pktmbuf_free(tx_pkts_burst[i]);
934                         ret = TEST_FAILED;
935                         goto out;
936                 }
937
938                 if (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkts_burst[i],
939                                         uint8_t *, RTE_ETHER_HDR_LEN), flags)) {
940                         while (i--)
941                                 rte_pktmbuf_free(tx_pkts_burst[i]);
942                         ret = TEST_FAILED;
943                         goto out;
944                 }
945
946                 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
947                         if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
948                                 rte_security_set_pkt_metadata(ctx, ses,
949                                                 tx_pkts_burst[i], NULL);
950                         tx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
951                 }
952         }
953         /* Send packet to ethdev for inline IPsec processing. */
954         nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_pkts);
955         if (nb_sent != nb_pkts) {
956                 printf("\nUnable to TX %d packets", nb_pkts);
957                 for ( ; nb_sent < nb_pkts; nb_sent++)
958                         rte_pktmbuf_free(tx_pkts_burst[nb_sent]);
959                 ret = TEST_FAILED;
960                 goto out;
961         }
962
963         rte_pause();
964
965         /* Receive back packet on loopback interface. */
966         do {
967                 rte_delay_ms(1);
968                 nb_rx += rte_eth_rx_burst(port_id, 0, &rx_pkts_burst[nb_rx],
969                                 nb_sent - nb_rx);
970                 if (nb_rx >= nb_sent)
971                         break;
972         } while (j++ < 5 || nb_rx == 0);
973
974         if (nb_rx != nb_sent) {
975                 printf("\nUnable to RX all %d packets", nb_sent);
976                 while (--nb_rx)
977                         rte_pktmbuf_free(rx_pkts_burst[nb_rx]);
978                 ret = TEST_FAILED;
979                 goto out;
980         }
981
982         for (i = 0; i < nb_rx; i++) {
983                 rte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN);
984
985                 ret = test_ipsec_post_process(rx_pkts_burst[i], td,
986                                               res_d, silent, flags);
987                 if (ret != TEST_SUCCESS) {
988                         for ( ; i < nb_rx; i++)
989                                 rte_pktmbuf_free(rx_pkts_burst[i]);
990                         goto out;
991                 }
992
993                 ret = test_ipsec_stats_verify(ctx, ses, flags,
994                                         td->ipsec_xform.direction);
995                 if (ret != TEST_SUCCESS) {
996                         for ( ; i < nb_rx; i++)
997                                 rte_pktmbuf_free(rx_pkts_burst[i]);
998                         goto out;
999                 }
1000
1001                 rte_pktmbuf_free(rx_pkts_burst[i]);
1002                 rx_pkts_burst[i] = NULL;
1003         }
1004
1005 out:
1006         if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS)
1007                 destroy_default_flow(port_id);
1008
1009         /* Destroy session so that other cases can create the session again */
1010         rte_security_session_destroy(ctx, ses);
1011         ses = NULL;
1012
1013         return ret;
1014 }
1015
1016 static int
1017 test_ipsec_inline_proto_all(const struct ipsec_test_flags *flags)
1018 {
1019         struct ipsec_test_data td_outb;
1020         struct ipsec_test_data td_inb;
1021         unsigned int i, nb_pkts = 1, pass_cnt = 0, fail_cnt = 0;
1022         int ret;
1023
1024         if (flags->iv_gen || flags->sa_expiry_pkts_soft ||
1025                         flags->sa_expiry_pkts_hard)
1026                 nb_pkts = IPSEC_TEST_PACKETS_MAX;
1027
1028         for (i = 0; i < RTE_DIM(alg_list); i++) {
1029                 test_ipsec_td_prepare(alg_list[i].param1,
1030                                       alg_list[i].param2,
1031                                       flags, &td_outb, 1);
1032
1033                 if (!td_outb.aead) {
1034                         enum rte_crypto_cipher_algorithm cipher_alg;
1035                         enum rte_crypto_auth_algorithm auth_alg;
1036
1037                         cipher_alg = td_outb.xform.chain.cipher.cipher.algo;
1038                         auth_alg = td_outb.xform.chain.auth.auth.algo;
1039
1040                         if (td_outb.aes_gmac && cipher_alg != RTE_CRYPTO_CIPHER_NULL)
1041                                 continue;
1042
1043                         /* ICV is not applicable for NULL auth */
1044                         if (flags->icv_corrupt &&
1045                             auth_alg == RTE_CRYPTO_AUTH_NULL)
1046                                 continue;
1047
1048                         /* IV is not applicable for NULL cipher */
1049                         if (flags->iv_gen &&
1050                             cipher_alg == RTE_CRYPTO_CIPHER_NULL)
1051                                 continue;
1052                 }
1053
1054                 if (flags->udp_encap)
1055                         td_outb.ipsec_xform.options.udp_encap = 1;
1056
1057                 ret = test_ipsec_inline_proto_process(&td_outb, &td_inb, nb_pkts,
1058                                                 false, flags);
1059                 if (ret == TEST_SKIPPED)
1060                         continue;
1061
1062                 if (ret == TEST_FAILED) {
1063                         printf("\n TEST FAILED");
1064                         test_ipsec_display_alg(alg_list[i].param1,
1065                                                alg_list[i].param2);
1066                         fail_cnt++;
1067                         continue;
1068                 }
1069
1070                 test_ipsec_td_update(&td_inb, &td_outb, 1, flags);
1071
1072                 ret = test_ipsec_inline_proto_process(&td_inb, NULL, nb_pkts,
1073                                                 false, flags);
1074                 if (ret == TEST_SKIPPED)
1075                         continue;
1076
1077                 if (ret == TEST_FAILED) {
1078                         printf("\n TEST FAILED");
1079                         test_ipsec_display_alg(alg_list[i].param1,
1080                                                alg_list[i].param2);
1081                         fail_cnt++;
1082                         continue;
1083                 }
1084
1085                 if (flags->display_alg)
1086                         test_ipsec_display_alg(alg_list[i].param1,
1087                                                alg_list[i].param2);
1088
1089                 pass_cnt++;
1090         }
1091
1092         printf("Tests passed: %d, failed: %d", pass_cnt, fail_cnt);
1093         if (fail_cnt > 0)
1094                 return TEST_FAILED;
1095         if (pass_cnt > 0)
1096                 return TEST_SUCCESS;
1097         else
1098                 return TEST_SKIPPED;
1099 }
1100
1101 static int
1102 test_ipsec_inline_proto_process_with_esn(struct ipsec_test_data td[],
1103                 struct ipsec_test_data res_d[],
1104                 int nb_pkts,
1105                 bool silent,
1106                 const struct ipsec_test_flags *flags)
1107 {
1108         struct rte_security_session_conf sess_conf = {0};
1109         struct ipsec_test_data *res_d_tmp = NULL;
1110         struct rte_crypto_sym_xform cipher = {0};
1111         struct rte_crypto_sym_xform auth = {0};
1112         struct rte_crypto_sym_xform aead = {0};
1113         struct rte_mbuf *rx_pkt = NULL;
1114         struct rte_mbuf *tx_pkt = NULL;
1115         int nb_rx, nb_sent;
1116         struct rte_security_session *ses;
1117         struct rte_security_ctx *ctx;
1118         uint32_t ol_flags;
1119         int i, ret;
1120
1121         if (td[0].aead) {
1122                 sess_conf.crypto_xform = &aead;
1123         } else {
1124                 if (td[0].ipsec_xform.direction ==
1125                                 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
1126                         sess_conf.crypto_xform = &cipher;
1127                         sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1128                         sess_conf.crypto_xform->next = &auth;
1129                         sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1130                 } else {
1131                         sess_conf.crypto_xform = &auth;
1132                         sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1133                         sess_conf.crypto_xform->next = &cipher;
1134                         sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1135                 }
1136         }
1137
1138         /* Create Inline IPsec session. */
1139         ret = create_inline_ipsec_session(&td[0], port_id, &ses, &ctx,
1140                                           &ol_flags, flags, &sess_conf);
1141         if (ret)
1142                 return ret;
1143
1144         if (td[0].ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
1145                 ret = create_default_flow(port_id);
1146                 if (ret)
1147                         goto out;
1148         }
1149
1150         for (i = 0; i < nb_pkts; i++) {
1151                 tx_pkt = init_packet(mbufpool, td[i].input_text.data,
1152                                         td[i].input_text.len);
1153                 if (tx_pkt == NULL) {
1154                         ret = TEST_FAILED;
1155                         goto out;
1156                 }
1157
1158                 if (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkt,
1159                                         uint8_t *, RTE_ETHER_HDR_LEN), flags)) {
1160                         ret = TEST_FAILED;
1161                         goto out;
1162                 }
1163
1164                 if (td[i].ipsec_xform.direction ==
1165                                 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
1166                         if (flags->antireplay) {
1167                                 sess_conf.ipsec.esn.value =
1168                                                 td[i].ipsec_xform.esn.value;
1169                                 ret = rte_security_session_update(ctx, ses,
1170                                                 &sess_conf);
1171                                 if (ret) {
1172                                         printf("Could not update ESN in session\n");
1173                                         rte_pktmbuf_free(tx_pkt);
1174                                         ret = TEST_SKIPPED;
1175                                         goto out;
1176                                 }
1177                         }
1178                         if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
1179                                 rte_security_set_pkt_metadata(ctx, ses,
1180                                                 tx_pkt, NULL);
1181                         tx_pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
1182                 }
1183                 /* Send packet to ethdev for inline IPsec processing. */
1184                 nb_sent = rte_eth_tx_burst(port_id, 0, &tx_pkt, 1);
1185                 if (nb_sent != 1) {
1186                         printf("\nUnable to TX packets");
1187                         rte_pktmbuf_free(tx_pkt);
1188                         ret = TEST_FAILED;
1189                         goto out;
1190                 }
1191
1192                 rte_pause();
1193
1194                 /* Receive back packet on loopback interface. */
1195                 do {
1196                         rte_delay_ms(1);
1197                         nb_rx = rte_eth_rx_burst(port_id, 0, &rx_pkt, 1);
1198                 } while (nb_rx == 0);
1199
1200                 rte_pktmbuf_adj(rx_pkt, RTE_ETHER_HDR_LEN);
1201
1202                 if (res_d != NULL)
1203                         res_d_tmp = &res_d[i];
1204
1205                 ret = test_ipsec_post_process(rx_pkt, &td[i],
1206                                               res_d_tmp, silent, flags);
1207                 if (ret != TEST_SUCCESS) {
1208                         rte_pktmbuf_free(rx_pkt);
1209                         goto out;
1210                 }
1211
1212                 ret = test_ipsec_stats_verify(ctx, ses, flags,
1213                                         td->ipsec_xform.direction);
1214                 if (ret != TEST_SUCCESS) {
1215                         rte_pktmbuf_free(rx_pkt);
1216                         goto out;
1217                 }
1218
1219                 rte_pktmbuf_free(rx_pkt);
1220                 rx_pkt = NULL;
1221                 tx_pkt = NULL;
1222         }
1223
1224 out:
1225         if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS)
1226                 destroy_default_flow(port_id);
1227
1228         /* Destroy session so that other cases can create the session again */
1229         rte_security_session_destroy(ctx, ses);
1230         ses = NULL;
1231
1232         return ret;
1233 }
1234
1235 static int
1236 ut_setup_inline_ipsec(void)
1237 {
1238         int ret;
1239
1240         /* Start device */
1241         ret = rte_eth_dev_start(port_id);
1242         if (ret < 0) {
1243                 printf("rte_eth_dev_start: err=%d, port=%d\n",
1244                         ret, port_id);
1245                 return ret;
1246         }
1247         /* always enable promiscuous */
1248         ret = rte_eth_promiscuous_enable(port_id);
1249         if (ret != 0) {
1250                 printf("rte_eth_promiscuous_enable: err=%s, port=%d\n",
1251                         rte_strerror(-ret), port_id);
1252                 return ret;
1253         }
1254
1255         check_all_ports_link_status(1, RTE_PORT_ALL);
1256
1257         return 0;
1258 }
1259
1260 static void
1261 ut_teardown_inline_ipsec(void)
1262 {
1263         struct rte_eth_ip_reassembly_params reass_conf = {0};
1264         uint16_t portid;
1265         int ret;
1266
1267         /* port tear down */
1268         RTE_ETH_FOREACH_DEV(portid) {
1269                 ret = rte_eth_dev_stop(portid);
1270                 if (ret != 0)
1271                         printf("rte_eth_dev_stop: err=%s, port=%u\n",
1272                                rte_strerror(-ret), portid);
1273
1274                 /* Clear reassembly configuration */
1275                 rte_eth_ip_reassembly_conf_set(portid, &reass_conf);
1276         }
1277 }
1278
1279 static int
1280 inline_ipsec_testsuite_setup(void)
1281 {
1282         uint16_t nb_rxd;
1283         uint16_t nb_txd;
1284         uint16_t nb_ports;
1285         int ret;
1286         uint16_t nb_rx_queue = 1, nb_tx_queue = 1;
1287
1288         printf("Start inline IPsec test.\n");
1289
1290         nb_ports = rte_eth_dev_count_avail();
1291         if (nb_ports < NB_ETHPORTS_USED) {
1292                 printf("At least %u port(s) used for test\n",
1293                        NB_ETHPORTS_USED);
1294                 return TEST_SKIPPED;
1295         }
1296
1297         ret = init_mempools(NB_MBUF);
1298         if (ret)
1299                 return ret;
1300
1301         if (tx_pkts_burst == NULL) {
1302                 tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff",
1303                                           MAX_TRAFFIC_BURST,
1304                                           sizeof(void *),
1305                                           RTE_CACHE_LINE_SIZE);
1306                 if (!tx_pkts_burst)
1307                         return TEST_FAILED;
1308
1309                 rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff",
1310                                           MAX_TRAFFIC_BURST,
1311                                           sizeof(void *),
1312                                           RTE_CACHE_LINE_SIZE);
1313                 if (!rx_pkts_burst)
1314                         return TEST_FAILED;
1315         }
1316
1317         printf("Generate %d packets\n", MAX_TRAFFIC_BURST);
1318
1319         nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
1320         nb_txd = RTE_TEST_TX_DESC_DEFAULT;
1321
1322         /* configuring port 0 for the test is enough */
1323         port_id = 0;
1324         /* port configure */
1325         ret = rte_eth_dev_configure(port_id, nb_rx_queue,
1326                                     nb_tx_queue, &port_conf);
1327         if (ret < 0) {
1328                 printf("Cannot configure device: err=%d, port=%d\n",
1329                          ret, port_id);
1330                 return ret;
1331         }
1332         ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]);
1333         if (ret < 0) {
1334                 printf("Cannot get mac address: err=%d, port=%d\n",
1335                          ret, port_id);
1336                 return ret;
1337         }
1338         printf("Port %u ", port_id);
1339         print_ethaddr("Address:", &ports_eth_addr[port_id]);
1340         printf("\n");
1341
1342         /* tx queue setup */
1343         ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,
1344                                      SOCKET_ID_ANY, &tx_conf);
1345         if (ret < 0) {
1346                 printf("rte_eth_tx_queue_setup: err=%d, port=%d\n",
1347                                 ret, port_id);
1348                 return ret;
1349         }
1350         /* rx queue steup */
1351         ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY,
1352                                      &rx_conf, mbufpool);
1353         if (ret < 0) {
1354                 printf("rte_eth_rx_queue_setup: err=%d, port=%d\n",
1355                                 ret, port_id);
1356                 return ret;
1357         }
1358         test_ipsec_alg_list_populate();
1359
1360         return 0;
1361 }
1362
1363 static void
1364 inline_ipsec_testsuite_teardown(void)
1365 {
1366         uint16_t portid;
1367         int ret;
1368
1369         /* port tear down */
1370         RTE_ETH_FOREACH_DEV(portid) {
1371                 ret = rte_eth_dev_reset(portid);
1372                 if (ret != 0)
1373                         printf("rte_eth_dev_reset: err=%s, port=%u\n",
1374                                rte_strerror(-ret), port_id);
1375         }
1376 }
1377
1378 static int
1379 test_inline_ip_reassembly(const void *testdata)
1380 {
1381         struct reassembly_vector reassembly_td = {0};
1382         const struct reassembly_vector *td = testdata;
1383         struct ip_reassembly_test_packet full_pkt;
1384         struct ip_reassembly_test_packet frags[MAX_FRAGS];
1385         struct ipsec_test_flags flags = {0};
1386         int i = 0;
1387
1388         reassembly_td.sa_data = td->sa_data;
1389         reassembly_td.nb_frags = td->nb_frags;
1390         reassembly_td.burst = td->burst;
1391
1392         memcpy(&full_pkt, td->full_pkt,
1393                         sizeof(struct ip_reassembly_test_packet));
1394         reassembly_td.full_pkt = &full_pkt;
1395
1396         test_vector_payload_populate(reassembly_td.full_pkt, true);
1397         for (; i < reassembly_td.nb_frags; i++) {
1398                 memcpy(&frags[i], td->frags[i],
1399                         sizeof(struct ip_reassembly_test_packet));
1400                 reassembly_td.frags[i] = &frags[i];
1401                 test_vector_payload_populate(reassembly_td.frags[i],
1402                                 (i == 0) ? true : false);
1403         }
1404
1405         return test_ipsec_with_reassembly(&reassembly_td, &flags);
1406 }
1407
1408 static int
1409 test_ipsec_inline_proto_known_vec(const void *test_data)
1410 {
1411         struct ipsec_test_data td_outb;
1412         struct ipsec_test_flags flags;
1413
1414         memset(&flags, 0, sizeof(flags));
1415
1416         memcpy(&td_outb, test_data, sizeof(td_outb));
1417
1418         if (td_outb.aead ||
1419             td_outb.xform.chain.cipher.cipher.algo != RTE_CRYPTO_CIPHER_NULL) {
1420                 /* Disable IV gen to be able to test with known vectors */
1421                 td_outb.ipsec_xform.options.iv_gen_disable = 1;
1422         }
1423
1424         return test_ipsec_inline_proto_process(&td_outb, NULL, 1,
1425                                 false, &flags);
1426 }
1427
1428 static int
1429 test_ipsec_inline_proto_known_vec_inb(const void *test_data)
1430 {
1431         const struct ipsec_test_data *td = test_data;
1432         struct ipsec_test_flags flags;
1433         struct ipsec_test_data td_inb;
1434
1435         memset(&flags, 0, sizeof(flags));
1436
1437         if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
1438                 test_ipsec_td_in_from_out(td, &td_inb);
1439         else
1440                 memcpy(&td_inb, td, sizeof(td_inb));
1441
1442         return test_ipsec_inline_proto_process(&td_inb, NULL, 1, false, &flags);
1443 }
1444
1445 static int
1446 test_ipsec_inline_proto_display_list(const void *data __rte_unused)
1447 {
1448         struct ipsec_test_flags flags;
1449
1450         memset(&flags, 0, sizeof(flags));
1451
1452         flags.display_alg = true;
1453
1454         return test_ipsec_inline_proto_all(&flags);
1455 }
1456
1457 static int
1458 test_ipsec_inline_proto_udp_encap(const void *data __rte_unused)
1459 {
1460         struct ipsec_test_flags flags;
1461
1462         memset(&flags, 0, sizeof(flags));
1463
1464         flags.udp_encap = true;
1465
1466         return test_ipsec_inline_proto_all(&flags);
1467 }
1468
1469 static int
1470 test_ipsec_inline_proto_udp_ports_verify(const void *data __rte_unused)
1471 {
1472         struct ipsec_test_flags flags;
1473
1474         memset(&flags, 0, sizeof(flags));
1475
1476         flags.udp_encap = true;
1477         flags.udp_ports_verify = true;
1478
1479         return test_ipsec_inline_proto_all(&flags);
1480 }
1481
1482 static int
1483 test_ipsec_inline_proto_err_icv_corrupt(const void *data __rte_unused)
1484 {
1485         struct ipsec_test_flags flags;
1486
1487         memset(&flags, 0, sizeof(flags));
1488
1489         flags.icv_corrupt = true;
1490
1491         return test_ipsec_inline_proto_all(&flags);
1492 }
1493
1494 static int
1495 test_ipsec_inline_proto_tunnel_dst_addr_verify(const void *data __rte_unused)
1496 {
1497         struct ipsec_test_flags flags;
1498
1499         memset(&flags, 0, sizeof(flags));
1500
1501         flags.tunnel_hdr_verify = RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR;
1502
1503         return test_ipsec_inline_proto_all(&flags);
1504 }
1505
1506 static int
1507 test_ipsec_inline_proto_tunnel_src_dst_addr_verify(const void *data __rte_unused)
1508 {
1509         struct ipsec_test_flags flags;
1510
1511         memset(&flags, 0, sizeof(flags));
1512
1513         flags.tunnel_hdr_verify = RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR;
1514
1515         return test_ipsec_inline_proto_all(&flags);
1516 }
1517
1518 static int
1519 test_ipsec_inline_proto_inner_ip_csum(const void *data __rte_unused)
1520 {
1521         struct ipsec_test_flags flags;
1522
1523         memset(&flags, 0, sizeof(flags));
1524
1525         flags.ip_csum = true;
1526
1527         return test_ipsec_inline_proto_all(&flags);
1528 }
1529
1530 static int
1531 test_ipsec_inline_proto_inner_l4_csum(const void *data __rte_unused)
1532 {
1533         struct ipsec_test_flags flags;
1534
1535         memset(&flags, 0, sizeof(flags));
1536
1537         flags.l4_csum = true;
1538
1539         return test_ipsec_inline_proto_all(&flags);
1540 }
1541
1542 static int
1543 test_ipsec_inline_proto_tunnel_v4_in_v4(const void *data __rte_unused)
1544 {
1545         struct ipsec_test_flags flags;
1546
1547         memset(&flags, 0, sizeof(flags));
1548
1549         flags.ipv6 = false;
1550         flags.tunnel_ipv6 = false;
1551
1552         return test_ipsec_inline_proto_all(&flags);
1553 }
1554
1555 static int
1556 test_ipsec_inline_proto_tunnel_v6_in_v6(const void *data __rte_unused)
1557 {
1558         struct ipsec_test_flags flags;
1559
1560         memset(&flags, 0, sizeof(flags));
1561
1562         flags.ipv6 = true;
1563         flags.tunnel_ipv6 = true;
1564
1565         return test_ipsec_inline_proto_all(&flags);
1566 }
1567
1568 static int
1569 test_ipsec_inline_proto_tunnel_v4_in_v6(const void *data __rte_unused)
1570 {
1571         struct ipsec_test_flags flags;
1572
1573         memset(&flags, 0, sizeof(flags));
1574
1575         flags.ipv6 = false;
1576         flags.tunnel_ipv6 = true;
1577
1578         return test_ipsec_inline_proto_all(&flags);
1579 }
1580
1581 static int
1582 test_ipsec_inline_proto_tunnel_v6_in_v4(const void *data __rte_unused)
1583 {
1584         struct ipsec_test_flags flags;
1585
1586         memset(&flags, 0, sizeof(flags));
1587
1588         flags.ipv6 = true;
1589         flags.tunnel_ipv6 = false;
1590
1591         return test_ipsec_inline_proto_all(&flags);
1592 }
1593
1594 static int
1595 test_ipsec_inline_proto_transport_v4(const void *data __rte_unused)
1596 {
1597         struct ipsec_test_flags flags;
1598
1599         memset(&flags, 0, sizeof(flags));
1600
1601         flags.ipv6 = false;
1602         flags.transport = true;
1603
1604         return test_ipsec_inline_proto_all(&flags);
1605 }
1606
1607 static int
1608 test_ipsec_inline_proto_transport_l4_csum(const void *data __rte_unused)
1609 {
1610         struct ipsec_test_flags flags = {
1611                 .l4_csum = true,
1612                 .transport = true,
1613         };
1614
1615         return test_ipsec_inline_proto_all(&flags);
1616 }
1617
1618 static int
1619 test_ipsec_inline_proto_stats(const void *data __rte_unused)
1620 {
1621         struct ipsec_test_flags flags;
1622
1623         memset(&flags, 0, sizeof(flags));
1624
1625         flags.stats_success = true;
1626
1627         return test_ipsec_inline_proto_all(&flags);
1628 }
1629
1630 static int
1631 test_ipsec_inline_proto_pkt_fragment(const void *data __rte_unused)
1632 {
1633         struct ipsec_test_flags flags;
1634
1635         memset(&flags, 0, sizeof(flags));
1636
1637         flags.fragment = true;
1638
1639         return test_ipsec_inline_proto_all(&flags);
1640
1641 }
1642
1643 static int
1644 test_ipsec_inline_proto_copy_df_inner_0(const void *data __rte_unused)
1645 {
1646         struct ipsec_test_flags flags;
1647
1648         memset(&flags, 0, sizeof(flags));
1649
1650         flags.df = TEST_IPSEC_COPY_DF_INNER_0;
1651
1652         return test_ipsec_inline_proto_all(&flags);
1653 }
1654
1655 static int
1656 test_ipsec_inline_proto_copy_df_inner_1(const void *data __rte_unused)
1657 {
1658         struct ipsec_test_flags flags;
1659
1660         memset(&flags, 0, sizeof(flags));
1661
1662         flags.df = TEST_IPSEC_COPY_DF_INNER_1;
1663
1664         return test_ipsec_inline_proto_all(&flags);
1665 }
1666
1667 static int
1668 test_ipsec_inline_proto_set_df_0_inner_1(const void *data __rte_unused)
1669 {
1670         struct ipsec_test_flags flags;
1671
1672         memset(&flags, 0, sizeof(flags));
1673
1674         flags.df = TEST_IPSEC_SET_DF_0_INNER_1;
1675
1676         return test_ipsec_inline_proto_all(&flags);
1677 }
1678
1679 static int
1680 test_ipsec_inline_proto_set_df_1_inner_0(const void *data __rte_unused)
1681 {
1682         struct ipsec_test_flags flags;
1683
1684         memset(&flags, 0, sizeof(flags));
1685
1686         flags.df = TEST_IPSEC_SET_DF_1_INNER_0;
1687
1688         return test_ipsec_inline_proto_all(&flags);
1689 }
1690
1691 static int
1692 test_ipsec_inline_proto_ipv4_copy_dscp_inner_0(const void *data __rte_unused)
1693 {
1694         struct ipsec_test_flags flags;
1695
1696         memset(&flags, 0, sizeof(flags));
1697
1698         flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0;
1699
1700         return test_ipsec_inline_proto_all(&flags);
1701 }
1702
1703 static int
1704 test_ipsec_inline_proto_ipv4_copy_dscp_inner_1(const void *data __rte_unused)
1705 {
1706         struct ipsec_test_flags flags;
1707
1708         memset(&flags, 0, sizeof(flags));
1709
1710         flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1;
1711
1712         return test_ipsec_inline_proto_all(&flags);
1713 }
1714
1715 static int
1716 test_ipsec_inline_proto_ipv4_set_dscp_0_inner_1(const void *data __rte_unused)
1717 {
1718         struct ipsec_test_flags flags;
1719
1720         memset(&flags, 0, sizeof(flags));
1721
1722         flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1;
1723
1724         return test_ipsec_inline_proto_all(&flags);
1725 }
1726
1727 static int
1728 test_ipsec_inline_proto_ipv4_set_dscp_1_inner_0(const void *data __rte_unused)
1729 {
1730         struct ipsec_test_flags flags;
1731
1732         memset(&flags, 0, sizeof(flags));
1733
1734         flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0;
1735
1736         return test_ipsec_inline_proto_all(&flags);
1737 }
1738
1739 static int
1740 test_ipsec_inline_proto_ipv6_copy_dscp_inner_0(const void *data __rte_unused)
1741 {
1742         struct ipsec_test_flags flags;
1743
1744         memset(&flags, 0, sizeof(flags));
1745
1746         flags.ipv6 = true;
1747         flags.tunnel_ipv6 = true;
1748         flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0;
1749
1750         return test_ipsec_inline_proto_all(&flags);
1751 }
1752
1753 static int
1754 test_ipsec_inline_proto_ipv6_copy_dscp_inner_1(const void *data __rte_unused)
1755 {
1756         struct ipsec_test_flags flags;
1757
1758         memset(&flags, 0, sizeof(flags));
1759
1760         flags.ipv6 = true;
1761         flags.tunnel_ipv6 = true;
1762         flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1;
1763
1764         return test_ipsec_inline_proto_all(&flags);
1765 }
1766
1767 static int
1768 test_ipsec_inline_proto_ipv6_set_dscp_0_inner_1(const void *data __rte_unused)
1769 {
1770         struct ipsec_test_flags flags;
1771
1772         memset(&flags, 0, sizeof(flags));
1773
1774         flags.ipv6 = true;
1775         flags.tunnel_ipv6 = true;
1776         flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1;
1777
1778         return test_ipsec_inline_proto_all(&flags);
1779 }
1780
1781 static int
1782 test_ipsec_inline_proto_ipv6_set_dscp_1_inner_0(const void *data __rte_unused)
1783 {
1784         struct ipsec_test_flags flags;
1785
1786         memset(&flags, 0, sizeof(flags));
1787
1788         flags.ipv6 = true;
1789         flags.tunnel_ipv6 = true;
1790         flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0;
1791
1792         return test_ipsec_inline_proto_all(&flags);
1793 }
1794
1795 static int
1796 test_ipsec_inline_proto_ipv4_ttl_decrement(const void *data __rte_unused)
1797 {
1798         struct ipsec_test_flags flags = {
1799                 .dec_ttl_or_hop_limit = true
1800         };
1801
1802         return test_ipsec_inline_proto_all(&flags);
1803 }
1804
1805 static int
1806 test_ipsec_inline_proto_ipv6_hop_limit_decrement(const void *data __rte_unused)
1807 {
1808         struct ipsec_test_flags flags = {
1809                 .ipv6 = true,
1810                 .dec_ttl_or_hop_limit = true
1811         };
1812
1813         return test_ipsec_inline_proto_all(&flags);
1814 }
1815
1816 static int
1817 test_ipsec_inline_proto_iv_gen(const void *data __rte_unused)
1818 {
1819         struct ipsec_test_flags flags;
1820
1821         memset(&flags, 0, sizeof(flags));
1822
1823         flags.iv_gen = true;
1824
1825         return test_ipsec_inline_proto_all(&flags);
1826 }
1827
1828 static int
1829 test_ipsec_inline_proto_known_vec_fragmented(const void *test_data)
1830 {
1831         struct ipsec_test_data td_outb;
1832         struct ipsec_test_flags flags;
1833
1834         memset(&flags, 0, sizeof(flags));
1835         flags.fragment = true;
1836
1837         memcpy(&td_outb, test_data, sizeof(td_outb));
1838
1839         /* Disable IV gen to be able to test with known vectors */
1840         td_outb.ipsec_xform.options.iv_gen_disable = 1;
1841
1842         return test_ipsec_inline_proto_process(&td_outb, NULL, 1, false,
1843                                                 &flags);
1844 }
1845
1846 static int
1847 test_ipsec_inline_pkt_replay(const void *test_data, const uint64_t esn[],
1848                       bool replayed_pkt[], uint32_t nb_pkts, bool esn_en,
1849                       uint64_t winsz)
1850 {
1851         struct ipsec_test_data td_outb[IPSEC_TEST_PACKETS_MAX];
1852         struct ipsec_test_data td_inb[IPSEC_TEST_PACKETS_MAX];
1853         struct ipsec_test_flags flags;
1854         uint32_t i, ret = 0;
1855
1856         memset(&flags, 0, sizeof(flags));
1857         flags.antireplay = true;
1858
1859         for (i = 0; i < nb_pkts; i++) {
1860                 memcpy(&td_outb[i], test_data, sizeof(td_outb));
1861                 td_outb[i].ipsec_xform.options.iv_gen_disable = 1;
1862                 td_outb[i].ipsec_xform.replay_win_sz = winsz;
1863                 td_outb[i].ipsec_xform.options.esn = esn_en;
1864         }
1865
1866         for (i = 0; i < nb_pkts; i++)
1867                 td_outb[i].ipsec_xform.esn.value = esn[i];
1868
1869         ret = test_ipsec_inline_proto_process_with_esn(td_outb, td_inb,
1870                                 nb_pkts, true, &flags);
1871         if (ret != TEST_SUCCESS)
1872                 return ret;
1873
1874         test_ipsec_td_update(td_inb, td_outb, nb_pkts, &flags);
1875
1876         for (i = 0; i < nb_pkts; i++) {
1877                 td_inb[i].ipsec_xform.options.esn = esn_en;
1878                 /* Set antireplay flag for packets to be dropped */
1879                 td_inb[i].ar_packet = replayed_pkt[i];
1880         }
1881
1882         ret = test_ipsec_inline_proto_process_with_esn(td_inb, NULL, nb_pkts,
1883                                 true, &flags);
1884
1885         return ret;
1886 }
1887
1888 static int
1889 test_ipsec_inline_proto_pkt_antireplay(const void *test_data, uint64_t winsz)
1890 {
1891
1892         uint32_t nb_pkts = 5;
1893         bool replayed_pkt[5];
1894         uint64_t esn[5];
1895
1896         /* 1. Advance the TOP of the window to WS * 2 */
1897         esn[0] = winsz * 2;
1898         /* 2. Test sequence number within the new window(WS + 1) */
1899         esn[1] = winsz + 1;
1900         /* 3. Test sequence number less than the window BOTTOM */
1901         esn[2] = winsz;
1902         /* 4. Test sequence number in the middle of the window */
1903         esn[3] = winsz + (winsz / 2);
1904         /* 5. Test replay of the packet in the middle of the window */
1905         esn[4] = winsz + (winsz / 2);
1906
1907         replayed_pkt[0] = false;
1908         replayed_pkt[1] = false;
1909         replayed_pkt[2] = true;
1910         replayed_pkt[3] = false;
1911         replayed_pkt[4] = true;
1912
1913         return test_ipsec_inline_pkt_replay(test_data, esn, replayed_pkt,
1914                         nb_pkts, false, winsz);
1915 }
1916
1917 static int
1918 test_ipsec_inline_proto_pkt_antireplay1024(const void *test_data)
1919 {
1920         return test_ipsec_inline_proto_pkt_antireplay(test_data, 1024);
1921 }
1922
1923 static int
1924 test_ipsec_inline_proto_pkt_antireplay2048(const void *test_data)
1925 {
1926         return test_ipsec_inline_proto_pkt_antireplay(test_data, 2048);
1927 }
1928
1929 static int
1930 test_ipsec_inline_proto_pkt_antireplay4096(const void *test_data)
1931 {
1932         return test_ipsec_inline_proto_pkt_antireplay(test_data, 4096);
1933 }
1934
1935 static int
1936 test_ipsec_inline_proto_pkt_esn_antireplay(const void *test_data, uint64_t winsz)
1937 {
1938
1939         uint32_t nb_pkts = 7;
1940         bool replayed_pkt[7];
1941         uint64_t esn[7];
1942
1943         /* Set the initial sequence number */
1944         esn[0] = (uint64_t)(0xFFFFFFFF - winsz);
1945         /* 1. Advance the TOP of the window to (1<<32 + WS/2) */
1946         esn[1] = (uint64_t)((1ULL << 32) + (winsz / 2));
1947         /* 2. Test sequence number within new window (1<<32 + WS/2 + 1) */
1948         esn[2] = (uint64_t)((1ULL << 32) - (winsz / 2) + 1);
1949         /* 3. Test with sequence number within window (1<<32 - 1) */
1950         esn[3] = (uint64_t)((1ULL << 32) - 1);
1951         /* 4. Test with sequence number within window (1<<32 - 1) */
1952         esn[4] = (uint64_t)(1ULL << 32);
1953         /* 5. Test with duplicate sequence number within
1954          * new window (1<<32 - 1)
1955          */
1956         esn[5] = (uint64_t)((1ULL << 32) - 1);
1957         /* 6. Test with duplicate sequence number within new window (1<<32) */
1958         esn[6] = (uint64_t)(1ULL << 32);
1959
1960         replayed_pkt[0] = false;
1961         replayed_pkt[1] = false;
1962         replayed_pkt[2] = false;
1963         replayed_pkt[3] = false;
1964         replayed_pkt[4] = false;
1965         replayed_pkt[5] = true;
1966         replayed_pkt[6] = true;
1967
1968         return test_ipsec_inline_pkt_replay(test_data, esn, replayed_pkt, nb_pkts,
1969                                      true, winsz);
1970 }
1971
1972 static int
1973 test_ipsec_inline_proto_pkt_esn_antireplay1024(const void *test_data)
1974 {
1975         return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 1024);
1976 }
1977
1978 static int
1979 test_ipsec_inline_proto_pkt_esn_antireplay2048(const void *test_data)
1980 {
1981         return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 2048);
1982 }
1983
1984 static int
1985 test_ipsec_inline_proto_pkt_esn_antireplay4096(const void *test_data)
1986 {
1987         return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 4096);
1988 }
1989
1990
1991
1992 static struct unit_test_suite inline_ipsec_testsuite  = {
1993         .suite_name = "Inline IPsec Ethernet Device Unit Test Suite",
1994         .setup = inline_ipsec_testsuite_setup,
1995         .teardown = inline_ipsec_testsuite_teardown,
1996         .unit_test_cases = {
1997                 TEST_CASE_NAMED_WITH_DATA(
1998                         "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 128)",
1999                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2000                         test_ipsec_inline_proto_known_vec, &pkt_aes_128_gcm),
2001                 TEST_CASE_NAMED_WITH_DATA(
2002                         "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 192)",
2003                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2004                         test_ipsec_inline_proto_known_vec, &pkt_aes_192_gcm),
2005                 TEST_CASE_NAMED_WITH_DATA(
2006                         "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 256)",
2007                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2008                         test_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm),
2009                 TEST_CASE_NAMED_WITH_DATA(
2010                         "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])",
2011                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2012                         test_ipsec_inline_proto_known_vec,
2013                         &pkt_aes_128_cbc_hmac_sha256),
2014                 TEST_CASE_NAMED_WITH_DATA(
2015                         "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])",
2016                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2017                         test_ipsec_inline_proto_known_vec,
2018                         &pkt_aes_128_cbc_hmac_sha384),
2019                 TEST_CASE_NAMED_WITH_DATA(
2020                         "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])",
2021                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2022                         test_ipsec_inline_proto_known_vec,
2023                         &pkt_aes_128_cbc_hmac_sha512),
2024                 TEST_CASE_NAMED_WITH_DATA(
2025                         "Outbound known vector (ESP tunnel mode IPv6 AES-GCM 128)",
2026                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2027                         test_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm_v6),
2028                 TEST_CASE_NAMED_WITH_DATA(
2029                         "Outbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])",
2030                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2031                         test_ipsec_inline_proto_known_vec,
2032                         &pkt_aes_128_cbc_hmac_sha256_v6),
2033                 TEST_CASE_NAMED_WITH_DATA(
2034                         "Outbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])",
2035                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2036                         test_ipsec_inline_proto_known_vec,
2037                         &pkt_null_aes_xcbc),
2038
2039                 TEST_CASE_NAMED_WITH_DATA(
2040                         "Outbound fragmented packet",
2041                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2042                         test_ipsec_inline_proto_known_vec_fragmented,
2043                         &pkt_aes_128_gcm_frag),
2044
2045                 TEST_CASE_NAMED_WITH_DATA(
2046                         "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 128)",
2047                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2048                         test_ipsec_inline_proto_known_vec_inb, &pkt_aes_128_gcm),
2049                 TEST_CASE_NAMED_WITH_DATA(
2050                         "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 192)",
2051                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2052                         test_ipsec_inline_proto_known_vec_inb, &pkt_aes_192_gcm),
2053                 TEST_CASE_NAMED_WITH_DATA(
2054                         "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 256)",
2055                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2056                         test_ipsec_inline_proto_known_vec_inb, &pkt_aes_256_gcm),
2057                 TEST_CASE_NAMED_WITH_DATA(
2058                         "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128)",
2059                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2060                         test_ipsec_inline_proto_known_vec_inb, &pkt_aes_128_cbc_null),
2061                 TEST_CASE_NAMED_WITH_DATA(
2062                         "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])",
2063                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2064                         test_ipsec_inline_proto_known_vec_inb,
2065                         &pkt_aes_128_cbc_hmac_sha256),
2066                 TEST_CASE_NAMED_WITH_DATA(
2067                         "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])",
2068                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2069                         test_ipsec_inline_proto_known_vec_inb,
2070                         &pkt_aes_128_cbc_hmac_sha384),
2071                 TEST_CASE_NAMED_WITH_DATA(
2072                         "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])",
2073                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2074                         test_ipsec_inline_proto_known_vec_inb,
2075                         &pkt_aes_128_cbc_hmac_sha512),
2076                 TEST_CASE_NAMED_WITH_DATA(
2077                         "Inbound known vector (ESP tunnel mode IPv6 AES-GCM 128)",
2078                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2079                         test_ipsec_inline_proto_known_vec_inb, &pkt_aes_256_gcm_v6),
2080                 TEST_CASE_NAMED_WITH_DATA(
2081                         "Inbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])",
2082                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2083                         test_ipsec_inline_proto_known_vec_inb,
2084                         &pkt_aes_128_cbc_hmac_sha256_v6),
2085                 TEST_CASE_NAMED_WITH_DATA(
2086                         "Inbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])",
2087                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2088                         test_ipsec_inline_proto_known_vec_inb,
2089                         &pkt_null_aes_xcbc),
2090
2091                 TEST_CASE_NAMED_ST(
2092                         "Combined test alg list",
2093                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2094                         test_ipsec_inline_proto_display_list),
2095
2096                 TEST_CASE_NAMED_ST(
2097                         "UDP encapsulation",
2098                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2099                         test_ipsec_inline_proto_udp_encap),
2100                 TEST_CASE_NAMED_ST(
2101                         "UDP encapsulation ports verification test",
2102                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2103                         test_ipsec_inline_proto_udp_ports_verify),
2104                 TEST_CASE_NAMED_ST(
2105                         "Negative test: ICV corruption",
2106                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2107                         test_ipsec_inline_proto_err_icv_corrupt),
2108                 TEST_CASE_NAMED_ST(
2109                         "Tunnel dst addr verification",
2110                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2111                         test_ipsec_inline_proto_tunnel_dst_addr_verify),
2112                 TEST_CASE_NAMED_ST(
2113                         "Tunnel src and dst addr verification",
2114                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2115                         test_ipsec_inline_proto_tunnel_src_dst_addr_verify),
2116                 TEST_CASE_NAMED_ST(
2117                         "Inner IP checksum",
2118                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2119                         test_ipsec_inline_proto_inner_ip_csum),
2120                 TEST_CASE_NAMED_ST(
2121                         "Inner L4 checksum",
2122                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2123                         test_ipsec_inline_proto_inner_l4_csum),
2124                 TEST_CASE_NAMED_ST(
2125                         "Tunnel IPv4 in IPv4",
2126                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2127                         test_ipsec_inline_proto_tunnel_v4_in_v4),
2128                 TEST_CASE_NAMED_ST(
2129                         "Tunnel IPv6 in IPv6",
2130                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2131                         test_ipsec_inline_proto_tunnel_v6_in_v6),
2132                 TEST_CASE_NAMED_ST(
2133                         "Tunnel IPv4 in IPv6",
2134                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2135                         test_ipsec_inline_proto_tunnel_v4_in_v6),
2136                 TEST_CASE_NAMED_ST(
2137                         "Tunnel IPv6 in IPv4",
2138                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2139                         test_ipsec_inline_proto_tunnel_v6_in_v4),
2140                 TEST_CASE_NAMED_ST(
2141                         "Transport IPv4",
2142                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2143                         test_ipsec_inline_proto_transport_v4),
2144                 TEST_CASE_NAMED_ST(
2145                         "Transport l4 checksum",
2146                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2147                         test_ipsec_inline_proto_transport_l4_csum),
2148                 TEST_CASE_NAMED_ST(
2149                         "Statistics: success",
2150                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2151                         test_ipsec_inline_proto_stats),
2152                 TEST_CASE_NAMED_ST(
2153                         "Fragmented packet",
2154                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2155                         test_ipsec_inline_proto_pkt_fragment),
2156                 TEST_CASE_NAMED_ST(
2157                         "Tunnel header copy DF (inner 0)",
2158                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2159                         test_ipsec_inline_proto_copy_df_inner_0),
2160                 TEST_CASE_NAMED_ST(
2161                         "Tunnel header copy DF (inner 1)",
2162                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2163                         test_ipsec_inline_proto_copy_df_inner_1),
2164                 TEST_CASE_NAMED_ST(
2165                         "Tunnel header set DF 0 (inner 1)",
2166                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2167                         test_ipsec_inline_proto_set_df_0_inner_1),
2168                 TEST_CASE_NAMED_ST(
2169                         "Tunnel header set DF 1 (inner 0)",
2170                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2171                         test_ipsec_inline_proto_set_df_1_inner_0),
2172                 TEST_CASE_NAMED_ST(
2173                         "Tunnel header IPv4 copy DSCP (inner 0)",
2174                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2175                         test_ipsec_inline_proto_ipv4_copy_dscp_inner_0),
2176                 TEST_CASE_NAMED_ST(
2177                         "Tunnel header IPv4 copy DSCP (inner 1)",
2178                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2179                         test_ipsec_inline_proto_ipv4_copy_dscp_inner_1),
2180                 TEST_CASE_NAMED_ST(
2181                         "Tunnel header IPv4 set DSCP 0 (inner 1)",
2182                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2183                         test_ipsec_inline_proto_ipv4_set_dscp_0_inner_1),
2184                 TEST_CASE_NAMED_ST(
2185                         "Tunnel header IPv4 set DSCP 1 (inner 0)",
2186                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2187                         test_ipsec_inline_proto_ipv4_set_dscp_1_inner_0),
2188                 TEST_CASE_NAMED_ST(
2189                         "Tunnel header IPv6 copy DSCP (inner 0)",
2190                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2191                         test_ipsec_inline_proto_ipv6_copy_dscp_inner_0),
2192                 TEST_CASE_NAMED_ST(
2193                         "Tunnel header IPv6 copy DSCP (inner 1)",
2194                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2195                         test_ipsec_inline_proto_ipv6_copy_dscp_inner_1),
2196                 TEST_CASE_NAMED_ST(
2197                         "Tunnel header IPv6 set DSCP 0 (inner 1)",
2198                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2199                         test_ipsec_inline_proto_ipv6_set_dscp_0_inner_1),
2200                 TEST_CASE_NAMED_ST(
2201                         "Tunnel header IPv6 set DSCP 1 (inner 0)",
2202                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2203                         test_ipsec_inline_proto_ipv6_set_dscp_1_inner_0),
2204                 TEST_CASE_NAMED_ST(
2205                         "Tunnel header IPv4 decrement inner TTL",
2206                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2207                         test_ipsec_inline_proto_ipv4_ttl_decrement),
2208                 TEST_CASE_NAMED_ST(
2209                         "Tunnel header IPv6 decrement inner hop limit",
2210                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2211                         test_ipsec_inline_proto_ipv6_hop_limit_decrement),
2212                 TEST_CASE_NAMED_ST(
2213                         "IV generation",
2214                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2215                         test_ipsec_inline_proto_iv_gen),
2216
2217
2218                 TEST_CASE_NAMED_WITH_DATA(
2219                         "Antireplay with window size 1024",
2220                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2221                         test_ipsec_inline_proto_pkt_antireplay1024,
2222                         &pkt_aes_128_gcm),
2223                 TEST_CASE_NAMED_WITH_DATA(
2224                         "Antireplay with window size 2048",
2225                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2226                         test_ipsec_inline_proto_pkt_antireplay2048,
2227                         &pkt_aes_128_gcm),
2228                 TEST_CASE_NAMED_WITH_DATA(
2229                         "Antireplay with window size 4096",
2230                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2231                         test_ipsec_inline_proto_pkt_antireplay4096,
2232                         &pkt_aes_128_gcm),
2233                 TEST_CASE_NAMED_WITH_DATA(
2234                         "ESN and Antireplay with window size 1024",
2235                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2236                         test_ipsec_inline_proto_pkt_esn_antireplay1024,
2237                         &pkt_aes_128_gcm),
2238                 TEST_CASE_NAMED_WITH_DATA(
2239                         "ESN and Antireplay with window size 2048",
2240                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2241                         test_ipsec_inline_proto_pkt_esn_antireplay2048,
2242                         &pkt_aes_128_gcm),
2243                 TEST_CASE_NAMED_WITH_DATA(
2244                         "ESN and Antireplay with window size 4096",
2245                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2246                         test_ipsec_inline_proto_pkt_esn_antireplay4096,
2247                         &pkt_aes_128_gcm),
2248
2249                 TEST_CASE_NAMED_WITH_DATA(
2250                         "IPv4 Reassembly with 2 fragments",
2251                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2252                         test_inline_ip_reassembly, &ipv4_2frag_vector),
2253                 TEST_CASE_NAMED_WITH_DATA(
2254                         "IPv6 Reassembly with 2 fragments",
2255                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2256                         test_inline_ip_reassembly, &ipv6_2frag_vector),
2257                 TEST_CASE_NAMED_WITH_DATA(
2258                         "IPv4 Reassembly with 4 fragments",
2259                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2260                         test_inline_ip_reassembly, &ipv4_4frag_vector),
2261                 TEST_CASE_NAMED_WITH_DATA(
2262                         "IPv6 Reassembly with 4 fragments",
2263                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2264                         test_inline_ip_reassembly, &ipv6_4frag_vector),
2265                 TEST_CASE_NAMED_WITH_DATA(
2266                         "IPv4 Reassembly with 5 fragments",
2267                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2268                         test_inline_ip_reassembly, &ipv4_5frag_vector),
2269                 TEST_CASE_NAMED_WITH_DATA(
2270                         "IPv6 Reassembly with 5 fragments",
2271                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2272                         test_inline_ip_reassembly, &ipv6_5frag_vector),
2273                 TEST_CASE_NAMED_WITH_DATA(
2274                         "IPv4 Reassembly with incomplete fragments",
2275                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2276                         test_inline_ip_reassembly, &ipv4_incomplete_vector),
2277                 TEST_CASE_NAMED_WITH_DATA(
2278                         "IPv4 Reassembly with overlapping fragments",
2279                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2280                         test_inline_ip_reassembly, &ipv4_overlap_vector),
2281                 TEST_CASE_NAMED_WITH_DATA(
2282                         "IPv4 Reassembly with out of order fragments",
2283                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2284                         test_inline_ip_reassembly, &ipv4_out_of_order_vector),
2285                 TEST_CASE_NAMED_WITH_DATA(
2286                         "IPv4 Reassembly with burst of 4 fragments",
2287                         ut_setup_inline_ipsec, ut_teardown_inline_ipsec,
2288                         test_inline_ip_reassembly, &ipv4_4frag_burst_vector),
2289
2290                 TEST_CASES_END() /**< NULL terminate unit test array */
2291         },
2292 };
2293
2294
2295 static int
2296 test_inline_ipsec(void)
2297 {
2298         return unit_test_suite_runner(&inline_ipsec_testsuite);
2299 }
2300
2301 #endif /* !RTE_EXEC_ENV_WINDOWS */
2302
2303 REGISTER_TEST_COMMAND(inline_ipsec_autotest, test_inline_ipsec);