【问题标题】:VLAN information using NETLINK使用 NETLINK 的 VLAN 信息
【发布时间】:2015-08-02 11:35:41
【问题描述】:

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

按照 cmets 的建议,我几乎没有研究过 NETLINK 人。我添加和删除了一个 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

【问题讨论】:

  • 阅读手册页并在遇到特定问题时返回。从man 7 netlink 开始,然后是man 7 rtnetlink。我认为你会得到一个RTM_NEWLINK 用于添加和RTM_DELINK 用于删除。查看 Network Manager 的源代码中的示例。

标签: c linux kernel netlink vlan


【解决方案1】:

在创建 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

【讨论】:

    【解决方案2】:

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

    基本上,将 RTM_NEWLINK 视为“接口更改状态”,而不仅仅是“创建新接口”。

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

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

    你看到的删除方式类似:

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

    【讨论】:

      【解决方案3】:

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

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

      顺便说一句,现在你可以使用strace 工具来调试netlink,例如

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

      然后在log文件中查找sendmsgsendto指令。

      【讨论】:

        最近更新 更多