xref: /dpdk/app/test/test_cryptodev_security_ipsec.c (revision d02c6bfcb99a7d5a3595e89a6a05c841767904c1)
1474f1202SAnoob Joseph /* SPDX-License-Identifier: BSD-3-Clause
2474f1202SAnoob Joseph  * Copyright(C) 2021 Marvell.
3474f1202SAnoob Joseph  */
4474f1202SAnoob Joseph 
53c60274cSJie Zhou #ifndef RTE_EXEC_ENV_WINDOWS
63c60274cSJie Zhou 
7474f1202SAnoob Joseph #include <rte_common.h>
8474f1202SAnoob Joseph #include <rte_cryptodev.h>
9cd928003STejasree Kondoj #include <rte_esp.h>
10474f1202SAnoob Joseph #include <rte_ip.h>
11474f1202SAnoob Joseph #include <rte_security.h>
1283243502SArchana Muniganti #include <rte_tcp.h>
13c8234341STejasree Kondoj #include <rte_udp.h>
14474f1202SAnoob Joseph 
15474f1202SAnoob Joseph #include "test.h"
16474f1202SAnoob Joseph #include "test_cryptodev_security_ipsec.h"
17474f1202SAnoob Joseph 
18cd928003STejasree Kondoj #define IV_LEN_MAX 16
19cd928003STejasree Kondoj 
208d290523SAnoob Joseph struct crypto_param_comb alg_list[RTE_DIM(aead_list) +
218d290523SAnoob Joseph 				  (RTE_DIM(cipher_list) *
228d290523SAnoob Joseph 				   RTE_DIM(auth_list))];
238d290523SAnoob Joseph 
249fb87fbfSTejasree Kondoj static bool
259fb87fbfSTejasree Kondoj is_valid_ipv4_pkt(const struct rte_ipv4_hdr *pkt)
269fb87fbfSTejasree Kondoj {
279fb87fbfSTejasree Kondoj 	/* The IP version number must be 4 */
289fb87fbfSTejasree Kondoj 	if (((pkt->version_ihl) >> 4) != 4)
299fb87fbfSTejasree Kondoj 		return false;
309fb87fbfSTejasree Kondoj 	/*
319fb87fbfSTejasree Kondoj 	 * The IP header length field must be large enough to hold the
329fb87fbfSTejasree Kondoj 	 * minimum length legal IP datagram (20 bytes = 5 words).
339fb87fbfSTejasree Kondoj 	 */
349fb87fbfSTejasree Kondoj 	if ((pkt->version_ihl & 0xf) < 5)
359fb87fbfSTejasree Kondoj 		return false;
369fb87fbfSTejasree Kondoj 
379fb87fbfSTejasree Kondoj 	/*
389fb87fbfSTejasree Kondoj 	 * The IP total length field must be large enough to hold the IP
399fb87fbfSTejasree Kondoj 	 * datagram header, whose length is specified in the IP header length
409fb87fbfSTejasree Kondoj 	 * field.
419fb87fbfSTejasree Kondoj 	 */
429fb87fbfSTejasree Kondoj 	if (rte_cpu_to_be_16(pkt->total_length) < sizeof(struct rte_ipv4_hdr))
439fb87fbfSTejasree Kondoj 		return false;
449fb87fbfSTejasree Kondoj 
459fb87fbfSTejasree Kondoj 	return true;
469fb87fbfSTejasree Kondoj }
479fb87fbfSTejasree Kondoj 
489fb87fbfSTejasree Kondoj static bool
499fb87fbfSTejasree Kondoj is_valid_ipv6_pkt(const struct rte_ipv6_hdr *pkt)
509fb87fbfSTejasree Kondoj {
519fb87fbfSTejasree Kondoj 	/* The IP version number must be 6 */
529fb87fbfSTejasree Kondoj 	if ((rte_be_to_cpu_32((pkt->vtc_flow)) >> 28) != 6)
539fb87fbfSTejasree Kondoj 		return false;
549fb87fbfSTejasree Kondoj 
559fb87fbfSTejasree Kondoj 	return true;
569fb87fbfSTejasree Kondoj }
579fb87fbfSTejasree Kondoj 
588d290523SAnoob Joseph void
598d290523SAnoob Joseph test_ipsec_alg_list_populate(void)
608d290523SAnoob Joseph {
618d290523SAnoob Joseph 	unsigned long i, j, index = 0;
628d290523SAnoob Joseph 
638d290523SAnoob Joseph 	for (i = 0; i < RTE_DIM(aead_list); i++) {
648d290523SAnoob Joseph 		alg_list[index].param1 = &aead_list[i];
658d290523SAnoob Joseph 		alg_list[index].param2 = NULL;
668d290523SAnoob Joseph 		index++;
678d290523SAnoob Joseph 	}
688d290523SAnoob Joseph 
698d290523SAnoob Joseph 	for (i = 0; i < RTE_DIM(cipher_list); i++) {
708d290523SAnoob Joseph 		for (j = 0; j < RTE_DIM(auth_list); j++) {
718d290523SAnoob Joseph 			alg_list[index].param1 = &cipher_list[i];
728d290523SAnoob Joseph 			alg_list[index].param2 = &auth_list[j];
738d290523SAnoob Joseph 			index++;
748d290523SAnoob Joseph 		}
758d290523SAnoob Joseph 	}
768d290523SAnoob Joseph }
776622d9c9SAnoob Joseph 
78474f1202SAnoob Joseph int
79474f1202SAnoob Joseph test_ipsec_sec_caps_verify(struct rte_security_ipsec_xform *ipsec_xform,
80474f1202SAnoob Joseph 			   const struct rte_security_capability *sec_cap,
81474f1202SAnoob Joseph 			   bool silent)
82474f1202SAnoob Joseph {
83474f1202SAnoob Joseph 	/* Verify security capabilities */
84474f1202SAnoob Joseph 
85474f1202SAnoob Joseph 	if (ipsec_xform->options.esn == 1 && sec_cap->ipsec.options.esn == 0) {
86474f1202SAnoob Joseph 		if (!silent)
87474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "ESN is not supported\n");
88474f1202SAnoob Joseph 		return -ENOTSUP;
89474f1202SAnoob Joseph 	}
90474f1202SAnoob Joseph 
91474f1202SAnoob Joseph 	if (ipsec_xform->options.udp_encap == 1 &&
92474f1202SAnoob Joseph 	    sec_cap->ipsec.options.udp_encap == 0) {
93474f1202SAnoob Joseph 		if (!silent)
94474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "UDP encapsulation is not supported\n");
95474f1202SAnoob Joseph 		return -ENOTSUP;
96474f1202SAnoob Joseph 	}
97474f1202SAnoob Joseph 
989ec50a52STejasree Kondoj 	if (ipsec_xform->options.udp_ports_verify == 1 &&
999ec50a52STejasree Kondoj 	    sec_cap->ipsec.options.udp_ports_verify == 0) {
1009ec50a52STejasree Kondoj 		if (!silent)
1019ec50a52STejasree Kondoj 			RTE_LOG(INFO, USER1, "UDP encapsulation ports "
1029ec50a52STejasree Kondoj 				"verification is not supported\n");
1039ec50a52STejasree Kondoj 		return -ENOTSUP;
1049ec50a52STejasree Kondoj 	}
1059ec50a52STejasree Kondoj 
106474f1202SAnoob Joseph 	if (ipsec_xform->options.copy_dscp == 1 &&
107474f1202SAnoob Joseph 	    sec_cap->ipsec.options.copy_dscp == 0) {
108474f1202SAnoob Joseph 		if (!silent)
109474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Copy DSCP is not supported\n");
110474f1202SAnoob Joseph 		return -ENOTSUP;
111474f1202SAnoob Joseph 	}
112474f1202SAnoob Joseph 
113474f1202SAnoob Joseph 	if (ipsec_xform->options.copy_flabel == 1 &&
114474f1202SAnoob Joseph 	    sec_cap->ipsec.options.copy_flabel == 0) {
115474f1202SAnoob Joseph 		if (!silent)
116474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Copy Flow Label is not supported\n");
117474f1202SAnoob Joseph 		return -ENOTSUP;
118474f1202SAnoob Joseph 	}
119474f1202SAnoob Joseph 
120474f1202SAnoob Joseph 	if (ipsec_xform->options.copy_df == 1 &&
121474f1202SAnoob Joseph 	    sec_cap->ipsec.options.copy_df == 0) {
122474f1202SAnoob Joseph 		if (!silent)
123474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Copy DP bit is not supported\n");
124474f1202SAnoob Joseph 		return -ENOTSUP;
125474f1202SAnoob Joseph 	}
126474f1202SAnoob Joseph 
127474f1202SAnoob Joseph 	if (ipsec_xform->options.dec_ttl == 1 &&
128474f1202SAnoob Joseph 	    sec_cap->ipsec.options.dec_ttl == 0) {
129474f1202SAnoob Joseph 		if (!silent)
130474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Decrement TTL is not supported\n");
131474f1202SAnoob Joseph 		return -ENOTSUP;
132474f1202SAnoob Joseph 	}
133474f1202SAnoob Joseph 
134474f1202SAnoob Joseph 	if (ipsec_xform->options.ecn == 1 && sec_cap->ipsec.options.ecn == 0) {
135474f1202SAnoob Joseph 		if (!silent)
136474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "ECN is not supported\n");
137474f1202SAnoob Joseph 		return -ENOTSUP;
138474f1202SAnoob Joseph 	}
139474f1202SAnoob Joseph 
140474f1202SAnoob Joseph 	if (ipsec_xform->options.stats == 1 &&
141474f1202SAnoob Joseph 	    sec_cap->ipsec.options.stats == 0) {
142474f1202SAnoob Joseph 		if (!silent)
143474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Stats is not supported\n");
144474f1202SAnoob Joseph 		return -ENOTSUP;
145474f1202SAnoob Joseph 	}
146474f1202SAnoob Joseph 
1470532f50cSAnoob Joseph 	if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&
1480532f50cSAnoob Joseph 	    (ipsec_xform->options.iv_gen_disable == 1) &&
1490532f50cSAnoob Joseph 	    (sec_cap->ipsec.options.iv_gen_disable != 1)) {
1500532f50cSAnoob Joseph 		if (!silent)
1510532f50cSAnoob Joseph 			RTE_LOG(INFO, USER1,
1520532f50cSAnoob Joseph 				"Application provided IV is not supported\n");
1530532f50cSAnoob Joseph 		return -ENOTSUP;
1540532f50cSAnoob Joseph 	}
1550532f50cSAnoob Joseph 
156270470eeSTejasree Kondoj 	if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
157270470eeSTejasree Kondoj 	    (ipsec_xform->options.tunnel_hdr_verify >
158270470eeSTejasree Kondoj 	    sec_cap->ipsec.options.tunnel_hdr_verify)) {
159270470eeSTejasree Kondoj 		if (!silent)
160270470eeSTejasree Kondoj 			RTE_LOG(INFO, USER1,
161270470eeSTejasree Kondoj 				"Tunnel header verify is not supported\n");
162270470eeSTejasree Kondoj 		return -ENOTSUP;
163270470eeSTejasree Kondoj 	}
164270470eeSTejasree Kondoj 
16583243502SArchana Muniganti 	if (ipsec_xform->options.ip_csum_enable == 1 &&
16683243502SArchana Muniganti 	    sec_cap->ipsec.options.ip_csum_enable == 0) {
16783243502SArchana Muniganti 		if (!silent)
16883243502SArchana Muniganti 			RTE_LOG(INFO, USER1,
16983243502SArchana Muniganti 				"Inner IP checksum is not supported\n");
17083243502SArchana Muniganti 		return -ENOTSUP;
17183243502SArchana Muniganti 	}
17283243502SArchana Muniganti 
17383243502SArchana Muniganti 	if (ipsec_xform->options.l4_csum_enable == 1 &&
17483243502SArchana Muniganti 	    sec_cap->ipsec.options.l4_csum_enable == 0) {
17583243502SArchana Muniganti 		if (!silent)
17683243502SArchana Muniganti 			RTE_LOG(INFO, USER1,
17783243502SArchana Muniganti 				"Inner L4 checksum is not supported\n");
17883243502SArchana Muniganti 		return -ENOTSUP;
17983243502SArchana Muniganti 	}
18083243502SArchana Muniganti 
181*d02c6bfcSTejasree Kondoj 	if (ipsec_xform->replay_win_sz > sec_cap->ipsec.replay_win_sz_max) {
182*d02c6bfcSTejasree Kondoj 		if (!silent)
183*d02c6bfcSTejasree Kondoj 			RTE_LOG(INFO, USER1,
184*d02c6bfcSTejasree Kondoj 				"Replay window size is not supported\n");
185*d02c6bfcSTejasree Kondoj 		return -ENOTSUP;
186*d02c6bfcSTejasree Kondoj 	}
187*d02c6bfcSTejasree Kondoj 
188474f1202SAnoob Joseph 	return 0;
189474f1202SAnoob Joseph }
190474f1202SAnoob Joseph 
191474f1202SAnoob Joseph int
192474f1202SAnoob Joseph test_ipsec_crypto_caps_aead_verify(
193474f1202SAnoob Joseph 		const struct rte_security_capability *sec_cap,
194474f1202SAnoob Joseph 		struct rte_crypto_sym_xform *aead)
195474f1202SAnoob Joseph {
196474f1202SAnoob Joseph 	const struct rte_cryptodev_symmetric_capability *sym_cap;
197474f1202SAnoob Joseph 	const struct rte_cryptodev_capabilities *crypto_cap;
198474f1202SAnoob Joseph 	int j = 0;
199474f1202SAnoob Joseph 
200474f1202SAnoob Joseph 	while ((crypto_cap = &sec_cap->crypto_capabilities[j++])->op !=
201474f1202SAnoob Joseph 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
202474f1202SAnoob Joseph 		if (crypto_cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
203474f1202SAnoob Joseph 				crypto_cap->sym.xform_type == aead->type &&
204474f1202SAnoob Joseph 				crypto_cap->sym.aead.algo == aead->aead.algo) {
205474f1202SAnoob Joseph 			sym_cap = &crypto_cap->sym;
206474f1202SAnoob Joseph 			if (rte_cryptodev_sym_capability_check_aead(sym_cap,
207474f1202SAnoob Joseph 					aead->aead.key.length,
208474f1202SAnoob Joseph 					aead->aead.digest_length,
209474f1202SAnoob Joseph 					aead->aead.aad_length,
210474f1202SAnoob Joseph 					aead->aead.iv.length) == 0)
211474f1202SAnoob Joseph 				return 0;
212474f1202SAnoob Joseph 		}
213474f1202SAnoob Joseph 	}
214474f1202SAnoob Joseph 
215474f1202SAnoob Joseph 	return -ENOTSUP;
216474f1202SAnoob Joseph }
217474f1202SAnoob Joseph 
21867d2a188SAnoob Joseph int
21967d2a188SAnoob Joseph test_ipsec_crypto_caps_cipher_verify(
22067d2a188SAnoob Joseph 		const struct rte_security_capability *sec_cap,
22167d2a188SAnoob Joseph 		struct rte_crypto_sym_xform *cipher)
22267d2a188SAnoob Joseph {
22367d2a188SAnoob Joseph 	const struct rte_cryptodev_symmetric_capability *sym_cap;
22467d2a188SAnoob Joseph 	const struct rte_cryptodev_capabilities *cap;
22567d2a188SAnoob Joseph 	int j = 0;
22667d2a188SAnoob Joseph 
22767d2a188SAnoob Joseph 	while ((cap = &sec_cap->crypto_capabilities[j++])->op !=
22867d2a188SAnoob Joseph 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
22967d2a188SAnoob Joseph 		if (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
23067d2a188SAnoob Joseph 				cap->sym.xform_type == cipher->type &&
23167d2a188SAnoob Joseph 				cap->sym.cipher.algo == cipher->cipher.algo) {
23267d2a188SAnoob Joseph 			sym_cap = &cap->sym;
23367d2a188SAnoob Joseph 			if (rte_cryptodev_sym_capability_check_cipher(sym_cap,
23467d2a188SAnoob Joseph 					cipher->cipher.key.length,
23567d2a188SAnoob Joseph 					cipher->cipher.iv.length) == 0)
23667d2a188SAnoob Joseph 				return 0;
23767d2a188SAnoob Joseph 		}
23867d2a188SAnoob Joseph 	}
23967d2a188SAnoob Joseph 
24067d2a188SAnoob Joseph 	return -ENOTSUP;
24167d2a188SAnoob Joseph }
24267d2a188SAnoob Joseph 
24367d2a188SAnoob Joseph int
24467d2a188SAnoob Joseph test_ipsec_crypto_caps_auth_verify(
24567d2a188SAnoob Joseph 		const struct rte_security_capability *sec_cap,
24667d2a188SAnoob Joseph 		struct rte_crypto_sym_xform *auth)
24767d2a188SAnoob Joseph {
24867d2a188SAnoob Joseph 	const struct rte_cryptodev_symmetric_capability *sym_cap;
24967d2a188SAnoob Joseph 	const struct rte_cryptodev_capabilities *cap;
25067d2a188SAnoob Joseph 	int j = 0;
25167d2a188SAnoob Joseph 
25267d2a188SAnoob Joseph 	while ((cap = &sec_cap->crypto_capabilities[j++])->op !=
25367d2a188SAnoob Joseph 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
25467d2a188SAnoob Joseph 		if (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
25567d2a188SAnoob Joseph 				cap->sym.xform_type == auth->type &&
25667d2a188SAnoob Joseph 				cap->sym.auth.algo == auth->auth.algo) {
25767d2a188SAnoob Joseph 			sym_cap = &cap->sym;
25867d2a188SAnoob Joseph 			if (rte_cryptodev_sym_capability_check_auth(sym_cap,
25967d2a188SAnoob Joseph 					auth->auth.key.length,
26067d2a188SAnoob Joseph 					auth->auth.digest_length,
26167d2a188SAnoob Joseph 					auth->auth.iv.length) == 0)
26267d2a188SAnoob Joseph 				return 0;
26367d2a188SAnoob Joseph 		}
26467d2a188SAnoob Joseph 	}
26567d2a188SAnoob Joseph 
26667d2a188SAnoob Joseph 	return -ENOTSUP;
26767d2a188SAnoob Joseph }
26867d2a188SAnoob Joseph 
269474f1202SAnoob Joseph void
270474f1202SAnoob Joseph test_ipsec_td_in_from_out(const struct ipsec_test_data *td_out,
271474f1202SAnoob Joseph 			  struct ipsec_test_data *td_in)
272474f1202SAnoob Joseph {
273474f1202SAnoob Joseph 	memcpy(td_in, td_out, sizeof(*td_in));
274474f1202SAnoob Joseph 
275474f1202SAnoob Joseph 	/* Populate output text of td_in with input text of td_out */
276474f1202SAnoob Joseph 	memcpy(td_in->output_text.data, td_out->input_text.data,
277474f1202SAnoob Joseph 	       td_out->input_text.len);
278474f1202SAnoob Joseph 	td_in->output_text.len = td_out->input_text.len;
279474f1202SAnoob Joseph 
280474f1202SAnoob Joseph 	/* Populate input text of td_in with output text of td_out */
281474f1202SAnoob Joseph 	memcpy(td_in->input_text.data, td_out->output_text.data,
282474f1202SAnoob Joseph 	       td_out->output_text.len);
283474f1202SAnoob Joseph 	td_in->input_text.len = td_out->output_text.len;
284474f1202SAnoob Joseph 
285474f1202SAnoob Joseph 	td_in->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
286474f1202SAnoob Joseph 
287474f1202SAnoob Joseph 	if (td_in->aead) {
288474f1202SAnoob Joseph 		td_in->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
289474f1202SAnoob Joseph 	} else {
290474f1202SAnoob Joseph 		td_in->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
291474f1202SAnoob Joseph 		td_in->xform.chain.cipher.cipher.op =
292474f1202SAnoob Joseph 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
293474f1202SAnoob Joseph 	}
294474f1202SAnoob Joseph }
295474f1202SAnoob Joseph 
29683243502SArchana Muniganti static bool
29783243502SArchana Muniganti is_ipv4(void *ip)
29883243502SArchana Muniganti {
29983243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4 = ip;
30083243502SArchana Muniganti 	uint8_t ip_ver;
30183243502SArchana Muniganti 
30283243502SArchana Muniganti 	ip_ver = (ipv4->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER;
30383243502SArchana Muniganti 	if (ip_ver == IPVERSION)
30483243502SArchana Muniganti 		return true;
30583243502SArchana Muniganti 	else
30683243502SArchana Muniganti 		return false;
30783243502SArchana Muniganti }
30883243502SArchana Muniganti 
30983243502SArchana Muniganti static void
31083243502SArchana Muniganti test_ipsec_csum_init(void *ip, bool l3, bool l4)
31183243502SArchana Muniganti {
31283243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4;
31383243502SArchana Muniganti 	struct rte_tcp_hdr *tcp;
31483243502SArchana Muniganti 	struct rte_udp_hdr *udp;
31583243502SArchana Muniganti 	uint8_t next_proto;
31683243502SArchana Muniganti 	uint8_t size;
31783243502SArchana Muniganti 
31883243502SArchana Muniganti 	if (is_ipv4(ip)) {
31983243502SArchana Muniganti 		ipv4 = ip;
32083243502SArchana Muniganti 		size = sizeof(struct rte_ipv4_hdr);
32183243502SArchana Muniganti 		next_proto = ipv4->next_proto_id;
32283243502SArchana Muniganti 
32383243502SArchana Muniganti 		if (l3)
32483243502SArchana Muniganti 			ipv4->hdr_checksum = 0;
32583243502SArchana Muniganti 	} else {
32683243502SArchana Muniganti 		size = sizeof(struct rte_ipv6_hdr);
32783243502SArchana Muniganti 		next_proto = ((struct rte_ipv6_hdr *)ip)->proto;
32883243502SArchana Muniganti 	}
32983243502SArchana Muniganti 
33083243502SArchana Muniganti 	if (l4) {
33183243502SArchana Muniganti 		switch (next_proto) {
33283243502SArchana Muniganti 		case IPPROTO_TCP:
33383243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)RTE_PTR_ADD(ip, size);
33483243502SArchana Muniganti 			tcp->cksum = 0;
33583243502SArchana Muniganti 			break;
33683243502SArchana Muniganti 		case IPPROTO_UDP:
33783243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)RTE_PTR_ADD(ip, size);
33883243502SArchana Muniganti 			udp->dgram_cksum = 0;
33983243502SArchana Muniganti 			break;
34083243502SArchana Muniganti 		default:
34183243502SArchana Muniganti 			return;
34283243502SArchana Muniganti 		}
34383243502SArchana Muniganti 	}
34483243502SArchana Muniganti }
34583243502SArchana Muniganti 
3466622d9c9SAnoob Joseph void
3476622d9c9SAnoob Joseph test_ipsec_td_prepare(const struct crypto_param *param1,
3486622d9c9SAnoob Joseph 		      const struct crypto_param *param2,
3496622d9c9SAnoob Joseph 		      const struct ipsec_test_flags *flags,
3506622d9c9SAnoob Joseph 		      struct ipsec_test_data *td_array,
3516622d9c9SAnoob Joseph 		      int nb_td)
3526622d9c9SAnoob Joseph 
3536622d9c9SAnoob Joseph {
3546622d9c9SAnoob Joseph 	struct ipsec_test_data *td;
3556622d9c9SAnoob Joseph 	int i;
3566622d9c9SAnoob Joseph 
3576622d9c9SAnoob Joseph 	memset(td_array, 0, nb_td * sizeof(*td));
3586622d9c9SAnoob Joseph 
3596622d9c9SAnoob Joseph 	for (i = 0; i < nb_td; i++) {
3606622d9c9SAnoob Joseph 		td = &td_array[i];
3618d290523SAnoob Joseph 
3628d290523SAnoob Joseph 		/* Prepare fields based on param */
3638d290523SAnoob Joseph 
3648d290523SAnoob Joseph 		if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
3656622d9c9SAnoob Joseph 			/* Copy template for packet & key fields */
3669fb87fbfSTejasree Kondoj 			if (flags->ipv6)
3679fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_256_gcm_v6, sizeof(*td));
3689fb87fbfSTejasree Kondoj 			else
3696622d9c9SAnoob Joseph 				memcpy(td, &pkt_aes_256_gcm, sizeof(*td));
3706622d9c9SAnoob Joseph 
3716622d9c9SAnoob Joseph 			td->aead = true;
3726622d9c9SAnoob Joseph 			td->xform.aead.aead.algo = param1->alg.aead;
3736622d9c9SAnoob Joseph 			td->xform.aead.aead.key.length = param1->key_length;
3748d290523SAnoob Joseph 		} else {
3758d290523SAnoob Joseph 			/* Copy template for packet & key fields */
3769fb87fbfSTejasree Kondoj 			if (flags->ipv6)
3779fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_128_cbc_hmac_sha256_v6,
3789fb87fbfSTejasree Kondoj 					sizeof(*td));
3799fb87fbfSTejasree Kondoj 			else
3809fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_128_cbc_hmac_sha256,
3819fb87fbfSTejasree Kondoj 					sizeof(*td));
3828d290523SAnoob Joseph 
3838d290523SAnoob Joseph 			td->aead = false;
3848d290523SAnoob Joseph 			td->xform.chain.cipher.cipher.algo = param1->alg.cipher;
3858d290523SAnoob Joseph 			td->xform.chain.cipher.cipher.key.length =
3868d290523SAnoob Joseph 					param1->key_length;
38767b5428dSAnoob Joseph 			td->xform.chain.cipher.cipher.iv.length =
38867b5428dSAnoob Joseph 					param1->iv_length;
3898d290523SAnoob Joseph 			td->xform.chain.auth.auth.algo = param2->alg.auth;
3908d290523SAnoob Joseph 			td->xform.chain.auth.auth.key.length =
3918d290523SAnoob Joseph 					param2->key_length;
3928d290523SAnoob Joseph 			td->xform.chain.auth.auth.digest_length =
3938d290523SAnoob Joseph 					param2->digest_length;
3948d290523SAnoob Joseph 
3958d290523SAnoob Joseph 		}
3960532f50cSAnoob Joseph 
3970532f50cSAnoob Joseph 		if (flags->iv_gen)
3980532f50cSAnoob Joseph 			td->ipsec_xform.options.iv_gen_disable = 0;
3994aa52f21SAnoob Joseph 
4004aa52f21SAnoob Joseph 		if (flags->sa_expiry_pkts_soft)
4014aa52f21SAnoob Joseph 			td->ipsec_xform.life.packets_soft_limit =
4024aa52f21SAnoob Joseph 					IPSEC_TEST_PACKETS_MAX - 1;
40383243502SArchana Muniganti 
40483243502SArchana Muniganti 		if (flags->ip_csum) {
40583243502SArchana Muniganti 			td->ipsec_xform.options.ip_csum_enable = 1;
40683243502SArchana Muniganti 			test_ipsec_csum_init(&td->input_text.data, true, false);
40783243502SArchana Muniganti 		}
40883243502SArchana Muniganti 
40983243502SArchana Muniganti 		if (flags->l4_csum) {
41083243502SArchana Muniganti 			td->ipsec_xform.options.l4_csum_enable = 1;
41183243502SArchana Muniganti 			test_ipsec_csum_init(&td->input_text.data, false, true);
41283243502SArchana Muniganti 		}
41383243502SArchana Muniganti 
41465d68c7cSAnoob Joseph 		if (flags->transport) {
41565d68c7cSAnoob Joseph 			td->ipsec_xform.mode =
41665d68c7cSAnoob Joseph 					RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT;
41765d68c7cSAnoob Joseph 		} else {
41865d68c7cSAnoob Joseph 			td->ipsec_xform.mode =
41965d68c7cSAnoob Joseph 					RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
42065d68c7cSAnoob Joseph 
4219fb87fbfSTejasree Kondoj 			if (flags->tunnel_ipv6)
4229fb87fbfSTejasree Kondoj 				td->ipsec_xform.tunnel.type =
4239fb87fbfSTejasree Kondoj 						RTE_SECURITY_IPSEC_TUNNEL_IPV6;
4249fb87fbfSTejasree Kondoj 			else
4259fb87fbfSTejasree Kondoj 				td->ipsec_xform.tunnel.type =
4269fb87fbfSTejasree Kondoj 						RTE_SECURITY_IPSEC_TUNNEL_IPV4;
42765d68c7cSAnoob Joseph 		}
42865d68c7cSAnoob Joseph 
4292c85598cSAnkur Dwivedi 		if (flags->stats_success)
4302c85598cSAnkur Dwivedi 			td->ipsec_xform.options.stats = 1;
4319fb87fbfSTejasree Kondoj 
432825ab5c3STejasree Kondoj 		if (flags->fragment) {
433825ab5c3STejasree Kondoj 			struct rte_ipv4_hdr *ip;
434825ab5c3STejasree Kondoj 			ip = (struct rte_ipv4_hdr *)&td->input_text.data;
435825ab5c3STejasree Kondoj 			ip->fragment_offset = 4;
436825ab5c3STejasree Kondoj 			ip->hdr_checksum = rte_ipv4_cksum(ip);
437825ab5c3STejasree Kondoj 		}
438825ab5c3STejasree Kondoj 
439e2cbb384SAnoob Joseph 		if (flags->df == TEST_IPSEC_COPY_DF_INNER_0 ||
440e2cbb384SAnoob Joseph 		    flags->df == TEST_IPSEC_COPY_DF_INNER_1)
441e2cbb384SAnoob Joseph 			td->ipsec_xform.options.copy_df = 1;
44270c60cfdSAnoob Joseph 
44370c60cfdSAnoob Joseph 		if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_0 ||
44470c60cfdSAnoob Joseph 		    flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1)
44570c60cfdSAnoob Joseph 			td->ipsec_xform.options.copy_dscp = 1;
4466622d9c9SAnoob Joseph 	}
4476622d9c9SAnoob Joseph }
4486622d9c9SAnoob Joseph 
4496622d9c9SAnoob Joseph void
4506622d9c9SAnoob Joseph test_ipsec_td_update(struct ipsec_test_data td_inb[],
4516622d9c9SAnoob Joseph 		     const struct ipsec_test_data td_outb[],
4526622d9c9SAnoob Joseph 		     int nb_td,
4536622d9c9SAnoob Joseph 		     const struct ipsec_test_flags *flags)
4546622d9c9SAnoob Joseph {
4556622d9c9SAnoob Joseph 	int i;
4566622d9c9SAnoob Joseph 
4576622d9c9SAnoob Joseph 	for (i = 0; i < nb_td; i++) {
4586622d9c9SAnoob Joseph 		memcpy(td_inb[i].output_text.data, td_outb[i].input_text.data,
4596622d9c9SAnoob Joseph 		       td_outb[i].input_text.len);
4606622d9c9SAnoob Joseph 		td_inb[i].output_text.len = td_outb->input_text.len;
4616622d9c9SAnoob Joseph 
4620f453190STejasree Kondoj 		if (flags->icv_corrupt) {
4630f453190STejasree Kondoj 			int icv_pos = td_inb[i].input_text.len - 4;
4640f453190STejasree Kondoj 			td_inb[i].input_text.data[icv_pos] += 1;
4650f453190STejasree Kondoj 		}
466c8234341STejasree Kondoj 
4676978f51eSAnoob Joseph 		if (flags->sa_expiry_pkts_hard)
4686978f51eSAnoob Joseph 			td_inb[i].ipsec_xform.life.packets_hard_limit =
4696978f51eSAnoob Joseph 					IPSEC_TEST_PACKETS_MAX - 1;
4706978f51eSAnoob Joseph 
471c8234341STejasree Kondoj 		if (flags->udp_encap)
472c8234341STejasree Kondoj 			td_inb[i].ipsec_xform.options.udp_encap = 1;
4730532f50cSAnoob Joseph 
4749ec50a52STejasree Kondoj 		if (flags->udp_ports_verify)
4759ec50a52STejasree Kondoj 			td_inb[i].ipsec_xform.options.udp_ports_verify = 1;
4769ec50a52STejasree Kondoj 
477270470eeSTejasree Kondoj 		td_inb[i].ipsec_xform.options.tunnel_hdr_verify =
478270470eeSTejasree Kondoj 			flags->tunnel_hdr_verify;
479270470eeSTejasree Kondoj 
48083243502SArchana Muniganti 		if (flags->ip_csum)
48183243502SArchana Muniganti 			td_inb[i].ipsec_xform.options.ip_csum_enable = 1;
48283243502SArchana Muniganti 
48383243502SArchana Muniganti 		if (flags->l4_csum)
48483243502SArchana Muniganti 			td_inb[i].ipsec_xform.options.l4_csum_enable = 1;
48583243502SArchana Muniganti 
4860532f50cSAnoob Joseph 		/* Clear outbound specific flags */
4870532f50cSAnoob Joseph 		td_inb[i].ipsec_xform.options.iv_gen_disable = 0;
4880f453190STejasree Kondoj 	}
4896622d9c9SAnoob Joseph }
4906622d9c9SAnoob Joseph 
4916622d9c9SAnoob Joseph void
4926622d9c9SAnoob Joseph test_ipsec_display_alg(const struct crypto_param *param1,
4936622d9c9SAnoob Joseph 		       const struct crypto_param *param2)
4946622d9c9SAnoob Joseph {
4958d290523SAnoob Joseph 	if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
4968d290523SAnoob Joseph 		printf("\t%s [%d]",
4976622d9c9SAnoob Joseph 		       rte_crypto_aead_algorithm_strings[param1->alg.aead],
4988d290523SAnoob Joseph 		       param1->key_length * 8);
4998d290523SAnoob Joseph 	} else {
5008d290523SAnoob Joseph 		printf("\t%s",
5018d290523SAnoob Joseph 		       rte_crypto_cipher_algorithm_strings[param1->alg.cipher]);
5028d290523SAnoob Joseph 		if (param1->alg.cipher != RTE_CRYPTO_CIPHER_NULL)
5038d290523SAnoob Joseph 			printf(" [%d]", param1->key_length * 8);
5048d290523SAnoob Joseph 		printf(" %s",
5058d290523SAnoob Joseph 		       rte_crypto_auth_algorithm_strings[param2->alg.auth]);
5068d290523SAnoob Joseph 		if (param2->alg.auth != RTE_CRYPTO_AUTH_NULL)
5078d290523SAnoob Joseph 			printf(" [%dB ICV]", param2->digest_length);
5088d290523SAnoob Joseph 	}
5098d290523SAnoob Joseph 	printf("\n");
5106622d9c9SAnoob Joseph }
5116622d9c9SAnoob Joseph 
512474f1202SAnoob Joseph static int
513474f1202SAnoob Joseph test_ipsec_tunnel_hdr_len_get(const struct ipsec_test_data *td)
514474f1202SAnoob Joseph {
515474f1202SAnoob Joseph 	int len = 0;
516474f1202SAnoob Joseph 
517474f1202SAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
518474f1202SAnoob Joseph 		if (td->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
519474f1202SAnoob Joseph 			if (td->ipsec_xform.tunnel.type ==
520474f1202SAnoob Joseph 					RTE_SECURITY_IPSEC_TUNNEL_IPV4)
521474f1202SAnoob Joseph 				len += sizeof(struct rte_ipv4_hdr);
522474f1202SAnoob Joseph 			else
523474f1202SAnoob Joseph 				len += sizeof(struct rte_ipv6_hdr);
524474f1202SAnoob Joseph 		}
525474f1202SAnoob Joseph 	}
526474f1202SAnoob Joseph 
527474f1202SAnoob Joseph 	return len;
528474f1202SAnoob Joseph }
529474f1202SAnoob Joseph 
530474f1202SAnoob Joseph static int
531cd928003STejasree Kondoj test_ipsec_iv_verify_push(struct rte_mbuf *m, const struct ipsec_test_data *td)
532cd928003STejasree Kondoj {
533cd928003STejasree Kondoj 	static uint8_t iv_queue[IV_LEN_MAX * IPSEC_TEST_PACKETS_MAX];
534cd928003STejasree Kondoj 	uint8_t *iv_tmp, *output_text = rte_pktmbuf_mtod(m, uint8_t *);
535cd928003STejasree Kondoj 	int i, iv_pos, iv_len;
536cd928003STejasree Kondoj 	static int index;
537cd928003STejasree Kondoj 
538cd928003STejasree Kondoj 	if (td->aead)
539cd928003STejasree Kondoj 		iv_len = td->xform.aead.aead.iv.length - td->salt.len;
540cd928003STejasree Kondoj 	else
541cd928003STejasree Kondoj 		iv_len = td->xform.chain.cipher.cipher.iv.length;
542cd928003STejasree Kondoj 
543cd928003STejasree Kondoj 	iv_pos = test_ipsec_tunnel_hdr_len_get(td) + sizeof(struct rte_esp_hdr);
544cd928003STejasree Kondoj 	output_text += iv_pos;
545cd928003STejasree Kondoj 
546cd928003STejasree Kondoj 	TEST_ASSERT(iv_len <= IV_LEN_MAX, "IV length greater than supported");
547cd928003STejasree Kondoj 
548cd928003STejasree Kondoj 	/* Compare against previous values */
549cd928003STejasree Kondoj 	for (i = 0; i < index; i++) {
550cd928003STejasree Kondoj 		iv_tmp = &iv_queue[i * IV_LEN_MAX];
551cd928003STejasree Kondoj 
552cd928003STejasree Kondoj 		if (memcmp(output_text, iv_tmp, iv_len) == 0) {
553cd928003STejasree Kondoj 			printf("IV repeated");
554cd928003STejasree Kondoj 			return TEST_FAILED;
555cd928003STejasree Kondoj 		}
556cd928003STejasree Kondoj 	}
557cd928003STejasree Kondoj 
558cd928003STejasree Kondoj 	/* Save IV for future comparisons */
559cd928003STejasree Kondoj 
560cd928003STejasree Kondoj 	iv_tmp = &iv_queue[index * IV_LEN_MAX];
561cd928003STejasree Kondoj 	memcpy(iv_tmp, output_text, iv_len);
562cd928003STejasree Kondoj 	index++;
563cd928003STejasree Kondoj 
564cd928003STejasree Kondoj 	if (index == IPSEC_TEST_PACKETS_MAX)
565cd928003STejasree Kondoj 		index = 0;
566cd928003STejasree Kondoj 
567cd928003STejasree Kondoj 	return TEST_SUCCESS;
568cd928003STejasree Kondoj }
569cd928003STejasree Kondoj 
570cd928003STejasree Kondoj static int
57183243502SArchana Muniganti test_ipsec_l3_csum_verify(struct rte_mbuf *m)
57283243502SArchana Muniganti {
57383243502SArchana Muniganti 	uint16_t actual_cksum, expected_cksum;
57483243502SArchana Muniganti 	struct rte_ipv4_hdr *ip;
57583243502SArchana Muniganti 
57683243502SArchana Muniganti 	ip = rte_pktmbuf_mtod(m, struct rte_ipv4_hdr *);
57783243502SArchana Muniganti 
57883243502SArchana Muniganti 	if (!is_ipv4((void *)ip))
57983243502SArchana Muniganti 		return TEST_SKIPPED;
58083243502SArchana Muniganti 
58183243502SArchana Muniganti 	actual_cksum = ip->hdr_checksum;
58283243502SArchana Muniganti 
58383243502SArchana Muniganti 	ip->hdr_checksum = 0;
58483243502SArchana Muniganti 
58583243502SArchana Muniganti 	expected_cksum = rte_ipv4_cksum(ip);
58683243502SArchana Muniganti 
58783243502SArchana Muniganti 	if (actual_cksum != expected_cksum)
58883243502SArchana Muniganti 		return TEST_FAILED;
58983243502SArchana Muniganti 
59083243502SArchana Muniganti 	return TEST_SUCCESS;
59183243502SArchana Muniganti }
59283243502SArchana Muniganti 
59383243502SArchana Muniganti static int
59483243502SArchana Muniganti test_ipsec_l4_csum_verify(struct rte_mbuf *m)
59583243502SArchana Muniganti {
59683243502SArchana Muniganti 	uint16_t actual_cksum = 0, expected_cksum = 0;
59783243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4;
59883243502SArchana Muniganti 	struct rte_ipv6_hdr *ipv6;
59983243502SArchana Muniganti 	struct rte_tcp_hdr *tcp;
60083243502SArchana Muniganti 	struct rte_udp_hdr *udp;
60183243502SArchana Muniganti 	void *ip, *l4;
60283243502SArchana Muniganti 
60383243502SArchana Muniganti 	ip = rte_pktmbuf_mtod(m, void *);
60483243502SArchana Muniganti 
60583243502SArchana Muniganti 	if (is_ipv4(ip)) {
60683243502SArchana Muniganti 		ipv4 = ip;
60783243502SArchana Muniganti 		l4 = RTE_PTR_ADD(ipv4, sizeof(struct rte_ipv4_hdr));
60883243502SArchana Muniganti 
60983243502SArchana Muniganti 		switch (ipv4->next_proto_id) {
61083243502SArchana Muniganti 		case IPPROTO_TCP:
61183243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)l4;
61283243502SArchana Muniganti 			actual_cksum = tcp->cksum;
61383243502SArchana Muniganti 			tcp->cksum = 0;
61483243502SArchana Muniganti 			expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4);
61583243502SArchana Muniganti 			break;
61683243502SArchana Muniganti 		case IPPROTO_UDP:
61783243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)l4;
61883243502SArchana Muniganti 			actual_cksum = udp->dgram_cksum;
61983243502SArchana Muniganti 			udp->dgram_cksum = 0;
62083243502SArchana Muniganti 			expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4);
62183243502SArchana Muniganti 			break;
62283243502SArchana Muniganti 		default:
62383243502SArchana Muniganti 			break;
62483243502SArchana Muniganti 		}
62583243502SArchana Muniganti 	} else {
62683243502SArchana Muniganti 		ipv6 = ip;
62783243502SArchana Muniganti 		l4 = RTE_PTR_ADD(ipv6, sizeof(struct rte_ipv6_hdr));
62883243502SArchana Muniganti 
62983243502SArchana Muniganti 		switch (ipv6->proto) {
63083243502SArchana Muniganti 		case IPPROTO_TCP:
63183243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)l4;
63283243502SArchana Muniganti 			actual_cksum = tcp->cksum;
63383243502SArchana Muniganti 			tcp->cksum = 0;
63483243502SArchana Muniganti 			expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4);
63583243502SArchana Muniganti 			break;
63683243502SArchana Muniganti 		case IPPROTO_UDP:
63783243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)l4;
63883243502SArchana Muniganti 			actual_cksum = udp->dgram_cksum;
63983243502SArchana Muniganti 			udp->dgram_cksum = 0;
64083243502SArchana Muniganti 			expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4);
64183243502SArchana Muniganti 			break;
64283243502SArchana Muniganti 		default:
64383243502SArchana Muniganti 			break;
64483243502SArchana Muniganti 		}
64583243502SArchana Muniganti 	}
64683243502SArchana Muniganti 
64783243502SArchana Muniganti 	if (actual_cksum != expected_cksum)
64883243502SArchana Muniganti 		return TEST_FAILED;
64983243502SArchana Muniganti 
65083243502SArchana Muniganti 	return TEST_SUCCESS;
65183243502SArchana Muniganti }
65283243502SArchana Muniganti 
65383243502SArchana Muniganti static int
654474f1202SAnoob Joseph test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
6556622d9c9SAnoob Joseph 		     bool silent, const struct ipsec_test_flags *flags)
656474f1202SAnoob Joseph {
657474f1202SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
658474f1202SAnoob Joseph 	uint32_t skip, len = rte_pktmbuf_pkt_len(m);
659e2cbb384SAnoob Joseph 	uint8_t td_output_text[4096];
66083243502SArchana Muniganti 	int ret;
661474f1202SAnoob Joseph 
6626978f51eSAnoob Joseph 	/* For tests with status as error for test success, skip verification */
6636978f51eSAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
6646978f51eSAnoob Joseph 	    (flags->icv_corrupt ||
665270470eeSTejasree Kondoj 	     flags->sa_expiry_pkts_hard ||
666*d02c6bfcSTejasree Kondoj 	     flags->tunnel_hdr_verify ||
667*d02c6bfcSTejasree Kondoj 	     td->ar_packet))
6680f453190STejasree Kondoj 		return TEST_SUCCESS;
6690f453190STejasree Kondoj 
670c8234341STejasree Kondoj 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
671c8234341STejasree Kondoj 	   flags->udp_encap) {
672c8234341STejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
673c8234341STejasree Kondoj 		const struct rte_ipv6_hdr *iph6;
674c8234341STejasree Kondoj 
675c8234341STejasree Kondoj 		if (td->ipsec_xform.tunnel.type ==
676c8234341STejasree Kondoj 				RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
677c8234341STejasree Kondoj 			iph4 = (const struct rte_ipv4_hdr *)output_text;
678c8234341STejasree Kondoj 			if (iph4->next_proto_id != IPPROTO_UDP) {
679c8234341STejasree Kondoj 				printf("UDP header is not found\n");
680c8234341STejasree Kondoj 				return TEST_FAILED;
681c8234341STejasree Kondoj 			}
682c8234341STejasree Kondoj 		} else {
683c8234341STejasree Kondoj 			iph6 = (const struct rte_ipv6_hdr *)output_text;
684c8234341STejasree Kondoj 			if (iph6->proto != IPPROTO_UDP) {
685c8234341STejasree Kondoj 				printf("UDP header is not found\n");
686c8234341STejasree Kondoj 				return TEST_FAILED;
687c8234341STejasree Kondoj 			}
688c8234341STejasree Kondoj 		}
689c8234341STejasree Kondoj 
690c8234341STejasree Kondoj 		len -= sizeof(struct rte_udp_hdr);
691c8234341STejasree Kondoj 		output_text += sizeof(struct rte_udp_hdr);
692c8234341STejasree Kondoj 	}
693c8234341STejasree Kondoj 
694474f1202SAnoob Joseph 	if (len != td->output_text.len) {
695474f1202SAnoob Joseph 		printf("Output length (%d) not matching with expected (%d)\n",
696474f1202SAnoob Joseph 			len, td->output_text.len);
697474f1202SAnoob Joseph 		return TEST_FAILED;
698474f1202SAnoob Joseph 	}
699474f1202SAnoob Joseph 
700b7986bdeSTejasree Kondoj 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&
701b7986bdeSTejasree Kondoj 				flags->fragment) {
702b7986bdeSTejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
703b7986bdeSTejasree Kondoj 		iph4 = (const struct rte_ipv4_hdr *)output_text;
704b7986bdeSTejasree Kondoj 		if (iph4->fragment_offset) {
705b7986bdeSTejasree Kondoj 			printf("Output packet is fragmented");
706b7986bdeSTejasree Kondoj 			return TEST_FAILED;
707b7986bdeSTejasree Kondoj 		}
708b7986bdeSTejasree Kondoj 	}
709b7986bdeSTejasree Kondoj 
710474f1202SAnoob Joseph 	skip = test_ipsec_tunnel_hdr_len_get(td);
711474f1202SAnoob Joseph 
712474f1202SAnoob Joseph 	len -= skip;
713474f1202SAnoob Joseph 	output_text += skip;
714474f1202SAnoob Joseph 
71583243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
71683243502SArchana Muniganti 				flags->ip_csum) {
717daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD)
71883243502SArchana Muniganti 			ret = test_ipsec_l3_csum_verify(m);
71983243502SArchana Muniganti 		else
72083243502SArchana Muniganti 			ret = TEST_FAILED;
72183243502SArchana Muniganti 
72283243502SArchana Muniganti 		if (ret == TEST_FAILED)
72383243502SArchana Muniganti 			printf("Inner IP checksum test failed\n");
72483243502SArchana Muniganti 
72583243502SArchana Muniganti 		return ret;
72683243502SArchana Muniganti 	}
72783243502SArchana Muniganti 
72883243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
72983243502SArchana Muniganti 				flags->l4_csum) {
730daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
73183243502SArchana Muniganti 			ret = test_ipsec_l4_csum_verify(m);
73283243502SArchana Muniganti 		else
73383243502SArchana Muniganti 			ret = TEST_FAILED;
73483243502SArchana Muniganti 
73583243502SArchana Muniganti 		if (ret == TEST_FAILED)
73683243502SArchana Muniganti 			printf("Inner L4 checksum test failed\n");
73783243502SArchana Muniganti 
73883243502SArchana Muniganti 		return ret;
73983243502SArchana Muniganti 	}
74083243502SArchana Muniganti 
741e2cbb384SAnoob Joseph 	memcpy(td_output_text, td->output_text.data + skip, len);
74283243502SArchana Muniganti 
743e2cbb384SAnoob Joseph 	if (test_ipsec_pkt_update(td_output_text, flags)) {
744e2cbb384SAnoob Joseph 		printf("Could not update expected vector");
745e2cbb384SAnoob Joseph 		return TEST_FAILED;
746e2cbb384SAnoob Joseph 	}
747e2cbb384SAnoob Joseph 
748e2cbb384SAnoob Joseph 	if (memcmp(output_text, td_output_text, len)) {
749474f1202SAnoob Joseph 		if (silent)
750474f1202SAnoob Joseph 			return TEST_FAILED;
751474f1202SAnoob Joseph 
752474f1202SAnoob Joseph 		printf("TestCase %s line %d: %s\n", __func__, __LINE__,
753474f1202SAnoob Joseph 			"output text not as expected\n");
754474f1202SAnoob Joseph 
755e2cbb384SAnoob Joseph 		rte_hexdump(stdout, "expected", td_output_text, len);
756474f1202SAnoob Joseph 		rte_hexdump(stdout, "actual", output_text, len);
757474f1202SAnoob Joseph 		return TEST_FAILED;
758474f1202SAnoob Joseph 	}
759474f1202SAnoob Joseph 
7606622d9c9SAnoob Joseph 	return TEST_SUCCESS;
7616622d9c9SAnoob Joseph }
7626622d9c9SAnoob Joseph 
7636622d9c9SAnoob Joseph static int
7646622d9c9SAnoob Joseph test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td,
7656622d9c9SAnoob Joseph 		   struct ipsec_test_data *res_d)
7666622d9c9SAnoob Joseph {
7676622d9c9SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
7686622d9c9SAnoob Joseph 	uint32_t len = rte_pktmbuf_pkt_len(m);
7696622d9c9SAnoob Joseph 
7706622d9c9SAnoob Joseph 	memcpy(res_d, td, sizeof(*res_d));
7716622d9c9SAnoob Joseph 	memcpy(res_d->input_text.data, output_text, len);
7726622d9c9SAnoob Joseph 	res_d->input_text.len = len;
7736622d9c9SAnoob Joseph 
7746622d9c9SAnoob Joseph 	res_d->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
7756622d9c9SAnoob Joseph 	if (res_d->aead) {
7766622d9c9SAnoob Joseph 		res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
7776622d9c9SAnoob Joseph 	} else {
7788d290523SAnoob Joseph 		res_d->xform.chain.cipher.cipher.op =
7798d290523SAnoob Joseph 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
7808d290523SAnoob Joseph 		res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
7816622d9c9SAnoob Joseph 	}
7826622d9c9SAnoob Joseph 
783474f1202SAnoob Joseph 	return TEST_SUCCESS;
784474f1202SAnoob Joseph }
785474f1202SAnoob Joseph 
78670c60cfdSAnoob Joseph static int
78770c60cfdSAnoob Joseph test_ipsec_iph4_hdr_validate(const struct rte_ipv4_hdr *iph4,
78870c60cfdSAnoob Joseph 			     const struct ipsec_test_flags *flags)
78970c60cfdSAnoob Joseph {
79070c60cfdSAnoob Joseph 	uint8_t tos, dscp;
79170c60cfdSAnoob Joseph 	uint16_t f_off;
79270c60cfdSAnoob Joseph 
79370c60cfdSAnoob Joseph 	if (!is_valid_ipv4_pkt(iph4)) {
79470c60cfdSAnoob Joseph 		printf("Tunnel outer header is not IPv4\n");
79570c60cfdSAnoob Joseph 		return -1;
79670c60cfdSAnoob Joseph 	}
79770c60cfdSAnoob Joseph 
79870c60cfdSAnoob Joseph 	f_off = rte_be_to_cpu_16(iph4->fragment_offset);
79970c60cfdSAnoob Joseph 	if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 ||
80070c60cfdSAnoob Joseph 	    flags->df == TEST_IPSEC_SET_DF_1_INNER_0) {
80170c60cfdSAnoob Joseph 		if (!(f_off & RTE_IPV4_HDR_DF_FLAG)) {
80270c60cfdSAnoob Joseph 			printf("DF bit is not set\n");
80370c60cfdSAnoob Joseph 			return -1;
80470c60cfdSAnoob Joseph 		}
80570c60cfdSAnoob Joseph 	} else {
80670c60cfdSAnoob Joseph 		if (f_off & RTE_IPV4_HDR_DF_FLAG) {
80770c60cfdSAnoob Joseph 			printf("DF bit is set\n");
80870c60cfdSAnoob Joseph 			return -1;
80970c60cfdSAnoob Joseph 		}
81070c60cfdSAnoob Joseph 	}
81170c60cfdSAnoob Joseph 
81270c60cfdSAnoob Joseph 	tos = iph4->type_of_service;
81370c60cfdSAnoob Joseph 	dscp = (tos & RTE_IPV4_HDR_DSCP_MASK) >> 2;
81470c60cfdSAnoob Joseph 
81570c60cfdSAnoob Joseph 	if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
81670c60cfdSAnoob Joseph 	    flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) {
81770c60cfdSAnoob Joseph 		if (dscp != TEST_IPSEC_DSCP_VAL) {
81870c60cfdSAnoob Joseph 			printf("DSCP value is not matching [exp: %x, actual: %x]\n",
81970c60cfdSAnoob Joseph 			       TEST_IPSEC_DSCP_VAL, dscp);
82070c60cfdSAnoob Joseph 			return -1;
82170c60cfdSAnoob Joseph 		}
82270c60cfdSAnoob Joseph 	} else {
82370c60cfdSAnoob Joseph 		if (dscp != 0) {
82470c60cfdSAnoob Joseph 			printf("DSCP value is set [exp: 0, actual: %x]\n",
82570c60cfdSAnoob Joseph 			       dscp);
82670c60cfdSAnoob Joseph 			return -1;
82770c60cfdSAnoob Joseph 		}
82870c60cfdSAnoob Joseph 	}
82970c60cfdSAnoob Joseph 
83070c60cfdSAnoob Joseph 	return 0;
83170c60cfdSAnoob Joseph }
83270c60cfdSAnoob Joseph 
83370c60cfdSAnoob Joseph static int
83470c60cfdSAnoob Joseph test_ipsec_iph6_hdr_validate(const struct rte_ipv6_hdr *iph6,
83570c60cfdSAnoob Joseph 			     const struct ipsec_test_flags *flags)
83670c60cfdSAnoob Joseph {
83770c60cfdSAnoob Joseph 	uint32_t vtc_flow;
83870c60cfdSAnoob Joseph 	uint8_t dscp;
83970c60cfdSAnoob Joseph 
84070c60cfdSAnoob Joseph 	if (!is_valid_ipv6_pkt(iph6)) {
84170c60cfdSAnoob Joseph 		printf("Tunnel outer header is not IPv6\n");
84270c60cfdSAnoob Joseph 		return -1;
84370c60cfdSAnoob Joseph 	}
84470c60cfdSAnoob Joseph 
84570c60cfdSAnoob Joseph 	vtc_flow = rte_be_to_cpu_32(iph6->vtc_flow);
84670c60cfdSAnoob Joseph 	dscp = (vtc_flow & RTE_IPV6_HDR_DSCP_MASK) >>
84770c60cfdSAnoob Joseph 	       (RTE_IPV6_HDR_TC_SHIFT + 2);
84870c60cfdSAnoob Joseph 
84970c60cfdSAnoob Joseph 	if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
85070c60cfdSAnoob Joseph 	    flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) {
85170c60cfdSAnoob Joseph 		if (dscp != TEST_IPSEC_DSCP_VAL) {
85270c60cfdSAnoob Joseph 			printf("DSCP value is not matching [exp: %x, actual: %x]\n",
85370c60cfdSAnoob Joseph 			       TEST_IPSEC_DSCP_VAL, dscp);
85470c60cfdSAnoob Joseph 			return -1;
85570c60cfdSAnoob Joseph 		}
85670c60cfdSAnoob Joseph 	} else {
85770c60cfdSAnoob Joseph 		if (dscp != 0) {
85870c60cfdSAnoob Joseph 			printf("DSCP value is set [exp: 0, actual: %x]\n",
85970c60cfdSAnoob Joseph 			       dscp);
86070c60cfdSAnoob Joseph 			return -1;
86170c60cfdSAnoob Joseph 		}
86270c60cfdSAnoob Joseph 	}
86370c60cfdSAnoob Joseph 
86470c60cfdSAnoob Joseph 	return 0;
86570c60cfdSAnoob Joseph }
86670c60cfdSAnoob Joseph 
867474f1202SAnoob Joseph int
868474f1202SAnoob Joseph test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
8696622d9c9SAnoob Joseph 			struct ipsec_test_data *res_d, bool silent,
8706622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags)
871474f1202SAnoob Joseph {
8729fb87fbfSTejasree Kondoj 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
873cd928003STejasree Kondoj 	int ret;
874cd928003STejasree Kondoj 
87565d68c7cSAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
87665d68c7cSAnoob Joseph 		const struct rte_ipv4_hdr *iph4;
87765d68c7cSAnoob Joseph 		const struct rte_ipv6_hdr *iph6;
87865d68c7cSAnoob Joseph 
87965d68c7cSAnoob Joseph 		if (flags->iv_gen) {
880cd928003STejasree Kondoj 			ret = test_ipsec_iv_verify_push(m, td);
881cd928003STejasree Kondoj 			if (ret != TEST_SUCCESS)
882cd928003STejasree Kondoj 				return ret;
883cd928003STejasree Kondoj 		}
884cd928003STejasree Kondoj 
88565d68c7cSAnoob Joseph 		iph4 = (const struct rte_ipv4_hdr *)output_text;
8869fb87fbfSTejasree Kondoj 
88765d68c7cSAnoob Joseph 		if (td->ipsec_xform.mode ==
88865d68c7cSAnoob Joseph 				RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) {
88965d68c7cSAnoob Joseph 			if (flags->ipv6) {
89065d68c7cSAnoob Joseph 				iph6 = (const struct rte_ipv6_hdr *)output_text;
89165d68c7cSAnoob Joseph 				if (is_valid_ipv6_pkt(iph6) == false) {
89265d68c7cSAnoob Joseph 					printf("Transport packet is not IPv6\n");
89365d68c7cSAnoob Joseph 					return TEST_FAILED;
89465d68c7cSAnoob Joseph 				}
89565d68c7cSAnoob Joseph 			} else {
89665d68c7cSAnoob Joseph 				if (is_valid_ipv4_pkt(iph4) == false) {
89765d68c7cSAnoob Joseph 					printf("Transport packet is not IPv4\n");
89865d68c7cSAnoob Joseph 					return TEST_FAILED;
89965d68c7cSAnoob Joseph 				}
90065d68c7cSAnoob Joseph 			}
90165d68c7cSAnoob Joseph 		} else {
9029fb87fbfSTejasree Kondoj 			if (td->ipsec_xform.tunnel.type ==
9039fb87fbfSTejasree Kondoj 					RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
90470c60cfdSAnoob Joseph 				if (test_ipsec_iph4_hdr_validate(iph4, flags))
9059fb87fbfSTejasree Kondoj 					return TEST_FAILED;
9069fb87fbfSTejasree Kondoj 			} else {
9079fb87fbfSTejasree Kondoj 				iph6 = (const struct rte_ipv6_hdr *)output_text;
90870c60cfdSAnoob Joseph 				if (test_ipsec_iph6_hdr_validate(iph6, flags))
9099fb87fbfSTejasree Kondoj 					return TEST_FAILED;
9109fb87fbfSTejasree Kondoj 			}
9119fb87fbfSTejasree Kondoj 		}
9129fb87fbfSTejasree Kondoj 	}
9139fb87fbfSTejasree Kondoj 
914474f1202SAnoob Joseph 	/*
915474f1202SAnoob Joseph 	 * In case of known vector tests & all inbound tests, res_d provided
916474f1202SAnoob Joseph 	 * would be NULL and output data need to be validated against expected.
917474f1202SAnoob Joseph 	 * For inbound, output_text would be plain packet and for outbound
918474f1202SAnoob Joseph 	 * output_text would IPsec packet. Validate by comparing against
919474f1202SAnoob Joseph 	 * known vectors.
9206622d9c9SAnoob Joseph 	 *
9216622d9c9SAnoob Joseph 	 * In case of combined mode tests, the output_text from outbound
9226622d9c9SAnoob Joseph 	 * operation (ie, IPsec packet) would need to be inbound processed to
9236622d9c9SAnoob Joseph 	 * obtain the plain text. Copy output_text to result data, 'res_d', so
9246622d9c9SAnoob Joseph 	 * that inbound processing can be done.
925474f1202SAnoob Joseph 	 */
9266622d9c9SAnoob Joseph 
9276622d9c9SAnoob Joseph 	if (res_d == NULL)
9286622d9c9SAnoob Joseph 		return test_ipsec_td_verify(m, td, silent, flags);
9296622d9c9SAnoob Joseph 	else
9306622d9c9SAnoob Joseph 		return test_ipsec_res_d_prepare(m, td, res_d);
931474f1202SAnoob Joseph }
932474f1202SAnoob Joseph 
933474f1202SAnoob Joseph int
934*d02c6bfcSTejasree Kondoj test_ipsec_status_check(const struct ipsec_test_data *td,
935*d02c6bfcSTejasree Kondoj 			struct rte_crypto_op *op,
9366622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags,
9374aa52f21SAnoob Joseph 			enum rte_security_ipsec_sa_direction dir,
9384aa52f21SAnoob Joseph 			int pkt_num)
939474f1202SAnoob Joseph {
940474f1202SAnoob Joseph 	int ret = TEST_SUCCESS;
941474f1202SAnoob Joseph 
942*d02c6bfcSTejasree Kondoj 	if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
943*d02c6bfcSTejasree Kondoj 	    td->ar_packet) {
944*d02c6bfcSTejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
945*d02c6bfcSTejasree Kondoj 			printf("Anti replay test case failed\n");
946*d02c6bfcSTejasree Kondoj 			return TEST_FAILED;
947*d02c6bfcSTejasree Kondoj 		} else {
948*d02c6bfcSTejasree Kondoj 			return TEST_SUCCESS;
949*d02c6bfcSTejasree Kondoj 		}
950*d02c6bfcSTejasree Kondoj 	}
951*d02c6bfcSTejasree Kondoj 
9526978f51eSAnoob Joseph 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
9536978f51eSAnoob Joseph 	    flags->sa_expiry_pkts_hard &&
9546978f51eSAnoob Joseph 	    pkt_num == IPSEC_TEST_PACKETS_MAX) {
9556978f51eSAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
9566978f51eSAnoob Joseph 			printf("SA hard expiry (pkts) test failed\n");
9576978f51eSAnoob Joseph 			return TEST_FAILED;
9586978f51eSAnoob Joseph 		} else {
9596978f51eSAnoob Joseph 			return TEST_SUCCESS;
9606978f51eSAnoob Joseph 		}
9616978f51eSAnoob Joseph 	}
9626978f51eSAnoob Joseph 
963270470eeSTejasree Kondoj 	if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
964270470eeSTejasree Kondoj 	    flags->tunnel_hdr_verify) {
965270470eeSTejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
966270470eeSTejasree Kondoj 			printf("Tunnel header verify test case failed\n");
967270470eeSTejasree Kondoj 			return TEST_FAILED;
968270470eeSTejasree Kondoj 		} else {
969270470eeSTejasree Kondoj 			return TEST_SUCCESS;
970270470eeSTejasree Kondoj 		}
971270470eeSTejasree Kondoj 	}
972270470eeSTejasree Kondoj 
9730f453190STejasree Kondoj 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && flags->icv_corrupt) {
9740f453190STejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
9750f453190STejasree Kondoj 			printf("ICV corruption test case failed\n");
9760f453190STejasree Kondoj 			ret = TEST_FAILED;
9770f453190STejasree Kondoj 		}
9780f453190STejasree Kondoj 	} else {
979474f1202SAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
9804aa52f21SAnoob Joseph 			printf("Security op processing failed [pkt_num: %d]\n",
9814aa52f21SAnoob Joseph 			       pkt_num);
9824aa52f21SAnoob Joseph 			ret = TEST_FAILED;
9834aa52f21SAnoob Joseph 		}
9844aa52f21SAnoob Joseph 	}
9854aa52f21SAnoob Joseph 
9864aa52f21SAnoob Joseph 	if (flags->sa_expiry_pkts_soft && pkt_num == IPSEC_TEST_PACKETS_MAX) {
9874aa52f21SAnoob Joseph 		if (!(op->aux_flags &
9884aa52f21SAnoob Joseph 		      RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY)) {
9894aa52f21SAnoob Joseph 			printf("SA soft expiry (pkts) test failed\n");
990474f1202SAnoob Joseph 			ret = TEST_FAILED;
991474f1202SAnoob Joseph 		}
9920f453190STejasree Kondoj 	}
993474f1202SAnoob Joseph 
994474f1202SAnoob Joseph 	return ret;
995474f1202SAnoob Joseph }
9962c85598cSAnkur Dwivedi 
9972c85598cSAnkur Dwivedi int
9982c85598cSAnkur Dwivedi test_ipsec_stats_verify(struct rte_security_ctx *ctx,
9992c85598cSAnkur Dwivedi 			struct rte_security_session *sess,
10002c85598cSAnkur Dwivedi 			const struct ipsec_test_flags *flags,
10012c85598cSAnkur Dwivedi 			enum rte_security_ipsec_sa_direction dir)
10022c85598cSAnkur Dwivedi {
10032c85598cSAnkur Dwivedi 	struct rte_security_stats stats = {0};
10042c85598cSAnkur Dwivedi 	int ret = TEST_SUCCESS;
10052c85598cSAnkur Dwivedi 
10062c85598cSAnkur Dwivedi 	if (flags->stats_success) {
10072c85598cSAnkur Dwivedi 		if (rte_security_session_stats_get(ctx, sess, &stats) < 0)
10082c85598cSAnkur Dwivedi 			return TEST_FAILED;
10092c85598cSAnkur Dwivedi 
10102c85598cSAnkur Dwivedi 		if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
10112c85598cSAnkur Dwivedi 			if (stats.ipsec.opackets != 1 ||
10122c85598cSAnkur Dwivedi 			    stats.ipsec.oerrors != 0)
10132c85598cSAnkur Dwivedi 				ret = TEST_FAILED;
10142c85598cSAnkur Dwivedi 		} else {
10152c85598cSAnkur Dwivedi 			if (stats.ipsec.ipackets != 1 ||
10162c85598cSAnkur Dwivedi 			    stats.ipsec.ierrors != 0)
10172c85598cSAnkur Dwivedi 				ret = TEST_FAILED;
10182c85598cSAnkur Dwivedi 		}
10192c85598cSAnkur Dwivedi 	}
10202c85598cSAnkur Dwivedi 
10212c85598cSAnkur Dwivedi 	return ret;
10222c85598cSAnkur Dwivedi }
1023e2cbb384SAnoob Joseph 
1024e2cbb384SAnoob Joseph int
1025e2cbb384SAnoob Joseph test_ipsec_pkt_update(uint8_t *pkt, const struct ipsec_test_flags *flags)
1026e2cbb384SAnoob Joseph {
1027e2cbb384SAnoob Joseph 	struct rte_ipv4_hdr *iph4;
102870c60cfdSAnoob Joseph 	struct rte_ipv6_hdr *iph6;
1029e2cbb384SAnoob Joseph 	bool cksum_dirty = false;
1030e2cbb384SAnoob Joseph 
1031e2cbb384SAnoob Joseph 	iph4 = (struct rte_ipv4_hdr *)pkt;
1032e2cbb384SAnoob Joseph 
1033e2cbb384SAnoob Joseph 	if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 ||
1034e2cbb384SAnoob Joseph 	    flags->df == TEST_IPSEC_SET_DF_0_INNER_1 ||
1035e2cbb384SAnoob Joseph 	    flags->df == TEST_IPSEC_COPY_DF_INNER_0 ||
1036e2cbb384SAnoob Joseph 	    flags->df == TEST_IPSEC_SET_DF_1_INNER_0) {
103770c60cfdSAnoob Joseph 		uint16_t frag_off;
1038e2cbb384SAnoob Joseph 
1039e2cbb384SAnoob Joseph 		if (!is_ipv4(iph4)) {
104070c60cfdSAnoob Joseph 			printf("Invalid packet type\n");
1041e2cbb384SAnoob Joseph 			return -1;
1042e2cbb384SAnoob Joseph 		}
1043e2cbb384SAnoob Joseph 
1044e2cbb384SAnoob Joseph 		frag_off = rte_be_to_cpu_16(iph4->fragment_offset);
1045e2cbb384SAnoob Joseph 
1046e2cbb384SAnoob Joseph 		if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 ||
1047e2cbb384SAnoob Joseph 		    flags->df == TEST_IPSEC_SET_DF_0_INNER_1)
1048e2cbb384SAnoob Joseph 			frag_off |= RTE_IPV4_HDR_DF_FLAG;
1049e2cbb384SAnoob Joseph 		else
1050e2cbb384SAnoob Joseph 			frag_off &= ~RTE_IPV4_HDR_DF_FLAG;
1051e2cbb384SAnoob Joseph 
1052e2cbb384SAnoob Joseph 		iph4->fragment_offset = rte_cpu_to_be_16(frag_off);
1053e2cbb384SAnoob Joseph 		cksum_dirty = true;
1054e2cbb384SAnoob Joseph 	}
1055e2cbb384SAnoob Joseph 
105670c60cfdSAnoob Joseph 	if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
105770c60cfdSAnoob Joseph 	    flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1 ||
105870c60cfdSAnoob Joseph 	    flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_0 ||
105970c60cfdSAnoob Joseph 	    flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) {
106070c60cfdSAnoob Joseph 
106170c60cfdSAnoob Joseph 		if (is_ipv4(iph4)) {
106270c60cfdSAnoob Joseph 			uint8_t tos;
106370c60cfdSAnoob Joseph 
106470c60cfdSAnoob Joseph 			tos = iph4->type_of_service;
106570c60cfdSAnoob Joseph 			if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
106670c60cfdSAnoob Joseph 			    flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
106770c60cfdSAnoob Joseph 				tos |= (RTE_IPV4_HDR_DSCP_MASK &
106870c60cfdSAnoob Joseph 					(TEST_IPSEC_DSCP_VAL << 2));
106970c60cfdSAnoob Joseph 			else
107070c60cfdSAnoob Joseph 				tos &= ~RTE_IPV4_HDR_DSCP_MASK;
107170c60cfdSAnoob Joseph 
107270c60cfdSAnoob Joseph 			iph4->type_of_service = tos;
107370c60cfdSAnoob Joseph 			cksum_dirty = true;
107470c60cfdSAnoob Joseph 		} else {
107570c60cfdSAnoob Joseph 			uint32_t vtc_flow;
107670c60cfdSAnoob Joseph 
107770c60cfdSAnoob Joseph 			iph6 = (struct rte_ipv6_hdr *)pkt;
107870c60cfdSAnoob Joseph 
107970c60cfdSAnoob Joseph 			vtc_flow = rte_be_to_cpu_32(iph6->vtc_flow);
108070c60cfdSAnoob Joseph 			if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
108170c60cfdSAnoob Joseph 			    flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
108270c60cfdSAnoob Joseph 				vtc_flow |= (RTE_IPV6_HDR_DSCP_MASK &
108370c60cfdSAnoob Joseph 					     (TEST_IPSEC_DSCP_VAL << (RTE_IPV6_HDR_TC_SHIFT + 2)));
108470c60cfdSAnoob Joseph 			else
108570c60cfdSAnoob Joseph 				vtc_flow &= ~RTE_IPV6_HDR_DSCP_MASK;
108670c60cfdSAnoob Joseph 
108770c60cfdSAnoob Joseph 			iph6->vtc_flow = rte_cpu_to_be_32(vtc_flow);
108870c60cfdSAnoob Joseph 		}
108970c60cfdSAnoob Joseph 	}
109070c60cfdSAnoob Joseph 
1091e2cbb384SAnoob Joseph 	if (cksum_dirty && is_ipv4(iph4)) {
1092e2cbb384SAnoob Joseph 		iph4->hdr_checksum = 0;
1093e2cbb384SAnoob Joseph 		iph4->hdr_checksum = rte_ipv4_cksum(iph4);
1094e2cbb384SAnoob Joseph 	}
1095e2cbb384SAnoob Joseph 
1096e2cbb384SAnoob Joseph 	return 0;
1097e2cbb384SAnoob Joseph }
10983c60274cSJie Zhou 
10993c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
1100