如何判断网络接口是物理(设备)还是虚拟(别名)?

如何判断网络接口是物理(设备)还是虚拟(别名)?

我有一个运行 OpenWrt(一种用于路由器的嵌入式 Linux)的小型家用路由器。它有五个以太网端口,其中一个标记为 WAN,四个标记为 LAN 1 至 4。它具有以下定义的网络接口ifconfig

root@TIBERIUS: ~ > ifconfig | grep Link
br-lan    Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
eth0      Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
lan1      Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
lan2      Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
lan3      Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
lan4      Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
lo        Link encap:Local Loopback
pppoe-wan Link encap:Point-to-Point Protocol
wan       Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
wlan0     Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0

可以看到,设备数量不少,但MAC地址只有一个。

据我了解,其中一些设备是虚拟的。我们先把lo和放在一边pppoe-wan,这是环回设备和我的 PPPoE 连接。但对于其余的,我该如何判断它们是物理的还是虚拟的?我知道有一个用于标记虚拟接口的命名约定,例如eth0.1,但显然这里没有遵守。让我们看看ifconfig其中两个接口的输出:

root@TIBERIUS: ~ > ifconfig wan
wan       Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:15007 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12055 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:13341276 (12.7 MiB)  TX bytes:1831757 (1.7 MiB)

root@TIBERIUS: ~ > ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:23:CD:20:C3:B0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:25799 errors:0 dropped:0 overruns:23 frame:0
          TX packets:25294 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:15481996 (14.7 MiB)  TX bytes:15160380 (14.4 MiB)
          Interrupt:4

txqueuelen除了具有非零的模糊细节之外eth0,唯一显着的区别是eth0有一个Interrupt条目,据我所知,这是一个硬件功能。那么,这就是通过查找Interrupt中的条目来判断网络接口是否为物理接口的方法吗ifconfig?或者,还有更好的方法?有没有一种简单直接的方法来确定网络设备是物理设备还是虚拟设备?

注意有一个相关问题虽然它确实有一个公认的答案,但它并不是结论性的。

更新

在回复 derobert 的回答时,以下是来自的信息ls -l /sys/class/net

br-lan      -> ../../devices/virtual/net/br-lan
eth0        -> ../../devices/platform/ag71xx.0/net/eth0
lan1        -> ../../devices/platform/dsa.0/net/lan1
lan2        -> ../../devices/platform/dsa.0/net/lan2
lan3        -> ../../devices/platform/dsa.0/net/lan3
lan4        -> ../../devices/platform/dsa.0/net/lan4
lo          -> ../../devices/virtual/net/lo
pppoe-wan   -> ../../devices/virtual/net/pppoe-wan
wan         -> ../../devices/platform/dsa.0/net/wan

[此列表的附录:wlan0本来也会显示wlan0 -> ../../devices/platform/ath9k/net/wlan0,但当我复制上面的列表时,我禁用了 WLAN,这就是它没有显示的原因。]

我想说的eth0是唯一的设备。不清楚dsa.0是什么。

并回复 Bryan Agee 的回答:

root@TIBERIUS: ~ > cat /etc/config/network

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config interface 'eth'
        option ifname 'eth0'
        option proto 'none'

config interface 'lan'
        option ifname 'lan1 lan2 lan3 lan4'
        option type 'bridge'
        option proto 'static'
        option ipaddr '192.168.33.1'
        option netmask '255.255.255.0'

config interface 'wan'
        option ifname 'wan'
        option proto 'pppoe'
        option username '…'
        option password '…'

答案1

您可以检查/sys

anthony@Zia:/sys/class/net$ ls -l /sys/class/net/
total 0
lrwxrwxrwx 1 root root 0 Dec 11 15:38 br0 -> ../../devices/virtual/net/br0
lrwxrwxrwx 1 root root 0 Dec 11 15:38 lan -> ../../devices/pci0000:00/0000:00:1e.0/0000:07:01.0/net/lan
lrwxrwxrwx 1 root root 0 Dec 11 15:38 lo -> ../../devices/virtual/net/lo
lrwxrwxrwx 1 root root 0 Dec 11 15:38 tun0 -> ../../devices/virtual/net/tun0

因此,实际设备显示在 /sys/class/net 中。注意别名(如 lan:0)不这样做(这样你就可以知道哪些是别名)。您可以清楚地看到哪些是实际硬件(lan),哪些不是(br0、lo、tun0)。

澄清

上面你能看出哪些是真实的,因为虚拟的都是虚拟的。而lan是在PCI总线上。

在您的例子中,您有六个:eth0、wan 和 lan1-4。这很奇怪,因为你说你总共只有五个端口。我猜想 eth0 实际上是硬连线到交换机芯片上的,其他 5 个端口是该交换机上的端口。 wlan0 可能也是真实的(可能是无线适配器),尽管它没有显示在 /sys... 中。

因此,我想说,出于所有实际目的,您真正的端口是 wan、lan1–4 和 wlan0。 br-lan 是一个桥接器,设置用于使所有 4 个 lan 端口充当交换机(因此您可以拆分该交换机)。

答案2

假设您的接口 MAC 地址是不是欺骗的,你可以尝试使用以太网工具:

ethtool -P {Network interface name}

永久地址:00:00:00:00:00:00” 将表明它是一个虚拟网络接口。

以下 bash 循环将显示所有网络接口的 MAC 地址:

for i in $(ip -o link show | awk -F': ' '{print $2}'); \
do mac=$(ethtool -P $i) \
&& printf '%-10s %-10s\n' "$i" "$mac"; \
done

lo         Permanent address: 00:00:00:00:00:00
enp5s0f0   Permanent address: 44:1e:a1:73:39:c8
enp4s0f0   Permanent address: 00:9c:02:b0:ef:20
enp5s0f1   Permanent address: 44:1e:a1:73:39:c9
enp4s0f1   Permanent address: 00:9c:02:b0:ef:24
virbr1     Permanent address: 00:00:00:00:00:00
virbr1-nic Permanent address: 00:00:00:00:00:00
virbr0     Permanent address: 00:00:00:00:00:00
virbr0-nic Permanent address: 00:00:00:00:00:00
vnet0      Permanent address: 00:00:00:00:00:00
vnet1      Permanent address: 00:00:00:00:00:00

答案3

sysfs 手册页

/系统/类/网络

此目录中的每个条目都是一个符号链接,表示在访问该目录的进程的网络命名空间中可见的真实或虚拟网络设备之一。这些符号链接中的每一个都引用 /sys/devices 目录中的条目。

因此,我们需要做的就是检查 sysfs 文件系统中是否存在链接到网络接口的物理设备,例如/sys/class/net/eth0/device

如果您知道接口名称,则可以使用一个简单的脚本:

#!/bin/bash

iface=eth0

if test -e /sys/class/net/${iface}/device; then
        echo $iface
fi

如果要打印所有物理设备的接口名称:

#!/bin/bash

while IFS='\n' read p1 line ;do
        iface=$(echo "$p1" | sed -n 's/[0-9]: \(.*\):.*/\1/p')

        if test -n $iface && ip addr show dev $iface >/dev/null 2>&1; then
                if test -e /sys/class/net/${iface}/device; then
                        echo $iface
                fi
        fi
done < <(ip address)

这是一个可以解决问题的单行文字:

echo $(cd /sys/class/net; dirname */device)

适合在 for 循环等中使用,例如:

for interface in $(cd /sys/class/net; dirname */device); do
    echo $interface
    # Do whatever else you may need to do with $interface
done

答案4

我试图弄清楚如何获取虚拟罐 (vcan) 设备的列表,并得出以下结论:

ip -details -oneline link | grep vcan

这将仅列出虚拟 can 设备。

如果您只想获取 vcan 设备名称列表,那么这应该可行:

ip -details -oneline link | grep vcan | awk -F': ' '{print $2}'

相关内容