diff mbox series

iplink: add an option to set IFLA_EXT_MASK attribute

Message ID 20240403032021.29899-1-renmingshuai@huawei.com (mailing list archive)
State Changes Requested
Delegated to: Stephen Hemminger
Headers show
Series iplink: add an option to set IFLA_EXT_MASK attribute | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

renmingshuai April 3, 2024, 3:20 a.m. UTC
Kernel has add IFLA_EXT_MASK attribute for indicating that certain
extended ifinfo values are requested by the user application. The ip
link show cmd always request VFs extended ifinfo.

RTM_GETLINK for greater than about 220 VFs truncates IFLA_VFINFO_LIST
due to the maximum reach of nlattr's nla_len being exceeded.
As a result, ip link show command only show the truncated VFs info sucn as:

    #ip link show dev eth0
    1: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...
        link/ether ...
        vf 0     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff ...
    Truncated VF list: eth0

Add an option to set IFLA_EXT_MASK attribute and users can choose to
show the extended ifinfo or not.

Signed-off-by: Mingshuai Ren <renmingshuai@huawei.com>
---
 ip/ip_common.h        |  1 +
 ip/ipaddress.c        | 23 +++++++++++++++++------
 ip/iplink.c           |  5 +++--
 man/man8/ip-link.8.in |  7 +++++++
 4 files changed, 28 insertions(+), 8 deletions(-)

Comments

Stephen Hemminger April 4, 2024, 12:35 a.m. UTC | #1
On Wed, 3 Apr 2024 11:20:21 +0800
renmingshuai <renmingshuai@huawei.com> wrote:

> Kernel has add IFLA_EXT_MASK attribute for indicating that certain
> extended ifinfo values are requested by the user application. The ip
> link show cmd always request VFs extended ifinfo.
> 
> RTM_GETLINK for greater than about 220 VFs truncates IFLA_VFINFO_LIST
> due to the maximum reach of nlattr's nla_len being exceeded.
> As a result, ip link show command only show the truncated VFs info sucn as:
> 
>     #ip link show dev eth0
>     1: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...
>         link/ether ...
>         vf 0     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff ...
>     Truncated VF list: eth0
> 
> Add an option to set IFLA_EXT_MASK attribute and users can choose to
> show the extended ifinfo or not.
> 
> Signed-off-by: Mingshuai Ren <renmingshuai@huawei.com>

Adding a new option with on/off seems like more than is necessary.
If we need an option it should just be one word. Any new filter should
have same conventions as existing filters.  Maybe 'novf'

And it looks like not sending IFLA_EXT_MASK will break the changes
made for the link filter already done for VF's.
renmingshuai April 8, 2024, 12:34 p.m. UTC | #2
>> Kernel has add IFLA_EXT_MASK attribute for indicating that certain
>> extended ifinfo values are requested by the user application. The ip
>> link show cmd always request VFs extended ifinfo.
>> 
>> RTM_GETLINK for greater than about 220 VFs truncates IFLA_VFINFO_LIST
>> due to the maximum reach of nlattr's nla_len being exceeded.
>> As a result, ip link show command only show the truncated VFs info
>> sucn as:
>> 
>>     #ip link show dev eth0
>>     1: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...
>>         link/ether ...
>>         vf 0     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
>>         ...
>>     Truncated VF list: eth0
>> 
>> Add an option to set IFLA_EXT_MASK attribute and users can choose to
>> show the extended ifinfo or not.
>> 
>> Signed-off-by: Mingshuai Ren <renmingshuai@huawei.com>
>
> Adding a new option with on/off seems like more than is necessary.
> If we need an option it should just be one word. Any new filter should
> have same conventions as existing filters.  Maybe 'novf'
> 
> And it looks like not sending IFLA_EXT_MASK will break the changes
> made for the link filter already done for VF's.

Thanks for your reply. As you suggested, I've added an option
named noVF, which has same conventions as existing filter.
Also, this new patch does not send RTEXT_FILTER_VF instead of
IFLA_EXT_MASK, and it does not break the changes made for the link
filter already done for VF's.
Please review it again.

---
 ip/ip_common.h        |  1 +
 ip/ipaddress.c        | 15 ++++++++++-----
 ip/iplink.c           |  2 +-
 man/man8/ip-link.8.in |  7 ++++++-
 4 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index b65c2b41..d3645a2c 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -30,6 +30,7 @@ struct link_filter {
 	int target_nsid;
 	bool have_proto;
 	int proto;
+	int vfinfo;
 };
 
 const char *get_ip_lib_dir(void);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e536912f..a8899dc4 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -2029,10 +2029,11 @@ static int ipaddr_flush(void)
 
 static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
 {
-	__u32 filt_mask;
+	__u32 filt_mask = 0;
 	int err;
 
-	filt_mask = RTEXT_FILTER_VF;
+	if (!filter.vfinfo)
+		filt_mask |= RTEXT_FILTER_VF;
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
 	err = addattr32(nlh, reqlen, IFLA_EXT_MASK, filt_mask);
@@ -2070,12 +2071,13 @@ static int ipaddr_link_get(int index, struct nlmsg_chain *linfo)
 		.i.ifi_family = filter.family,
 		.i.ifi_index = index,
 	};
-	__u32 filt_mask = RTEXT_FILTER_VF;
+	__u32 filt_mask = 0;
 	struct nlmsghdr *answer;
 
+	if (!filter.vfinfo)
+		filt_mask |= RTEXT_FILTER_VF;
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
-
 	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
 
 	if (rtnl_talk(&rth, &req.n, &answer) < 0) {
@@ -2139,6 +2141,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 	ipaddr_reset_filter(oneline, 0);
 	filter.showqueue = 1;
 	filter.family = preferred_family;
+	filter.vfinfo = 0;
 
 	if (action == IPADD_FLUSH) {
 		if (argc <= 0) {
@@ -2221,6 +2224,8 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 				invarg("\"proto\" value is invalid\n", *argv);
 			filter.have_proto = true;
 			filter.proto = proto;
+		} else if (strcmp(*argv, "noVF") == 0) {
+			filter.vfinfo = -1;
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
@@ -2274,7 +2279,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.vfinfo < 0 ? 0 : RTEXT_FILTER_VF) < 0) {
 			perror("Cannot send link get request");
 			delete_json_obj();
 			exit(1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 95314af5..ad4b068b 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -111,7 +111,7 @@ void iplink_usage(void)
 		"		[ gro_max_size BYTES ] [ gro_ipv4_max_size BYTES ]\n"
 		"\n"
 		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
-		"		[nomaster]\n"
+		"		[nomaster] [ noVF ]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 31e2d7f0..dd497d5f 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -202,7 +202,8 @@ ip-link \- network device configuration
 .IR ETYPE " ] ["
 .B vrf
 .IR NAME " ] ["
-.BR nomaster " ]"
+.BR nomaster " ] ["
+.BR noVF " ]"
 
 .ti -8
 .B ip link xstats
@@ -2898,6 +2899,10 @@ output.
 .B nomaster
 only show devices with no master
 
+.TP
+.B noVF
+only show devices with no VF info
+
 .SS  ip link xstats - display extended statistics
 
 .TP
Stephen Hemminger April 9, 2024, 12:29 a.m. UTC | #3
On Mon, 8 Apr 2024 20:34:58 +0800
renmingshuai <renmingshuai@huawei.com> wrote:

> >> Kernel has add IFLA_EXT_MASK attribute for indicating that certain
> >> extended ifinfo values are requested by the user application. The ip
> >> link show cmd always request VFs extended ifinfo.
> >> 
> >> RTM_GETLINK for greater than about 220 VFs truncates IFLA_VFINFO_LIST
> >> due to the maximum reach of nlattr's nla_len being exceeded.
> >> As a result, ip link show command only show the truncated VFs info
> >> sucn as:
> >> 
> >>     #ip link show dev eth0
> >>     1: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...
> >>         link/ether ...
> >>         vf 0     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
> >>         ...
> >>     Truncated VF list: eth0
> >> 
> >> Add an option to set IFLA_EXT_MASK attribute and users can choose to
> >> show the extended ifinfo or not.
> >> 
> >> Signed-off-by: Mingshuai Ren <renmingshuai@huawei.com>  
> >
> > Adding a new option with on/off seems like more than is necessary.
> > If we need an option it should just be one word. Any new filter should
> > have same conventions as existing filters.  Maybe 'novf'
> > 
> > And it looks like not sending IFLA_EXT_MASK will break the changes
> > made for the link filter already done for VF's.  
> 
> Thanks for your reply. As you suggested, I've added an option
> named noVF, which has same conventions as existing filter.
> Also, this new patch does not send RTEXT_FILTER_VF instead of
> IFLA_EXT_MASK, and it does not break the changes made for the link
> filter already done for VF's.
> Please review it again.

Did you read my comment. Any new option should look the same as all
the other options in the command.  Is there any option to ip commands
that uses mixed case? No. Please stick to lower case.
renmingshuai April 9, 2024, 1:53 a.m. UTC | #4
> > >> Kernel has add IFLA_EXT_MASK attribute for indicating that certain
> > >> extended ifinfo values are requested by the user application. The ip
> > >> link show cmd always request VFs extended ifinfo.
> > >> 
> > >> RTM_GETLINK for greater than about 220 VFs truncates IFLA_VFINFO_LIST
> > >> due to the maximum reach of nlattr's nla_len being exceeded.
> > >> As a result, ip link show command only show the truncated VFs info
> > >> sucn as:
> > >> 
> > >>     #ip link show dev eth0
> > >>     1: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...
> > >>         link/ether ...
> > >>         vf 0     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
> > >>         ...
> > >>     Truncated VF list: eth0
> > >> 
> > >> Add an option to set IFLA_EXT_MASK attribute and users can choose to
> > >> show the extended ifinfo or not.
> > >> 
> > >> Signed-off-by: Mingshuai Ren <renmingshuai@huawei.com>  
> > >
> > > Adding a new option with on/off seems like more than is necessary.
> > > If we need an option it should just be one word. Any new filter should
> > > have same conventions as existing filters.  Maybe 'novf'
> > > 
> > > And it looks like not sending IFLA_EXT_MASK will break the changes
> > > made for the link filter already done for VF's.  
> > 
> > Thanks for your reply. As you suggested, I've added an option
> > named noVF, which has same conventions as existing filter.
> > Also, this new patch does not send RTEXT_FILTER_VF instead of
> > IFLA_EXT_MASK, and it does not break the changes made for the link
> > filter already done for VF's.
> > Please review it again.
> 
> Did you read my comment. Any new option should look the same as all
> the other options in the command.  Is there any option to ip commands
> that uses mixed case? No. Please stick to lower case.

Apologies for not considering the use of lower case. I have replaced noVF with novf.
Please review it again. Thanks a lot.
By the way, do I need to submit a new patch?

---
 ip/ip_common.h        |  1 +
 ip/ipaddress.c        | 15 ++++++++++-----
 ip/iplink.c           |  2 +-
 man/man8/ip-link.8.in |  7 ++++++-
 4 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index b65c2b41..d3645a2c 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -30,6 +30,7 @@ struct link_filter {
 	int target_nsid;
 	bool have_proto;
 	int proto;
+	int vfinfo;
 };
 
 const char *get_ip_lib_dir(void);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e536912f..e7e5ce76 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -2029,10 +2029,11 @@ static int ipaddr_flush(void)
 
 static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
 {
-	__u32 filt_mask;
+	__u32 filt_mask = 0;
 	int err;
 
-	filt_mask = RTEXT_FILTER_VF;
+	if (!filter.vfinfo)
+		filt_mask |= RTEXT_FILTER_VF;
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
 	err = addattr32(nlh, reqlen, IFLA_EXT_MASK, filt_mask);
@@ -2070,12 +2071,13 @@ static int ipaddr_link_get(int index, struct nlmsg_chain *linfo)
 		.i.ifi_family = filter.family,
 		.i.ifi_index = index,
 	};
-	__u32 filt_mask = RTEXT_FILTER_VF;
+	__u32 filt_mask = 0;
 	struct nlmsghdr *answer;
 
+	if (!filter.vfinfo)
+		filt_mask |= RTEXT_FILTER_VF;
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
-
 	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
 
 	if (rtnl_talk(&rth, &req.n, &answer) < 0) {
@@ -2139,6 +2141,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 	ipaddr_reset_filter(oneline, 0);
 	filter.showqueue = 1;
 	filter.family = preferred_family;
+	filter.vfinfo = 0;
 
 	if (action == IPADD_FLUSH) {
 		if (argc <= 0) {
@@ -2221,6 +2224,8 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 				invarg("\"proto\" value is invalid\n", *argv);
 			filter.have_proto = true;
 			filter.proto = proto;
+		} else if (strcmp(*argv, "novf") == 0) {
+			filter.vfinfo = -1;
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
@@ -2274,7 +2279,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.vfinfo < 0 ? 0 : RTEXT_FILTER_VF) < 0) {
 			perror("Cannot send link get request");
 			delete_json_obj();
 			exit(1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 95314af5..1bb4a998 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -111,7 +111,7 @@ void iplink_usage(void)
 		"		[ gro_max_size BYTES ] [ gro_ipv4_max_size BYTES ]\n"
 		"\n"
 		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
-		"		[nomaster]\n"
+		"		[nomaster] [ novf ]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 31e2d7f0..066ad874 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -202,7 +202,8 @@ ip-link \- network device configuration
 .IR ETYPE " ] ["
 .B vrf
 .IR NAME " ] ["
-.BR nomaster " ]"
+.BR nomaster " ] ["
+.BR novf " ]"
 
 .ti -8
 .B ip link xstats
@@ -2898,6 +2899,10 @@ output.
 .B nomaster
 only show devices with no master
 
+.TP
+.B novf
+only show devices with no VF info
+
 .SS  ip link xstats - display extended statistics
 
 .TP
David Ahern April 9, 2024, 2:47 p.m. UTC | #5
On 4/8/24 7:53 PM, renmingshuai wrote:
> By the way, do I need to submit a new patch?

yes, please send a formal patch.
diff mbox series

Patch

diff --git a/ip/ip_common.h b/ip/ip_common.h
index b65c2b41..d6a36845 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -30,6 +30,7 @@  struct link_filter {
 	int target_nsid;
 	bool have_proto;
 	int proto;
+	bool ext_info;
 };
 
 const char *get_ip_lib_dir(void);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e536912f..b533c0fc 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -2035,9 +2035,11 @@  static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
 	filt_mask = RTEXT_FILTER_VF;
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
-	err = addattr32(nlh, reqlen, IFLA_EXT_MASK, filt_mask);
-	if (err)
-		return err;
+	if (filter.ext_info) {
+		err = addattr32(nlh, reqlen, IFLA_EXT_MASK, filt_mask);
+		if (err)
+			return err;
+	}
 
 	if (filter.master) {
 		err = addattr32(nlh, reqlen, IFLA_MASTER, filter.master);
@@ -2075,8 +2077,8 @@  static int ipaddr_link_get(int index, struct nlmsg_chain *linfo)
 
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
-
-	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
+	if (filter.ext_info)
+		addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
 
 	if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 		perror("Cannot send link request");
@@ -2139,6 +2141,7 @@  static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 	ipaddr_reset_filter(oneline, 0);
 	filter.showqueue = 1;
 	filter.family = preferred_family;
+	filter.ext_info = true;
 
 	if (action == IPADD_FLUSH) {
 		if (argc <= 0) {
@@ -2221,6 +2224,14 @@  static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 				invarg("\"proto\" value is invalid\n", *argv);
 			filter.have_proto = true;
 			filter.proto = proto;
+		} else if (strcmp(*argv, "extinfo") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "on") == 0)
+				filter.ext_info = true;
+			else if (strcmp(*argv, "off") == 0)
+				filter.ext_info = false;
+			else
+				invarg("must be \"on\" or \"off\"", "extinfo");
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
@@ -2274,7 +2285,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.ext_info ? RTEXT_FILTER_VF : 0) < 0) {
 			perror("Cannot send link get request");
 			delete_json_obj();
 			exit(1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 95314af5..97f26e5d 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -111,7 +111,7 @@  void iplink_usage(void)
 		"		[ gro_max_size BYTES ] [ gro_ipv4_max_size BYTES ]\n"
 		"\n"
 		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
-		"		[nomaster]\n"
+		"		[nomaster] [ extinfo { on | off } ]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
@@ -1115,7 +1115,8 @@  int iplink_get(char *name, __u32 filt_mask)
 
 	if (!show_stats)
 		filt_mask |= RTEXT_FILTER_SKIP_STATS;
-	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
+	if (filt_mask)
+		addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
 
 	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 31e2d7f0..c2a59ff7 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -203,6 +203,7 @@  ip-link \- network device configuration
 .B vrf
 .IR NAME " ] ["
 .BR nomaster " ]"
+.RB "[ " extinfo " { " on " | " off " } ]"
 
 .ti -8
 .B ip link xstats
@@ -2898,6 +2899,10 @@  output.
 .B nomaster
 only show devices with no master
 
+.TP
+.BR "extinfo on" or "extinfo off"
+specifies whether to show the extended ifinfo.
+
 .SS  ip link xstats - display extended statistics
 
 .TP