diff options
author | Jakub Kicinski <kuba@kernel.org> | 2025-05-20 09:19:16 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2025-05-21 12:38:23 -0700 |
commit | 4e4dc6db2b92bced802bdc19c8ef46a1821151be (patch) | |
tree | a64318a6308a8eb8af604e78dc3bb555229aac35 | |
parent | 33baf6f73a7ce7ca6a05f9ac2c0758f34f04a423 (diff) |
tools: ynl: add a sample for TC
Add a very simple TC dump sample with decoding of fq_codel attrs:
# ./tools/net/ynl/samples/tc
dummy0: fq_codel limit: 10240p target: 5ms new_flow_cnt: 0
proving that selector passing (for stats) works.
Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://patch.msgid.link/20250520161916.413298-13-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | tools/net/ynl/samples/.gitignore | 1 | ||||
-rw-r--r-- | tools/net/ynl/samples/tc.c | 80 |
2 files changed, 81 insertions, 0 deletions
diff --git a/tools/net/ynl/samples/.gitignore b/tools/net/ynl/samples/.gitignore index b3ec3fb0929f..7f5fca7682d7 100644 --- a/tools/net/ynl/samples/.gitignore +++ b/tools/net/ynl/samples/.gitignore @@ -6,3 +6,4 @@ page-pool rt-addr rt-link rt-route +tc diff --git a/tools/net/ynl/samples/tc.c b/tools/net/ynl/samples/tc.c new file mode 100644 index 000000000000..0bfff0fdd792 --- /dev/null +++ b/tools/net/ynl/samples/tc.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> +#include <string.h> + +#include <ynl.h> + +#include <net/if.h> + +#include "tc-user.h" + +static void tc_qdisc_print(struct tc_getqdisc_rsp *q) +{ + char ifname[IF_NAMESIZE]; + const char *name; + + name = if_indextoname(q->_hdr.tcm_ifindex, ifname); + if (name) + printf("%16s: ", name); + + if (q->_len.kind) { + printf("%s ", q->kind); + + if (q->options._present.fq_codel) { + struct tc_fq_codel_attrs *fq_codel; + struct tc_fq_codel_xstats *stats; + + fq_codel = &q->options.fq_codel; + stats = q->stats2.app.fq_codel; + + if (fq_codel->_present.limit) + printf("limit: %dp ", fq_codel->limit); + if (fq_codel->_present.target) + printf("target: %dms ", + (fq_codel->target + 500) / 1000); + if (q->stats2.app._len.fq_codel) + printf("new_flow_cnt: %d ", + stats->qdisc_stats.new_flow_count); + } + } + + printf("\n"); +} + +int main(int argc, char **argv) +{ + struct tc_getqdisc_req_dump *req; + struct tc_getqdisc_list *rsp; + struct ynl_error yerr; + struct ynl_sock *ys; + + ys = ynl_sock_create(&ynl_tc_family, &yerr); + if (!ys) { + fprintf(stderr, "YNL: %s\n", yerr.msg); + return 1; + } + + req = tc_getqdisc_req_dump_alloc(); + if (!req) + goto err_destroy; + + rsp = tc_getqdisc_dump(ys, req); + tc_getqdisc_req_dump_free(req); + if (!rsp) + goto err_close; + + if (ynl_dump_empty(rsp)) + fprintf(stderr, "Error: no addresses reported\n"); + ynl_dump_foreach(rsp, qdisc) + tc_qdisc_print(qdisc); + tc_getqdisc_list_free(rsp); + + ynl_sock_destroy(ys); + return 0; + +err_close: + fprintf(stderr, "YNL: %s\n", ys->err.msg); +err_destroy: + ynl_sock_destroy(ys); + return 2; +} |