DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 0/2] examples/l3fwd: ACL mode fixups and improvements
@ 2024-05-02 15:28 Konstantin Ananyev
  2024-05-02 15:28 ` [PATCH 1/2] examples/l3fwd: fix crash in ACL mode for mixed traffic Konstantin Ananyev
  2024-05-02 15:28 ` [PATCH 2/2] examples/l3fwd: avoid packets reorder in ACL mode Konstantin Ananyev
  0 siblings, 2 replies; 3+ messages in thread
From: Konstantin Ananyev @ 2024-05-02 15:28 UTC (permalink / raw)
  To: dev; +Cc: Konstantin Ananyev

From: Konstantin Ananyev <konstantin.ananyev@huawei.com>

Konstantin Ananyev (2):
  examples/l3fwd: fix crash in ACL mode for mixed traffic
  examples/l3fwd: avoid packets reordering in ACL mode

 examples/l3fwd/l3fwd_acl.c        | 125 +++++++++++++++++++-----------
 examples/l3fwd/l3fwd_acl_scalar.h |  71 +++++++++--------
 2 files changed, 118 insertions(+), 78 deletions(-)

-- 
2.35.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] examples/l3fwd: fix crash in ACL mode for mixed traffic
  2024-05-02 15:28 [PATCH 0/2] examples/l3fwd: ACL mode fixups and improvements Konstantin Ananyev
@ 2024-05-02 15:28 ` Konstantin Ananyev
  2024-05-02 15:28 ` [PATCH 2/2] examples/l3fwd: avoid packets reorder in ACL mode Konstantin Ananyev
  1 sibling, 0 replies; 3+ messages in thread
From: Konstantin Ananyev @ 2024-05-02 15:28 UTC (permalink / raw)
  To: dev; +Cc: Konstantin Ananyev, stable

From: Konstantin Ananyev <konstantin.ananyev@huawei.com>

When running l3fwd in ACL mode, if we'll have mix of IPv4/IPv6 packets in
the same burst, it will most likely cause a crash.
The reason for that is that we split our burst of packets into 2 arrays -
one for ipv4, another for ipv6 for classify().
But then we try to send all packets as one burst again, not taking into account
that acl_search.res_ipv4[] will be set only for ipv4 packets.
Same story for ipv6.
The fix is straightforward: use two already split arrays for TX.

Bugzilla ID: 1434
Fixes: 6de0ea50e9b9 ("examples/l3fwd: merge l3fwd-acl example")
Cc: stable@dpdk.org

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>
---
 examples/l3fwd/l3fwd_acl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c
index 401692bcec..d9e4ae543f 100644
--- a/examples/l3fwd/l3fwd_acl.c
+++ b/examples/l3fwd/l3fwd_acl.c
@@ -1073,9 +1073,9 @@ acl_main_loop(__rte_unused void *dummy)
 
 					l3fwd_acl_send_packets(
 						qconf,
-						pkts_burst,
+						acl_search.m_ipv4,
 						acl_search.res_ipv4,
-						nb_rx);
+						acl_search.num_ipv4);
 				}
 
 				if (acl_search.num_ipv6) {
@@ -1088,9 +1088,9 @@ acl_main_loop(__rte_unused void *dummy)
 
 					l3fwd_acl_send_packets(
 						qconf,
-						pkts_burst,
+						acl_search.m_ipv6,
 						acl_search.res_ipv6,
-						nb_rx);
+						acl_search.num_ipv6);
 				}
 			}
 		}
-- 
2.35.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] examples/l3fwd: avoid packets reorder in ACL mode
  2024-05-02 15:28 [PATCH 0/2] examples/l3fwd: ACL mode fixups and improvements Konstantin Ananyev
  2024-05-02 15:28 ` [PATCH 1/2] examples/l3fwd: fix crash in ACL mode for mixed traffic Konstantin Ananyev
@ 2024-05-02 15:28 ` Konstantin Ananyev
  1 sibling, 0 replies; 3+ messages in thread
From: Konstantin Ananyev @ 2024-05-02 15:28 UTC (permalink / raw)
  To: dev; +Cc: Konstantin Ananyev

From: Konstantin Ananyev <konstantin.ananyev@huawei.com>

In ACL mode l3fwd first do classify() and send() for ipv4 packets,
then the same procedure for ipv6.
That might cause packets reordering within one ingress queue.
Probably not a big deal, as order within each flow are still preserved,
but better to be avoided anyway.
Specially considering that in other modes (lpm, fib, em) l3fwd does preserve
the order no matter of packet's IP version.
This patch aims to make ACL mode to behave in the same manner and preserve
packet's order within the same ingress queue.
Also these changes allow ACL mode to use common (and hopefully better optimized)
send_packets_multi() function at TX path.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>
---
 examples/l3fwd/l3fwd_acl.c        | 125 +++++++++++++++++++-----------
 examples/l3fwd/l3fwd_acl_scalar.h |  71 +++++++++--------
 2 files changed, 118 insertions(+), 78 deletions(-)

diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c
index d9e4ae543f..ab8222c9db 100644
--- a/examples/l3fwd/l3fwd_acl.c
+++ b/examples/l3fwd/l3fwd_acl.c
@@ -235,18 +235,6 @@ enum {
 RTE_ACL_RULE_DEF(acl4_rule, RTE_DIM(ipv4_defs));
 RTE_ACL_RULE_DEF(acl6_rule, RTE_DIM(ipv6_defs));
 
-struct acl_search_t {
-	const uint8_t *data_ipv4[MAX_PKT_BURST];
-	struct rte_mbuf *m_ipv4[MAX_PKT_BURST];
-	uint32_t res_ipv4[MAX_PKT_BURST];
-	int num_ipv4;
-
-	const uint8_t *data_ipv6[MAX_PKT_BURST];
-	struct rte_mbuf *m_ipv6[MAX_PKT_BURST];
-	uint32_t res_ipv6[MAX_PKT_BURST];
-	int num_ipv6;
-};
-
 static struct {
 	struct rte_acl_ctx *acx_ipv4[NB_SOCKETS];
 	struct rte_acl_ctx *acx_ipv6[NB_SOCKETS];
@@ -988,11 +976,86 @@ setup_acl(const int socket_id)
 
 }
 
+static inline void
+dump_denied_pkt(const struct rte_mbuf *pkt, uint32_t res)
+{
+#ifdef L3FWDACL_DEBUG
+	if ((res & ACL_DENY_SIGNATURE) != 0) {
+		if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type))
+			dump_acl4_rule(pkt, res);
+		else if (RTE_ETH_IS_IPV6_HDR(pkt[i]->packet_type))
+			dump_acl6_rule(pkt[i], res[i]);
+	}
+#else
+	RTE_SET_USED(pkt);
+	RTE_SET_USED(res);
+#endif
+}
+
+static inline void
+acl_process_pkts(struct rte_mbuf *pkts[MAX_PKT_BURST],
+	uint16_t hops[MAX_PKT_BURST], uint32_t num, int32_t socketid)
+{
+	uint32_t i, n4, n6, res;
+	struct acl_search_t acl_search;
+
+	/* split packets burst depending on packet type (IPv4/IPv6) */
+	l3fwd_acl_prepare_acl_parameter(pkts, &acl_search, num);
+
+	if (acl_search.num_ipv4)
+		rte_acl_classify(acl_config.acx_ipv4[socketid],
+				acl_search.data_ipv4,
+				acl_search.res_ipv4,
+				acl_search.num_ipv4,
+				DEFAULT_MAX_CATEGORIES);
+
+	if (acl_search.num_ipv6)
+		rte_acl_classify(acl_config.acx_ipv6[socketid],
+				acl_search.data_ipv6,
+				acl_search.res_ipv6,
+				acl_search.num_ipv6,
+				DEFAULT_MAX_CATEGORIES);
+
+	/* combine lookup results back, into one array of next hops */
+	n4 = 0;
+	n6 = 0;
+	for (i = 0; i != num; i++) {
+		switch (acl_search.types[i]) {
+		case TYPE_IPV4:
+			res = acl_search.res_ipv4[n4++];
+			break;
+		case TYPE_IPV6:
+			res = acl_search.res_ipv6[n6++];
+			break;
+		default:
+			res = 0;
+		}
+		if (likely((res & ACL_DENY_SIGNATURE) == 0 && res != 0))
+			hops[i] = res - FWD_PORT_SHIFT;
+		else {
+			hops[i] = BAD_PORT;
+			dump_denied_pkt(pkts[i], res);
+		}
+	}
+}
+
+static inline void
+acl_send_packets(struct lcore_conf *qconf, struct rte_mbuf *pkts[],
+	uint16_t hops[], uint32_t num)
+{
+#if defined ACL_SEND_MULTI
+	send_packets_multi(qconf, pkts, hops, num);
+#else
+	send_packets_single(qconf, pkts, hops, num);
+#endif
+}
+
 /* main processing loop */
 int
 acl_main_loop(__rte_unused void *dummy)
 {
 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+	uint16_t hops[MAX_PKT_BURST];
 	unsigned int lcore_id;
 	uint64_t prev_tsc, diff_tsc, cur_tsc;
 	int i, nb_rx;
@@ -1048,7 +1111,7 @@ acl_main_loop(__rte_unused void *dummy)
 		}
 
 		/*
-		 * Read packet from RX queues
+		 * Read packet from RX queues and process them
 		 */
 		for (i = 0; i < qconf->n_rx_queue; ++i) {
 
@@ -1058,40 +1121,10 @@ acl_main_loop(__rte_unused void *dummy)
 				pkts_burst, MAX_PKT_BURST);
 
 			if (nb_rx > 0) {
-				struct acl_search_t acl_search;
-
-				l3fwd_acl_prepare_acl_parameter(pkts_burst, &acl_search,
+				acl_process_pkts(pkts_burst, hops, nb_rx,
+					socketid);
+				acl_send_packets(qconf, pkts_burst, hops,
 					nb_rx);
-
-				if (acl_search.num_ipv4) {
-					rte_acl_classify(
-						acl_config.acx_ipv4[socketid],
-						acl_search.data_ipv4,
-						acl_search.res_ipv4,
-						acl_search.num_ipv4,
-						DEFAULT_MAX_CATEGORIES);
-
-					l3fwd_acl_send_packets(
-						qconf,
-						acl_search.m_ipv4,
-						acl_search.res_ipv4,
-						acl_search.num_ipv4);
-				}
-
-				if (acl_search.num_ipv6) {
-					rte_acl_classify(
-						acl_config.acx_ipv6[socketid],
-						acl_search.data_ipv6,
-						acl_search.res_ipv6,
-						acl_search.num_ipv6,
-						DEFAULT_MAX_CATEGORIES);
-
-					l3fwd_acl_send_packets(
-						qconf,
-						acl_search.m_ipv6,
-						acl_search.res_ipv6,
-						acl_search.num_ipv6);
-				}
 			}
 		}
 	}
diff --git a/examples/l3fwd/l3fwd_acl_scalar.h b/examples/l3fwd/l3fwd_acl_scalar.h
index 542c303d3b..cb22bb49aa 100644
--- a/examples/l3fwd/l3fwd_acl_scalar.h
+++ b/examples/l3fwd/l3fwd_acl_scalar.h
@@ -6,7 +6,40 @@
 #define L3FWD_ACL_SCALAR_H
 
 #include "l3fwd.h"
+#if defined RTE_ARCH_X86
+#include "l3fwd_sse.h"
+#elif defined __ARM_NEON
+#include "l3fwd_neon.h"
+#elif defined RTE_ARCH_PPC_64
+#include "l3fwd_altivec.h"
+#else
 #include "l3fwd_common.h"
+#endif
+/*
+ * If the machine has SSE, NEON or PPC 64 then multiple packets
+ * can be sent at once if not only single packets will be sent.
+ */
+#if defined RTE_ARCH_X86 || defined __ARM_NEON || defined RTE_ARCH_PPC_64
+#define ACL_SEND_MULTI
+#endif
+
+#define TYPE_NONE	0
+#define TYPE_IPV4	1
+#define TYPE_IPV6	2
+
+struct acl_search_t {
+
+	uint32_t num_ipv4;
+	uint32_t num_ipv6;
+
+	uint8_t types[MAX_PKT_BURST];
+
+	const uint8_t *data_ipv4[MAX_PKT_BURST];
+	uint32_t res_ipv4[MAX_PKT_BURST];
+
+	const uint8_t *data_ipv6[MAX_PKT_BURST];
+	uint32_t res_ipv6[MAX_PKT_BURST];
+};
 
 static inline void
 l3fwd_acl_prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
@@ -16,16 +49,16 @@ l3fwd_acl_prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl
 
 	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
 		/* Fill acl structure */
-		acl->data_ipv4[acl->num_ipv4] = MBUF_IPV4_2PROTO(pkt);
-		acl->m_ipv4[(acl->num_ipv4)++] = pkt;
+		acl->data_ipv4[acl->num_ipv4++] = MBUF_IPV4_2PROTO(pkt);
+		acl->types[index] = TYPE_IPV4;
 
 	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
 		/* Fill acl structure */
-		acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
-		acl->m_ipv6[(acl->num_ipv6)++] = pkt;
+		acl->data_ipv6[acl->num_ipv6++] = MBUF_IPV6_2PROTO(pkt);
+		acl->types[index] = TYPE_IPV6;
 	} else {
-		/* Unknown type, drop the packet */
-		rte_pktmbuf_free(pkt);
+		/* Unknown type, will drop the packet */
+		acl->types[index] = TYPE_NONE;
 	}
 }
 
@@ -80,30 +113,4 @@ send_packets_single(struct lcore_conf *qconf, struct rte_mbuf *pkts[], uint16_t
 	}
 }
 
-static inline void
-l3fwd_acl_send_packets(struct lcore_conf *qconf, struct rte_mbuf *pkts[], uint32_t res[],
-	uint32_t nb_tx)
-{
-	uint32_t i;
-	uint16_t dst_port[nb_tx];
-
-	for (i = 0; i != nb_tx; i++) {
-		if (likely((res[i] & ACL_DENY_SIGNATURE) == 0 && res[i] != 0)) {
-			dst_port[i] = res[i] - FWD_PORT_SHIFT;
-		} else {
-			dst_port[i] = BAD_PORT;
-#ifdef L3FWDACL_DEBUG
-			if ((res & ACL_DENY_SIGNATURE) != 0) {
-				if (RTE_ETH_IS_IPV4_HDR(pkts[i]->packet_type))
-					dump_acl4_rule(pkts[i], res[i]);
-				else if (RTE_ETH_IS_IPV6_HDR(pkt[i]->packet_type))
-					dump_acl6_rule(pkt[i], res[i]);
-			}
-#endif
-		}
-	}
-
-	send_packets_single(qconf, pkts, dst_port, nb_tx);
-}
-
 #endif /* L3FWD_ACL_SCALAR_H */
-- 
2.35.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-05-02 15:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-02 15:28 [PATCH 0/2] examples/l3fwd: ACL mode fixups and improvements Konstantin Ananyev
2024-05-02 15:28 ` [PATCH 1/2] examples/l3fwd: fix crash in ACL mode for mixed traffic Konstantin Ananyev
2024-05-02 15:28 ` [PATCH 2/2] examples/l3fwd: avoid packets reorder in ACL mode Konstantin Ananyev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).