@@ -9348,6 +9348,7 @@ test_ipsec_proto_process(const struct ipsec_test_data td[],
0xe82c, 0x4887};
const struct rte_ipv4_hdr *ipv4 =
(const struct rte_ipv4_hdr *)td[0].output_text.data;
+ int nb_segs = flags->nb_segs_in_mbuf ? flags->nb_segs_in_mbuf : 1;
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct crypto_unittest_params *ut_params = &unittest_params;
struct rte_security_capability_idx sec_cap_idx;
@@ -9356,9 +9357,9 @@ test_ipsec_proto_process(const struct ipsec_test_data td[],
uint8_t dev_id = ts_params->valid_devs[0];
enum rte_security_ipsec_sa_direction dir;
struct ipsec_test_data *res_d_tmp = NULL;
+ uint8_t input_text[IPSEC_TEXT_MAX_LEN];
int salt_len, i, ret = TEST_SUCCESS;
struct rte_security_ctx *ctx;
- uint8_t *input_text;
uint32_t src, dst;
uint32_t verify;
@@ -9543,20 +9544,16 @@ test_ipsec_proto_process(const struct ipsec_test_data td[],
}
}
- /* Setup source mbuf payload */
- ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
- memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
- rte_pktmbuf_tailroom(ut_params->ibuf));
-
- input_text = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
- td[i].input_text.len);
-
- memcpy(input_text, td[i].input_text.data,
- td[i].input_text.len);
-
+ /* Copy test data before modification */
+ memcpy(input_text, td[i].input_text.data, td[i].input_text.len);
if (test_ipsec_pkt_update(input_text, flags))
return TEST_FAILED;
+ /* Setup source mbuf payload */
+ ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, td[i].input_text.len,
+ nb_segs, 0);
+ pktmbuf_write(ut_params->ibuf, 0, td[i].input_text.len, input_text);
+
/* Generate crypto op data structure */
ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC);
@@ -10253,6 +10250,30 @@ test_ipsec_proto_ipv6_set_dscp_1_inner_0(const void *data __rte_unused)
return test_ipsec_proto_all(&flags);
}
+static int
+test_ipsec_proto_sgl(const void *data __rte_unused)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct rte_cryptodev_info dev_info;
+
+ struct ipsec_test_flags flags = {
+ .nb_segs_in_mbuf = 5
+ };
+
+ if (gbl_driver_id == rte_cryptodev_driver_id_get(
+ RTE_STR(CRYPTODEV_NAME_CN10K_PMD)))
+ return TEST_SKIPPED;
+
+ rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+ if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+ printf("Device doesn't support in-place scatter-gather. "
+ "Test Skipped.\n");
+ return TEST_SKIPPED;
+ }
+
+ return test_ipsec_proto_all(&flags);
+}
+
static int
test_ipsec_pkt_replay(const void *test_data, const uint64_t esn[],
bool replayed_pkt[], uint32_t nb_pkts, bool esn_en,
@@ -15564,6 +15585,10 @@ static struct unit_test_suite ipsec_proto_testsuite = {
"Tunnel header IPv6 decrement inner hop limit",
ut_setup_security, ut_teardown,
test_ipsec_proto_ipv6_hop_limit_decrement),
+ TEST_CASE_NAMED_ST(
+ "Multi-segmented mode",
+ ut_setup_security, ut_teardown,
+ test_ipsec_proto_sgl),
TEST_CASES_END() /**< NULL terminate unit test array */
}
};
@@ -664,12 +664,12 @@ test_ipsec_tunnel_hdr_len_get(const struct ipsec_test_data *td)
}
static int
-test_ipsec_iv_verify_push(struct rte_mbuf *m, const struct ipsec_test_data *td)
+test_ipsec_iv_verify_push(const uint8_t *output_text, const struct ipsec_test_data *td)
{
static uint8_t iv_queue[IV_LEN_MAX * IPSEC_TEST_PACKETS_MAX];
- uint8_t *iv_tmp, *output_text = rte_pktmbuf_mtod(m, uint8_t *);
int i, iv_pos, iv_len;
static int index;
+ uint8_t *iv_tmp;
if (td->aead)
iv_len = td->xform.aead.aead.iv.length - td->salt.len;
@@ -704,12 +704,12 @@ test_ipsec_iv_verify_push(struct rte_mbuf *m, const struct ipsec_test_data *td)
}
static int
-test_ipsec_l3_csum_verify(struct rte_mbuf *m)
+test_ipsec_l3_csum_verify(uint8_t *output_text)
{
uint16_t actual_cksum, expected_cksum;
struct rte_ipv4_hdr *ip;
- ip = rte_pktmbuf_mtod(m, struct rte_ipv4_hdr *);
+ ip = (struct rte_ipv4_hdr *)output_text;
if (!is_ipv4((void *)ip))
return TEST_SKIPPED;
@@ -727,26 +727,16 @@ test_ipsec_l3_csum_verify(struct rte_mbuf *m)
}
static int
-test_ipsec_l4_csum_verify(struct rte_mbuf *m)
+test_ipsec_l4_csum_verify(uint8_t *output_text)
{
uint16_t actual_cksum = 0, expected_cksum = 0;
- uint32_t len = rte_pktmbuf_pkt_len(m);
- uint8_t data_arr[IPSEC_TEXT_MAX_LEN];
struct rte_ipv4_hdr *ipv4;
struct rte_ipv6_hdr *ipv6;
- uint8_t *data = data_arr;
struct rte_tcp_hdr *tcp;
struct rte_udp_hdr *udp;
- const uint8_t *ptr;
void *ip, *l4;
- ptr = rte_pktmbuf_read(m, 0, len, data_arr);
- if (!ptr)
- return -EINVAL;
- else if (ptr != data_arr)
- data = rte_pktmbuf_mtod_offset(m, uint8_t *, 0);
-
- ip = (struct rte_ipv4_hdr *)data;
+ ip = output_text;
if (is_ipv4(ip)) {
ipv4 = ip;
@@ -823,14 +813,11 @@ test_ipsec_ttl_or_hop_decrement_verify(void *received, void *expected)
}
static int
-test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
- bool silent, const struct ipsec_test_flags *flags)
+test_ipsec_td_verify(uint8_t *output_text, uint32_t len, uint32_t ol_flags,
+ const struct ipsec_test_data *td, bool silent, const struct ipsec_test_flags *flags)
{
- uint32_t skip, len = rte_pktmbuf_pkt_len(m);
uint8_t td_output_text[IPSEC_TEXT_MAX_LEN];
- uint8_t data_arr[IPSEC_TEXT_MAX_LEN];
- uint8_t *output_text = data_arr;
- const uint8_t *ptr;
+ uint32_t skip;
int ret;
/* For tests with status as error for test success, skip verification */
@@ -841,12 +828,6 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
td->ar_packet))
return TEST_SUCCESS;
- ptr = rte_pktmbuf_read(m, 0, len, data_arr);
- if (!ptr)
- return -EINVAL;
- else if (ptr != data_arr)
- output_text = rte_pktmbuf_mtod_offset(m, uint8_t *, 0);
-
if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
flags->udp_encap) {
@@ -870,15 +851,10 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
}
}
- skip = test_ipsec_tunnel_hdr_len_get(td);
-
- len -= skip;
- output_text += skip;
-
if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
flags->ip_csum) {
- if (m->ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD)
- ret = test_ipsec_l3_csum_verify(m);
+ if (ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD)
+ ret = test_ipsec_l3_csum_verify(output_text);
else
ret = TEST_FAILED;
@@ -890,8 +866,8 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
flags->l4_csum) {
- if (m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
- ret = test_ipsec_l4_csum_verify(m);
+ if (ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
+ ret = test_ipsec_l4_csum_verify(output_text);
else
ret = TEST_FAILED;
@@ -901,6 +877,11 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
return ret;
}
+ skip = test_ipsec_tunnel_hdr_len_get(td);
+
+ len -= skip;
+ output_text += skip;
+
memcpy(td_output_text, td->output_text.data + skip, len);
if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
@@ -932,25 +913,13 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
}
static int
-test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td,
- struct ipsec_test_data *res_d)
+test_ipsec_res_d_prepare(const uint8_t *output_text, uint32_t len,
+ const struct ipsec_test_data *td, struct ipsec_test_data *res_d)
{
- uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
- uint32_t len = rte_pktmbuf_pkt_len(m);
- struct rte_mbuf *next = m;
- uint32_t off = 0;
-
memcpy(res_d, td, sizeof(*res_d));
- while (next && off < len) {
- output_text = rte_pktmbuf_mtod(next, uint8_t *);
- if (off + next->data_len > sizeof(res_d->input_text.data))
- break;
- memcpy(&res_d->input_text.data[off], output_text, next->data_len);
- off += next->data_len;
- next = next->next;
- }
- res_d->input_text.len = off;
+ memcpy(&res_d->input_text.data, output_text, len);
+ res_d->input_text.len = len;
res_d->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
if (res_d->aead) {
@@ -1069,19 +1038,27 @@ test_ipsec_iph6_hdr_validate(const struct rte_ipv6_hdr *iph6,
}
int
-test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
+test_ipsec_post_process(const struct rte_mbuf *m, const struct ipsec_test_data *td,
struct ipsec_test_data *res_d, bool silent,
const struct ipsec_test_flags *flags)
{
- uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
+ uint32_t len = rte_pktmbuf_pkt_len(m);
+ uint8_t output_text[IPSEC_TEXT_MAX_LEN];
+ const uint8_t *output;
int ret;
+ /* Copy mbuf payload to continuous buffer */
+ output = rte_pktmbuf_read(m, 0, len, output_text);
+ if (output != output_text)
+ /* Single segment mbuf, copy manually */
+ memcpy(output_text, output, len);
+
if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
const struct rte_ipv4_hdr *iph4;
const struct rte_ipv6_hdr *iph6;
if (flags->iv_gen) {
- ret = test_ipsec_iv_verify_push(m, td);
+ ret = test_ipsec_iv_verify_push(output_text, td);
if (ret != TEST_SUCCESS)
return ret;
}
@@ -1181,9 +1158,9 @@ test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
*/
if (res_d == NULL)
- return test_ipsec_td_verify(m, td, silent, flags);
+ return test_ipsec_td_verify(output_text, len, m->ol_flags, td, silent, flags);
else
- return test_ipsec_res_d_prepare(m, td, res_d);
+ return test_ipsec_res_d_prepare(output_text, len, td, res_d);
}
int
@@ -109,6 +109,7 @@ struct ipsec_test_flags {
bool dec_ttl_or_hop_limit;
bool ah;
uint32_t plaintext_len;
+ int nb_segs_in_mbuf;
};
struct crypto_param {
@@ -288,7 +289,7 @@ void test_ipsec_td_update(struct ipsec_test_data td_inb[],
void test_ipsec_display_alg(const struct crypto_param *param1,
const struct crypto_param *param2);
-int test_ipsec_post_process(struct rte_mbuf *m,
+int test_ipsec_post_process(const struct rte_mbuf *m,
const struct ipsec_test_data *td,
struct ipsec_test_data *res_d, bool silent,
const struct ipsec_test_flags *flags);