Support testing inline reassembly with multi seg in inline ipsec multi seg test command.
Signed-off-by: Nithin Dabilpuram <ndabilpu...@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(-) 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; } -- 2.25.1