[3/3] app/test: test inline reassembly with multi seg

Message ID 20230605082122.422934-3-ndabilpuram@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: akhil goyal
Headers
Series [1/3] examples/ipsec-secgw: avoid error pkt prints in fast path |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/github-robot: build success github build: passed
ci/iol-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/intel-Functional success Functional PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-unit-testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-aarch-unit-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS

Commit Message

Nithin Dabilpuram June 5, 2023, 8:21 a.m. UTC
  Support testing inline reassembly with multi seg in
inline ipsec multi seg test command.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
---
 app/test/test_security_inline_proto.c         | 17 ++++--
 app/test/test_security_inline_proto_vectors.h | 53 ++++++++++++++++++-
 2 files changed, 64 insertions(+), 6 deletions(-)
  

Patch

diff --git a/app/test/test_security_inline_proto.c b/app/test/test_security_inline_proto.c
index 79858e559f..7f6fa0ad8c 100644
--- a/app/test/test_security_inline_proto.c
+++ b/app/test/test_security_inline_proto.c
@@ -1624,6 +1624,8 @@  inline_ipsec_testsuite_setup(void)
 		 * Without SG mode, default value is picked.
 		 */
 		plaintext_len = local_port_conf.rxmode.mtu - 256;
+	} else {
+		plaintext_len = 0;
 	}
 
 	return 0;
@@ -1934,6 +1936,7 @@  test_inline_ip_reassembly(const void *testdata)
 	const struct reassembly_vector *td = testdata;
 	struct ip_reassembly_test_packet full_pkt;
 	struct ip_reassembly_test_packet frags[MAX_FRAGS];
+	uint16_t extra_data, extra_data_sum = 0;
 	struct ipsec_test_flags flags = {0};
 	int i = 0;
 
@@ -1945,14 +1948,22 @@  test_inline_ip_reassembly(const void *testdata)
 			sizeof(struct ip_reassembly_test_packet));
 	reassembly_td.full_pkt = &full_pkt;
 
-	test_vector_payload_populate(reassembly_td.full_pkt, true);
 	for (; i < reassembly_td.nb_frags; i++) {
 		memcpy(&frags[i], td->frags[i],
 			sizeof(struct ip_reassembly_test_packet));
 		reassembly_td.frags[i] = &frags[i];
+
+		/* Add extra data for multi-seg test on all fragments except last one */
+		extra_data = 0;
+		if (plaintext_len && reassembly_td.frags[i]->len < plaintext_len &&
+		    (i != reassembly_td.nb_frags - 1))
+			extra_data = ((plaintext_len - reassembly_td.frags[i]->len) & ~0x7ULL);
+
 		test_vector_payload_populate(reassembly_td.frags[i],
-				(i == 0) ? true : false);
+				(i == 0) ? true : false, extra_data, extra_data_sum);
+		extra_data_sum += extra_data;
 	}
+	test_vector_payload_populate(reassembly_td.full_pkt, true, extra_data_sum, 0);
 
 	return test_ipsec_with_reassembly(&reassembly_td, &flags);
 }
@@ -2667,8 +2678,6 @@  test_ipsec_inline_proto_pkt_esn_antireplay4096(const void *test_data)
 	return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 4096);
 }
 
-
-
 static struct unit_test_suite inline_ipsec_testsuite  = {
 	.suite_name = "Inline IPsec Ethernet Device Unit Test Suite",
 	.unit_test_cases = {
diff --git a/app/test/test_security_inline_proto_vectors.h b/app/test/test_security_inline_proto_vectors.h
index 003537e200..61a045b446 100644
--- a/app/test/test_security_inline_proto_vectors.h
+++ b/app/test/test_security_inline_proto_vectors.h
@@ -17,7 +17,7 @@  uint8_t dummy_ipv6_eth_hdr[] = {
 		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd,
 };
 
-#define MAX_FRAG_LEN		 1500
+#define MAX_FRAG_LEN		 IPSEC_TEXT_MAX_LEN
 #define MAX_FRAGS		 6
 #define MAX_PKT_LEN		 (MAX_FRAG_LEN * MAX_FRAGS)
 
@@ -468,9 +468,13 @@  struct ip_reassembly_test_packet pkt_ipv4_udp_p3_f5 = {
 
 static inline void
 test_vector_payload_populate(struct ip_reassembly_test_packet *pkt,
-		bool first_frag)
+			     bool first_frag, uint16_t extra_data, uint16_t extra_data_sum)
 {
+	bool is_ipv6 = ((pkt->data[0] >> 4) == 0x6);
 	uint32_t i = pkt->l4_offset;
+	uint16_t len, off;
+	size_t ext_len = 0;
+	int proto;
 
 	/**
 	 * For non-fragmented packets and first frag, skip 8 bytes from
@@ -479,6 +483,51 @@  test_vector_payload_populate(struct ip_reassembly_test_packet *pkt,
 	if (first_frag)
 		i += 8;
 
+	/* Fixup header and checksum */
+	if (extra_data || extra_data_sum) {
+		if (is_ipv6) {
+			struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)pkt->data;
+			struct rte_ipv6_fragment_ext *frag_ext;
+			uint8_t *p = pkt->data;
+			uint16_t old_off;
+
+			len = rte_be_to_cpu_16(hdr->payload_len) + extra_data;
+			hdr->payload_len = rte_cpu_to_be_16(len);
+
+			/* Find frag extension header to add to frag offset */
+			if (extra_data_sum) {
+				proto = hdr->proto;
+				p += sizeof(struct rte_ipv6_hdr);
+				while (proto != IPPROTO_FRAGMENT &&
+				       (proto = rte_ipv6_get_next_ext(p, proto, &ext_len) >= 0))
+					p += ext_len;
+
+				/* Found fragment header, update the frag offset */
+				if (proto == IPPROTO_FRAGMENT) {
+					frag_ext = (struct rte_ipv6_fragment_ext *)p;
+					old_off = rte_be_to_cpu_16(frag_ext->frag_data);
+					off = old_off & 0xFFF8;
+					off += extra_data_sum;
+					frag_ext->frag_data = rte_cpu_to_be_16(off |
+									       (old_off & 0x7));
+				}
+			}
+		} else {
+			struct rte_ipv4_hdr *hdr = (struct rte_ipv4_hdr *)pkt->data;
+			uint16_t old_off = rte_be_to_cpu_16(hdr->fragment_offset);
+
+			len = rte_be_to_cpu_16(hdr->total_length) + extra_data;
+			off = old_off & 0x1FFF;
+			off += (extra_data_sum >> 3);
+
+			hdr->total_length = rte_cpu_to_be_16(len);
+			hdr->fragment_offset = rte_cpu_to_be_16(off | (old_off & 0xe000));
+			hdr->hdr_checksum = 0;
+			hdr->hdr_checksum = rte_ipv4_cksum(hdr);
+		}
+		pkt->len += extra_data;
+	}
+
 	for (; i < pkt->len; i++)
 		pkt->data[i] = 0x58;
 }