All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Pirko <jiri@resnulli.us>
To: Zaboj Campula <zaboj.campula@post.cz>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH] iproute2: show network device dependency tree
Date: Sun, 26 Feb 2017 08:56:33 +0100	[thread overview]
Message-ID: <20170226075633.GA1788@nanopsycho> (raw)
In-Reply-To: <1488054142.3856.15.camel@post.cz>

Sat, Feb 25, 2017 at 09:22:22PM CET, zaboj.campula@post.cz wrote:
>On Sat, 2017-02-25 at 18:39 +0100, Jiri Pirko wrote:
>> > Sat, Feb 25, 2017 at 05:59:00PM CET, zaboj.campula@post.cz wrote:
>> > Add the argument '-tree' to ip-link to show network devices dependency tree.
>> > 
>> > Example:
>> > 
>> > $ ip -tree link
>> > eth0
>> >    bond0
>> > eth1
>> >    bond0
>> > eth2
>> >    bond1
>> > eth3
>> >    bond1
>> 
>> 
>> Hmm, what is this good for? I'm probably missing something...
>
>I consider this kind of output useful when troubleshooting a complex
>configuration with many interfaces. It may show relations among
>interfaces.

Did you see https://github.com/jbenc/plotnetcfg ?


>
>
>> 
>> 
>> 
>> > 
>> > > > Signed-off-by: Zaboj Campula <zaboj.campula@post.cz>
>> > ---
>> > include/utils.h |  1 +
>> > ip/ip.c         |  5 ++-
>> > ip/ipaddress.c  | 97 ++++++++++++++++++++++++++++++++++++++++++++++++---------
>> > 3 files changed, 87 insertions(+), 16 deletions(-)
>> > 
>> > diff --git a/include/utils.h b/include/utils.h
>> > index 22369e0..f1acf4d 100644
>> > --- a/include/utils.h
>> > +++ b/include/utils.h
>> > @@ -20,6 +20,7 @@ extern int show_raw;
>> > extern int resolve_hosts;
>> > extern int oneline;
>> > extern int brief;
>> > +extern int tree;;
>> > extern int timestamp;
>> > extern int timestamp_short;
>> > extern const char * _SL_;
>> > diff --git a/ip/ip.c b/ip/ip.c
>> > index 07050b0..29747a5 100644
>> > --- a/ip/ip.c
>> > +++ b/ip/ip.c
>> > @@ -33,6 +33,7 @@ int show_details;
>> > int resolve_hosts;
>> > int oneline;
>> > int brief;
>> > +int tree;
>> > int timestamp;
>> > const char *_SL_;
>> > int force;
>> > @@ -57,7 +58,7 @@ static void usage(void)
>> > "                    -h[uman-readable] | -iec |\n"
>> > "                    -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
>> > "                    -4 | -6 | -I | -D | -B | -0 |\n"
>> > -"                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n"
>> > +"                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] | -tr[ee] |\n"
>> > "                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
>> > "                    -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n");
>> > 	exit(-1);
>> > @@ -257,6 +258,8 @@ int main(int argc, char **argv)
>> > > > 			batch_file = argv[1];
>> > > > 		} else if (matches(opt, "-brief") == 0) {
>> > > > 			++brief;
>> > > > +		} else if (matches(opt, "-tree") == 0) {
>> > > > +			++tree;
>> > > > 		} else if (matches(opt, "-rcvbuf") == 0) {
>> > > > 			unsigned int size;
>> > 
>> > diff --git a/ip/ipaddress.c b/ip/ipaddress.c
>> > index 242c6ea..5ebcb1a 100644
>> > --- a/ip/ipaddress.c
>> > +++ b/ip/ipaddress.c
>> > @@ -1534,6 +1534,69 @@ static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
>> > 	return 0;
>> > }
>> > 
>> > +static int has_master(struct nlmsg_chain *linfo, int index)
>> > +{
>> > > > +	struct nlmsg_list *l;
>> > > > +	struct rtattr *tb[IFLA_MAX+1];
>> > > > +	int len;
>> > > > +	for (l = linfo->head; l; l = l->next) {
>> > > > +		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
>> > > > +		len = l->h.nlmsg_len;
>> > > > +		len -= NLMSG_LENGTH(sizeof(*ifi));
>> > > > +		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
>> > > > +		if (tb[IFLA_MASTER] && *(int *)RTA_DATA(tb[IFLA_MASTER]) == index)
>> > > > +			return 1;
>> > > > +	}
>> > > > +	return 0;
>> > +}
>> > +
>> > +static struct nlmsg_list *get_master(struct nlmsg_chain *linfo, struct rtattr **tb)
>> > +{
>> > > > +	struct nlmsg_list *l;
>> > > > +	if (tb[IFLA_MASTER]) {
>> > > > +		int master = *(int *)RTA_DATA(tb[IFLA_MASTER]);
>> > > > +		for (l = linfo->head; l; l = l->next) {
>> > > > +			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
>> > > > +			if (ifi->ifi_index == master)
>> > > > +				return l;
>> > > > +		}
>> > > > +	}
>> > > > +	return NULL;
>> > +}
>> > +
>> > +static void print_dev_tree_item(struct nlmsg_chain *linfo, struct nlmsg_list *l, int indent) {
>> > > > +	char *name;
>> > > > +	int len;
>> > > > +	struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
>> > > > +	struct rtattr *tb[IFLA_MAX+1];
>> > > > +	len = l->h.nlmsg_len;
>> > > > +	len -= NLMSG_LENGTH(sizeof(*ifi));
>> > > > +	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
>> > > > +	name = (char *)(tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
>> > +
>> > > > +	printf("%*s%s\n", indent * 4, "", name);
>> > +
>> > > > +	struct nlmsg_list *master = get_master(linfo, tb);
>> > > > +	if (master) {
>> > > > +		if (indent > 8) {
>> > > > +			printf("%*s...\n", (indent + 1) * 4, "");
>> > > > +		} else {
>> > > > +			print_dev_tree_item(linfo, master, indent + 1);
>> > > > +		}
>> > > > +	}
>> > +}
>> > +
>> > +static void print_devtree(struct nlmsg_chain *linfo)
>> > +{
>> > > > +	struct nlmsg_list *l;
>> > > > +	for (l = linfo->head; l; l = l->next) {
>> > > > +		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
>> > > > +		if (!has_master(linfo, ifi->ifi_index)) {
>> > > > +			print_dev_tree_item(linfo, l, 0);
>> > > > +		}
>> > > > +	}
>> > +}
>> > +
>> > static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
>> > {
>> > 	struct nlmsg_chain linfo = { NULL, NULL};
>> > @@ -1742,23 +1805,27 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
>> > > > 		ipaddr_filter(&linfo, &ainfo);
>> > 	}
>> > 
>> > > > -	for (l = linfo.head; l; l = l->next) {
>> > > > -		int res = 0;
>> > > > -		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
>> > -
>> > > > -		if (brief) {
>> > > > -			if (print_linkinfo_brief(NULL, &l->h, stdout) == 0)
>> > > > +	if (tree) {
>> > > > +		print_devtree(&linfo);
>> > > > +	} else {
>> > > > +		for (l = linfo.head; l; l = l->next) {
>> > > > +			int res = 0;
>> > > > +			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
>> > +
>> > > > +			 if (brief) {
>> > > > +				if (print_linkinfo_brief(NULL, &l->h, stdout) == 0)
>> > > > +					if (filter.family != AF_PACKET)
>> > > > +						print_selected_addrinfo(ifi,
>> > > > +									ainfo.head,
>> > > > +									stdout);
>> > > > +			} else if (no_link ||
>> > > > +				 (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
>> > > > 				if (filter.family != AF_PACKET)
>> > > > 					print_selected_addrinfo(ifi,
>> > > > -								ainfo.head,
>> > > > -								stdout);
>> > > > -		} else if (no_link ||
>> > > > -			 (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
>> > > > -			if (filter.family != AF_PACKET)
>> > > > -				print_selected_addrinfo(ifi,
>> > > > -							ainfo.head, stdout);
>> > > > -			if (res > 0 && !do_link && show_stats)
>> > > > -				print_link_stats(stdout, &l->h);
>> > > > +								ainfo.head, stdout);
>> > > > +				if (res > 0 && !do_link && show_stats)
>> > > > +					print_link_stats(stdout, &l->h);
>> > > > +			}
>> > > > 		}
>> > 	}
>> > 	fflush(stdout);
>> > -- 
>> > 2.9.3
>> > 

  reply	other threads:[~2017-02-26  7:57 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-25 16:59 [PATCH] iproute2: show network device dependency tree Zaboj Campula
2017-02-25 17:39 ` Jiri Pirko
2017-02-25 20:22   ` Zaboj Campula
2017-02-26  7:56     ` Jiri Pirko [this message]
2017-02-26 14:00       ` Zaboj Campula
2017-02-26 14:46         ` Jiri Pirko
2017-02-27 16:38           ` Jiri Benc
2017-02-28 20:07             ` Zaboj Campula
2017-03-01 10:22               ` Jiri Benc
2017-03-02 19:51                 ` Zaboj Campula
2017-02-27 17:26       ` Stephen Hemminger
2017-02-27 18:52 ` Stephen Hemminger
2017-02-27 18:55 ` Stephen Hemminger
2017-02-28 20:19   ` Zaboj Campula
2017-02-28 21:47     ` Jiri Pirko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170226075633.GA1788@nanopsycho \
    --to=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    --cc=zaboj.campula@post.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.