naccyde / rpms / iproute

Forked from rpms/iproute 7 months ago
Clone

Blame SOURCES/0143-tc-introduce-tc_qdisc_block_exists-helper.patch

36cfb7
From 2e2ac620670997b59d65a73b0af3e77431be3c18 Mon Sep 17 00:00:00 2001
36cfb7
From: Andrea Claudi <aclaudi@redhat.com>
36cfb7
Date: Tue, 18 Jun 2019 20:01:45 +0200
36cfb7
Subject: [PATCH] tc: introduce tc_qdisc_block_exists helper
36cfb7
36cfb7
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1721291
36cfb7
Upstream Status: iproute2.git commit d0bcedd549566
36cfb7
Conflicts: context change due to missing commit 6f7df6b2a1fef
36cfb7
           ("tc: Optimize gact action lookup")
36cfb7
36cfb7
commit d0bcedd549566a87354aa804df3be6be80681ee9
36cfb7
Author: Jiri Pirko <jiri@mellanox.com>
36cfb7
Date:   Sat Jan 20 11:00:27 2018 +0100
36cfb7
36cfb7
    tc: introduce tc_qdisc_block_exists helper
36cfb7
36cfb7
    This hepler used qdisc dump to list all qdisc and find if block index in
36cfb7
    question is used by any of them. That means the block with specified
36cfb7
    index exists.
36cfb7
36cfb7
    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
36cfb7
    Signed-off-by: David Ahern <dsahern@gmail.com>
36cfb7
---
36cfb7
 tc/tc_qdisc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
36cfb7
 tc/tc_util.h  |  2 ++
36cfb7
 2 files changed, 63 insertions(+)
36cfb7
36cfb7
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
36cfb7
index 8b0c5c72dbad1..f8e06ccf205a0 100644
36cfb7
--- a/tc/tc_qdisc.c
36cfb7
+++ b/tc/tc_qdisc.c
36cfb7
@@ -366,3 +366,64 @@ int do_qdisc(int argc, char **argv)
36cfb7
 	fprintf(stderr, "Command \"%s\" is unknown, try \"tc qdisc help\".\n", *argv);
36cfb7
 	return -1;
36cfb7
 }
36cfb7
+
36cfb7
+struct tc_qdisc_block_exists_ctx {
36cfb7
+	__u32 block_index;
36cfb7
+	bool found;
36cfb7
+};
36cfb7
+
36cfb7
+static int tc_qdisc_block_exists_cb(const struct sockaddr_nl *who,
36cfb7
+				    struct nlmsghdr *n, void *arg)
36cfb7
+{
36cfb7
+	struct tc_qdisc_block_exists_ctx *ctx = arg;
36cfb7
+	struct tcmsg *t = NLMSG_DATA(n);
36cfb7
+	struct rtattr *tb[TCA_MAX+1];
36cfb7
+	int len = n->nlmsg_len;
36cfb7
+
36cfb7
+	if (n->nlmsg_type != RTM_NEWQDISC)
36cfb7
+		return 0;
36cfb7
+
36cfb7
+	len -= NLMSG_LENGTH(sizeof(*t));
36cfb7
+	if (len < 0)
36cfb7
+		return -1;
36cfb7
+
36cfb7
+	parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len);
36cfb7
+
36cfb7
+	if (tb[TCA_KIND] == NULL)
36cfb7
+		return -1;
36cfb7
+
36cfb7
+	if (tb[TCA_INGRESS_BLOCK] &&
36cfb7
+	    RTA_PAYLOAD(tb[TCA_INGRESS_BLOCK]) >= sizeof(__u32)) {
36cfb7
+		__u32 block = rta_getattr_u32(tb[TCA_INGRESS_BLOCK]);
36cfb7
+
36cfb7
+		if (block == ctx->block_index)
36cfb7
+			ctx->found = true;
36cfb7
+	}
36cfb7
+
36cfb7
+	if (tb[TCA_EGRESS_BLOCK] &&
36cfb7
+	    RTA_PAYLOAD(tb[TCA_EGRESS_BLOCK]) >= sizeof(__u32)) {
36cfb7
+		__u32 block = rta_getattr_u32(tb[TCA_EGRESS_BLOCK]);
36cfb7
+
36cfb7
+		if (block == ctx->block_index)
36cfb7
+			ctx->found = true;
36cfb7
+	}
36cfb7
+	return 0;
36cfb7
+}
36cfb7
+
36cfb7
+bool tc_qdisc_block_exists(__u32 block_index)
36cfb7
+{
36cfb7
+	struct tc_qdisc_block_exists_ctx ctx = { .block_index = block_index };
36cfb7
+	struct tcmsg t = { .tcm_family = AF_UNSPEC };
36cfb7
+
36cfb7
+	if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {
36cfb7
+		perror("Cannot send dump request");
36cfb7
+		return false;
36cfb7
+	}
36cfb7
+
36cfb7
+	if (rtnl_dump_filter(&rth, tc_qdisc_block_exists_cb, &ctx) < 0) {
36cfb7
+		perror("Dump terminated\n");
36cfb7
+		return false;
36cfb7
+	}
36cfb7
+
36cfb7
+	return ctx.found;
36cfb7
+}
36cfb7
diff --git a/tc/tc_util.h b/tc/tc_util.h
36cfb7
index 5c54ad384eae6..8344c11833ee8 100644
36cfb7
--- a/tc/tc_util.h
36cfb7
+++ b/tc/tc_util.h
36cfb7
@@ -122,4 +122,6 @@ int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
36cfb7
 int cls_names_init(char *path);
36cfb7
 void cls_names_uninit(void);
36cfb7
 
36cfb7
+bool tc_qdisc_block_exists(__u32 block_index);
36cfb7
+
36cfb7
 #endif
36cfb7
-- 
e138d9
2.21.0
36cfb7