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

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