test/crypto: add copy and set DSCP cases
authorAnoob Joseph <anoobj@marvell.com>
Mon, 31 Jan 2022 16:43:56 +0000 (22:13 +0530)
committerAkhil Goyal <gakhil@marvell.com>
Tue, 22 Feb 2022 18:05:11 +0000 (19:05 +0100)
Add test cases to verify copy and set DSCP with
IPv4 and IPv6 tunnels.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Acked-by: Akhil Goyal <gakhil@marvell.com>
app/test/test_cryptodev.c
app/test/test_cryptodev_security_ipsec.c
app/test/test_cryptodev_security_ipsec.h

index a63c199..ca79ff2 100644 (file)
@@ -9185,7 +9185,21 @@ test_ipsec_proto_process(const struct ipsec_test_data td[],
                        if (flags->df == TEST_IPSEC_SET_DF_1_INNER_0)
                                ipsec_xform.tunnel.ipv4.df = 1;
 
+                       if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
+                               ipsec_xform.tunnel.ipv4.dscp = 0;
+
+                       if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0)
+                               ipsec_xform.tunnel.ipv4.dscp =
+                                               TEST_IPSEC_DSCP_VAL;
+
                } else {
+                       if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
+                               ipsec_xform.tunnel.ipv6.dscp = 0;
+
+                       if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0)
+                               ipsec_xform.tunnel.ipv6.dscp =
+                                               TEST_IPSEC_DSCP_VAL;
+
                        memcpy(&ipsec_xform.tunnel.ipv6.src_addr, &v6_src,
                               sizeof(v6_src));
                        memcpy(&ipsec_xform.tunnel.ipv6.dst_addr, &v6_dst,
@@ -9770,6 +9784,126 @@ test_ipsec_proto_set_df_1_inner_0(const void *data __rte_unused)
        return test_ipsec_proto_all(&flags);
 }
 
+static int
+test_ipsec_proto_ipv4_copy_dscp_inner_0(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv4_copy_dscp_inner_1(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv4_set_dscp_0_inner_1(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       if (gbl_driver_id == rte_cryptodev_driver_id_get(
+                       RTE_STR(CRYPTODEV_NAME_CN9K_PMD)))
+               return TEST_SKIPPED;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv4_set_dscp_1_inner_0(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       if (gbl_driver_id == rte_cryptodev_driver_id_get(
+                       RTE_STR(CRYPTODEV_NAME_CN9K_PMD)))
+               return TEST_SKIPPED;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv6_copy_dscp_inner_0(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.ipv6 = true;
+       flags.tunnel_ipv6 = true;
+       flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv6_copy_dscp_inner_1(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.ipv6 = true;
+       flags.tunnel_ipv6 = true;
+       flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv6_set_dscp_0_inner_1(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       if (gbl_driver_id == rte_cryptodev_driver_id_get(
+                       RTE_STR(CRYPTODEV_NAME_CN9K_PMD)))
+               return TEST_SKIPPED;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.ipv6 = true;
+       flags.tunnel_ipv6 = true;
+       flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1;
+
+       return test_ipsec_proto_all(&flags);
+}
+
+static int
+test_ipsec_proto_ipv6_set_dscp_1_inner_0(const void *data __rte_unused)
+{
+       struct ipsec_test_flags flags;
+
+       if (gbl_driver_id == rte_cryptodev_driver_id_get(
+                       RTE_STR(CRYPTODEV_NAME_CN9K_PMD)))
+               return TEST_SKIPPED;
+
+       memset(&flags, 0, sizeof(flags));
+
+       flags.ipv6 = true;
+       flags.tunnel_ipv6 = true;
+       flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0;
+
+       return test_ipsec_proto_all(&flags);
+}
+
 static int
 test_PDCP_PROTO_all(void)
 {
@@ -14808,6 +14942,38 @@ static struct unit_test_suite ipsec_proto_testsuite  = {
                        "Tunnel header set DF 1 (inner 0)",
                        ut_setup_security, ut_teardown,
                        test_ipsec_proto_set_df_1_inner_0),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv4 copy DSCP (inner 0)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv4_copy_dscp_inner_0),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv4 copy DSCP (inner 1)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv4_copy_dscp_inner_1),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv4 set DSCP 0 (inner 1)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv4_set_dscp_0_inner_1),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv4 set DSCP 1 (inner 0)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv4_set_dscp_1_inner_0),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv6 copy DSCP (inner 0)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv6_copy_dscp_inner_0),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv6 copy DSCP (inner 1)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv6_copy_dscp_inner_1),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv6 set DSCP 0 (inner 1)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv6_set_dscp_0_inner_1),
+               TEST_CASE_NAMED_ST(
+                       "Tunnel header IPv6 set DSCP 1 (inner 0)",
+                       ut_setup_security, ut_teardown,
+                       test_ipsec_proto_ipv6_set_dscp_1_inner_0),
                TEST_CASES_END() /**< NULL terminate unit test array */
        }
 };
index 229eadf..970d4d4 100644 (file)
@@ -432,6 +432,10 @@ test_ipsec_td_prepare(const struct crypto_param *param1,
                if (flags->df == TEST_IPSEC_COPY_DF_INNER_0 ||
                    flags->df == TEST_IPSEC_COPY_DF_INNER_1)
                        td->ipsec_xform.options.copy_df = 1;
+
+               if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_0 ||
+                   flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1)
+                       td->ipsec_xform.options.copy_dscp = 1;
        }
 }
 
@@ -771,6 +775,87 @@ test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td,
        return TEST_SUCCESS;
 }
 
+static int
+test_ipsec_iph4_hdr_validate(const struct rte_ipv4_hdr *iph4,
+                            const struct ipsec_test_flags *flags)
+{
+       uint8_t tos, dscp;
+       uint16_t f_off;
+
+       if (!is_valid_ipv4_pkt(iph4)) {
+               printf("Tunnel outer header is not IPv4\n");
+               return -1;
+       }
+
+       f_off = rte_be_to_cpu_16(iph4->fragment_offset);
+       if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 ||
+           flags->df == TEST_IPSEC_SET_DF_1_INNER_0) {
+               if (!(f_off & RTE_IPV4_HDR_DF_FLAG)) {
+                       printf("DF bit is not set\n");
+                       return -1;
+               }
+       } else {
+               if (f_off & RTE_IPV4_HDR_DF_FLAG) {
+                       printf("DF bit is set\n");
+                       return -1;
+               }
+       }
+
+       tos = iph4->type_of_service;
+       dscp = (tos & RTE_IPV4_HDR_DSCP_MASK) >> 2;
+
+       if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
+           flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) {
+               if (dscp != TEST_IPSEC_DSCP_VAL) {
+                       printf("DSCP value is not matching [exp: %x, actual: %x]\n",
+                              TEST_IPSEC_DSCP_VAL, dscp);
+                       return -1;
+               }
+       } else {
+               if (dscp != 0) {
+                       printf("DSCP value is set [exp: 0, actual: %x]\n",
+                              dscp);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+static int
+test_ipsec_iph6_hdr_validate(const struct rte_ipv6_hdr *iph6,
+                            const struct ipsec_test_flags *flags)
+{
+       uint32_t vtc_flow;
+       uint8_t dscp;
+
+       if (!is_valid_ipv6_pkt(iph6)) {
+               printf("Tunnel outer header is not IPv6\n");
+               return -1;
+       }
+
+       vtc_flow = rte_be_to_cpu_32(iph6->vtc_flow);
+       dscp = (vtc_flow & RTE_IPV6_HDR_DSCP_MASK) >>
+              (RTE_IPV6_HDR_TC_SHIFT + 2);
+
+       if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
+           flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) {
+               if (dscp != TEST_IPSEC_DSCP_VAL) {
+                       printf("DSCP value is not matching [exp: %x, actual: %x]\n",
+                              TEST_IPSEC_DSCP_VAL, dscp);
+                       return -1;
+               }
+       } else {
+               if (dscp != 0) {
+                       printf("DSCP value is set [exp: 0, actual: %x]\n",
+                              dscp);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 int
 test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
                        struct ipsec_test_data *res_d, bool silent,
@@ -808,33 +893,12 @@ test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
                } else {
                        if (td->ipsec_xform.tunnel.type ==
                                        RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
-                               uint16_t f_off;
-
-                               if (is_valid_ipv4_pkt(iph4) == false) {
-                                       printf("Tunnel outer header is not IPv4\n");
+                               if (test_ipsec_iph4_hdr_validate(iph4, flags))
                                        return TEST_FAILED;
-                               }
-
-                               f_off = rte_be_to_cpu_16(iph4->fragment_offset);
-
-                               if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 ||
-                                   flags->df == TEST_IPSEC_SET_DF_1_INNER_0) {
-                                       if (!(f_off & RTE_IPV4_HDR_DF_FLAG)) {
-                                               printf("DF bit is not set\n");
-                                               return TEST_FAILED;
-                                       }
-                               } else {
-                                       if ((f_off & RTE_IPV4_HDR_DF_FLAG)) {
-                                               printf("DF bit is set\n");
-                                               return TEST_FAILED;
-                                       }
-                               }
                        } else {
                                iph6 = (const struct rte_ipv6_hdr *)output_text;
-                               if (is_valid_ipv6_pkt(iph6) == false) {
-                                       printf("Tunnel outer header is not IPv6\n");
+                               if (test_ipsec_iph6_hdr_validate(iph6, flags))
                                        return TEST_FAILED;
-                               }
                        }
                }
        }
@@ -942,8 +1006,8 @@ int
 test_ipsec_pkt_update(uint8_t *pkt, const struct ipsec_test_flags *flags)
 {
        struct rte_ipv4_hdr *iph4;
+       struct rte_ipv6_hdr *iph6;
        bool cksum_dirty = false;
-       uint16_t frag_off;
 
        iph4 = (struct rte_ipv4_hdr *)pkt;
 
@@ -951,9 +1015,10 @@ test_ipsec_pkt_update(uint8_t *pkt, const struct ipsec_test_flags *flags)
            flags->df == TEST_IPSEC_SET_DF_0_INNER_1 ||
            flags->df == TEST_IPSEC_COPY_DF_INNER_0 ||
            flags->df == TEST_IPSEC_SET_DF_1_INNER_0) {
+               uint16_t frag_off;
 
                if (!is_ipv4(iph4)) {
-                       printf("Invalid packet type");
+                       printf("Invalid packet type\n");
                        return -1;
                }
 
@@ -969,6 +1034,41 @@ test_ipsec_pkt_update(uint8_t *pkt, const struct ipsec_test_flags *flags)
                cksum_dirty = true;
        }
 
+       if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
+           flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1 ||
+           flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_0 ||
+           flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) {
+
+               if (is_ipv4(iph4)) {
+                       uint8_t tos;
+
+                       tos = iph4->type_of_service;
+                       if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
+                           flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
+                               tos |= (RTE_IPV4_HDR_DSCP_MASK &
+                                       (TEST_IPSEC_DSCP_VAL << 2));
+                       else
+                               tos &= ~RTE_IPV4_HDR_DSCP_MASK;
+
+                       iph4->type_of_service = tos;
+                       cksum_dirty = true;
+               } else {
+                       uint32_t vtc_flow;
+
+                       iph6 = (struct rte_ipv6_hdr *)pkt;
+
+                       vtc_flow = rte_be_to_cpu_32(iph6->vtc_flow);
+                       if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 ||
+                           flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)
+                               vtc_flow |= (RTE_IPV6_HDR_DSCP_MASK &
+                                            (TEST_IPSEC_DSCP_VAL << (RTE_IPV6_HDR_TC_SHIFT + 2)));
+                       else
+                               vtc_flow &= ~RTE_IPV6_HDR_DSCP_MASK;
+
+                       iph6->vtc_flow = rte_cpu_to_be_32(vtc_flow);
+               }
+       }
+
        if (cksum_dirty && is_ipv4(iph4)) {
                iph4->hdr_checksum = 0;
                iph4->hdr_checksum = rte_ipv4_cksum(iph4);
index 12a9b77..c4ecfaf 100644 (file)
@@ -57,6 +57,15 @@ enum df_flags {
        TEST_IPSEC_SET_DF_1_INNER_0,
 };
 
+#define TEST_IPSEC_DSCP_VAL 0x12
+
+enum dscp_flags {
+       TEST_IPSEC_COPY_DSCP_INNER_0 = 1,
+       TEST_IPSEC_COPY_DSCP_INNER_1,
+       TEST_IPSEC_SET_DSCP_0_INNER_1,
+       TEST_IPSEC_SET_DSCP_1_INNER_0,
+};
+
 struct ipsec_test_flags {
        bool display_alg;
        bool sa_expiry_pkts_soft;
@@ -74,6 +83,7 @@ struct ipsec_test_flags {
        bool fragment;
        bool stats_success;
        enum df_flags df;
+       enum dscp_flags dscp;
 };
 
 struct crypto_param {