7

With iproute2 userspace tools one can display the network devices using the ip commands verb link show( sometimes shortened to l sh ).

The output generate does not display the TYPE of link/interface device.

root@box:/# ip link show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 
2: eno3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether bc:97:e1:58:10:18 brd ff:ff:ff:ff:ff:ff 
3: eno1np0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether bc:97:e1:58:10:1a brd ff:ff:ff:ff:ff:ff
4: eno2np1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether bc:97:e1:58:10:1b brd ff:ff:ff:ff:ff:ff

Each of the linkes tells infos like mtu, the UP/DOWN twice in a redundant way, however there is no indication apparent to me which tells its type. Also I cannot find any indication in the manpages hot to display the TYPE, albeit there are many of them:

TYPE := [ bridge | bridge_slave | bond | bond_slave | 
          can | dummy | hsr | ifb | ipoib | macvlan | 
          macvtap | vcan | veth | vlan | vxlan | ip6tnl | 
          ipip | sit | gre | gretap | erspan | ip6gre | 
          ip6gretap | ip6erspan | vti | vrf | nlmon |
          ipvlan | lowpan | geneve | macsec ]  

Is there a builtin way with the ip2route tools to output the TYPE in the listing?

9

The interface type information, being rarely used, is normally displayed only by adding the -details option to ip:

-d, -details

    Output more detailed information.

So ip -details link show would display this information for all these interfaces, but also many other additional informations like:

$ ip -d link show lxcbr0
7: lxcbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 
    bridge forward_delay 1500 hello_time 200 max_age 2000 ageing_time 30000 stp_state 0 priority 32768 vlan_filtering 0 vlan_protocol 802.1Q bridge_id 8000.0:16:3e:0:0:0 designated_root 8000.0:16:3e:0:0:0 root_port 0 root_path_cost 0 topology_change 0 topology_change_detected 0 hello_timer    0.00 tcn_timer    0.00 topology_change_timer    0.00 gc_timer   34.76 vlan_default_pvid 1 vlan_stats_enabled 0 vlan_stats_per_port 0 group_fwd_mask 0 group_address 01:80:c2:00:00:00 mcast_snooping 1 mcast_router 1 mcast_query_use_ifaddr 0 mcast_querier 0 mcast_hash_elasticity 16 mcast_hash_max 4096 mcast_last_member_count 2 mcast_startup_query_count 2 mcast_last_member_interval 100 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000 mcast_startup_query_interval 3124 mcast_stats_enabled 0 mcast_igmp_version 2 mcast_mld_version 1 nf_call_iptables 0 nf_call_ip6tables 0 nf_call_arptables 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 

with bridge at the start of the 3rd line here.


Using JSON output along the jq command (which is a must-have tool when processing JSON from shell) allows to reliably parse the command's output, still without having to know beforehand the types, if one wants only to retrieve this information along the interface name.

$ ip -details -json link show | jq --join-output '.[] | .ifname," ",.linkinfo.info_kind,"\n"'
lo null
dummy0 dummy
dummy2 dummy
lxcbr0 bridge
wlan0 null
eth0 null
virbr0 bridge
virbr0-nic tun
tap0 tun
veth0 veth
test veth
wireguard0 wireguard
vethZ0ZQFJ veth

Real interfaces (as well as lo) have no type (ie .[].linkinfo.info_kind doesn't exist) and jq will return null for a non-existent field. It can be filtered out with this instead:

ip -details -json link show | jq --join-output '.[] | .ifname," ", if .linkinfo.info_kind != null then .linkinfo.info_kind else empty end, "\n"'

Actually, the search feature of ip link show puts together the kind and the slave kind as type, and the detailed output would show one on 3rd line, the other on 4th line. In JSON output those are two different fields: .[].linkinfo.info_kind and .[].linkinfo.info_slave_kind, so the slave types would require an other command, same for displaying both. Here's an example for both:

ip -details -json link show | jq --join-output '
.[] |
    if .ifname != null then
        .ifname,
        " ",
        if .linkinfo.info_kind != null then
            .linkinfo.info_kind
        else
            empty
        end,
        " ",
        if .linkinfo.info_slave_kind != null then
            .linkinfo.info_slave_kind
        else
            empty
        end,
        "\n"
    else
        empty
    end
'

which outputs instead:

lo  
dummy0 dummy 
dummy2 dummy 
lxcbr0 bridge 
wlan0  
eth0  
virbr0 bridge 
virbr0-nic tun bridge
tap0 tun 
veth0 veth 
test veth 
wireguard0 wireguard 
vethZ0ZQFJ veth bridge

and shows here virbr0-nic being a tun (really tuntap the fact that it's tun or tap is in a sub-field) device as well as a bridge slave, and vethZ0ZQFJ a veth device as well as a bridge slave.

This same jq filter above will also cope when fed with filtered output from ip ... link show ... type ...slave when querying for slave interfaces, which apparently returns extra empty objects for non-matching interfaces, by ignoring (empty) entries without interface name. So starting the line with ip -details -json link show type bridge_slave | would return only:

virbr0-nic tun bridge
vethZ0ZQFJ veth bridge
| improve this answer | |
  • not very related note: this same information kind/type can be checked in nftables during the packet path. There are real use cases , but this rule: meta iifkind "wireguard" meta l4proto { icmp, ipv6-icmp } counter would keep statistics on received ICMP packets through any wireguard interface. – A.B Oct 24 at 10:00
1

This is a script I employ to get the info

#!/bin/bash

TYPES="bridge bridge_slave bond bond_slave can dummy hsr ifb ipoib macvlan macvtap vcan veth vlan vxlan ip6tnl ipip sit gre gretap erspan ip6gre ip6gretap ip6erspan vti vrf nlmon ipvlan lowpan geneve macsec"


for TYPE in $TYPES
do

        echo "TYPE $TYPE"
        ip link show type "$TYPE"
done

This inserts the information into a output like ip link show

#!/bin/bash

TYPES="bridge bridge_slave bond bond_slave can dummy hsr ifb ipoib macvlan macvtap vcan veth vlan vxlan ip6tnl ipip sit gre gretap erspan ip6gre ip6gretap ip6erspan vti vrf nlmon ipvlan lowpan geneve macsec"
 
# intially query all links
# (since output is 2 lines per link, squash into single line, and sort,
#  so we can use `comm`)
LINK_ALL="$(ip link show | paste - - | sort)"
# initial empty
LINK_RESULT=""

# populate $LINK_RESULT
for TYPE in $TYPES
do

  # using specific `ip link show type`
  # ( again use `paste` and sort
  #  -> each link info being 2 lines is put in one
  #  -> sorting required for `comm` )
  LINK_TYPE="$(ip link show type "$TYPE" | paste - - | sort)"

  # where there any links of this type ?
  test -n "$LINK_TYPE" && {
    # then remove from the initial set
    LINK_ALL="$(comm -3 <(echo "$LINK_ALL") <(echo "$LINK_TYPE"))"
    # add to result set (and insert link TYPE information)
    LINK_RESULT="$(echo "$LINK_RESULT"; echo "$LINK_TYPE" | sed 's/>/>'" type=$TYPE"'/g')"
  }

done

# Since ordnary NICs and lo have no type they have not been found before
# join them
LINK_RESULT="$LINK_ALL $(echo "$LINK_RESULT")"

# Output result undoing the paste
echo "$LINK_RESULT" | sed 's:link/:\n    link/:g'
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.