diff mbox series

[1/3] ip: Allow query link with extended vf properties

Message ID 1572463033-26368-2-git-send-email-lariel@mellanox.com
State Superseded
Delegated to: David Ahern
Headers show
Series VGT+ support | expand

Commit Message

Ariel Levkovich Oct. 30, 2019, 7:17 p.m. UTC
Adding vf num filter to ip link show command for querying
extended information of a specific vf.

When specifying a vf num, the kernel may return additional
vf information that takes up large amount of memory and
can't be included when querying the entire list of vfs
due to attribute size limitation.

The usage is:
ip link show dev <ifname> vf <vf_num>

Only the specified VF's information will be returned
and presented in this case.

Signed-off-by: Ariel Levkovich <lariel@mellanox.com>
---
 include/uapi/linux/if_link.h   |  1 +
 include/uapi/linux/rtnetlink.h |  1 +
 ip/ip_common.h                 |  2 +-
 ip/ipaddress.c                 | 16 +++++++++++++++-
 ip/iplink.c                    |  6 ++++--
 man/man8/ip-link.8.in          | 13 ++++++++++++-
 6 files changed, 34 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 1c49f43..d39017b 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -169,6 +169,7 @@  enum {
 	IFLA_MAX_MTU,
 	IFLA_PROP_LIST,
 	IFLA_ALT_IFNAME, /* Alternative ifname */
+	IFLA_VF_NUM,
 	__IFLA_MAX
 };
 
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 4b93791..8fc7f5d 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -758,6 +758,7 @@  enum {
 #define RTEXT_FILTER_BRVLAN	(1 << 1)
 #define RTEXT_FILTER_BRVLAN_COMPRESSED	(1 << 2)
 #define	RTEXT_FILTER_SKIP_STATS	(1 << 3)
+#define	RTEXT_FILTER_VF_EXT	(1 << 4)
 
 /* End of information exported to user level */
 
diff --git a/ip/ip_common.h b/ip/ip_common.h
index cd916ec..4151232 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -83,7 +83,7 @@  int netns_identify_pid(const char *pidstr, char *name, int len);
 int do_seg6(int argc, char **argv);
 int do_ipnh(int argc, char **argv);
 
-int iplink_get(char *name, __u32 filt_mask);
+int iplink_get(char *name, __u32 filt_mask, int vf);
 int iplink_ifla_xstats(int argc, char **argv);
 
 int ip_link_list(req_filter_fn_t filter_fn, struct nlmsg_chain *linfo);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index bc8f5ba..0521fdc 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1874,9 +1874,11 @@  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}, *ainfo = &_ainfo;
+	int filter_mask = RTEXT_FILTER_VF;
 	struct nlmsg_list *l;
 	char *filter_dev = NULL;
 	int no_link = 0;
+	int vf = -1;
 
 	ipaddr_reset_filter(oneline, 0);
 	filter.showqueue = 1;
@@ -1953,6 +1955,18 @@  static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			} else {
 				filter.kind = *argv;
 			}
+		} else if (strcmp(*argv, "vf") == 0) {
+			if (vf >= 0)
+				duparg2("vf", *argv);
+
+			if (!filter_dev)
+				missarg("dev");
+
+			NEXT_ARG();
+			if (get_integer(&vf,  *argv, 0))
+				invarg("Invalid \"vf\" value\n", *argv);
+			else
+				filter_mask = RTEXT_FILTER_VF_EXT;
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
@@ -2006,7 +2020,7 @@  static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 	 * the link device
 	 */
 	if (filter_dev && filter.group == -1 && do_link == 1) {
-		if (iplink_get(filter_dev, RTEXT_FILTER_VF) < 0) {
+		if (iplink_get(filter_dev, filter_mask, vf) < 0) {
 			perror("Cannot send link get request");
 			delete_json_obj();
 			exit(1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 212a088..ef33232 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -107,7 +107,7 @@  void iplink_usage(void)
 		"			[ protodown { on | off } ]\n"
 		"			[ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n"
 		"\n"
-		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
+		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE] [vf VF_NUM]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
@@ -1092,7 +1092,7 @@  static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 	return 0;
 }
 
-int iplink_get(char *name, __u32 filt_mask)
+int iplink_get(char *name, __u32 filt_mask, int vf)
 {
 	struct iplink_req req = {
 		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -1107,6 +1107,8 @@  int iplink_get(char *name, __u32 filt_mask)
 			  IFLA_IFNAME, name, strlen(name) + 1);
 	}
 	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
+	if (filt_mask & RTEXT_FILTER_VF_EXT)
+		addattr32(&req.n, sizeof(req), IFLA_VF_NUM, vf);
 
 	if (rtnl_talk(&rth, &req.n, &answer) < 0)
 		return -2;
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index a8ae72d..29744d4 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -176,7 +176,9 @@  ip-link \- network device configuration
 .B type
 .IR ETYPE " ] ["
 .B vrf
-.IR NAME " ]"
+.IR NAME " ] ["
+.B vf
+.IR NUM " ]"
 
 .ti -8
 .B ip link xstats
@@ -2396,6 +2398,15 @@  interface list by comparing it with the relevant attribute in case the kernel
 didn't filter already. Therefore any string is accepted, but may lead to empty
 output.
 
+.TP
+.BI vf " NUM "
+.I NUM
+specifies a Virtual Function device to be configured.
+
+The associated PF device must be specified using the
+.B dev
+parameter.
+
 .SS  ip link xstats - display extended statistics
 
 .TP