+
+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 */