使用 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 接口,您得到:
- 通知新接口 eth2.75 处于 DOWN 状态
- 底层物理接口 eth2 的状态通知(它现在有一个 "subordinate" 它没有的接口
之前 - 例如一些 NIC 卡有硬件卸载来过滤
不需要的 VLAN 标记。该接口现在可能需要更新 NIC
ETC。)。 eth2 处于 UP 状态并保持这种状态 - 但它的内部状态
改变了。
- eth2.75 从 DOWN 状态变为 UP 状态的通知。
以类似的删除方式,您会看到:
- eth2 状态变化的通知(与 eth2.75 和
VLAN)
- eth2.75 从 UP 状态变为 DOWN 状态的通知
- 删除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
文件中查找 sendmsg
或 sendto
说明。
如何使用 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 接口,您得到:
- 通知新接口 eth2.75 处于 DOWN 状态
- 底层物理接口 eth2 的状态通知(它现在有一个 "subordinate" 它没有的接口 之前 - 例如一些 NIC 卡有硬件卸载来过滤 不需要的 VLAN 标记。该接口现在可能需要更新 NIC ETC。)。 eth2 处于 UP 状态并保持这种状态 - 但它的内部状态 改变了。
- eth2.75 从 DOWN 状态变为 UP 状态的通知。
以类似的删除方式,您会看到:
- eth2 状态变化的通知(与 eth2.75 和 VLAN)
- eth2.75 从 UP 状态变为 DOWN 状态的通知
- 删除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
文件中查找 sendmsg
或 sendto
说明。