From: Vidya Sagar Velumuri <[email protected]>

Add test to verify Rx inject.

Signed-off-by: Anoob Joseph <[email protected]>
Signed-off-by: Vidya Sagar Velumuri <[email protected]>
---
 app/test/test_cryptodev.c                | 326 +++++++++++++++++++----
 app/test/test_cryptodev_security_ipsec.h |   1 +
 2 files changed, 274 insertions(+), 53 deletions(-)

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index fb2af40b99..b74bbb1348 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -17,6 +17,7 @@
 
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
+#include <rte_ethdev.h>
 #include <rte_ip.h>
 #include <rte_string_fns.h>
 #include <rte_tcp.h>
@@ -1426,6 +1427,81 @@ ut_setup_security(void)
        return dev_configure_and_start(0);
 }
 
+static int
+ut_setup_security_rx_inject(void)
+{
+       struct rte_mempool *mbuf_pool = rte_mempool_lookup("CRYPTO_MBUFPOOL");
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct rte_eth_conf port_conf = {
+               .rxmode = {
+                       .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM |
+                                   RTE_ETH_RX_OFFLOAD_SECURITY,
+               },
+               .txmode = {
+                       .offloads = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE,
+               },
+               .lpbk_mode = 1,  /* Enable loopback */
+       };
+       struct rte_cryptodev_info dev_info;
+       struct rte_eth_rxconf rx_conf = {
+               .rx_thresh = {
+                       .pthresh = 8,
+                       .hthresh = 8,
+                       .wthresh = 8,
+               },
+               .rx_free_thresh = 32,
+       };
+       uint16_t nb_ports;
+       int ret;
+
+       rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+       if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_SECURITY_RX_INJECT)) {
+               RTE_LOG(INFO, USER1, "Feature requirements for IPsec Rx inject 
test case not met\n"
+                      );
+               return TEST_SKIPPED;
+       }
+
+       nb_ports = rte_eth_dev_count_avail();
+       if (nb_ports == 0)
+               return TEST_SKIPPED;
+
+       ret = rte_eth_dev_configure(0 /* port_id */,
+                                   1 /* nb_rx_queue */,
+                                   0 /* nb_tx_queue */,
+                                   &port_conf);
+       if (ret) {
+               printf("Could not configure ethdev port 0 [err=%d]\n", ret);
+               return TEST_SKIPPED;
+       }
+
+       /* Rx queue setup */
+       ret = rte_eth_rx_queue_setup(0 /* port_id */,
+                                    0 /* rx_queue_id */,
+                                    1024 /* nb_rx_desc */,
+                                    SOCKET_ID_ANY,
+                                    &rx_conf,
+                                    mbuf_pool);
+       if (ret) {
+               printf("Could not setup eth port 0 queue 0\n");
+               return TEST_SKIPPED;
+       }
+
+       ret = rte_eth_dev_start(0);
+       if (ret) {
+               printf("Could not start ethdev");
+               return TEST_SKIPPED;
+       }
+
+       ret = rte_eth_promiscuous_enable(0);
+       if (ret) {
+               printf("Could not enable promiscuous mode");
+               return TEST_SKIPPED;
+       }
+
+       /* Configure and start cryptodev with no features disabled */
+       return dev_configure_and_start(0);
+}
+
 void
 ut_teardown(void)
 {
@@ -1478,6 +1554,21 @@ ut_teardown(void)
        rte_cryptodev_stop(ts_params->valid_devs[0]);
 }
 
+static void
+ut_teardown_rx_inject(void)
+{
+       int ret;
+
+       if  (rte_eth_dev_count_avail() != 0) {
+               ret = rte_eth_dev_reset(0);
+               if (ret)
+                       printf("Could not reset eth port 0");
+
+       }
+
+       ut_teardown();
+}
+
 static int
 test_device_configure_invalid_dev_id(void)
 {
@@ -9748,6 +9839,145 @@ test_PDCP_SDAP_PROTO_decap_all(void)
        return (all_err == TEST_SUCCESS) ? TEST_SUCCESS : TEST_FAILED;
 }
 
+static int
+test_ipsec_proto_crypto_op_enq(struct crypto_testsuite_params *ts_params,
+                              struct crypto_unittest_params *ut_params,
+                              struct rte_security_ipsec_xform *ipsec_xform,
+                              const struct ipsec_test_data *td,
+                              const struct ipsec_test_flags *flags,
+                              int pkt_num)
+{
+       uint8_t dev_id = ts_params->valid_devs[0];
+       enum rte_security_ipsec_sa_direction dir;
+       int ret;
+
+       dir = ipsec_xform->direction;
+
+       /* Generate crypto op data structure */
+       ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
+                               RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+       if (!ut_params->op) {
+               printf("Could not allocate crypto op");
+               return TEST_FAILED;
+       }
+
+       /* Attach session to operation */
+       rte_security_attach_session(ut_params->op, ut_params->sec_session);
+
+       /* Set crypto operation mbufs */
+       ut_params->op->sym->m_src = ut_params->ibuf;
+       ut_params->op->sym->m_dst = NULL;
+
+       /* Copy IV in crypto operation when IV generation is disabled */
+       if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
+           ipsec_xform->options.iv_gen_disable == 1) {
+               uint8_t *iv = rte_crypto_op_ctod_offset(ut_params->op,
+                                                       uint8_t *,
+                                                       IV_OFFSET);
+               int len;
+
+               if (td->aead)
+                       len = td->xform.aead.aead.iv.length;
+               else if (td->aes_gmac)
+                       len = td->xform.chain.auth.auth.iv.length;
+               else
+                       len = td->xform.chain.cipher.cipher.iv.length;
+
+               memcpy(iv, td->iv.data, len);
+       }
+
+       /* Process crypto operation */
+       process_crypto_request(dev_id, ut_params->op);
+
+       ret = test_ipsec_status_check(td, ut_params->op, flags, dir, pkt_num);
+
+       rte_crypto_op_free(ut_params->op);
+       ut_params->op = NULL;
+
+       return ret;
+}
+
+static int
+test_ipsec_proto_mbuf_enq(struct crypto_testsuite_params *ts_params,
+                         struct crypto_unittest_params *ut_params,
+                         struct rte_security_ctx *ctx)
+{
+       struct rte_security_session **sec_sess;
+       struct rte_security_ctx *eth_sec_ctx;
+       struct rte_ether_hdr *hdr;
+       struct rte_mbuf *m;
+       uint64_t timeout;
+       void *userdata;
+       int ret;
+
+       RTE_SET_USED(ts_params);
+
+       hdr = (void *)rte_pktmbuf_prepend(ut_params->ibuf, sizeof(struct 
rte_ether_hdr));
+       hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
+
+       ut_params->ibuf->l2_len = sizeof(struct rte_ether_hdr);
+
+       sec_sess = (struct rte_security_session **)&ut_params->sec_session;
+       ret = rte_security_inb_pkt_rx_inject(ctx, &ut_params->ibuf, sec_sess, 
1);
+
+       if (ret != 1)
+               return TEST_FAILED;
+
+       ut_params->ibuf = NULL;
+
+       /* Add a timeout for 1 s */
+       timeout = rte_get_tsc_cycles() + rte_get_tsc_hz();
+
+       do {
+               /* Get packet from port 0, queue 0 */
+               ret = rte_eth_rx_burst(0, 0, &m, 1);
+       } while ((ret == 0) && (rte_get_tsc_cycles() > timeout));
+
+       if (ret == 0) {
+               printf("Could not receive packets from ethdev\n");
+               return TEST_FAILED;
+       }
+
+       if (m == NULL) {
+               printf("Received mbuf is NULL\n");
+               return TEST_FAILED;
+       }
+
+       ut_params->ibuf = m;
+
+       if (!(m->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD)) {
+               printf("Received packet is not Rx security processed\n");
+               return TEST_FAILED;
+       }
+
+       if (m->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED) {
+               printf("Received packet has failed Rx security processing\n");
+               return TEST_FAILED;
+       }
+
+       eth_sec_ctx = rte_eth_dev_get_sec_ctx(0);
+       if (eth_sec_ctx == NULL) {
+               printf("Could not fetch ethdev sec ctx\n");
+               return TEST_FAILED;
+       }
+
+       /*
+        * 'ut_params' is set as userdata. Verify that the field is returned
+        * correctly.
+        */
+
+       userdata = rte_security_dynfield(m);
+       if (userdata != ut_params) {
+               printf("Userdata retrieved not matching expected\n");
+               return TEST_FAILED;
+       }
+
+       /* Trim L2 header */
+       rte_pktmbuf_adj(m, sizeof(struct rte_ether_hdr));
+
+       return TEST_SUCCESS;
+}
+
 static int
 test_ipsec_proto_process(const struct ipsec_test_data td[],
                         struct ipsec_test_data res_d[],
@@ -9937,6 +10167,9 @@ test_ipsec_proto_process(const struct ipsec_test_data 
td[],
                }
        }
 
+       if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && flags->rx_inject)
+               sess_conf.userdata = ut_params;
+
        /* Create security session */
        ut_params->sec_session = rte_security_session_create(ctx, &sess_conf,
                                        ts_params->session_mpool);
@@ -9959,58 +10192,29 @@ test_ipsec_proto_process(const struct ipsec_test_data 
td[],
 
                /* 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;
+               if (test_ipsec_pkt_update(input_text, flags)) {
+                       ret = TEST_FAILED;
+                       goto mbuf_free;
+               }
 
                /* 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);
-               if (!ut_params->op) {
-                       printf("TestCase %s line %d: %s\n",
-                               __func__, __LINE__,
-                               "failed to allocate crypto op");
-                       ret = TEST_FAILED;
-                       goto crypto_op_free;
-               }
-
-               /* Attach session to operation */
-               rte_security_attach_session(ut_params->op,
-                                           ut_params->sec_session);
-
-               /* Set crypto operation mbufs */
-               ut_params->op->sym->m_src = ut_params->ibuf;
-               ut_params->op->sym->m_dst = NULL;
-
-               /* Copy IV in crypto operation when IV generation is disabled */
-               if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
-                   ipsec_xform.options.iv_gen_disable == 1) {
-                       uint8_t *iv = rte_crypto_op_ctod_offset(ut_params->op,
-                                                               uint8_t *,
-                                                               IV_OFFSET);
-                       int len;
-
-                       if (td[i].aead)
-                               len = td[i].xform.aead.aead.iv.length;
-                       else if (td[i].aes_gmac)
-                               len = td[i].xform.chain.auth.auth.iv.length;
-                       else
-                               len = td[i].xform.chain.cipher.cipher.iv.length;
-
-                       memcpy(iv, td[i].iv.data, len);
-               }
-
-               /* Process crypto operation */
-               process_crypto_request(dev_id, ut_params->op);
+               if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
+                   flags->rx_inject)
+                       ret = test_ipsec_proto_mbuf_enq(ts_params, ut_params,
+                                                       ctx);
+               else
+                       ret = test_ipsec_proto_crypto_op_enq(ts_params,
+                                                            ut_params,
+                                                            &ipsec_xform,
+                                                            &td[i], flags,
+                                                            i + 1);
 
-               ret = test_ipsec_status_check(&td[i], ut_params->op, flags, dir,
-                                             i + 1);
                if (ret != TEST_SUCCESS)
-                       goto crypto_op_free;
+                       goto mbuf_free;
 
                if (res_d != NULL)
                        res_d_tmp = &res_d[i];
@@ -10018,24 +10222,18 @@ test_ipsec_proto_process(const struct ipsec_test_data 
td[],
                ret = test_ipsec_post_process(ut_params->ibuf, &td[i],
                                              res_d_tmp, silent, flags);
                if (ret != TEST_SUCCESS)
-                       goto crypto_op_free;
+                       goto mbuf_free;
 
                ret = test_ipsec_stats_verify(ctx, ut_params->sec_session,
                                              flags, dir);
                if (ret != TEST_SUCCESS)
-                       goto crypto_op_free;
-
-               rte_crypto_op_free(ut_params->op);
-               ut_params->op = NULL;
+                       goto mbuf_free;
 
                rte_pktmbuf_free(ut_params->ibuf);
                ut_params->ibuf = NULL;
        }
 
-crypto_op_free:
-       rte_crypto_op_free(ut_params->op);
-       ut_params->op = NULL;
-
+mbuf_free:
        rte_pktmbuf_free(ut_params->ibuf);
        ut_params->ibuf = NULL;
 
@@ -10100,6 +10298,24 @@ test_ipsec_proto_known_vec_fragmented(const void 
*test_data)
        return test_ipsec_proto_process(&td_outb, NULL, 1, false, &flags);
 }
 
+static int
+test_ipsec_proto_known_vec_inb_rx_inject(const void *test_data)
+{
+       const struct ipsec_test_data *td = test_data;
+       struct ipsec_test_flags flags;
+       struct ipsec_test_data td_inb;
+
+       memset(&flags, 0, sizeof(flags));
+       flags.rx_inject = true;
+
+       if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
+               test_ipsec_td_in_from_out(td, &td_inb);
+       else
+               memcpy(&td_inb, td, sizeof(td_inb));
+
+       return test_ipsec_proto_process(&td_inb, NULL, 1, false, &flags);
+}
+
 static int
 test_ipsec_proto_all(const struct ipsec_test_flags *flags)
 {
@@ -16133,6 +16349,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_WITH_DATA(
+                       "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 
128) Rx inject",
+                       ut_setup_security_rx_inject, ut_teardown_rx_inject,
+                       test_ipsec_proto_known_vec_inb_rx_inject, 
&pkt_aes_128_gcm),
                TEST_CASE_NAMED_ST(
                        "Multi-segmented mode",
                        ut_setup_security, ut_teardown,
diff --git a/app/test/test_cryptodev_security_ipsec.h 
b/app/test/test_cryptodev_security_ipsec.h
index 92e641ba0b..29fe0af6c6 100644
--- a/app/test/test_cryptodev_security_ipsec.h
+++ b/app/test/test_cryptodev_security_ipsec.h
@@ -110,6 +110,7 @@ struct ipsec_test_flags {
        bool ah;
        uint32_t plaintext_len;
        int nb_segs_in_mbuf;
+       bool rx_inject;
 };
 
 struct crypto_param {
-- 
2.25.1

Reply via email to