* [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
@ 2026-02-19 9:25 Harsh raj Singh
2026-02-20 17:25 ` Stephen Hemminger
0 siblings, 1 reply; 7+ messages in thread
From: Harsh raj Singh @ 2026-02-19 9:25 UTC (permalink / raw)
To: dev
From 9d87abade4e79b4377367bbcbf79a1095beed127 Mon Sep 17 00:00:00 2001
From: Harsh Raj Singh <harshraj215@gmail.com>
Date: Thu, 19 Feb 2026 14:16:16 +0530
Subject: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
This example demonstrates usage of the DPDK ACL library
to classify packets based on:
- protocol
- source IPv4
- destination IPv4
- source port
- destination port
Packets matching ACL rules are forwarded,
others are dropped.
The example provides a minimal reference
for developers wanting to integrate ACL
classification into packet forwarding paths.
Signed-off-by: Harsh Raj Singh <harshraj215@gmail.com>
---
examples/l2fwd_acl/README.md | 18 +++
examples/l2fwd_acl/main.c | 249 +++++++++++++++++++++++++++++++++
examples/l2fwd_acl/meson.build | 4 +
examples/meson.build | 1 +
4 files changed, 272 insertions(+)
create mode 100644 examples/l2fwd_acl/README.md
create mode 100644 examples/l2fwd_acl/main.c
create mode 100644 examples/l2fwd_acl/meson.build
diff --git a/examples/l2fwd_acl/README.md b/examples/l2fwd_acl/README.md
new file mode 100644
index 0000000000..5b5494e297
--- /dev/null
+++ b/examples/l2fwd_acl/README.md
@@ -0,0 +1,18 @@
+L2 Forwarding with ACL Example
+==============================
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
2026-02-19 9:25 [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example Harsh raj Singh
@ 2026-02-20 17:25 ` Stephen Hemminger
0 siblings, 0 replies; 7+ messages in thread
From: Stephen Hemminger @ 2026-02-20 17:25 UTC (permalink / raw)
To: Harsh raj Singh; +Cc: dev
On Thu, 19 Feb 2026 14:55:02 +0530
Harsh raj Singh <singhharshraj215@gmail.com> wrote:
> From 9d87abade4e79b4377367bbcbf79a1095beed127 Mon Sep 17 00:00:00 2001
> From: Harsh Raj Singh <harshraj215@gmail.com>
> Date: Thu, 19 Feb 2026 14:16:16 +0530
> Subject: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
>
> This example demonstrates usage of the DPDK ACL library
> to classify packets based on:
>
> - protocol
> - source IPv4
> - destination IPv4
> - source port
> - destination port
>
> Packets matching ACL rules are forwarded,
> others are dropped.
>
> The example provides a minimal reference
> for developers wanting to integrate ACL
> classification into packet forwarding paths.
>
> Signed-off-by: Harsh Raj Singh <harshraj215@gmail.com>
> ---
> examples/l2fwd_acl/README.md | 18 +++
> examples/l2fwd_acl/main.c | 249 +++++++++++++++++++++++++++++++++
> examples/l2fwd_acl/meson.build | 4 +
> examples/meson.build | 1 +
> 4 files changed, 272 insertions(+)
> create mode 100644 examples/l2fwd_acl/README.md
> create mode 100644 examples/l2fwd_acl/main.c
> create mode 100644 examples/l2fwd_acl/meson.build
>
> diff --git a/examples/l2fwd_acl/README.md b/examples/l2fwd_acl/README.md
> new file mode 100644
> index 0000000000..5b5494e297
> --- /dev/null
> +++ b/examples/l2fwd_acl/README.md
> @@ -0,0 +1,18 @@
> +L2 Forwarding with ACL Example
> +==============================
Patch is corrupt and truncated.
The rest of the patch never got sent in email.
Check your mail client or use git send-email.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
@ 2026-02-20 18:43 Harsh raj Singh
2026-02-23 4:28 ` Harsh raj Singh
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Harsh raj Singh @ 2026-02-20 18:43 UTC (permalink / raw)
To: dev
[-- Attachment #1: Type: text/plain, Size: 103 bytes --]
Hi,
Please find attached my patch adding an ACL-based L2 forwarding example.
Thanks,
Harsh Raj Singh
[-- Attachment #2: 0001-examples-l2fwd_acl-add-ACL-based-L2-forwarding-examp.patch --]
[-- Type: text/x-patch, Size: 9558 bytes --]
From 27423213cde0594243b96114d67ade6f51cdf764 Mon Sep 17 00:00:00 2001
From: Harsh Raj Singh <harshraj215@gmail.com>
Date: Thu, 19 Feb 2026 14:16:16 +0530
Subject: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
This example demonstrates usage of the DPDK ACL library
to classify packets based on:
- protocol
- source IPv4
- destination IPv4
- source port
- destination port
Packets matching ACL rules are forwarded,
others are dropped.
The example provides a minimal reference
for developers wanting to integrate ACL
classification into packet forwarding paths.
Signed-off-by: Harsh Raj Singh <harshraj215@gmail.com>
---
examples/l2fwd_acl/README.md | 18 +++
examples/l2fwd_acl/main.c | 247 +++++++++++++++++++++++++++++++++
examples/l2fwd_acl/meson.build | 3 +
examples/meson.build | 1 +
4 files changed, 269 insertions(+)
create mode 100644 examples/l2fwd_acl/README.md
create mode 100644 examples/l2fwd_acl/main.c
create mode 100644 examples/l2fwd_acl/meson.build
diff --git a/examples/l2fwd_acl/README.md b/examples/l2fwd_acl/README.md
new file mode 100644
index 0000000000..5b5494e297
--- /dev/null
+++ b/examples/l2fwd_acl/README.md
@@ -0,0 +1,18 @@
+L2 Forwarding with ACL Example
+==============================
+
+This example demonstrates use of the DPDK ACL library
+to classify packets based on:
+
+- protocol
+- source IPv4
+- destination IPv4
+- source port
+- destination port
+
+Packets matching ACL rules are forwarded,
+others are dropped.
+
+Run:
+
+./dpdk-l2fwd-acl -l 0-2 -n 4 -- -p 0x1
diff --git a/examples/l2fwd_acl/main.c b/examples/l2fwd_acl/main.c
new file mode 100644
index 0000000000..6e05145b33
--- /dev/null
+++ b/examples/l2fwd_acl/main.c
@@ -0,0 +1,247 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * l2fwd_acl example: demonstrates use of DPDK ACL library
+ */
+
+#include <stdbool.h>
+#include <signal.h>
+#include <getopt.h>
+#include <stdlib.h>
+
+#include <rte_acl.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_ip.h>
+#include <rte_mbuf.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
+#include <rte_log.h>
+
+#define NUM_FIELDS 5
+#define MAX_RULES 32
+#define NB_MBUF 8192
+#define BURST 32
+
+/* ---- Correct DPDK logging style ---- */
+#define RTE_LOGTYPE_L2FWD_ACL RTE_LOGTYPE_USER1
+#define LOGTYPE_L2FWD_ACL RTE_LOGTYPE_L2FWD_ACL
+
+RTE_ACL_RULE_DEF(acl_rule, NUM_FIELDS);
+
+struct pkt_key {
+ uint8_t proto;
+ uint32_t src_ip;
+ uint32_t dst_ip;
+ uint16_t src_port;
+ uint16_t dst_port;
+};
+
+enum {
+ PROTO_FIELD,
+ SRC_FIELD,
+ DST_FIELD,
+ SPORT_FIELD,
+ DPORT_FIELD
+};
+
+static volatile bool force_quit;
+static uint32_t portmask = 0x1;
+
+static struct rte_acl_field_def field_defs[NUM_FIELDS] = {
+ { RTE_ACL_FIELD_TYPE_BITMASK, sizeof(uint8_t), PROTO_FIELD, 0, offsetof(struct pkt_key, proto) },
+ { RTE_ACL_FIELD_TYPE_MASK, sizeof(uint32_t), SRC_FIELD, 1, offsetof(struct pkt_key, src_ip) },
+ { RTE_ACL_FIELD_TYPE_MASK, sizeof(uint32_t), DST_FIELD, 2, offsetof(struct pkt_key, dst_ip) },
+ { RTE_ACL_FIELD_TYPE_RANGE, sizeof(uint16_t), SPORT_FIELD, 3, offsetof(struct pkt_key, src_port) },
+ { RTE_ACL_FIELD_TYPE_RANGE, sizeof(uint16_t), DPORT_FIELD, 3, offsetof(struct pkt_key, dst_port) },
+};
+
+static void
+signal_handler(int sig)
+{
+ if (sig == SIGINT || sig == SIGTERM)
+ force_quit = true;
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ int opt;
+ while ((opt = getopt(argc, argv, "p:")) != -1) {
+ switch (opt) {
+ case 'p':
+ portmask = strtoul(optarg, NULL, 16);
+ break;
+ default:
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* ---------------- ACL INITIALIZATION ---------------- */
+
+static struct rte_acl_ctx *
+init_acl(void)
+{
+ struct rte_acl_param prm = {
+ .name = "acl_ctx",
+ .socket_id = rte_socket_id(),
+ .rule_size = RTE_ACL_RULE_SZ(NUM_FIELDS),
+ .max_rule_num = MAX_RULES
+ };
+
+ struct rte_acl_ctx *ctx = rte_acl_create(&prm);
+ if (!ctx)
+ rte_exit(EXIT_FAILURE, "ACL create failed\n");
+
+ struct acl_rule rule;
+ memset(&rule, 0, sizeof(rule));
+
+ rule.data.priority = 10;
+ rule.data.category_mask = 1;
+ rule.data.userdata = 1;
+
+ rule.field[PROTO_FIELD].value.u8 = IPPROTO_TCP;
+ rule.field[PROTO_FIELD].mask_range.u8 = 0xFF;
+
+ rule.field[SRC_FIELD].value.u32 =
+ rte_be_to_cpu_32(RTE_IPV4(172,17,166,200));
+ rule.field[SRC_FIELD].mask_range.u32 = 32;
+
+ rule.field[DST_FIELD].value.u32 = 0;
+ rule.field[DST_FIELD].mask_range.u32 = 0;
+
+ rule.field[SPORT_FIELD].value.u16 = 0;
+ rule.field[SPORT_FIELD].mask_range.u16 = 65535;
+
+ rule.field[DPORT_FIELD].value.u16 = 0;
+ rule.field[DPORT_FIELD].mask_range.u16 = 65535;
+
+ if (rte_acl_add_rules(ctx, (struct rte_acl_rule *)&rule, 1) < 0)
+ rte_exit(EXIT_FAILURE, "ACL rule add failed\n");
+
+ struct rte_acl_config cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.num_categories = 1;
+ cfg.num_fields = NUM_FIELDS;
+ memcpy(cfg.defs, field_defs, sizeof(field_defs));
+
+ if (rte_acl_build(ctx, &cfg) != 0)
+ rte_exit(EXIT_FAILURE, "ACL build failed\n");
+
+ RTE_LOG(INFO, L2FWD_ACL, "ACL ready\n");
+ return ctx;
+}
+
+/* ---------------- MAIN ---------------- */
+
+int main(int argc, char **argv)
+{
+ force_quit = false;
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ int ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "EAL init failed\n");
+
+ argc -= ret;
+ argv += ret;
+
+ if (parse_args(argc, argv) < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ struct rte_acl_ctx *acl_ctx = init_acl();
+
+ struct rte_mempool *mp = rte_pktmbuf_pool_create(
+ "mbuf_pool", NB_MBUF, 256, 0,
+ RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+
+ if (!mp)
+ rte_exit(EXIT_FAILURE, "mempool failed\n");
+
+ uint16_t port_id;
+ RTE_ETH_FOREACH_DEV(port_id) {
+
+ if (!(portmask & (1 << port_id)))
+ continue;
+
+ struct rte_eth_conf conf = {0};
+
+ if (rte_eth_dev_configure(port_id, 1, 1, &conf) < 0)
+ rte_exit(EXIT_FAILURE, "port configure failed\n");
+
+ if (rte_eth_rx_queue_setup(port_id, 0, 1024,
+ rte_eth_dev_socket_id(port_id), NULL, mp) < 0)
+ rte_exit(EXIT_FAILURE, "rx setup failed\n");
+
+ if (rte_eth_tx_queue_setup(port_id, 0, 1024,
+ rte_eth_dev_socket_id(port_id), NULL) < 0)
+ rte_exit(EXIT_FAILURE, "tx setup failed\n");
+
+ if (rte_eth_dev_start(port_id) < 0)
+ rte_exit(EXIT_FAILURE, "port start failed\n");
+
+ rte_eth_promiscuous_enable(port_id);
+
+ RTE_LOG(INFO, L2FWD_ACL, "Started port %u\n", port_id);
+ }
+
+ struct rte_mbuf *bufs[BURST];
+
+ while (!force_quit) {
+
+ RTE_ETH_FOREACH_DEV(port_id) {
+
+ if (!(portmask & (1 << port_id)))
+ continue;
+
+ uint16_t nb = rte_eth_rx_burst(port_id, 0, bufs, BURST);
+ if (!nb) continue;
+
+ for (int i = 0; i < nb; i++) {
+
+ struct rte_mbuf *m = bufs[i];
+ struct rte_ether_hdr *eth =
+ rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
+
+ if (eth->ether_type !=
+ rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
+ rte_pktmbuf_free(m);
+ continue;
+ }
+
+ struct rte_ipv4_hdr *ip =
+ (struct rte_ipv4_hdr *)(eth + 1);
+
+ struct pkt_key key = {0};
+ key.proto = ip->next_proto_id;
+ key.src_ip = rte_be_to_cpu_32(ip->src_addr);
+ key.dst_ip = rte_be_to_cpu_32(ip->dst_addr);
+
+ uint8_t *l4 = (uint8_t *)ip + (ip->ihl * 4);
+
+ if (key.proto == IPPROTO_TCP) {
+ struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *)l4;
+ key.src_port = rte_be_to_cpu_16(tcp->src_port);
+ key.dst_port = rte_be_to_cpu_16(tcp->dst_port);
+ } else if (key.proto == IPPROTO_UDP) {
+ struct rte_udp_hdr *udp = (struct rte_udp_hdr *)l4;
+ key.src_port = rte_be_to_cpu_16(udp->src_port);
+ key.dst_port = rte_be_to_cpu_16(udp->dst_port);
+ }
+
+ const uint8_t *data[1] = {(const uint8_t *)&key};
+ uint32_t res[1];
+
+ rte_acl_classify(acl_ctx, data, res, 1, 1);
+
+ if (res[0])
+ rte_eth_tx_burst(port_id, 0, &m, 1);
+ else
+ rte_pktmbuf_free(m);
+ }
+ }
+ }
+
+ return 0;
diff --git a/examples/l2fwd_acl/meson.build b/examples/l2fwd_acl/meson.build
new file mode 100644
index 0000000000..331dd545e9
--- /dev/null
+++ b/examples/l2fwd_acl/meson.build
@@ -0,0 +1,3 @@
+sources = files('main.c')
+
+deps += ['acl', 'ethdev', 'mbuf', 'net']
diff --git a/examples/meson.build b/examples/meson.build
index 25d9c88457..bce2982229 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -24,6 +24,7 @@ all_examples = [
'ipsec-secgw',
'ipv4_multicast',
'l2fwd',
+ 'l2fwd_acl',
'l2fwd-cat',
'l2fwd-crypto',
'l2fwd-event',
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
2026-02-20 18:43 Harsh raj Singh
@ 2026-02-23 4:28 ` Harsh raj Singh
2026-02-23 9:09 ` Harsh raj Singh
2026-02-23 17:07 ` Stephen Hemminger
2026-02-23 17:08 ` Stephen Hemminger
2 siblings, 1 reply; 7+ messages in thread
From: Harsh raj Singh @ 2026-02-23 4:28 UTC (permalink / raw)
To: dev
do i have any update on it
On Sat, Feb 21, 2026 at 12:13 AM Harsh raj Singh
<singhharshraj215@gmail.com> wrote:
>
> Hi,
>
> Please find attached my patch adding an ACL-based L2 forwarding example.
>
> Thanks,
> Harsh Raj Singh
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
2026-02-23 4:28 ` Harsh raj Singh
@ 2026-02-23 9:09 ` Harsh raj Singh
0 siblings, 0 replies; 7+ messages in thread
From: Harsh raj Singh @ 2026-02-23 9:09 UTC (permalink / raw)
To: dev
[-- Attachment #1: Type: text/plain, Size: 459 bytes --]
v2:
- Fixed indentation (tabs not spaces)
- Fixed checkpatch issues
- Fixed sign-off email mismatch
On Mon, Feb 23, 2026 at 9:58 AM Harsh raj Singh
<singhharshraj215@gmail.com> wrote:
>
> do i have any update on it
>
> On Sat, Feb 21, 2026 at 12:13 AM Harsh raj Singh
> <singhharshraj215@gmail.com> wrote:
> >
> > Hi,
> >
> > Please find attached my patch adding an ACL-based L2 forwarding example.
> >
> > Thanks,
> > Harsh Raj Singh
[-- Attachment #2: l2fwd_acl_v2.patch --]
[-- Type: text/x-patch, Size: 8148 bytes --]
From 8600ad787479e644df1abc7d213803fa77fb4fa4 Mon Sep 17 00:00:00 2001
From: Harsh Raj Singh <singhharshraj215@gmail.com>
Date: Mon, 23 Feb 2026 14:30:16 +0530
Subject: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
This example demonstrates usage of the DPDK ACL library
to classify packets based on 5-tuple fields and forward
only matching packets.
Signed-off-by: Harsh Raj Singh <singhharshraj215@gmail.com>
---
examples/l2fwd_acl/README.md | 18 +++
examples/l2fwd_acl/main.c | 274 +++++++++++++++++++++++++++++++++
examples/l2fwd_acl/meson.build | 3 +
3 files changed, 295 insertions(+)
create mode 100644 examples/l2fwd_acl/README.md
create mode 100644 examples/l2fwd_acl/main.c
create mode 100644 examples/l2fwd_acl/meson.build
diff --git a/examples/l2fwd_acl/README.md b/examples/l2fwd_acl/README.md
new file mode 100644
index 0000000000..5b5494e297
--- /dev/null
+++ b/examples/l2fwd_acl/README.md
@@ -0,0 +1,18 @@
+L2 Forwarding with ACL Example
+==============================
+
+This example demonstrates use of the DPDK ACL library
+to classify packets based on:
+
+- protocol
+- source IPv4
+- destination IPv4
+- source port
+- destination port
+
+Packets matching ACL rules are forwarded,
+others are dropped.
+
+Run:
+
+./dpdk-l2fwd-acl -l 0-2 -n 4 -- -p 0x1
diff --git a/examples/l2fwd_acl/main.c b/examples/l2fwd_acl/main.c
new file mode 100644
index 0000000000..9800adb8c8
--- /dev/null
+++ b/examples/l2fwd_acl/main.c
@@ -0,0 +1,274 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * l2fwd_acl example: demonstrates use of DPDK ACL library
+ */
+
+#include <getopt.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <rte_acl.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_ip.h>
+#include <rte_log.h>
+#include <rte_mbuf.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
+
+#define NUM_FIELDS 5
+#define MAX_RULES 32
+#define NB_MBUF 8192
+#define BURST 32
+
+/* ---- Correct DPDK logging style ---- */
+#define RTE_LOGTYPE_L2FWD_ACL RTE_LOGTYPE_USER1
+#define LOGTYPE_L2FWD_ACL RTE_LOGTYPE_L2FWD_ACL
+
+RTE_ACL_RULE_DEF(acl_rule, NUM_FIELDS);
+
+struct pkt_key {
+ uint8_t proto;
+ uint32_t src_ip;
+ uint32_t dst_ip;
+ uint16_t src_port;
+ uint16_t dst_port;
+};
+
+enum {
+ PROTO_FIELD,
+ SRC_FIELD,
+ DST_FIELD,
+ SPORT_FIELD,
+ DPORT_FIELD
+};
+
+static volatile bool force_quit;
+static uint32_t portmask = 0x1;
+
+static struct rte_acl_field_def field_defs[NUM_FIELDS] = {
+ { RTE_ACL_FIELD_TYPE_BITMASK, sizeof(uint8_t), PROTO_FIELD, 0,
+ offsetof(struct pkt_key, proto) },
+ { RTE_ACL_FIELD_TYPE_MASK, sizeof(uint32_t), SRC_FIELD, 1,
+ offsetof(struct pkt_key, src_ip) },
+ { RTE_ACL_FIELD_TYPE_MASK, sizeof(uint32_t), DST_FIELD, 2,
+ offsetof(struct pkt_key, dst_ip) },
+ { RTE_ACL_FIELD_TYPE_RANGE, sizeof(uint16_t), SPORT_FIELD, 3,
+ offsetof(struct pkt_key, src_port) },
+ { RTE_ACL_FIELD_TYPE_RANGE, sizeof(uint16_t), DPORT_FIELD, 3,
+ offsetof(struct pkt_key, dst_port) },
+};
+
+static void
+signal_handler(int sig)
+{
+ if (sig == SIGINT || sig == SIGTERM)
+ force_quit = true;
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, "p:")) != -1) {
+ switch (opt) {
+ case 'p':
+ portmask = strtoul(optarg, NULL, 16);
+ break;
+ default:
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* ---------------- ACL INITIALIZATION ---------------- */
+
+static struct rte_acl_ctx *
+init_acl(void)
+{
+ struct rte_acl_param prm = {
+ .name = "acl_ctx",
+ .socket_id = rte_socket_id(),
+ .rule_size = RTE_ACL_RULE_SZ(NUM_FIELDS),
+ .max_rule_num = MAX_RULES,
+ };
+
+ struct rte_acl_ctx *ctx = rte_acl_create(&prm);
+ if (!ctx)
+ rte_exit(EXIT_FAILURE, "ACL create failed\n");
+
+ struct acl_rule rule;
+ memset(&rule, 0, sizeof(rule));
+
+ rule.data.priority = 10;
+ rule.data.category_mask = 1;
+ rule.data.userdata = 1;
+
+ rule.field[PROTO_FIELD].value.u8 = IPPROTO_TCP;
+ rule.field[PROTO_FIELD].mask_range.u8 = 0xFF;
+
+ rule.field[SRC_FIELD].value.u32 =
+ rte_be_to_cpu_32(RTE_IPV4(172, 17, 166, 200));
+ rule.field[SRC_FIELD].mask_range.u32 = 32;
+
+ rule.field[DST_FIELD].value.u32 = 0;
+ rule.field[DST_FIELD].mask_range.u32 = 0;
+
+ rule.field[SPORT_FIELD].value.u16 = 0;
+ rule.field[SPORT_FIELD].mask_range.u16 = 65535;
+
+ rule.field[DPORT_FIELD].value.u16 = 0;
+ rule.field[DPORT_FIELD].mask_range.u16 = 65535;
+
+ if (rte_acl_add_rules(ctx,
+ (struct rte_acl_rule *)&rule, 1) < 0)
+ rte_exit(EXIT_FAILURE, "ACL rule add failed\n");
+
+ struct rte_acl_config cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.num_categories = 1;
+ cfg.num_fields = NUM_FIELDS;
+ memcpy(cfg.defs, field_defs, sizeof(field_defs));
+
+ if (rte_acl_build(ctx, &cfg) != 0)
+ rte_exit(EXIT_FAILURE, "ACL build failed\n");
+
+ RTE_LOG(INFO, L2FWD_ACL, "ACL ready\n");
+ return ctx;
+}
+
+/* ---------------- MAIN ---------------- */
+
+int
+main(int argc, char **argv)
+{
+ force_quit = false;
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ int ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "EAL init failed\n");
+
+ argc -= ret;
+ argv += ret;
+
+ if (parse_args(argc, argv) < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ struct rte_acl_ctx *acl_ctx = init_acl();
+
+ struct rte_mempool *mp = rte_pktmbuf_pool_create(
+ "mbuf_pool", NB_MBUF, 256, 0,
+ RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+
+ if (!mp)
+ rte_exit(EXIT_FAILURE, "mempool failed\n");
+
+ uint16_t port_id;
+
+ RTE_ETH_FOREACH_DEV(port_id) {
+
+ if (!(portmask & (1 << port_id)))
+ continue;
+
+ struct rte_eth_conf conf = {0};
+
+ if (rte_eth_dev_configure(port_id, 1, 1, &conf) < 0)
+ rte_exit(EXIT_FAILURE, "port configure failed\n");
+
+ if (rte_eth_rx_queue_setup(port_id, 0, 1024,
+ rte_eth_dev_socket_id(port_id),
+ NULL, mp) < 0)
+ rte_exit(EXIT_FAILURE, "rx setup failed\n");
+
+ if (rte_eth_tx_queue_setup(port_id, 0, 1024,
+ rte_eth_dev_socket_id(port_id),
+ NULL) < 0)
+ rte_exit(EXIT_FAILURE, "tx setup failed\n");
+
+ if (rte_eth_dev_start(port_id) < 0)
+ rte_exit(EXIT_FAILURE, "port start failed\n");
+
+ rte_eth_promiscuous_enable(port_id);
+
+ RTE_LOG(INFO, L2FWD_ACL,
+ "Started port %u\n", port_id);
+ }
+
+ struct rte_mbuf *bufs[BURST];
+
+ while (!force_quit) {
+
+ RTE_ETH_FOREACH_DEV(port_id) {
+
+ if (!(portmask & (1 << port_id)))
+ continue;
+
+ uint16_t nb =
+ rte_eth_rx_burst(port_id, 0, bufs, BURST);
+
+ if (!nb)
+ continue;
+
+ for (int i = 0; i < nb; i++) {
+
+ struct rte_mbuf *m = bufs[i];
+ struct rte_ether_hdr *eth =
+ rte_pktmbuf_mtod(m,
+ struct rte_ether_hdr *);
+
+ if (eth->ether_type !=
+ rte_cpu_to_be_16(
+ RTE_ETHER_TYPE_IPV4)) {
+ rte_pktmbuf_free(m);
+ continue;
+ }
+
+ struct rte_ipv4_hdr *ip =
+ (struct rte_ipv4_hdr *)(eth + 1);
+
+ struct pkt_key key = {0};
+ key.proto = ip->next_proto_id;
+ key.src_ip = rte_be_to_cpu_32(ip->src_addr);
+ key.dst_ip = rte_be_to_cpu_32(ip->dst_addr);
+
+ uint8_t *l4 =
+ (uint8_t *)ip + (ip->ihl * 4);
+
+ if (key.proto == IPPROTO_TCP) {
+ struct rte_tcp_hdr *tcp =
+ (struct rte_tcp_hdr *)l4;
+ key.src_port =
+ rte_be_to_cpu_16(tcp->src_port);
+ key.dst_port =
+ rte_be_to_cpu_16(tcp->dst_port);
+ } else if (key.proto == IPPROTO_UDP) {
+ struct rte_udp_hdr *udp =
+ (struct rte_udp_hdr *)l4;
+ key.src_port =
+ rte_be_to_cpu_16(udp->src_port);
+ key.dst_port =
+ rte_be_to_cpu_16(udp->dst_port);
+ }
+
+ const uint8_t *data[1] = {
+ (const uint8_t *)&key,
+ };
+ uint32_t res[1];
+
+ rte_acl_classify(acl_ctx, data, res, 1, 1);
+
+ if (res[0])
+ rte_eth_tx_burst(port_id, 0, &m, 1);
+ else
+ rte_pktmbuf_free(m);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/examples/l2fwd_acl/meson.build b/examples/l2fwd_acl/meson.build
new file mode 100644
index 0000000000..331dd545e9
--- /dev/null
+++ b/examples/l2fwd_acl/meson.build
@@ -0,0 +1,3 @@
+sources = files('main.c')
+
+deps += ['acl', 'ethdev', 'mbuf', 'net']
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
2026-02-20 18:43 Harsh raj Singh
2026-02-23 4:28 ` Harsh raj Singh
@ 2026-02-23 17:07 ` Stephen Hemminger
2026-02-23 17:08 ` Stephen Hemminger
2 siblings, 0 replies; 7+ messages in thread
From: Stephen Hemminger @ 2026-02-23 17:07 UTC (permalink / raw)
To: Harsh raj Singh; +Cc: dev
On Sat, 21 Feb 2026 00:13:33 +0530
Harsh raj Singh <singhharshraj215@gmail.com> wrote:
> diff --git a/examples/l2fwd_acl/main.c b/examples/l2fwd_acl/main.c
> new file mode 100644
> index 0000000000..6e05145b33
> --- /dev/null
> +++ b/examples/l2fwd_acl/main.c
> @@ -0,0 +1,247 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * l
New files should have a copyright.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example
2026-02-20 18:43 Harsh raj Singh
2026-02-23 4:28 ` Harsh raj Singh
2026-02-23 17:07 ` Stephen Hemminger
@ 2026-02-23 17:08 ` Stephen Hemminger
2 siblings, 0 replies; 7+ messages in thread
From: Stephen Hemminger @ 2026-02-23 17:08 UTC (permalink / raw)
To: Harsh raj Singh; +Cc: dev
On Sat, 21 Feb 2026 00:13:33 +0530
Harsh raj Singh <singhharshraj215@gmail.com> wrote:
> diff --git a/examples/meson.build b/examples/meson.build
> index 25d9c88457..bce2982229 100644
> --- a/examples/meson.build
> +++ b/examples/meson.build
> @@ -24,6 +24,7 @@ all_examples = [
> 'ipsec-secgw',
> 'ipv4_multicast',
> 'l2fwd',
> + 'l2fwd_acl',
> 'l2fwd-cat',
> 'l2fwd-crypto
Should be named l2fwd-acl not l2fwd_acl for consistency
with other variants.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-02-23 17:08 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 9:25 [PATCH] examples/l2fwd_acl: add ACL-based L2 forwarding example Harsh raj Singh
2026-02-20 17:25 ` Stephen Hemminger
-- strict thread matches above, loose matches on Subject: below --
2026-02-20 18:43 Harsh raj Singh
2026-02-23 4:28 ` Harsh raj Singh
2026-02-23 9:09 ` Harsh raj Singh
2026-02-23 17:07 ` Stephen Hemminger
2026-02-23 17:08 ` Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox