如何知道进程是否附加到 Tap 接口?

如何知道进程是否附加到 Tap 接口?

我有时会遇到带有分接头接口的机器(例如,当 KVM 运行时)。我如何知道哪个进程附加到 TAP 接口?

答案1

每个文件描述符都有一个/proc/PID/fdinfo/编号条目,例如:

# cat /proc/24332/fdinfo/28
pos:    0
flags:  0104002
mnt_id: 18
iff:    tap0123acdc-66

因此,通过接口名称,您可以通过以下方式获取 pid:

# egrep -l iff:.*tap0123acdc-66 /proc/*/fdinfo/* 2>/dev/null|cut -d/ -f3
24332

答案2

这让我感到好奇,我查看了 Linux 内核源代码(我假设你的问题是关于 Linux 的)。

看来答案比你想象的要困难。这TUN/TAP API 教程页面提供了一些见解。基本上,您的程序通过打开/dev/net/tun并向其发送TUNSETIFF ioctl.如果一切顺利,将创建一个接口,内核为您提供其名称和文件描述符,这就是您管理它的方式。

这里有两个问题:

  1. 内核不存储发送 ioctl 的进程的 PID struct tun_struct(TUN 和 TAP 在很大程度上共享相同的数据结构)。
  2. 进程可以将接口标记为持久,关闭其文件描述符,然后将其用作普通网络接口。

实际上,我怀疑 2 不会发生太多。检查一个openvpn进程,lsof发现它仍然打开了 TAP 设备的文件描述符,并且显然正在使用它,但由于/dev/net/tun是一种像 一样的多路复用设备/dev/ptmx,您可以使用lsof来找出当前正在使用 TUN/TAP 设备的进程,但是你无法知道什么进程正在使用什么设备。

有一些间接的方法可以解决根本问题。对于 OpenVPN,我使用隧道设置脚本,使用更具描述性的名称来命名tunX/设备,其中包括 OpenVPN 配置文件的基本名称。tapX因此,/etc/openvpn/foo.conf引出了一个vpn-foo设备。然后我可以将 OpenvVPN 进程与其使用的接口关联起来。不过,还没有必要使用 QEmu/KVM 来做到这一点。

答案3

在 FreeBSD 或任何其他 BSD 衍生产品上:

ifconfig tap0

应该显示哪个进程连接到该接口:

tap0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=80000<LINKSTATE>
    ether 58:9c:fc:10:8f:2b
    groups: tap
    media: Ethernet autoselect
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
    Opened by PID 2672

相关内容