From: Zahari Doychev <zahari.doychev@linux.com>
To: donald.hunter@gmail.com, kuba@kernel.org
Cc: davem@davemloft.net, edumazet@google.com, pabeni@redhat.com,
horms@kernel.org, jacob.e.keller@intel.com, ast@fiberby.net,
matttbe@kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, jhs@mojatatu.com,
xiyou.wangcong@gmail.com, jiri@resnulli.us,
johannes@sipsolutions.net, zahari.doychev@linux.com
Subject: [PATCH 1/4] ynl: samples: add tc filter add example
Date: Sat, 18 Oct 2025 17:17:34 +0200 [thread overview]
Message-ID: <20251018151737.365485-2-zahari.doychev@linux.com> (raw)
In-Reply-To: <20251018151737.365485-1-zahari.doychev@linux.com>
Add a simple tool that demonstrates adding a flower filter with two
VLAN push actions. This example can be invoked as:
# ./tools/samples/tc-filter-add p2
# tc -j -p filter show dev p2 ingress pref 2211
[ {
"protocol": "802.1Q",
"kind": "flower",
"chain": 0
},{
"protocol": "802.1Q",
"kind": "flower",
"chain": 0,
"options": {
"handle": 1,
"keys": {
"num_of_vlans": 3,
"vlan_id": 255,
"vlan_prio": 5
},
"not_in_hw": true,
"actions": [ {
"order": 1,
"kind": "vlan",
"vlan_action": "push",
"id": 255,
"control_action": {
"type": "pass"
},
"index": 5,
"ref": 1,
"bind": 1
},{
"order": 2,
"kind": "vlan",
"vlan_action": "push",
"id": 555,
"control_action": {
"type": "pass"
},
"index": 6,
"ref": 1,
"bind": 1
} ]
}
} ]
This shows the filter with two VLAN push actions, verifying that tc action
attributes are handled correctly.
Signed-off-by: Zahari Doychev <zahari.doychev@linux.com>
---
tools/net/ynl/Makefile.deps | 1 +
tools/net/ynl/samples/.gitignore | 1 +
tools/net/ynl/samples/tc-filter-add.c | 92 +++++++++++++++++++++++++++
3 files changed, 94 insertions(+)
create mode 100644 tools/net/ynl/samples/tc-filter-add.c
diff --git a/tools/net/ynl/Makefile.deps b/tools/net/ynl/Makefile.deps
index 865fd2e8519e..96c390af060e 100644
--- a/tools/net/ynl/Makefile.deps
+++ b/tools/net/ynl/Makefile.deps
@@ -47,4 +47,5 @@ CFLAGS_tc:= $(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h) \
$(call get_hdr_inc,_TC_MIRRED_H,tc_act/tc_mirred.h) \
$(call get_hdr_inc,_TC_SKBEDIT_H,tc_act/tc_skbedit.h) \
$(call get_hdr_inc,_TC_TUNNEL_KEY_H,tc_act/tc_tunnel_key.h)
+CFLAGS_tc-filter-add:=$(CFLAGS_tc)
CFLAGS_tcp_metrics:=$(call get_hdr_inc,_LINUX_TCP_METRICS_H,tcp_metrics.h)
diff --git a/tools/net/ynl/samples/.gitignore b/tools/net/ynl/samples/.gitignore
index 7f5fca7682d7..05087ee323ba 100644
--- a/tools/net/ynl/samples/.gitignore
+++ b/tools/net/ynl/samples/.gitignore
@@ -7,3 +7,4 @@ rt-addr
rt-link
rt-route
tc
+tc-filter-add
diff --git a/tools/net/ynl/samples/tc-filter-add.c b/tools/net/ynl/samples/tc-filter-add.c
new file mode 100644
index 000000000000..b9c6f30f2a30
--- /dev/null
+++ b/tools/net/ynl/samples/tc-filter-add.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <linux/pkt_sched.h>
+#include <linux/tc_act/tc_vlan.h>
+#include <linux/tc_act/tc_gact.h>
+#include <net/if.h>
+
+#include <ynl.h>
+
+#include "tc-user.h"
+
+int main(int argc, char **argv)
+{
+ struct tc_newtfilter_req *req;
+ struct tc_act_attrs *acts;
+ struct tc_vlan p = {
+ .v_action = TCA_VLAN_ACT_PUSH
+ };
+ __u16 flags = NLM_F_EXCL | NLM_F_CREATE;
+ struct ynl_error yerr;
+ struct ynl_sock *ys;
+ int ifi;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <interface_name>\n", argv[0]);
+ return 1;
+ }
+ ifi = if_nametoindex(argv[1]);
+ if (!ifi) {
+ perror("if_nametoindex");
+ return 1;
+ }
+
+ ys = ynl_sock_create(&ynl_tc_family, &yerr);
+ if (!ys) {
+ fprintf(stderr, "YNL: %s\n", yerr.msg);
+ return 1;
+ }
+
+ req = tc_newtfilter_req_alloc();
+ if (!req) {
+ fprintf(stderr, "tc_newtfilter_req_alloc failed\n");
+ goto err_destroy;
+ }
+ memset(req, 0, sizeof(*req));
+
+ acts = tc_act_attrs_alloc(2);
+ if (!acts) {
+ fprintf(stderr, "tc_act_attrs_alloc\n");
+ goto err_act;
+ }
+ memset(acts, 0, sizeof(*acts));
+
+ req->_hdr.tcm_ifindex = ifi;
+ req->_hdr.tcm_parent = TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS);
+ req->_hdr.tcm_info = TC_H_MAKE((2211 << 16), htons(0x8100));
+ req->chain = 0;
+
+ tc_newtfilter_req_set_nlflags(req, flags);
+ tc_newtfilter_req_set_kind(req, "flower");
+ tc_newtfilter_req_set_options_flower_key_vlan_id(req, 255);
+ tc_newtfilter_req_set_options_flower_key_vlan_prio(req, 5);
+ tc_newtfilter_req_set_options_flower_key_num_of_vlans(req, 3);
+
+ __tc_newtfilter_req_set_options_flower_act(req, acts, 2);
+
+ tc_act_attrs_set_kind(&acts[0], "vlan");
+ tc_act_attrs_set_options_vlan_parms(&acts[0], &p, sizeof(p));
+ tc_act_attrs_set_options_vlan_push_vlan_id(&acts[0], 255);
+ tc_act_attrs_set_kind(&acts[1], "vlan");
+ tc_act_attrs_set_options_vlan_parms(&acts[1], &p, sizeof(p));
+ tc_act_attrs_set_options_vlan_push_vlan_id(&acts[1], 555);
+
+ tc_newtfilter_req_set_options_flower_flags(req, 0);
+ tc_newtfilter_req_set_options_flower_key_eth_type(req, htons(0x8100));
+
+ if (tc_newtfilter(ys, req))
+ fprintf(stderr, "YNL: %s\n", ys->err.msg);
+
+ tc_newtfilter_req_free(req);
+ ynl_sock_destroy(ys);
+ return 0;
+
+err_act:
+ tc_newtfilter_req_free(req);
+err_destroy:
+ ynl_sock_destroy(ys);
+ return 2;
+}
--
2.51.0
next prev parent reply other threads:[~2025-10-18 15:18 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-18 15:17 [PATCH 0/4] tools: ynl: Fix tc filters with actions Zahari Doychev
2025-10-18 15:17 ` Zahari Doychev [this message]
2025-10-20 23:20 ` [PATCH 1/4] ynl: samples: add tc filter add example Jakub Kicinski
2025-10-21 17:21 ` Zahari Doychev
2025-10-18 15:17 ` [PATCH 2/4] tools: ynl: zero-initialize struct ynl_sock memory Zahari Doychev
2025-10-20 23:16 ` Jakub Kicinski
2025-10-21 17:36 ` Zahari Doychev
2025-10-21 23:22 ` Jakub Kicinski
2025-10-22 19:59 ` Zahari Doychev
2025-10-18 15:17 ` [PATCH 3/4] tools: ynl: call nested attribute free function for indexed arrays Zahari Doychev
2025-10-20 23:19 ` Jakub Kicinski
2025-10-18 15:17 ` [PATCH 4/4] tools: ynl: add start-index property " Zahari Doychev
2025-10-20 23:32 ` Jakub Kicinski
2025-10-21 17:50 ` Zahari Doychev
2025-10-21 22:52 ` Asbjørn Sloth Tønnesen
2025-10-21 23:24 ` Jakub Kicinski
2025-10-22 19:37 ` Asbjørn Sloth Tønnesen
2025-10-22 20:03 ` Zahari Doychev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251018151737.365485-2-zahari.doychev@linux.com \
--to=zahari.doychev@linux.com \
--cc=ast@fiberby.net \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jacob.e.keller@intel.com \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=johannes@sipsolutions.net \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matttbe@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=xiyou.wangcong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®