]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
tc: introduce tc_qdisc_block_exists helper
authorJiri Pirko <jiri@mellanox.com>
Sat, 20 Jan 2018 10:00:27 +0000 (11:00 +0100)
committerDavid Ahern <dsahern@gmail.com>
Sun, 21 Jan 2018 18:42:35 +0000 (10:42 -0800)
This hepler used qdisc dump to list all qdisc and find if block index in
question is used by any of them. That means the block with specified
index exists.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
tc/tc_qdisc.c
tc/tc_util.h

index 70279b9dc8767390b880f8c83e6fa84a5d769aed..54701c263d5fb717edf80fdf9e16c9bb6a94c2f0 100644 (file)
@@ -412,3 +412,64 @@ int do_qdisc(int argc, char **argv)
        fprintf(stderr, "Command \"%s\" is unknown, try \"tc qdisc help\".\n", *argv);
        return -1;
 }
+
+struct tc_qdisc_block_exists_ctx {
+       __u32 block_index;
+       bool found;
+};
+
+static int tc_qdisc_block_exists_cb(const struct sockaddr_nl *who,
+                                   struct nlmsghdr *n, void *arg)
+{
+       struct tc_qdisc_block_exists_ctx *ctx = arg;
+       struct tcmsg *t = NLMSG_DATA(n);
+       struct rtattr *tb[TCA_MAX+1];
+       int len = n->nlmsg_len;
+
+       if (n->nlmsg_type != RTM_NEWQDISC)
+               return 0;
+
+       len -= NLMSG_LENGTH(sizeof(*t));
+       if (len < 0)
+               return -1;
+
+       parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len);
+
+       if (tb[TCA_KIND] == NULL)
+               return -1;
+
+       if (tb[TCA_INGRESS_BLOCK] &&
+           RTA_PAYLOAD(tb[TCA_INGRESS_BLOCK]) >= sizeof(__u32)) {
+               __u32 block = rta_getattr_u32(tb[TCA_INGRESS_BLOCK]);
+
+               if (block == ctx->block_index)
+                       ctx->found = true;
+       }
+
+       if (tb[TCA_EGRESS_BLOCK] &&
+           RTA_PAYLOAD(tb[TCA_EGRESS_BLOCK]) >= sizeof(__u32)) {
+               __u32 block = rta_getattr_u32(tb[TCA_EGRESS_BLOCK]);
+
+               if (block == ctx->block_index)
+                       ctx->found = true;
+       }
+       return 0;
+}
+
+bool tc_qdisc_block_exists(__u32 block_index)
+{
+       struct tc_qdisc_block_exists_ctx ctx = { .block_index = block_index };
+       struct tcmsg t = { .tcm_family = AF_UNSPEC };
+
+       if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {
+               perror("Cannot send dump request");
+               return false;
+       }
+
+       if (rtnl_dump_filter(&rth, tc_qdisc_block_exists_cb, &ctx) < 0) {
+               perror("Dump terminated\n");
+               return false;
+       }
+
+       return ctx.found;
+}
index e354765ff1ed08bf41032e62596004620adc8ddf..cd2ff5964e19938adf1eae0db81b09049278cf13 100644 (file)
@@ -134,4 +134,6 @@ void cls_names_uninit(void);
 
 int action_a2n(char *arg, int *result, bool allow_num);
 
+bool tc_qdisc_block_exists(__u32 block_index);
+
 #endif