Message ID | 20220108195824.23840-1-littlesmilingcloud@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | David Ahern |
Headers | show |
Series | [iproute2,v2] ip: Extend filter links/addresses | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
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?
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?
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?
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
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(-)