使用 NETLINK 的 VLAN 信息

VLAN information using NETLINK

如何使用 C 中的 NETLINK 套接字获取从内核到用户空间的 VLAN 子接口的添加和删除等 VLAN 信息?

我没有按照评论中的建议对NETLINK man进行研究。我添加和删除了一个 VLAN 子接口并使用 netlink 套接字程序进行监控。增删各收到3条消息。 添加发送 3 条 NEWLINK 消息,删除发送 2 条 NEWLINK 和 1 条 DELLINK 消息。为什么会这样?

添加新的 VLAN 接口 eth1.75:

RTM_NEWLINK Link eth2.75 Down
RTM_NEWLINK Link eth2 Up
RTM_NEWLINK Link eth2.75 Up

删除 VLAN 接口 eth2.75:

RTM_NEWLINK Link eth2 Up
RTM_NEWLINK Link eth2.75 Down
RTM_DELLINK eth2.75

创建 netlink 套接字时,它创建了 3 个设备。这就是您收到 3 个事件的原因。这是它在 add 事件时创建的 3 个设备。

  • 网络子系统。
  • 发送队列子系统。
  • 接收队列子系统。

net子系统是上层控制设备。另外两个是 queues 用于处理数据。您可以如下验证。

当我执行 udevadm monitor --env 并创建 vlan 时,我从内核中得到以下事件:

UDEV  [305215.045416] add      /devices/virtual/net/vpn0 (net)
ACTION=add
DEVPATH=/devices/virtual/net/vpn0
ID_MM_CANDIDATE=1
IFINDEX=10
INTERFACE=vpn0
SEQNUM=3665
SUBSYSTEM=net
USEC_INITIALIZED=5215023319

UDEV  [305215.046658] add      /devices/virtual/net/vpn0/queues/rx-0 (queues)
ACTION=add
DEVPATH=/devices/virtual/net/vpn0/queues/rx-0
SEQNUM=3666
SUBSYSTEM=queues
USEC_INITIALIZED=15044665

UDEV  [305215.047628] add      /devices/virtual/net/vpn0/queues/tx-0 (queues)
ACTION=add
DEVPATH=/devices/virtual/net/vpn0/queues/tx-0
SEQNUM=3667
SUBSYSTEM=queues
USEC_INITIALIZED=5215044729

RTM_NEWLINK 接口状态的每次更改都会发送消息,通常来自 netdev_state_change(参见:http://lxr.free-electrons.com/source/net/core/dev.c#L1226)。

基本上,将 RTM_NEWLINK 视为 "an interface changed state",而不仅仅是 "a new interface created"。

例如,对于添加 VLAN 接口,您得到:

  1. 通知新接口 eth2.75 处于 DOWN 状态
  2. 底层物理接口 eth2 的状态通知(它现在有一个 "subordinate" 它没有的接口 之前 - 例如一些 NIC 卡有硬件卸载来过滤 不需要的 VLAN 标记。该接口现在可能需要更新 NIC ETC。)。 eth2 处于 UP 状态并保持这种状态 - 但它的内部状态 改变了。
  3. eth2.75 从 DOWN 状态变为 UP 状态的通知。

以类似的删除方式,您会看到:

  1. eth2 状态变化的通知(与 eth2.75 和 VLAN)
  2. eth2.75 从 UP 状态变为 DOWN 状态的通知
  3. 删除eth2.75接口的通知

可能您正在使用 ifupdown 实用程序,例如ifup,对吧?

出于某种原因,它包含一个奇怪的逻辑:在添加或升级过程中,如果接口名称包含点符号 ('.'),则它会在处理子接口之前为“父”接口调用 ip link set up .它还包含与您正在写的类似的“放下”过程的特殊逻辑。您可以在 ifupdown 个来源的“link.defn”文件中查看。

顺便说一句,现在您可以使用 strace 实用程序来调试网络链接,例如

sudo strace ip link add link eth2 name eth2.75 type vlan id 75 2> ./log.

然后在 log 文件中查找 sendmsgsendto 说明。