X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=inline;f=app%2Ftest%2Ftest_cryptodev_security_ipsec.c;h=970d4d435db00399fc1a611f328aa9c9b8c66929;hb=70c60cfd93e75f91325c4f2b648df3a0200e7014;hp=ccce63f0adb0fc2a544189c32189fc58311d47dd;hpb=b7986bde8e2159b75b45ff92579d9ba19bda4c1b;p=dpdk.git diff --git a/app/test/test_cryptodev_security_ipsec.c b/app/test/test_cryptodev_security_ipsec.c index ccce63f0ad..970d4d435d 100644 --- a/app/test/test_cryptodev_security_ipsec.c +++ b/app/test/test_cryptodev_security_ipsec.c @@ -2,6 +2,8 @@ * Copyright(C) 2021 Marvell. */ +#ifndef RTE_EXEC_ENV_WINDOWS + #include #include #include @@ -375,6 +377,8 @@ test_ipsec_td_prepare(const struct crypto_param *param1, td->xform.chain.cipher.cipher.algo = param1->alg.cipher; td->xform.chain.cipher.cipher.key.length = param1->key_length; + td->xform.chain.cipher.cipher.iv.length = + param1->iv_length; td->xform.chain.auth.auth.algo = param2->alg.auth; td->xform.chain.auth.auth.key.length = param2->key_length; @@ -400,13 +404,38 @@ test_ipsec_td_prepare(const struct crypto_param *param1, test_ipsec_csum_init(&td->input_text.data, false, true); } - if (flags->tunnel_ipv6) - td->ipsec_xform.tunnel.type = - RTE_SECURITY_IPSEC_TUNNEL_IPV6; - else - td->ipsec_xform.tunnel.type = - RTE_SECURITY_IPSEC_TUNNEL_IPV4; + if (flags->transport) { + td->ipsec_xform.mode = + RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT; + } else { + td->ipsec_xform.mode = + RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + + if (flags->tunnel_ipv6) + td->ipsec_xform.tunnel.type = + RTE_SECURITY_IPSEC_TUNNEL_IPV6; + else + td->ipsec_xform.tunnel.type = + RTE_SECURITY_IPSEC_TUNNEL_IPV4; + } + + if (flags->stats_success) + td->ipsec_xform.options.stats = 1; + if (flags->fragment) { + struct rte_ipv4_hdr *ip; + ip = (struct rte_ipv4_hdr *)&td->input_text.data; + ip->fragment_offset = 4; + ip->hdr_checksum = rte_ipv4_cksum(ip); + } + + 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; } } @@ -620,6 +649,7 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td, { uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *); uint32_t skip, len = rte_pktmbuf_pkt_len(m); + uint8_t td_output_text[4096]; int ret; /* For tests with status as error for test success, skip verification */ @@ -700,16 +730,21 @@ test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td, return ret; } + memcpy(td_output_text, td->output_text.data + skip, len); + + if (test_ipsec_pkt_update(td_output_text, flags)) { + printf("Could not update expected vector"); + return TEST_FAILED; + } - if (memcmp(output_text, td->output_text.data + skip, len)) { + if (memcmp(output_text, td_output_text, len)) { if (silent) return TEST_FAILED; printf("TestCase %s line %d: %s\n", __func__, __LINE__, "output text not as expected\n"); - rte_hexdump(stdout, "expected", td->output_text.data + skip, - len); + rte_hexdump(stdout, "expected", td_output_text, len); rte_hexdump(stdout, "actual", output_text, len); return TEST_FAILED; } @@ -740,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, @@ -748,29 +864,41 @@ test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td, uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *); int ret; - if (flags->iv_gen && - td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { - ret = test_ipsec_iv_verify_push(m, td); - if (ret != TEST_SUCCESS) - return ret; - } - if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { const struct rte_ipv4_hdr *iph4; const struct rte_ipv6_hdr *iph6; - if (td->ipsec_xform.tunnel.type == - RTE_SECURITY_IPSEC_TUNNEL_IPV4) { - iph4 = (const struct rte_ipv4_hdr *)output_text; - if (is_valid_ipv4_pkt(iph4) == false) { - printf("Outer header is not IPv4\n"); - return TEST_FAILED; + if (flags->iv_gen) { + ret = test_ipsec_iv_verify_push(m, td); + if (ret != TEST_SUCCESS) + return ret; + } + + iph4 = (const struct rte_ipv4_hdr *)output_text; + + if (td->ipsec_xform.mode == + RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) { + if (flags->ipv6) { + iph6 = (const struct rte_ipv6_hdr *)output_text; + if (is_valid_ipv6_pkt(iph6) == false) { + printf("Transport packet is not IPv6\n"); + return TEST_FAILED; + } + } else { + if (is_valid_ipv4_pkt(iph4) == false) { + printf("Transport packet is not IPv4\n"); + return TEST_FAILED; + } } } else { - iph6 = (const struct rte_ipv6_hdr *)output_text; - if (is_valid_ipv6_pkt(iph6) == false) { - printf("Outer header is not IPv6\n"); - return TEST_FAILED; + if (td->ipsec_xform.tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV4) { + if (test_ipsec_iph4_hdr_validate(iph4, flags)) + return TEST_FAILED; + } else { + iph6 = (const struct rte_ipv6_hdr *)output_text; + if (test_ipsec_iph6_hdr_validate(iph6, flags)) + return TEST_FAILED; } } } @@ -846,3 +974,107 @@ test_ipsec_status_check(struct rte_crypto_op *op, return ret; } + +int +test_ipsec_stats_verify(struct rte_security_ctx *ctx, + struct rte_security_session *sess, + const struct ipsec_test_flags *flags, + enum rte_security_ipsec_sa_direction dir) +{ + struct rte_security_stats stats = {0}; + int ret = TEST_SUCCESS; + + if (flags->stats_success) { + if (rte_security_session_stats_get(ctx, sess, &stats) < 0) + return TEST_FAILED; + + if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { + if (stats.ipsec.opackets != 1 || + stats.ipsec.oerrors != 0) + ret = TEST_FAILED; + } else { + if (stats.ipsec.ipackets != 1 || + stats.ipsec.ierrors != 0) + ret = TEST_FAILED; + } + } + + return ret; +} + +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; + + iph4 = (struct rte_ipv4_hdr *)pkt; + + if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 || + 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\n"); + return -1; + } + + frag_off = rte_be_to_cpu_16(iph4->fragment_offset); + + if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 || + flags->df == TEST_IPSEC_SET_DF_0_INNER_1) + frag_off |= RTE_IPV4_HDR_DF_FLAG; + else + frag_off &= ~RTE_IPV4_HDR_DF_FLAG; + + iph4->fragment_offset = rte_cpu_to_be_16(frag_off); + 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); + } + + return 0; +} + +#endif /* !RTE_EXEC_ENV_WINDOWS */