netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH iproute2 0/6] Add support for vrf keyword
@ 2016-06-14 20:59 David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 1/6] ip vrf: Add name_is_vrf David Ahern
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Currently the syntax for VRF related commands is rather kludgy and
inconsistent from one subcommand to another. This set adds support
for the VRF keyword to the link, address, neigh, and route commands
to improve the user experience listing data associated with vrfs,
modifying routes or doing a route lookup.

David Ahern (6):
  ip vrf: Add name_is_vrf
  ip link/addr: Add support for vrf keyword
  ip neigh: Add support for keyword
  ip route: Change type mask to bitmask
  ip vrf: Add ipvrf_get_table
  ip route: Add support for vrf keyword

 ip/ip_common.h  |   3 ++
 ip/ipaddress.c  |  11 ++++++
 ip/iplink.c     |  15 ++++++-
 ip/iplink_vrf.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ip/ipneigh.c    |  14 ++++++-
 ip/iproute.c    |  43 ++++++++++++++++----
 6 files changed, 195 insertions(+), 10 deletions(-)

-- 
2.1.4

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

* [PATCH iproute2 1/6] ip vrf: Add name_is_vrf
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
@ 2016-06-14 20:59 ` David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 2/6] ip link/addr: Add support for vrf keyword David Ahern
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Add name_is_vrf function to determine if given name corresponds to a
VRF device.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/ip_common.h  |  2 ++
 ip/iplink_vrf.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index e8da9e034b15..410eb135774a 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -90,6 +90,8 @@ struct link_util *get_link_slave_kind(const char *slave_kind);
 
 void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
 
+bool name_is_vrf(char *name);
+
 #ifndef	INFINITY_LIFE_TIME
 #define     INFINITY_LIFE_TIME      0xFFFFFFFFU
 #endif
diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c
index e3c7b4652da5..abd43c08423e 100644
--- a/ip/iplink_vrf.c
+++ b/ip/iplink_vrf.c
@@ -96,3 +96,56 @@ struct link_util vrf_slave_link_util = {
 	.print_opt	= vrf_slave_print_opt,
 	.slave          = true,
 };
+
+bool name_is_vrf(char *name)
+{
+	struct {
+		struct nlmsghdr		n;
+		struct ifinfomsg	i;
+		char			buf[1024];
+	} req = {
+		.n = {
+			.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+			.nlmsg_flags = NLM_F_REQUEST,
+			.nlmsg_type  = RTM_GETLINK,
+		},
+		.i = {
+			.ifi_family  = preferred_family,
+		},
+	};
+	struct {
+		struct nlmsghdr n;
+		char buf[8192];
+	} answer;
+	struct rtattr *tb[IFLA_MAX+1];
+	struct rtattr *li[IFLA_INFO_MAX+1];
+	struct ifinfomsg *ifi;
+	int len;
+
+	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
+
+	if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
+		goto err;
+
+	ifi = NLMSG_DATA(&answer.n);
+	len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
+	if (len < 0) {
+		fprintf(stderr, "BUG: Invalid response to link query.\n");
+		goto err;
+	}
+
+	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+	if (!tb[IFLA_LINKINFO])
+		goto err;
+
+	parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+
+	if (!li[IFLA_INFO_KIND])
+		goto err;
+
+	return strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf") == 0;
+
+err:
+	return false;
+}
-- 
2.1.4

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

* [PATCH iproute2 2/6] ip link/addr: Add support for vrf keyword
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 1/6] ip vrf: Add name_is_vrf David Ahern
@ 2016-06-14 20:59 ` David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 3/6] ip neigh: Add support for keyword David Ahern
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Add vrf keyword to 'ip link' and 'ip addr' commands (common list code).

Allows:
1. Adding a link to a VRF using the vrf name:
     $ ip link set NAME vrf NAME

   Versus the current syntax:
     $ ip link set NAME master DEV
   Removing a link from a VRF still uses 'ip link set NAME nomaster'

2. Showing links associated with a VRF:
       $ ip link show vrf NAME

   Versus the current syntax:
     $ ip link show master DEV

3. List addresses associated with links in a VRF
     $ ip addr show vrf NAME

   Versus the current syntax:
     $ ip addr show master DEV

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/ipaddress.c | 11 +++++++++++
 ip/iplink.c    | 15 +++++++++++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index df363b070d5d..170c4f5d1eb5 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -77,6 +77,7 @@ static void usage(void)
 	fprintf(stderr, "       ip address del IFADDR dev IFNAME [mngtmpaddr]\n");
 	fprintf(stderr, "       ip address {show|save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n");
 	fprintf(stderr, "                            [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
+	fprintf(stderr, "                            [ vrf NAME ]\n");
 	fprintf(stderr, "       ip address {showdump|restore}\n");
 	fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
 	fprintf(stderr, "          [ broadcast ADDR ] [ anycast ADDR ]\n");
@@ -1613,6 +1614,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			if (!ifindex)
 				invarg("Device does not exist\n", *argv);
 			filter.master = ifindex;
+		} else if (strcmp(*argv, "vrf") == 0) {
+			int ifindex;
+
+			NEXT_ARG();
+			ifindex = ll_name_to_index(*argv);
+			if (!ifindex)
+				invarg("Not a valid VRF name\n", *argv);
+			if (!name_is_vrf(*argv))
+				invarg("Not a valid VRF name\n", *argv);
+			filter.master = ifindex;
 		} else if (do_link && strcmp(*argv, "type") == 0) {
 			NEXT_ARG();
 			filter.kind = *argv;
diff --git a/ip/iplink.c b/ip/iplink.c
index d2e586b6d133..d564aca6406e 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -82,11 +82,11 @@ void iplink_usage(void)
 	fprintf(stderr, "				   [ query_rss { on | off} ]\n");
 	fprintf(stderr, "				   [ state { auto | enable | disable} ] ]\n");
 	fprintf(stderr, "				   [ trust { on | off} ] ]\n");
-	fprintf(stderr, "			  [ master DEVICE ]\n");
+	fprintf(stderr, "			  [ master DEVICE ][ vrf NAME ]\n");
 	fprintf(stderr, "			  [ nomaster ]\n");
 	fprintf(stderr, "			  [ addrgenmode { eui64 | none | stable_secret | random } ]\n");
 	fprintf(stderr, "	                  [ protodown { on | off } ]\n");
-	fprintf(stderr, "       ip link show [ DEVICE | group GROUP ] [up] [master DEV] [type TYPE]\n");
+	fprintf(stderr, "       ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n");
 
 	if (iplink_have_newlink()) {
 		fprintf(stderr, "       ip link help [ TYPE ]\n");
@@ -565,6 +565,17 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
 				invarg("Device does not exist\n", *argv);
 			addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
 				  &ifindex, 4);
+		} else if (strcmp(*argv, "vrf") == 0) {
+			int ifindex;
+
+			NEXT_ARG();
+			ifindex = ll_name_to_index(*argv);
+			if (!ifindex)
+				invarg("Not a valid VRF name\n", *argv);
+			if (!name_is_vrf(*argv))
+				invarg("Not a valid VRF name\n", *argv);
+			addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
+				  &ifindex, sizeof(ifindex));
 		} else if (matches(*argv, "nomaster") == 0) {
 			int ifindex = 0;
 
-- 
2.1.4

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

* [PATCH iproute2 3/6] ip neigh: Add support for keyword
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 1/6] ip vrf: Add name_is_vrf David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 2/6] ip link/addr: Add support for vrf keyword David Ahern
@ 2016-06-14 20:59 ` David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 4/6] ip route: Change type mask to bitmask David Ahern
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Add vrf keyword to 'ip neigh' commands. Allows listing neighbor
entries for all links associated with a given VRF.
  $ ip neigh show vrf NAME

versus current syntax:
  $ ip neigh show master DEV

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/ipneigh.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/ip/ipneigh.c b/ip/ipneigh.c
index 4ddb747e2086..3e444712645f 100644
--- a/ip/ipneigh.c
+++ b/ip/ipneigh.c
@@ -48,7 +48,8 @@ static void usage(void)
 {
 	fprintf(stderr, "Usage: ip neigh { add | del | change | replace }\n"
 			"                { ADDR [ lladdr LLADDR ] [ nud STATE ] | proxy ADDR } [ dev DEV ]\n");
-	fprintf(stderr, "       ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n\n");
+	fprintf(stderr, "       ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n");
+	fprintf(stderr, "                                 [ vrf NAME ]\n\n");
 	fprintf(stderr, "STATE := { permanent | noarp | stale | reachable | none |\n"
 			"           incomplete | delay | probe | failed }\n");
 	exit(-1);
@@ -385,6 +386,17 @@ static int do_show_or_flush(int argc, char **argv, int flush)
 				invarg("Device does not exist\n", *argv);
 			addattr32(&req.n, sizeof(req), NDA_MASTER, ifindex);
 			filter.master = ifindex;
+		} else if (strcmp(*argv, "vrf") == 0) {
+			int ifindex;
+
+			NEXT_ARG();
+			ifindex = ll_name_to_index(*argv);
+			if (!ifindex)
+				invarg("Not a valid VRF name\n", *argv);
+			if (!name_is_vrf(*argv))
+				invarg("Not a valid VRF name\n", *argv);
+			addattr32(&req.n, sizeof(req), NDA_MASTER, ifindex);
+			filter.master = ifindex;
 		} else if (strcmp(*argv, "unused") == 0) {
 			filter.unused_only = 1;
 		} else if (strcmp(*argv, "nud") == 0) {
-- 
2.1.4

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

* [PATCH iproute2 4/6] ip route: Change type mask to bitmask
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
                   ` (2 preceding siblings ...)
  2016-06-14 20:59 ` [PATCH iproute2 3/6] ip neigh: Add support for keyword David Ahern
@ 2016-06-14 20:59 ` David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 5/6] ip vrf: Add ipvrf_get_table David Ahern
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Allow option to select multiple route types to show or exlude
specific route types.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/iproute.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 8224d7ffa94b..aae693d17be8 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -113,7 +113,7 @@ static struct
 	int flushe;
 	int protocol, protocolmask;
 	int scope, scopemask;
-	int type, typemask;
+	__u64 typemask;
 	int tos, tosmask;
 	int iif, iifmask;
 	int oif, oifmask;
@@ -178,7 +178,8 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
 		return 0;
 	if ((filter.scope^r->rtm_scope)&filter.scopemask)
 		return 0;
-	if ((filter.type^r->rtm_type)&filter.typemask)
+
+	if (filter.typemask && !(filter.typemask & (1 << r->rtm_type)))
 		return 0;
 	if ((filter.tos^r->rtm_tos)&filter.tosmask)
 		return 0;
@@ -365,7 +366,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 
 	if (n->nlmsg_type == RTM_DELROUTE)
 		fprintf(fp, "Deleted ");
-	if ((r->rtm_type != RTN_UNICAST || show_details > 0) && !filter.type)
+	if ((r->rtm_type != RTN_UNICAST || show_details > 0) &&
+	    (!filter.typemask || (filter.typemask & (1 << r->rtm_type))))
 		fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
 
 	if (tb[RTA_DST]) {
@@ -1433,10 +1435,9 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
 			int type;
 
 			NEXT_ARG();
-			filter.typemask = -1;
 			if (rtnl_rtntype_a2n(&type, *argv))
 				invarg("node type value is invalid\n", *argv);
-			filter.type = type;
+			filter.typemask = (1<<type);
 		} else if (strcmp(*argv, "dev") == 0 ||
 			   strcmp(*argv, "oif") == 0) {
 			NEXT_ARG();
-- 
2.1.4

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

* [PATCH iproute2 5/6] ip vrf: Add ipvrf_get_table
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
                   ` (3 preceding siblings ...)
  2016-06-14 20:59 ` [PATCH iproute2 4/6] ip route: Change type mask to bitmask David Ahern
@ 2016-06-14 20:59 ` David Ahern
  2016-06-14 20:59 ` [PATCH iproute2 6/6] ip route: Add support for vrf keyword David Ahern
  2016-06-24  1:46 ` [PATCH iproute2 0/6] " David Ahern
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Add ipvrf_get_table to lookup table id for device name. Returns 0
on any error or if name is not a VRF device.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/ip_common.h  |  1 +
 ip/iplink_vrf.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index 410eb135774a..8fdb7219fc2b 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -90,6 +90,7 @@ struct link_util *get_link_slave_kind(const char *slave_kind);
 
 void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
 
+__u32 ipvrf_get_table(char *name);
 bool name_is_vrf(char *name);
 
 #ifndef	INFINITY_LIFE_TIME
diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c
index abd43c08423e..2eecb4564f7e 100644
--- a/ip/iplink_vrf.c
+++ b/ip/iplink_vrf.c
@@ -97,6 +97,72 @@ struct link_util vrf_slave_link_util = {
 	.slave          = true,
 };
 
+/* returns table id if name is a VRF device */
+__u32 ipvrf_get_table(char *name)
+{
+	struct {
+		struct nlmsghdr		n;
+		struct ifinfomsg	i;
+		char			buf[1024];
+	} req = {
+		.n = {
+			.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+			.nlmsg_flags = NLM_F_REQUEST,
+			.nlmsg_type  = RTM_GETLINK,
+		},
+		.i = {
+			.ifi_family  = preferred_family,
+		},
+	};
+	struct {
+		struct nlmsghdr n;
+		char buf[8192];
+	} answer;
+	struct rtattr *tb[IFLA_MAX+1];
+	struct rtattr *li[IFLA_INFO_MAX+1];
+	struct rtattr *vrf_attr[IFLA_VRF_MAX + 1];
+	struct ifinfomsg *ifi;
+	__u32 tb_id = 0;
+	int len;
+
+	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
+
+	if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
+		goto err;
+
+	ifi = NLMSG_DATA(&answer.n);
+	len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
+	if (len < 0) {
+		fprintf(stderr, "BUG: Invalid response to link query.\n");
+		goto err;
+	}
+
+	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+	if (!tb[IFLA_LINKINFO])
+		goto err;
+
+	parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+
+	if (!li[IFLA_INFO_KIND] || !li[IFLA_INFO_DATA])
+		goto err;
+
+	if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf"))
+		goto err;
+
+	parse_rtattr_nested(vrf_attr, IFLA_VRF_MAX, li[IFLA_INFO_DATA]);
+	if (vrf_attr[IFLA_VRF_TABLE])
+		tb_id = rta_getattr_u32(vrf_attr[IFLA_VRF_TABLE]);
+
+	if (!tb_id)
+		fprintf(stderr, "BUG: VRF %s is missing table id\n", name);
+
+	return tb_id;
+
+err:
+	return 0;
+}
+
 bool name_is_vrf(char *name)
 {
 	struct {
-- 
2.1.4

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

* [PATCH iproute2 6/6] ip route: Add support for vrf keyword
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
                   ` (4 preceding siblings ...)
  2016-06-14 20:59 ` [PATCH iproute2 5/6] ip vrf: Add ipvrf_get_table David Ahern
@ 2016-06-14 20:59 ` David Ahern
  2016-06-24  1:46 ` [PATCH iproute2 0/6] " David Ahern
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-14 20:59 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Add vrf keyword to 'ip route' commands. Allows:
1. Users can list routes by VRF name:
       $ ip route show vrf NAME

   VRF tables have all routes including local and broadcast routes.
   The VRF keyword filters LOCAL and BROADCAST routes; to see all
   routes the table option can be used. Or to see local routes only
   for a VRF:
       $ ip route show vrf NAME type local

   Contrast with current syntax:
       $ ip route show table ID

   where the user needs to find the vrf to table ID or maintain a
   text file in /etc/iproute2/rt_tables.d.

2. Add or delete a route for a VRF:
       $ ip route {add|delete} vrf NAME <route spec>

   Similarly for this command, users currently need to use table
   option and know the table id or maintain a mapping.

3. Do a route lookup for a VRF:
       $ ip route get vrf NAME ADDRESS

   Contrast with current syntax:
       $ ip route get oif DEV ADDRESS

   (specifying table id for route get does not work kernel side).

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/iproute.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index aae693d17be8..bd661c16cb46 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -67,10 +67,10 @@ static void usage(void)
 	fprintf(stderr, "       ip route showdump\n");
 	fprintf(stderr, "       ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
 	fprintf(stderr, "                            [ oif STRING ] [ tos TOS ]\n");
-	fprintf(stderr, "                            [ mark NUMBER ]\n");
+	fprintf(stderr, "                            [ mark NUMBER ] [ vrf NAME ]\n");
 	fprintf(stderr, "       ip route { add | del | change | append | replace } ROUTE\n");
 	fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n");
-	fprintf(stderr, "            [ table TABLE_ID ] [ proto RTPROTO ]\n");
+	fprintf(stderr, "            [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n");
 	fprintf(stderr, "            [ type TYPE ] [ scope SCOPE ]\n");
 	fprintf(stderr, "ROUTE := NODE_SPEC [ INFO_SPEC ]\n");
 	fprintf(stderr, "NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]\n");
@@ -1141,6 +1141,20 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
 				addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
 			}
 			table_ok = 1;
+		} else if (matches(*argv, "vrf") == 0) {
+			__u32 tid;
+
+			NEXT_ARG();
+			tid = ipvrf_get_table(*argv);
+			if (tid == 0)
+				invarg("Invalid VRF\n", *argv);
+			if (tid < 256)
+				req.r.rtm_table = tid;
+			else {
+				req.r.rtm_table = RT_TABLE_UNSPEC;
+				addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+			}
+			table_ok = 1;
 		} else if (strcmp(*argv, "dev") == 0 ||
 			   strcmp(*argv, "oif") == 0) {
 			NEXT_ARG();
@@ -1395,6 +1409,15 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
 				}
 			} else
 				filter.tb = tid;
+		} else if (matches(*argv, "vrf") == 0) {
+			__u32 tid;
+
+			NEXT_ARG();
+			tid = ipvrf_get_table(*argv);
+			if (tid == 0)
+				invarg("Invalid VRF\n", *argv);
+			filter.tb = tid;
+			filter.typemask = ~(1 << RTN_LOCAL | 1<<RTN_BROADCAST);
 		} else if (matches(*argv, "cached") == 0 ||
 			   matches(*argv, "cloned") == 0) {
 			filter.cloned = 1;
@@ -1681,6 +1704,11 @@ static int iproute_get(int argc, char **argv)
 			req.r.rtm_flags |= RTM_F_NOTIFY;
 		} else if (matches(*argv, "connected") == 0) {
 			connected = 1;
+		} else if (matches(*argv, "vrf") == 0) {
+			NEXT_ARG();
+			if (!name_is_vrf(*argv))
+				invarg("Invalid VRF\n", *argv);
+			odev = *argv;
 		} else {
 			inet_prefix addr;
 
-- 
2.1.4

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

* Re: [PATCH iproute2 0/6] Add support for vrf keyword
  2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
                   ` (5 preceding siblings ...)
  2016-06-14 20:59 ` [PATCH iproute2 6/6] ip route: Add support for vrf keyword David Ahern
@ 2016-06-24  1:46 ` David Ahern
  6 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-24  1:46 UTC (permalink / raw)
  To: netdev, Stephen Hemminger

On 6/14/16 2:59 PM, David Ahern wrote:
> Currently the syntax for VRF related commands is rather kludgy and
> inconsistent from one subcommand to another. This set adds support
> for the VRF keyword to the link, address, neigh, and route commands
> to improve the user experience listing data associated with vrfs,
> modifying routes or doing a route lookup.
>
> David Ahern (6):
>   ip vrf: Add name_is_vrf
>   ip link/addr: Add support for vrf keyword
>   ip neigh: Add support for keyword
>   ip route: Change type mask to bitmask
>   ip vrf: Add ipvrf_get_table
>   ip route: Add support for vrf keyword
>
>  ip/ip_common.h  |   3 ++
>  ip/ipaddress.c  |  11 ++++++
>  ip/iplink.c     |  15 ++++++-
>  ip/iplink_vrf.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  ip/ipneigh.c    |  14 ++++++-
>  ip/iproute.c    |  43 ++++++++++++++++----
>  6 files changed, 195 insertions(+), 10 deletions(-)
>

Stephen: This patchset is marked 'Changes Requested' in patchworks, yet 
I have not seen any responses to them. What change was requested?

David

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

* [PATCH iproute2 1/6] ip vrf: Add name_is_vrf
  2016-06-27 18:50 [PATCH v2 " David Ahern
@ 2016-06-27 18:50 ` David Ahern
  2016-06-29 15:06   ` Stephen Hemminger
  0 siblings, 1 reply; 11+ messages in thread
From: David Ahern @ 2016-06-27 18:50 UTC (permalink / raw)
  To: netdev; +Cc: stephen, David Ahern

Add name_is_vrf function to determine if given name corresponds to a
VRF device.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 ip/ip_common.h  |  2 ++
 ip/iplink_vrf.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index e8da9e034b15..410eb135774a 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -90,6 +90,8 @@ struct link_util *get_link_slave_kind(const char *slave_kind);
 
 void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
 
+bool name_is_vrf(char *name);
+
 #ifndef	INFINITY_LIFE_TIME
 #define     INFINITY_LIFE_TIME      0xFFFFFFFFU
 #endif
diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c
index e3c7b4652da5..abd43c08423e 100644
--- a/ip/iplink_vrf.c
+++ b/ip/iplink_vrf.c
@@ -96,3 +96,56 @@ struct link_util vrf_slave_link_util = {
 	.print_opt	= vrf_slave_print_opt,
 	.slave          = true,
 };
+
+bool name_is_vrf(char *name)
+{
+	struct {
+		struct nlmsghdr		n;
+		struct ifinfomsg	i;
+		char			buf[1024];
+	} req = {
+		.n = {
+			.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+			.nlmsg_flags = NLM_F_REQUEST,
+			.nlmsg_type  = RTM_GETLINK,
+		},
+		.i = {
+			.ifi_family  = preferred_family,
+		},
+	};
+	struct {
+		struct nlmsghdr n;
+		char buf[8192];
+	} answer;
+	struct rtattr *tb[IFLA_MAX+1];
+	struct rtattr *li[IFLA_INFO_MAX+1];
+	struct ifinfomsg *ifi;
+	int len;
+
+	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
+
+	if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
+		goto err;
+
+	ifi = NLMSG_DATA(&answer.n);
+	len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
+	if (len < 0) {
+		fprintf(stderr, "BUG: Invalid response to link query.\n");
+		goto err;
+	}
+
+	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+	if (!tb[IFLA_LINKINFO])
+		goto err;
+
+	parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+
+	if (!li[IFLA_INFO_KIND])
+		goto err;
+
+	return strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf") == 0;
+
+err:
+	return false;
+}
-- 
2.1.4

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

* Re: [PATCH iproute2 1/6] ip vrf: Add name_is_vrf
  2016-06-27 18:50 ` [PATCH iproute2 1/6] ip vrf: Add name_is_vrf David Ahern
@ 2016-06-29 15:06   ` Stephen Hemminger
  2016-06-29 16:57     ` David Ahern
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Hemminger @ 2016-06-29 15:06 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev

On Mon, 27 Jun 2016 11:50:56 -0700
David Ahern <dsa@cumulusnetworks.com> wrote:

> diff --git a/ip/ip_common.h b/ip/ip_common.h
> index e8da9e034b15..410eb135774a 100644
> --- a/ip/ip_common.h
> +++ b/ip/ip_common.h
> @@ -90,6 +90,8 @@ struct link_util *get_link_slave_kind(const char *slave_kind);
>  
>  void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
>  
> +bool name_is_vrf(char *name);
> +
>  #ifndef	INFINITY_LIFE_TIME
>  #define     INFINITY_LIFE_TIME      0xFFFFFFFFU
>  #endif
> diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c
> index e3c7b4652da5..abd43c08423e 100644
> --- a/ip/iplink_vrf.c
> +++ b/ip/iplink_vrf.c
> @@ -96,3 +96,56 @@ struct link_util vrf_slave_link_util = {
>  	.print_opt	= vrf_slave_print_opt,
>  	.slave          = true,
>  };
> +
> +bool name_is_vrf(char *name)

Why not?
bool name_is_vrf(const char *name)

> +{
> +	struct {
> +		struct nlmsghdr		n;
> +		struct ifinfomsg	i;
> +		char			buf[1024];
> +	} req = {
> +		.n = {
> +			.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
> +			.nlmsg_flags = NLM_F_REQUEST,
> +			.nlmsg_type  = RTM_GETLINK,
> +		},
> +		.i = {
> +			.ifi_family  = preferred_family,
> +		},
> +	};
> +	struct {
> +		struct nlmsghdr n;
> +		char buf[8192];
> +	} answer;
> +	struct rtattr *tb[IFLA_MAX+1];
> +	struct rtattr *li[IFLA_INFO_MAX+1];
> +	struct ifinfomsg *ifi;
> +	int len;
> +
> +	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
> +
> +	if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
> +		goto err;
Just return false instead of all these goto's?
Also you might want to give some indication of error.

> +
> +	ifi = NLMSG_DATA(&answer.n);
> +	len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
> +	if (len < 0) {
> +		fprintf(stderr, "BUG: Invalid response to link query.\n");
> +		goto err;
> +	}
> +
> +	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
> +
> +	if (!tb[IFLA_LINKINFO])
> +		goto err;
> +
> +	parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
> +
> +	if (!li[IFLA_INFO_KIND])
> +		goto err;
> +
> +	return strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf") == 0;
> +
> +err:
> +	return false;
> +}

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

* Re: [PATCH iproute2 1/6] ip vrf: Add name_is_vrf
  2016-06-29 15:06   ` Stephen Hemminger
@ 2016-06-29 16:57     ` David Ahern
  0 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2016-06-29 16:57 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On 6/29/16 9:06 AM, Stephen Hemminger wrote:
> On Mon, 27 Jun 2016 11:50:56 -0700
> David Ahern <dsa@cumulusnetworks.com> wrote:
>
>> diff --git a/ip/ip_common.h b/ip/ip_common.h
>> index e8da9e034b15..410eb135774a 100644
>> --- a/ip/ip_common.h
>> +++ b/ip/ip_common.h
>> @@ -90,6 +90,8 @@ struct link_util *get_link_slave_kind(const char *slave_kind);
>>
>>  void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
>>
>> +bool name_is_vrf(char *name);
>> +
>>  #ifndef	INFINITY_LIFE_TIME
>>  #define     INFINITY_LIFE_TIME      0xFFFFFFFFU
>>  #endif
>> diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c
>> index e3c7b4652da5..abd43c08423e 100644
>> --- a/ip/iplink_vrf.c
>> +++ b/ip/iplink_vrf.c
>> @@ -96,3 +96,56 @@ struct link_util vrf_slave_link_util = {
>>  	.print_opt	= vrf_slave_print_opt,
>>  	.slave          = true,
>>  };
>> +
>> +bool name_is_vrf(char *name)
>
> Why not?
> bool name_is_vrf(const char *name)

sure.

>
>> +{
>> +	struct {
>> +		struct nlmsghdr		n;
>> +		struct ifinfomsg	i;
>> +		char			buf[1024];
>> +	} req = {
>> +		.n = {
>> +			.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
>> +			.nlmsg_flags = NLM_F_REQUEST,
>> +			.nlmsg_type  = RTM_GETLINK,
>> +		},
>> +		.i = {
>> +			.ifi_family  = preferred_family,
>> +		},
>> +	};
>> +	struct {
>> +		struct nlmsghdr n;
>> +		char buf[8192];
>> +	} answer;
>> +	struct rtattr *tb[IFLA_MAX+1];
>> +	struct rtattr *li[IFLA_INFO_MAX+1];
>> +	struct ifinfomsg *ifi;
>> +	int len;
>> +
>> +	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
>> +
>> +	if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
>> +		goto err;
> Just return false instead of all these goto's?
> Also you might want to give some indication of error.

Any failure and the user gets the message "not a VRF". The reason can be 
the device is not a VRF or the device does not exist but that's the same 
thing in this case:

$ ./ip link show vrf foo
Error: argument "foo" is wrong: Not a valid VRF name

$ ./ip link show vrf eth1
Error: argument "eth1" is wrong: Not a valid VRF name

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

end of thread, other threads:[~2016-06-29 16:57 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-14 20:59 [PATCH iproute2 0/6] Add support for vrf keyword David Ahern
2016-06-14 20:59 ` [PATCH iproute2 1/6] ip vrf: Add name_is_vrf David Ahern
2016-06-14 20:59 ` [PATCH iproute2 2/6] ip link/addr: Add support for vrf keyword David Ahern
2016-06-14 20:59 ` [PATCH iproute2 3/6] ip neigh: Add support for keyword David Ahern
2016-06-14 20:59 ` [PATCH iproute2 4/6] ip route: Change type mask to bitmask David Ahern
2016-06-14 20:59 ` [PATCH iproute2 5/6] ip vrf: Add ipvrf_get_table David Ahern
2016-06-14 20:59 ` [PATCH iproute2 6/6] ip route: Add support for vrf keyword David Ahern
2016-06-24  1:46 ` [PATCH iproute2 0/6] " David Ahern
  -- strict thread matches above, loose matches on Subject: below --
2016-06-27 18:50 [PATCH v2 " David Ahern
2016-06-27 18:50 ` [PATCH iproute2 1/6] ip vrf: Add name_is_vrf David Ahern
2016-06-29 15:06   ` Stephen Hemminger
2016-06-29 16:57     ` David Ahern

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).