summaryrefslogtreecommitdiffstats
path: root/src/nl-tctree-list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nl-tctree-list.c')
-rw-r--r--src/nl-tctree-list.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/nl-tctree-list.c b/src/nl-tctree-list.c
new file mode 100644
index 0000000..6f6bf56
--- /dev/null
+++ b/src/nl-tctree-list.c
@@ -0,0 +1,147 @@
+/*
+ * src/nl-tctree-list.c List Traffic Control Tree
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include "utils.h"
+#include <linux/pkt_sched.h>
+
+static struct nl_sock *sock;
+static struct nl_cache *qdisc_cache, *class_cache;
+static struct nl_dump_params params = {
+ .dp_type = NL_DUMP_DETAILS,
+};
+
+static int ifindex;
+static void print_qdisc(struct nl_object *, void *);
+
+static void print_usage(void)
+{
+ printf(
+ "Usage: nl-tctree-list [OPTION]...\n"
+ "\n"
+ "Options\n"
+ " -f, --format=TYPE Output format { brief | details | stats }\n"
+ " -h, --help Show this help\n"
+ " -v, --version Show versioning information\n"
+ );
+ exit(0);
+}
+
+static void print_class(struct nl_object *obj, void *arg)
+{
+ struct rtnl_qdisc *leaf;
+ struct rtnl_class *class = (struct rtnl_class *) obj;
+ struct nl_cache *cls_cache;
+ uint32_t parent = rtnl_class_get_handle(class);
+
+ params.dp_prefix = (int)(long) arg;
+ nl_object_dump(obj, &params);
+
+ leaf = rtnl_class_leaf_qdisc(class, qdisc_cache);
+ if (leaf)
+ print_qdisc((struct nl_object *) leaf, arg + 2);
+
+ rtnl_class_foreach_child(class, class_cache, &print_class, arg + 2);
+
+ if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
+ return;
+
+ params.dp_prefix = (int)(long) arg + 2;
+ nl_cache_dump(cls_cache, &params);
+ nl_cache_free(cls_cache);
+}
+
+static void print_qdisc(struct nl_object *obj, void *arg)
+{
+ struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) obj;
+ struct nl_cache *cls_cache;
+ uint32_t parent = rtnl_qdisc_get_handle(qdisc);
+
+ params.dp_prefix = (int)(long) arg;
+ nl_object_dump(obj, &params);
+
+ rtnl_qdisc_foreach_child(qdisc, class_cache, &print_class, arg + 2);
+
+ if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
+ return;
+
+ params.dp_prefix = (int)(long) arg + 2;
+ nl_cache_dump(cls_cache, &params);
+ nl_cache_free(cls_cache);
+}
+
+static void print_link(struct nl_object *obj, void *arg)
+{
+ struct rtnl_link *link = (struct rtnl_link *) obj;
+ struct rtnl_qdisc *qdisc;
+
+ ifindex = rtnl_link_get_ifindex(link);
+ params.dp_prefix = 0;
+ nl_object_dump(obj, &params);
+
+ if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0)
+ return;
+
+ qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT);
+ if (qdisc) {
+ print_qdisc((struct nl_object *) qdisc, (void *) 2);
+ rtnl_qdisc_put(qdisc);
+ }
+
+ qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, 0);
+ if (qdisc) {
+ print_qdisc((struct nl_object *) qdisc, (void *) 2);
+ rtnl_qdisc_put(qdisc);
+ }
+
+ qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_INGRESS);
+ if (qdisc) {
+ print_qdisc((struct nl_object *) qdisc, (void *) 2);
+ rtnl_qdisc_put(qdisc);
+ }
+
+ nl_cache_free(class_cache);
+}
+
+int main(int argc, char *argv[])
+{
+ struct nl_cache *link_cache;
+
+ sock = nlt_alloc_socket();
+ nlt_connect(sock, NETLINK_ROUTE);
+ link_cache = nlt_alloc_link_cache(sock);
+ qdisc_cache = nlt_alloc_qdisc_cache(sock);
+
+ params.dp_fd = stdout;
+
+ for (;;) {
+ int c, optidx = 0;
+ static struct option long_opts[] = {
+ { "format", 1, 0, 'f' },
+ { "help", 0, 0, 'h' },
+ { "version", 0, 0, 'v' },
+ { 0, 0, 0, 0 }
+ };
+
+ c = getopt_long(argc, argv, "f:hv", long_opts, &optidx);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
+ case 'h': print_usage(); break;
+ case 'v': nlt_print_version(); break;
+ }
+ }
+
+ nl_cache_foreach(link_cache, &print_link, NULL);
+
+ return 0;
+}