Home | History | Annotate | Download | only in src
      1 /*
      2  * src/nl-tctree-list.c		List Traffic Control Tree
      3  *
      4  *	This library is free software; you can redistribute it and/or
      5  *	modify it under the terms of the GNU Lesser General Public
      6  *	License as published by the Free Software Foundation version 2.1
      7  *	of the License.
      8  *
      9  * Copyright (c) 2003-2009 Thomas Graf <tgraf (at) suug.ch>
     10  */
     11 
     12 #include <netlink/cli/utils.h>
     13 #include <netlink/cli/link.h>
     14 #include <netlink/cli/qdisc.h>
     15 #include <linux/pkt_sched.h>
     16 
     17 static struct nl_sock *sock;
     18 static struct nl_cache *qdisc_cache, *class_cache;
     19 static struct nl_dump_params params = {
     20 	.dp_type = NL_DUMP_DETAILS,
     21 };
     22 
     23 static int ifindex;
     24 static void print_qdisc(struct nl_object *, void *);
     25 
     26 static void print_usage(void)
     27 {
     28 	printf(
     29 	"Usage: nl-tctree-list [OPTION]...\n"
     30 	"\n"
     31 	"Options\n"
     32 	" -f, --format=TYPE	Output format { brief | details | stats }\n"
     33 	" -h, --help            Show this help\n"
     34 	" -v, --version		Show versioning information\n"
     35 	);
     36 	exit(0);
     37 }
     38 
     39 static void print_class(struct nl_object *obj, void *arg)
     40 {
     41 	struct rtnl_qdisc *leaf;
     42 	struct rtnl_class *class = (struct rtnl_class *) obj;
     43 	struct nl_cache *cls_cache;
     44 	uint32_t parent = rtnl_class_get_handle(class);
     45 
     46 	params.dp_prefix = (int)(long) arg;
     47 	nl_object_dump(obj, &params);
     48 
     49 	leaf = rtnl_class_leaf_qdisc(class, qdisc_cache);
     50 	if (leaf)
     51 		print_qdisc((struct nl_object *) leaf, arg + 2);
     52 
     53 	rtnl_class_foreach_child(class, class_cache, &print_class, arg + 2);
     54 
     55 	if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
     56 		return;
     57 
     58 	params.dp_prefix = (int)(long) arg + 2;
     59 	nl_cache_dump(cls_cache, &params);
     60 	nl_cache_free(cls_cache);
     61 }
     62 
     63 static void print_qdisc(struct nl_object *obj, void *arg)
     64 {
     65 	struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) obj;
     66 	struct nl_cache *cls_cache;
     67 	uint32_t parent = rtnl_qdisc_get_handle(qdisc);
     68 
     69 	params.dp_prefix = (int)(long) arg;
     70 	nl_object_dump(obj, &params);
     71 
     72 	rtnl_qdisc_foreach_child(qdisc, class_cache, &print_class, arg + 2);
     73 
     74 	if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
     75 		return;
     76 
     77 	params.dp_prefix = (int)(long) arg + 2;
     78 	nl_cache_dump(cls_cache, &params);
     79 	nl_cache_free(cls_cache);
     80 }
     81 
     82 static void print_link(struct nl_object *obj, void *arg)
     83 {
     84 	struct rtnl_link *link = (struct rtnl_link *) obj;
     85 	struct rtnl_qdisc *qdisc;
     86 
     87 	ifindex = rtnl_link_get_ifindex(link);
     88 	params.dp_prefix = 0;
     89 	nl_object_dump(obj, &params);
     90 
     91 	if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0)
     92 		return;
     93 
     94 	qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT);
     95 	if (qdisc) {
     96 		print_qdisc((struct nl_object *) qdisc, (void *) 2);
     97 		rtnl_qdisc_put(qdisc);
     98 	}
     99 
    100 	qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, 0);
    101 	if (qdisc) {
    102 		print_qdisc((struct nl_object *) qdisc, (void *) 2);
    103 		rtnl_qdisc_put(qdisc);
    104 	}
    105 
    106 	qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_INGRESS);
    107 	if (qdisc) {
    108 		print_qdisc((struct nl_object *) qdisc, (void *) 2);
    109 		rtnl_qdisc_put(qdisc);
    110 	}
    111 
    112 	nl_cache_free(class_cache);
    113 }
    114 
    115 int main(int argc, char *argv[])
    116 {
    117 	struct nl_cache *link_cache;
    118 
    119 	sock = nl_cli_alloc_socket();
    120 	nl_cli_connect(sock, NETLINK_ROUTE);
    121 	link_cache = nl_cli_link_alloc_cache(sock);
    122 	qdisc_cache = nl_cli_qdisc_alloc_cache(sock);
    123 
    124 	params.dp_fd = stdout;
    125 
    126 	for (;;) {
    127 		int c, optidx = 0;
    128 		static struct option long_opts[] = {
    129 			{ "format", 1, 0, 'f' },
    130 			{ "help", 0, 0, 'h' },
    131 			{ "version", 0, 0, 'v' },
    132 			{ 0, 0, 0, 0 }
    133 		};
    134 
    135 		c = getopt_long(argc, argv, "f:hv", long_opts, &optidx);
    136 		if (c == -1)
    137 			break;
    138 
    139 		switch (c) {
    140 		case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break;
    141 		case 'h': print_usage(); break;
    142 		case 'v': nl_cli_print_version(); break;
    143 		}
    144 	}
    145 
    146 	nl_cache_foreach(link_cache, &print_link, NULL);
    147 
    148 	return 0;
    149 }
    150