All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2 0/4] ip: Add vrf show commmand
@ 2017-05-27 23:34 David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 1/4] ip address: Export ip_linkaddr_list David Ahern
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: David Ahern @ 2017-05-27 23:34 UTC (permalink / raw)
  To: netdev, stephen; +Cc: David Ahern

Refactor ip address to export its capability to save a list of nlmsg's
for links and its link filter. Use both to add an 'ip vrf show' command
to list all configured VRF with table id.

David Ahern (4):
  ip address: Export ip_linkaddr_list
  ip address: Move filter struct to ip_common.h
  ip address: Change print_linkinfo_brief to take filter as an input
  ip vrf: Add show command

 include/libnetlink.h |  10 ++++
 ip/ip_common.h       |  27 ++++++++-
 ip/ipaddress.c       | 144 +++++++++++++++++++++++-------------------------
 ip/iplink.c          |   2 +-
 ip/ipvrf.c           | 153 +++++++++++++++++++++++++++++++++++++++++++++++++--
 man/man8/ip-vrf.8    |  11 ++++
 6 files changed, 266 insertions(+), 81 deletions(-)

-- 
2.11.0 (Apple Git-81)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH iproute2 1/4] ip address: Export ip_linkaddr_list
  2017-05-27 23:34 [PATCH iproute2 0/4] ip: Add vrf show commmand David Ahern
@ 2017-05-27 23:34 ` David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 2/4] ip address: Move filter struct to ip_common.h David Ahern
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: David Ahern @ 2017-05-27 23:34 UTC (permalink / raw)
  To: netdev, stephen; +Cc: David Ahern

ipaddr_list_flush_or_save generates a list of nlmsg's for links and
optionally for addresses. Move the code into ip_linkaddr_list and
export it along with the supporting infrastructure.

API to use this function is:
        struct nlmsg_chain linfo = { NULL, NULL};
        struct nlmsg_chain ainfo = { NULL, NULL};

        ip_linkaddr_list(family, filter_req, &linfo, &ainfo);

        ... error checking and code looping over linfo/ainfo ...

        free_nlmsg_chain(&linfo);
        free_nlmsg_chain(&ainfo);

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 include/libnetlink.h | 10 ++++++
 ip/ip_common.h       |  4 +++
 ip/ipaddress.c       | 87 +++++++++++++++++++++++++++++-----------------------
 3 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/include/libnetlink.h b/include/libnetlink.h
index c43ab0a2d9d9..643c3bc56929 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -25,6 +25,16 @@ struct rtnl_handle {
 	int			flags;
 };
 
+struct nlmsg_list {
+	struct nlmsg_list *next;
+	struct nlmsghdr   h;
+};
+
+struct nlmsg_chain {
+	struct nlmsg_list *head;
+	struct nlmsg_list *tail;
+};
+
 extern int rcvbuf;
 
 int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions)
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 202fc399e61a..450b45ac2b60 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -65,6 +65,10 @@ int do_seg6(int argc, char **argv);
 int iplink_get(unsigned int flags, char *name, __u32 filt_mask);
 int iplink_ifla_xstats(int argc, char **argv);
 
+int ip_linkaddr_list(int family, req_filter_fn_t filter_fn,
+		     struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo);
+void free_nlmsg_chain(struct nlmsg_chain *info);
+
 static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
 {
 	__u32 table = r->rtm_table;
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index b8d9c7d917fe..c805b929134d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1211,16 +1211,6 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 	return 0;
 }
 
-struct nlmsg_list {
-	struct nlmsg_list *next;
-	struct nlmsghdr	  h;
-};
-
-struct nlmsg_chain {
-	struct nlmsg_list *head;
-	struct nlmsg_list *tail;
-};
-
 static int print_selected_addrinfo(struct ifinfomsg *ifi,
 				   struct nlmsg_list *ainfo, FILE *fp)
 {
@@ -1371,7 +1361,7 @@ static int ipaddr_restore(void)
 	exit(rtnl_from_file(stdin, &restore_handler, NULL));
 }
 
-static void free_nlmsg_chain(struct nlmsg_chain *info)
+void free_nlmsg_chain(struct nlmsg_chain *info)
 {
 	struct nlmsg_list *l, *n;
 
@@ -1534,10 +1524,43 @@ static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
 	return 0;
 }
 
+/* fills in linfo with link data and optionally ainfo with address info
+ * caller can walk lists as desired and must call free_nlmsg_chain for
+ * both when done
+ */
+int ip_linkaddr_list(int family, req_filter_fn_t filter_fn,
+		     struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
+{
+	if (rtnl_wilddump_req_filter_fn(&rth, preferred_family, RTM_GETLINK,
+					filter_fn) < 0) {
+		perror("Cannot send dump request");
+		return 1;
+	}
+
+	if (rtnl_dump_filter(&rth, store_nlmsg, linfo) < 0) {
+		fprintf(stderr, "Dump terminated\n");
+		return 1;
+	}
+
+	if (ainfo) {
+		if (rtnl_wilddump_request(&rth, family, RTM_GETADDR) < 0) {
+			perror("Cannot send dump request");
+			return 1;
+		}
+
+		if (rtnl_dump_filter(&rth, store_nlmsg, ainfo) < 0) {
+			fprintf(stderr, "Dump terminated\n");
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 {
 	struct nlmsg_chain linfo = { NULL, NULL};
-	struct nlmsg_chain ainfo = { NULL, NULL};
+	struct nlmsg_chain _ainfo = { NULL, NULL}, *ainfo = NULL;
 	struct nlmsg_list *l;
 	char *filter_dev = NULL;
 	int no_link = 0;
@@ -1714,33 +1737,19 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 		exit(0);
 	}
 
-	if (rtnl_wilddump_req_filter_fn(&rth, preferred_family, RTM_GETLINK,
-					iplink_filter_req) < 0) {
-		perror("Cannot send dump request");
-		exit(1);
-	}
-
-	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) {
-		fprintf(stderr, "Dump terminated\n");
-		exit(1);
-	}
-
 	if (filter.family != AF_PACKET) {
+		ainfo = &_ainfo;
+
 		if (filter.oneline)
 			no_link = 1;
+	}
 
-		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
-			perror("Cannot send dump request");
-			exit(1);
-		}
-
-		if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo) < 0) {
-			fprintf(stderr, "Dump terminated\n");
-			exit(1);
-		}
+	if (ip_linkaddr_list(filter.family, iplink_filter_req,
+			     &linfo, ainfo) != 0)
+		goto out;
 
-		ipaddr_filter(&linfo, &ainfo);
-	}
+	if (filter.family != AF_PACKET)
+		ipaddr_filter(&linfo, ainfo);
 
 	for (l = linfo.head; l; l = l->next) {
 		int res = 0;
@@ -1750,20 +1759,22 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			if (print_linkinfo_brief(NULL, &l->h, stdout) == 0)
 				if (filter.family != AF_PACKET)
 					print_selected_addrinfo(ifi,
-								ainfo.head,
+								ainfo->head,
 								stdout);
 		} else if (no_link ||
-			 (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
+			  (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
 			if (filter.family != AF_PACKET)
 				print_selected_addrinfo(ifi,
-							ainfo.head, stdout);
+							ainfo->head, stdout);
 			if (res > 0 && !do_link && show_stats)
 				print_link_stats(stdout, &l->h);
 		}
 	}
 	fflush(stdout);
 
-	free_nlmsg_chain(&ainfo);
+out:
+	if (ainfo)
+		free_nlmsg_chain(ainfo);
 	free_nlmsg_chain(&linfo);
 
 	return 0;
-- 
2.11.0 (Apple Git-81)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH iproute2 2/4] ip address: Move filter struct to ip_common.h
  2017-05-27 23:34 [PATCH iproute2 0/4] ip: Add vrf show commmand David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 1/4] ip address: Export ip_linkaddr_list David Ahern
@ 2017-05-27 23:34 ` David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 3/4] ip address: Change print_linkinfo_brief to take filter as an input David Ahern
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: David Ahern @ 2017-05-27 23:34 UTC (permalink / raw)
  To: netdev, stephen; +Cc: David Ahern

Move filter struct to ip_common.h as struct link_filter.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 ip/ip_common.h | 20 ++++++++++++++++++++
 ip/ipaddress.c | 22 +---------------------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index 450b45ac2b60..2b3cf7049b65 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -1,3 +1,23 @@
+struct link_filter {
+	int ifindex;
+	int family;
+	int oneline;
+	int showqueue;
+	inet_prefix pfx;
+	int scope, scopemask;
+	int flags, flagmask;
+	int up;
+	char *label;
+	int flushed;
+	char *flushb;
+	int flushp;
+	int flushe;
+	int group;
+	int master;
+	char *kind;
+	char *slave_kind;
+};
+
 int get_operstate(const char *name);
 int print_linkinfo(const struct sockaddr_nl *who,
 		   struct nlmsghdr *n, void *arg);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index c805b929134d..3e2c38a8e53e 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -44,27 +44,7 @@ enum {
 	IPADD_SAVE,
 };
 
-static struct
-{
-	int ifindex;
-	int family;
-	int oneline;
-	int showqueue;
-	inet_prefix pfx;
-	int scope, scopemask;
-	int flags, flagmask;
-	int up;
-	char *label;
-	int flushed;
-	char *flushb;
-	int flushp;
-	int flushe;
-	int group;
-	int master;
-	char *kind;
-	char *slave_kind;
-} filter;
-
+static struct link_filter filter;
 static int do_link;
 
 static void usage(void) __attribute__((noreturn));
-- 
2.11.0 (Apple Git-81)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH iproute2 3/4] ip address: Change print_linkinfo_brief to take filter as an input
  2017-05-27 23:34 [PATCH iproute2 0/4] ip: Add vrf show commmand David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 1/4] ip address: Export ip_linkaddr_list David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 2/4] ip address: Move filter struct to ip_common.h David Ahern
@ 2017-05-27 23:34 ` David Ahern
  2017-05-27 23:34 ` [PATCH iproute2 4/4] ip vrf: Add show command David Ahern
  2017-05-31  0:56 ` [PATCH iproute2 0/4] ip: Add vrf show commmand Stephen Hemminger
  4 siblings, 0 replies; 6+ messages in thread
From: David Ahern @ 2017-05-27 23:34 UTC (permalink / raw)
  To: netdev, stephen; +Cc: David Ahern

Change print_linkinfo_brief to take the filter as an input arg.
If the arg is NULL, use the global filter in ipaddress.c.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 ip/ip_common.h |  3 ++-
 ip/ipaddress.c | 35 ++++++++++++++++++++---------------
 ip/iplink.c    |  2 +-
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index 2b3cf7049b65..77e9dd06b864 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -22,7 +22,8 @@ int get_operstate(const char *name);
 int print_linkinfo(const struct sockaddr_nl *who,
 		   struct nlmsghdr *n, void *arg);
 int print_linkinfo_brief(const struct sockaddr_nl *who,
-			 struct nlmsghdr *n, void *arg);
+			 struct nlmsghdr *n, void *arg,
+			 struct link_filter *filter);
 int print_addrinfo(const struct sockaddr_nl *who,
 		   struct nlmsghdr *n, void *arg);
 int print_addrlabel(const struct sockaddr_nl *who,
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 3e2c38a8e53e..4900dce09df8 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -634,7 +634,8 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
 }
 
 int print_linkinfo_brief(const struct sockaddr_nl *who,
-				struct nlmsghdr *n, void *arg)
+			 struct nlmsghdr *n, void *arg,
+			 struct link_filter *pfilter)
 {
 	FILE *fp = (FILE *)arg;
 	struct ifinfomsg *ifi = NLMSG_DATA(n);
@@ -651,9 +652,12 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
 	if (len < 0)
 		return -1;
 
-	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
+	if (!pfilter)
+		pfilter = &filter;
+
+	if (pfilter->ifindex && ifi->ifi_index != pfilter->ifindex)
 		return -1;
-	if (filter.up && !(ifi->ifi_flags&IFF_UP))
+	if (pfilter->up && !(ifi->ifi_flags&IFF_UP))
 		return -1;
 
 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
@@ -664,30 +668,30 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
 		name = rta_getattr_str(tb[IFLA_IFNAME]);
 	}
 
-	if (filter.label &&
-	    (!filter.family || filter.family == AF_PACKET) &&
-	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
+	if (pfilter->label &&
+	    (!pfilter->family || pfilter->family == AF_PACKET) &&
+	    fnmatch(pfilter->label, RTA_DATA(tb[IFLA_IFNAME]), 0))
 		return -1;
 
 	if (tb[IFLA_GROUP]) {
 		int group = rta_getattr_u32(tb[IFLA_GROUP]);
 
-		if (filter.group != -1 && group != filter.group)
+		if (pfilter->group != -1 && group != pfilter->group)
 			return -1;
 	}
 
 	if (tb[IFLA_MASTER]) {
 		int master = rta_getattr_u32(tb[IFLA_MASTER]);
 
-		if (filter.master > 0 && master != filter.master)
+		if (pfilter->master > 0 && master != pfilter->master)
 			return -1;
-	} else if (filter.master > 0)
+	} else if (pfilter->master > 0)
 		return -1;
 
-	if (filter.kind && match_link_kind(tb, filter.kind, 0))
+	if (pfilter->kind && match_link_kind(tb, pfilter->kind, 0))
 		return -1;
 
-	if (filter.slave_kind && match_link_kind(tb, filter.slave_kind, 1))
+	if (pfilter->slave_kind && match_link_kind(tb, pfilter->slave_kind, 1))
 		return -1;
 
 	if (n->nlmsg_type == RTM_DELLINK)
@@ -713,7 +717,7 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
 	if (tb[IFLA_OPERSTATE])
 		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
 
-	if (filter.family == AF_PACKET) {
+	if (pfilter->family == AF_PACKET) {
 		SPRINT_BUF(b1);
 		if (tb[IFLA_ADDRESS]) {
 			color_fprintf(fp, COLOR_MAC, "%s ",
@@ -724,10 +728,10 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
 		}
 	}
 
-	if (filter.family == AF_PACKET)
+	if (pfilter->family == AF_PACKET)
 		print_link_flags(fp, ifi->ifi_flags, m_flag);
 
-	if (filter.family == AF_PACKET)
+	if (pfilter->family == AF_PACKET)
 		fprintf(fp, "\n");
 	fflush(fp);
 	return 0;
@@ -1736,7 +1740,8 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
 
 		if (brief) {
-			if (print_linkinfo_brief(NULL, &l->h, stdout) == 0)
+			if (print_linkinfo_brief(NULL, &l->h,
+						 stdout, NULL) == 0)
 				if (filter.family != AF_PACKET)
 					print_selected_addrinfo(ifi,
 								ainfo->head,
diff --git a/ip/iplink.c b/ip/iplink.c
index ae1c70ebcc81..58af402cc5eb 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -1036,7 +1036,7 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
 		return -2;
 
 	if (brief)
-		print_linkinfo_brief(NULL, &answer.n, stdout);
+		print_linkinfo_brief(NULL, &answer.n, stdout, NULL);
 	else
 		print_linkinfo(NULL, &answer.n, stdout);
 
-- 
2.11.0 (Apple Git-81)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH iproute2 4/4] ip vrf: Add show command
  2017-05-27 23:34 [PATCH iproute2 0/4] ip: Add vrf show commmand David Ahern
                   ` (2 preceding siblings ...)
  2017-05-27 23:34 ` [PATCH iproute2 3/4] ip address: Change print_linkinfo_brief to take filter as an input David Ahern
@ 2017-05-27 23:34 ` David Ahern
  2017-05-31  0:56 ` [PATCH iproute2 0/4] ip: Add vrf show commmand Stephen Hemminger
  4 siblings, 0 replies; 6+ messages in thread
From: David Ahern @ 2017-05-27 23:34 UTC (permalink / raw)
  To: netdev, stephen; +Cc: David Ahern

Add show command to list all configured VRF and their table ids.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 ip/ipvrf.c        | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/man8/ip-vrf.8 |  11 ++++
 2 files changed, 159 insertions(+), 5 deletions(-)

diff --git a/ip/ipvrf.c b/ip/ipvrf.c
index 0f611b44b78a..0094cf8557cd 100644
--- a/ip/ipvrf.c
+++ b/ip/ipvrf.c
@@ -32,9 +32,12 @@
 
 #define CGRP_PROC_FILE  "/cgroup.procs"
 
+static struct link_filter vrf_filter;
+
 static void usage(void)
 {
-	fprintf(stderr, "Usage: ip vrf exec [NAME] cmd ...\n");
+	fprintf(stderr, "Usage: ip vrf show [NAME] ...\n");
+	fprintf(stderr, "       ip vrf exec [NAME] cmd ...\n");
 	fprintf(stderr, "       ip vrf identify [PID]\n");
 	fprintf(stderr, "       ip vrf pids [NAME]\n");
 
@@ -467,13 +470,148 @@ void vrf_reset(void)
 	vrf_switch("default");
 }
 
-int do_ipvrf(int argc, char **argv)
+static int ipvrf_filter_req(struct nlmsghdr *nlh, int reqlen)
+{
+	struct rtattr *linkinfo;
+	int err;
+
+	if (vrf_filter.kind) {
+		linkinfo = addattr_nest(nlh, reqlen, IFLA_LINKINFO);
+
+		err = addattr_l(nlh, reqlen, IFLA_INFO_KIND, vrf_filter.kind,
+				strlen(vrf_filter.kind));
+		if (err)
+			return err;
+
+		addattr_nest_end(nlh, linkinfo);
+	}
+
+	return 0;
+}
+
+/* input arg is linkinfo */
+static __u32 vrf_table_linkinfo(struct rtattr *li[])
+{
+	struct rtattr *attr[IFLA_VRF_MAX + 1];
+
+	if (li[IFLA_INFO_DATA]) {
+		parse_rtattr_nested(attr, IFLA_VRF_MAX, li[IFLA_INFO_DATA]);
+
+		if (attr[IFLA_VRF_TABLE])
+			return rta_getattr_u32(attr[IFLA_VRF_TABLE]);
+	}
+
+	return 0;
+}
+
+static int ipvrf_print(struct nlmsghdr *n)
+{
+	struct ifinfomsg *ifi = NLMSG_DATA(n);
+	struct rtattr *tb[IFLA_MAX+1];
+	struct rtattr *li[IFLA_INFO_MAX+1];
+	int len = n->nlmsg_len;
+	const char *name;
+	__u32 tb_id;
+
+	len -= NLMSG_LENGTH(sizeof(*ifi));
+	if (len < 0)
+		return 0;
+
+	if (vrf_filter.ifindex && vrf_filter.ifindex != ifi->ifi_index)
+		return 0;
+
+	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+	/* kernel does not support filter by master device */
+	if (tb[IFLA_MASTER]) {
+		int master = *(int *)RTA_DATA(tb[IFLA_MASTER]);
+
+		if (vrf_filter.master && master != vrf_filter.master)
+			return 0;
+	}
+
+	if (!tb[IFLA_IFNAME]) {
+		fprintf(stderr,
+			"BUG: device with ifindex %d has nil ifname\n",
+			ifi->ifi_index);
+		return 0;
+	}
+	name = rta_getattr_str(tb[IFLA_IFNAME]);
+
+	/* missing LINKINFO means not VRF. e.g., kernel does not
+	 * support filtering on kind, so userspace needs to handle
+	 */
+	if (!tb[IFLA_LINKINFO])
+		return 0;
+
+	parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+
+	if (!li[IFLA_INFO_KIND])
+		return 0;
+
+	if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf"))
+		return 0;
+
+	tb_id = vrf_table_linkinfo(li);
+	if (!tb_id) {
+		fprintf(stderr,
+			"BUG: VRF %s is missing table id\n", name);
+		return 0;
+	}
+
+	printf("%-16s %5u", name, tb_id);
+
+	printf("\n");
+	return 1;
+}
+
+static int ipvrf_show(int argc, char **argv)
 {
-	if (argc == 0) {
-		fprintf(stderr, "No command given. Try \"ip vrf help\".\n");
-		exit(-1);
+	struct nlmsg_chain linfo = { NULL, NULL};
+	int rc = 0;
+
+	vrf_filter.kind = "vrf";
+
+	if (argc > 1)
+		usage();
+
+	if (argc == 1) {
+		__u32 tb_id;
+
+		tb_id = ipvrf_get_table(argv[0]);
+		if (!tb_id) {
+			fprintf(stderr, "Invalid VRF\n");
+			return 1;
+		}
+		printf("%s %u\n", argv[0], tb_id);
+		return 0;
 	}
 
+	if (ip_linkaddr_list(0, ipvrf_filter_req, &linfo, NULL) == 0) {
+		struct nlmsg_list *l;
+		unsigned nvrf = 0;
+		int n;
+
+		n = printf("%-16s  %5s\n", "Name", "Table");
+		printf("%.*s\n", n-1, "-----------------------");
+		for (l = linfo.head; l; l = l->next)
+			nvrf += ipvrf_print(&l->h);
+
+		if (!nvrf)
+			printf("No VRF has been configured\n");
+	} else
+		rc = 1;
+
+	free_nlmsg_chain(&linfo);
+
+	return rc;
+}
+
+int do_ipvrf(int argc, char **argv)
+{
+	if (argc == 0)
+		return ipvrf_show(0, NULL);
+
 	if (matches(*argv, "identify") == 0)
 		return ipvrf_identify(argc-1, argv+1);
 
@@ -483,6 +621,11 @@ int do_ipvrf(int argc, char **argv)
 	if (matches(*argv, "exec") == 0)
 		return ipvrf_exec(argc-1, argv+1);
 
+	if (matches(*argv, "show") == 0 ||
+	    matches(*argv, "lst") == 0 ||
+	    matches(*argv, "list") == 0)
+		return ipvrf_show(argc-1, argv+1);
+
 	if (matches(*argv, "help") == 0)
 		usage();
 
diff --git a/man/man8/ip-vrf.8 b/man/man8/ip-vrf.8
index 57a7c7692ce8..187893393be2 100644
--- a/man/man8/ip-vrf.8
+++ b/man/man8/ip-vrf.8
@@ -13,6 +13,10 @@ ip-vrf \- run a command against a vrf
 .sp
 
 .ti -8
+.BR "ip vrf show"
+.RI "[ " NAME " ]"
+
+.ti -8
 .BR "ip vrf identify"
 .RI "[ " PID " ]"
 
@@ -45,6 +49,13 @@ is a helper to run a command against a specific VRF with the VRF association
 inherited parent to child.
 
 .TP
+.B ip vrf show [ NAME ] - Show all configured VRF
+.sp
+This command lists all VRF and their corresponding table ids. If NAME is
+given, then only that VRF and table id is shown. The latter command is
+useful for scripting where the table id for a VRF is needed.
+
+.TP
 .B ip vrf exec [ NAME ] cmd ... - Run cmd against the named VRF
 .sp
 This command allows applications that are VRF unaware to be run against
-- 
2.11.0 (Apple Git-81)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH iproute2 0/4] ip: Add vrf show commmand
  2017-05-27 23:34 [PATCH iproute2 0/4] ip: Add vrf show commmand David Ahern
                   ` (3 preceding siblings ...)
  2017-05-27 23:34 ` [PATCH iproute2 4/4] ip vrf: Add show command David Ahern
@ 2017-05-31  0:56 ` Stephen Hemminger
  4 siblings, 0 replies; 6+ messages in thread
From: Stephen Hemminger @ 2017-05-31  0:56 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev

On Sat, 27 May 2017 17:34:46 -0600
David Ahern <dsahern@gmail.com> wrote:

> Refactor ip address to export its capability to save a list of nlmsg's
> for links and its link filter. Use both to add an 'ip vrf show' command
> to list all configured VRF with table id.
> 
> David Ahern (4):
>   ip address: Export ip_linkaddr_list
>   ip address: Move filter struct to ip_common.h
>   ip address: Change print_linkinfo_brief to take filter as an input
>   ip vrf: Add show command
> 
>  include/libnetlink.h |  10 ++++
>  ip/ip_common.h       |  27 ++++++++-
>  ip/ipaddress.c       | 144 +++++++++++++++++++++++-------------------------
>  ip/iplink.c          |   2 +-
>  ip/ipvrf.c           | 153 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  man/man8/ip-vrf.8    |  11 ++++
>  6 files changed, 266 insertions(+), 81 deletions(-)
> 

Looks good, series applied to master.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-05-31  0:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-27 23:34 [PATCH iproute2 0/4] ip: Add vrf show commmand David Ahern
2017-05-27 23:34 ` [PATCH iproute2 1/4] ip address: Export ip_linkaddr_list David Ahern
2017-05-27 23:34 ` [PATCH iproute2 2/4] ip address: Move filter struct to ip_common.h David Ahern
2017-05-27 23:34 ` [PATCH iproute2 3/4] ip address: Change print_linkinfo_brief to take filter as an input David Ahern
2017-05-27 23:34 ` [PATCH iproute2 4/4] ip vrf: Add show command David Ahern
2017-05-31  0:56 ` [PATCH iproute2 0/4] ip: Add vrf show commmand Stephen Hemminger

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.