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

On Sun, 2017-02-26 at 08:56 +0100, Jiri Pirko wrote:
> 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 ?
> 

Thanks for the link. I haven't seen plotnetcfg and I like it.
It is handy when the analyzed system has GUI.


> 
> > 
> > 
> > > 
> > > 
> > > 
> > > > 
> > > > > > > > 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 14:00 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
2017-02-26 14:00       ` Zaboj Campula [this message]
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=1488117614.1903.2.camel@post.cz \
    --to=zaboj.campula@post.cz \
    --cc=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).