All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2 v2] ip: Extend filter links/addresses
@ 2022-01-08 19:58 Anton Danilov
  2022-01-11 16:35 ` David Ahern
  0 siblings, 1 reply; 5+ messages in thread
From: Anton Danilov @ 2022-01-08 19:58 UTC (permalink / raw)
  To: littlesmilingcloud, Stephen Hemminger; +Cc: netdev

This patch improves the filtering of links/addresses with the next
features:
1. Additional types: ether, loopback, ppp
2. Exclude of specific interface type with 'exclude_type' option

Examples:
ip link show type ether
ip address show exclude_type ppp

Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
---
 ip/ip_common.h           |  1 +
 ip/ipaddress.c           | 52 ++++++++++++++++++++++++++++++++++++----
 ip/iplink.c              |  2 +-
 man/man8/ip-address.8.in | 16 ++++++++++++-
 man/man8/ip-link.8.in    | 13 +++++++---
 5 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index ea04c8ff..38377be4 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -26,6 +26,7 @@ struct link_filter {
 	int master;
 	char *kind;
 	char *slave_kind;
+	char *exclude_kind;
 	int target_nsid;
 };
 
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 4109d8bd..c1f0ccde 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -60,7 +60,7 @@ static void usage(void)
 		"       ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n"
 		"                            [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n"
 		"       ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"
-		"                         [ nomaster ]\n"
+		"                         [ nomaster ] [ exclude_type TYPE ]\n"
 		"                         [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"
 		"                         [ label LABEL ] [up] [ vrf NAME ] ]\n"
 		"       ip address {showdump|restore}\n"
@@ -227,6 +227,28 @@ static int match_link_kind(struct rtattr **tb, const char *kind, bool slave)
 	return strcmp(parse_link_kind(tb[IFLA_LINKINFO], slave), kind);
 }
 
+static int match_if_type_name(unsigned short if_type, const char *type_name)
+{
+
+	char *expected_type_name;
+
+	switch (if_type) {
+	case ARPHRD_ETHER:
+		expected_type_name = "ether";
+		break;
+	case ARPHRD_LOOPBACK:
+		expected_type_name = "loopback";
+		break;
+	case ARPHRD_PPP:
+		expected_type_name = "ppp";
+		break;
+	default:
+		expected_type_name = "";
+	}
+
+	return !strcmp(type_name, expected_type_name);
+}
+
 static void print_linktype(FILE *fp, struct rtattr *tb)
 {
 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
@@ -1023,8 +1045,18 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
 	} else if (filter.master > 0)
 		return -1;
 
-	if (filter.kind && match_link_kind(tb, filter.kind, 0))
-		return -1;
+	if (filter.exclude_kind) {
+		if (match_link_kind(tb, filter.exclude_kind, 0) == 0 ||
+		    (!tb[IFLA_LINKINFO] && match_if_type_name(ifi->ifi_type, filter.exclude_kind)))
+			return -1;
+	}
+
+	if (filter.kind) {
+		if (!tb[IFLA_LINKINFO] && match_if_type_name(ifi->ifi_type, filter.kind))
+			;
+		else if (match_link_kind(tb, filter.kind, 0) != 0)
+			return -1;
+	}
 
 	if (filter.slave_kind && match_link_kind(tb, filter.slave_kind, 1))
 		return -1;
@@ -1971,7 +2003,9 @@ static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
 			return err;
 	}
 
-	if (filter.kind) {
+	if (filter.kind && !strcmp(filter.kind, "ether") &&
+	    !strcmp(filter.kind, "loopback") && !strcmp(filter.kind, "ppp")) {
+
 		struct rtattr *linkinfo;
 
 		linkinfo = addattr_nest(nlh, reqlen, IFLA_LINKINFO);
@@ -2137,6 +2171,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			} else {
 				filter.kind = *argv;
 			}
+		} else if (strcmp(*argv, "exclude_type") == 0) {
+			int soff;
+
+			NEXT_ARG();
+			soff = strlen(*argv) - strlen("_slave");
+			if (!strcmp(*argv + soff, "_slave")) {
+				invarg("Not a valid type for exclude\n", *argv);
+			} else {
+				filter.exclude_kind = *argv;
+			}
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
diff --git a/ip/iplink.c b/ip/iplink.c
index a3ea775d..e0d49cab 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -120,7 +120,7 @@ void iplink_usage(void)
 		"		[ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n"
 		"\n"
 		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
-		"		[nomaster]\n"
+		"		[exclude_type TYPE] [nomaster]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
diff --git a/man/man8/ip-address.8.in b/man/man8/ip-address.8.in
index 65f67e06..21de3d77 100644
--- a/man/man8/ip-address.8.in
+++ b/man/man8/ip-address.8.in
@@ -45,6 +45,8 @@ ip-address \- protocol address management
 .IR PATTERN " ] [ "
 .B  master
 .IR DEVICE " ] [ "
+.B  exclude_type
+.IR TYPE " ] [ "
 .B  type
 .IR TYPE " ] [ "
 .B vrf
@@ -138,7 +140,10 @@ ip-address \- protocol address management
 .BR ipvlan " |"
 .BR lowpan " |"
 .BR geneve " |"
-.BR macsec " ]"
+.BR macsec " |"
+.BR ether " |"
+.BR loopback " |"
+.BR ppp " ]"
 
 .SH "DESCRIPTION"
 The
@@ -337,6 +342,10 @@ 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 exclude_type " TYPE"
+don't list linterfaces of the given type.
+
 .TP
 .B up
 only list running interfaces.
@@ -441,6 +450,11 @@ Same as above except that only addresses assigned to active network interfaces
 are shown.
 .RE
 .PP
+ip address show type ether
+.RS 4
+Shows IPv4 and IPv6 addresses assigned to all physical ethernetl interfaces
+.RE
+.PP
 ip address show dev eth0
 .RS 4
 Shows IPv4 and IPv6 addresses assigned to network interface eth0.
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 19a0c9ca..60cbb5c7 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -176,10 +176,12 @@ ip-link \- network device configuration
 .BR up " ] ["
 .B master
 .IR DEVICE " ] ["
-.B type
-.IR ETYPE " ] ["
 .B vrf
 .IR NAME " ] ["
+.B type
+.IR ETYPE " ] ["
+.B exclude_type
+.IR ETYPE " ] ["
 .BR nomaster " ]"
 
 .ti -8
@@ -237,7 +239,7 @@ ip-link \- network device configuration
 
 .ti -8
 .IR ETYPE " := [ " TYPE " |"
-.BR bridge_slave " | " bond_slave " ]"
+.BR ether " | " loopback " | " ppp " | " bridge_slave " | " bond_slave " ]"
 
 .ti -8
 .IR VFVLAN-LIST " := [ "  VFVLAN-LIST " ] " VFVLAN
@@ -2630,6 +2632,11 @@ ip link show type vlan
 Shows the vlan devices.
 .RE
 .PP
+ip link show exclude_type ppp
+.RS 4
+List the network interfaces except PPP devices.
+.RE
+.PP
 ip link show master br0
 .RS 4
 Shows devices enslaved by br0
-- 
2.20.1


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

* Re: [PATCH iproute2 v2] ip: Extend filter links/addresses
  2022-01-08 19:58 [PATCH iproute2 v2] ip: Extend filter links/addresses Anton Danilov
@ 2022-01-11 16:35 ` David Ahern
  2022-01-11 19:09   ` Anton Danilov
  0 siblings, 1 reply; 5+ messages in thread
From: David Ahern @ 2022-01-11 16:35 UTC (permalink / raw)
  To: Anton Danilov, Stephen Hemminger; +Cc: netdev

On 1/8/22 12:58 PM, Anton Danilov wrote:
> @@ -227,6 +227,28 @@ static int match_link_kind(struct rtattr **tb, const char *kind, bool slave)
>  	return strcmp(parse_link_kind(tb[IFLA_LINKINFO], slave), kind);
>  }
>  
> +static int match_if_type_name(unsigned short if_type, const char *type_name)
> +{
> +
> +	char *expected_type_name;
> +
> +	switch (if_type) {
> +	case ARPHRD_ETHER:
> +		expected_type_name = "ether";
> +		break;
> +	case ARPHRD_LOOPBACK:
> +		expected_type_name = "loopback";
> +		break;
> +	case ARPHRD_PPP:
> +		expected_type_name = "ppp";
> +		break;
> +	default:
> +		expected_type_name = "";
> +	}
> +
> +	return !strcmp(type_name, expected_type_name);

current 'type' filtering is the 'kind' string in the rtnl_link_ops --
bridge, veth, vlan, vrf, etc. You are now wanting to add 'exclude_type'
and make it based on hardware type. That is a confusing user api.

What type of interface filtering is motivating this change? e.g., link /
address lists but ignoring say vlan or veth devices?

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

* Re: [PATCH iproute2 v2] ip: Extend filter links/addresses
  2022-01-11 16:35 ` David Ahern
@ 2022-01-11 19:09   ` Anton Danilov
  2022-01-12 17:57     ` David Ahern
  0 siblings, 1 reply; 5+ messages in thread
From: Anton Danilov @ 2022-01-11 19:09 UTC (permalink / raw)
  To: David Ahern; +Cc: Stephen Hemminger, Linux Kernel Network Developers

Hello, David.

> current 'type' filtering is the 'kind' string in the rtnl_link_ops --
> bridge, veth, vlan, vrf, etc. You are now wanting to add 'exclude_type'
> and make it based on hardware type. That is a confusing user api.

The 'exclude_type' options first checks the 'kind' in the
rtnl_link_ops, then the hardware type.

> What type of interface filtering is motivating this change? e.g., link /
> address lists but ignoring say vlan or veth devices?

Yep, sure. If you use the kvm hypervisors, you can see a lot of veth
devices. I think an ability to hide them is a good feature.

Filtering by 'kind' value has not been touched.


On Tue, 11 Jan 2022 at 19:35, David Ahern <dsahern@gmail.com> wrote:
>
> On 1/8/22 12:58 PM, Anton Danilov wrote:
> > @@ -227,6 +227,28 @@ static int match_link_kind(struct rtattr **tb, const char *kind, bool slave)
> >       return strcmp(parse_link_kind(tb[IFLA_LINKINFO], slave), kind);
> >  }
> >
> > +static int match_if_type_name(unsigned short if_type, const char *type_name)
> > +{
> > +
> > +     char *expected_type_name;
> > +
> > +     switch (if_type) {
> > +     case ARPHRD_ETHER:
> > +             expected_type_name = "ether";
> > +             break;
> > +     case ARPHRD_LOOPBACK:
> > +             expected_type_name = "loopback";
> > +             break;
> > +     case ARPHRD_PPP:
> > +             expected_type_name = "ppp";
> > +             break;
> > +     default:
> > +             expected_type_name = "";
> > +     }
> > +
> > +     return !strcmp(type_name, expected_type_name);
>
> current 'type' filtering is the 'kind' string in the rtnl_link_ops --
> bridge, veth, vlan, vrf, etc. You are now wanting to add 'exclude_type'
> and make it based on hardware type. That is a confusing user api.
>
> What type of interface filtering is motivating this change? e.g., link /
> address lists but ignoring say vlan or veth devices?



-- 
Anton Danilov.

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

* Re: [PATCH iproute2 v2] ip: Extend filter links/addresses
  2022-01-11 19:09   ` Anton Danilov
@ 2022-01-12 17:57     ` David Ahern
  0 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2022-01-12 17:57 UTC (permalink / raw)
  To: Anton Danilov; +Cc: Stephen Hemminger, Linux Kernel Network Developers

On 1/11/22 12:09 PM, Anton Danilov wrote:
> Hello, David.
> 
>> current 'type' filtering is the 'kind' string in the rtnl_link_ops --
>> bridge, veth, vlan, vrf, etc. You are now wanting to add 'exclude_type'
>> and make it based on hardware type. That is a confusing user api.
> 
> The 'exclude_type' options first checks the 'kind' in the
> rtnl_link_ops, then the hardware type.

ok; missed that on the first pass.

Update the commit message to say filtering by "hardware type"

>> On 1/8/22 12:58 PM, Anton Danilov wrote:
>>> @@ -227,6 +227,28 @@ static int match_link_kind(struct rtattr **tb, const char *kind, bool slave)
>>>       return strcmp(parse_link_kind(tb[IFLA_LINKINFO], slave), kind);
>>>  }
>>>
>>> +static int match_if_type_name(unsigned short if_type, const char *type_name)
>>> +{
>>> +
>>> +     char *expected_type_name;
>>> +
>>> +     switch (if_type) {
>>> +     case ARPHRD_ETHER:
>>> +             expected_type_name = "ether";
>>> +             break;
>>> +     case ARPHRD_LOOPBACK:
>>> +             expected_type_name = "loopback";
>>> +             break;
>>> +     case ARPHRD_PPP:
>>> +             expected_type_name = "ppp";

ppp devices have kind set, so ARPHRD_PPP should not be needed.


Also, you have supported hardware types in multiple places - this match
function and the filter.kind check. Make 1 table with supported types
and use that table with helpers or both paths.

Why not allow exclude by "_slave" type? e.g., should all devices but
bridge ports?


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

* [PATCH iproute2 v2] ip: Extend filter links/addresses
@ 2022-01-08 19:47 Антон Данилов
  0 siblings, 0 replies; 5+ messages in thread
From: Антон Данилов @ 2022-01-08 19:47 UTC (permalink / raw)
  To: Stephen Hamminger; +Cc: Anton Danilov, netdev

From: Anton Danilov <littlesmilingcloud@gmail.com>

This patch improves the filtering of links/addresses with the next
features:
1. Additional types: ether, loopback, ppp
2. Exclude of specific interface type with 'exclude_type' option

Examples:
ip link show type ether
ip address show exclude_type ppp

Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
---
 ip/ip_common.h           |  1 +
 ip/ipaddress.c           | 52 ++++++++++++++++++++++++++++++++++++----
 ip/iplink.c              |  2 +-
 man/man8/ip-address.8.in | 16 ++++++++++++-
 man/man8/ip-link.8.in    | 13 +++++++---
 5 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index ea04c8ff..38377be4 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -26,6 +26,7 @@ struct link_filter {
 	int master;
 	char *kind;
 	char *slave_kind;
+	char *exclude_kind;
 	int target_nsid;
 };
 
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 4109d8bd..c1f0ccde 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -60,7 +60,7 @@ static void usage(void)
 		"       ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n"
 		"                            [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n"
 		"       ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"
-		"                         [ nomaster ]\n"
+		"                         [ nomaster ] [ exclude_type TYPE ]\n"
 		"                         [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"
 		"                         [ label LABEL ] [up] [ vrf NAME ] ]\n"
 		"       ip address {showdump|restore}\n"
@@ -227,6 +227,28 @@ static int match_link_kind(struct rtattr **tb, const char *kind, bool slave)
 	return strcmp(parse_link_kind(tb[IFLA_LINKINFO], slave), kind);
 }
 
+static int match_if_type_name(unsigned short if_type, const char *type_name)
+{
+
+	char *expected_type_name;
+
+	switch (if_type) {
+	case ARPHRD_ETHER:
+		expected_type_name = "ether";
+		break;
+	case ARPHRD_LOOPBACK:
+		expected_type_name = "loopback";
+		break;
+	case ARPHRD_PPP:
+		expected_type_name = "ppp";
+		break;
+	default:
+		expected_type_name = "";
+	}
+
+	return !strcmp(type_name, expected_type_name);
+}
+
 static void print_linktype(FILE *fp, struct rtattr *tb)
 {
 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
@@ -1023,8 +1045,18 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
 	} else if (filter.master > 0)
 		return -1;
 
-	if (filter.kind && match_link_kind(tb, filter.kind, 0))
-		return -1;
+	if (filter.exclude_kind) {
+		if (match_link_kind(tb, filter.exclude_kind, 0) == 0 ||
+		    (!tb[IFLA_LINKINFO] && match_if_type_name(ifi->ifi_type, filter.exclude_kind)))
+			return -1;
+	}
+
+	if (filter.kind) {
+		if (!tb[IFLA_LINKINFO] && match_if_type_name(ifi->ifi_type, filter.kind))
+			;
+		else if (match_link_kind(tb, filter.kind, 0) != 0)
+			return -1;
+	}
 
 	if (filter.slave_kind && match_link_kind(tb, filter.slave_kind, 1))
 		return -1;
@@ -1971,7 +2003,9 @@ static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
 			return err;
 	}
 
-	if (filter.kind) {
+	if (filter.kind && !strcmp(filter.kind, "ether") &&
+	    !strcmp(filter.kind, "loopback") && !strcmp(filter.kind, "ppp")) {
+
 		struct rtattr *linkinfo;
 
 		linkinfo = addattr_nest(nlh, reqlen, IFLA_LINKINFO);
@@ -2137,6 +2171,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			} else {
 				filter.kind = *argv;
 			}
+		} else if (strcmp(*argv, "exclude_type") == 0) {
+			int soff;
+
+			NEXT_ARG();
+			soff = strlen(*argv) - strlen("_slave");
+			if (!strcmp(*argv + soff, "_slave")) {
+				invarg("Not a valid type for exclude\n", *argv);
+			} else {
+				filter.exclude_kind = *argv;
+			}
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
diff --git a/ip/iplink.c b/ip/iplink.c
index a3ea775d..e0d49cab 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -120,7 +120,7 @@ void iplink_usage(void)
 		"		[ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n"
 		"\n"
 		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
-		"		[nomaster]\n"
+		"		[exclude_type TYPE] [nomaster]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
diff --git a/man/man8/ip-address.8.in b/man/man8/ip-address.8.in
index 65f67e06..21de3d77 100644
--- a/man/man8/ip-address.8.in
+++ b/man/man8/ip-address.8.in
@@ -45,6 +45,8 @@ ip-address \- protocol address management
 .IR PATTERN " ] [ "
 .B  master
 .IR DEVICE " ] [ "
+.B  exclude_type
+.IR TYPE " ] [ "
 .B  type
 .IR TYPE " ] [ "
 .B vrf
@@ -138,7 +140,10 @@ ip-address \- protocol address management
 .BR ipvlan " |"
 .BR lowpan " |"
 .BR geneve " |"
-.BR macsec " ]"
+.BR macsec " |"
+.BR ether " |"
+.BR loopback " |"
+.BR ppp " ]"
 
 .SH "DESCRIPTION"
 The
@@ -337,6 +342,10 @@ 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 exclude_type " TYPE"
+don't list linterfaces of the given type.
+
 .TP
 .B up
 only list running interfaces.
@@ -441,6 +450,11 @@ Same as above except that only addresses assigned to active network interfaces
 are shown.
 .RE
 .PP
+ip address show type ether
+.RS 4
+Shows IPv4 and IPv6 addresses assigned to all physical ethernetl interfaces
+.RE
+.PP
 ip address show dev eth0
 .RS 4
 Shows IPv4 and IPv6 addresses assigned to network interface eth0.
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 19a0c9ca..60cbb5c7 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -176,10 +176,12 @@ ip-link \- network device configuration
 .BR up " ] ["
 .B master
 .IR DEVICE " ] ["
-.B type
-.IR ETYPE " ] ["
 .B vrf
 .IR NAME " ] ["
+.B type
+.IR ETYPE " ] ["
+.B exclude_type
+.IR ETYPE " ] ["
 .BR nomaster " ]"
 
 .ti -8
@@ -237,7 +239,7 @@ ip-link \- network device configuration
 
 .ti -8
 .IR ETYPE " := [ " TYPE " |"
-.BR bridge_slave " | " bond_slave " ]"
+.BR ether " | " loopback " | " ppp " | " bridge_slave " | " bond_slave " ]"
 
 .ti -8
 .IR VFVLAN-LIST " := [ "  VFVLAN-LIST " ] " VFVLAN
@@ -2630,6 +2632,11 @@ ip link show type vlan
 Shows the vlan devices.
 .RE
 .PP
+ip link show exclude_type ppp
+.RS 4
+List the network interfaces except PPP devices.
+.RE
+.PP
 ip link show master br0
 .RS 4
 Shows devices enslaved by br0
-- 
2.20.1


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

end of thread, other threads:[~2022-01-12 17:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-08 19:58 [PATCH iproute2 v2] ip: Extend filter links/addresses Anton Danilov
2022-01-11 16:35 ` David Ahern
2022-01-11 19:09   ` Anton Danilov
2022-01-12 17:57     ` David Ahern
  -- strict thread matches above, loose matches on Subject: below --
2022-01-08 19:47 Антон Данилов

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.