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
