使用 NETLINK 的 Vlan 接口详细信息

Vlan interface details using NETLINK

我知道可以使用 NETLINK 中的 RTE_NEWLINK 消息类型来检测新接口的添加。 Netlink 发送一条消息,我们可以使用 (if_indextoname & if_nametoindex).

获取接口的索引和名称

我的问题是,如果我们添加一个 VLAN 接口,它会发送一条带有接口名称的消息(例如:eth1.10)。此 vlan 号是否仅在接口名称中可用 或者它在 NL_MSG 结构内的任何地方都可用。我不想解析 接口名称和获取 VLAN 号

我执行了下面的代码并添加了一个vlan子接口,但是从属性结构中找不到vlan信息。即使 RTM_NEWLINK 检测到新界面,它也没有打印任何内容。如果我在代码中的错误位置查找 VLAN 信息,请纠正我。

 if(nl_msg_hdr->nlmsg_type == RTM_NEWLINK)
    {
            struct ifinfomsg *ifi;
            struct rtattr *rt_attr;
            int    rtattrlen;
            ifi = (struct ifinfomsg *) NLMSG_DATA(nl_msg_hdr);
            printf("RTM_NEWLINK");
    for (;RTA_OK(rt_attr, rtattrlen); rt_attr = RTA_NEXT(rt_attr, rtattrlen)) {

            if (rt_attr->rta_type == IFLA_LINKINFO)
                            printf(" IFLA_LINKINFO \n");
            if (rt_attr->rta_type == IFLA_LINK)
                            printf(" IFLA_LINK \n");
            if (rt_attr->rta_type == IFLA_INFO_DATA)
                            printf(" IFLA_INFO_DATA\n");
            if (rt_attr->rta_type == IFLA_VLAN_ID)
                            printf(" IFLA_VLAN_ID\n");
   }
}



x/200bx nl_msg_hdr - 200 bytes hex-dump (VLAN ID is 33 in my case)

0x7fffffffd250: 0xa4    0x04    0x00    0x00    0x10    0x00    0x00    0x00
0x7fffffffd258: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffd260: 0x00    0x00    0x01    0x00    0x27    0x00    0x00    0x00
0x7fffffffd268: 0x02    0x10    0x00    0x00    0xff    0xff    0xff    0xff
0x7fffffffd270: 0x0d    0x00    0x03    0x00    0x76    0x65    0x74    0x68
0x7fffffffd278: 0x31    0x2e    0x33    0x33    0x00    0x00    0x00    0x00
0x7fffffffd280: 0x08    0x00    0x0d    0x00    0x00    0x00    0x00    0x00
0x7fffffffd288: 0x05    0x00    0x10    0x00    0x02    0x00    0x00    0x00
0x7fffffffd290: 0x05    0x00    0x11    0x00    0x00    0x00    0x00    0x00
0x7fffffffd298: 0x08    0x00    0x04    0x00    0xdc    0x05    0x00    0x00
0x7fffffffd2a0: 0x08    0x00    0x1b    0x00    0x00    0x00    0x00    0x00
0x7fffffffd2a8: 0x08    0x00    0x1e    0x00    0x00    0x00    0x00    0x00
0x7fffffffd2b0: 0x08    0x00    0x1f    0x00    0x01    0x00    0x00    0x00
0x7fffffffd2b8: 0x08    0x00    0x20    0x00    0x01    0x00    0x00    0x00
0x7fffffffd2c0: 0x08    0x00    0x05    0x00    0x0a    0x00    0x00    0x00
0x7fffffffd2c8: 0x05    0x00    0x21    0x00    0x01    0x00    0x00    0x00
0x7fffffffd2d0: 0x09    0x00    0x06    0x00    0x6e    0x6f    0x6f    0x70
0x7fffffffd2d8: 0x00    0x00    0x00    0x00    0x24    0x00    0x0e    0x00
0x7fffffffd2e0: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffd2e8: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffd2f0: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffd2f8: 0x00    0x00    0x00    0x00    0x00    0x88    0xff    0xff
0x7fffffffd300: 0x0a    0x00    0x01    0x00    0x66    0x0f    0x70    0x37
0x7fffffffd308: 0x0b    0x27    0x00    0x00    0x0a    0x00    0x02    0x00
0x7fffffffd310: 0xff    0xff    0xff    0xff    0xff    0xff    0x00    0x00

vlan 信息在 RTM_NEWLINK 消息中可用:IFLA_LINKINFO / IFLA_INFO_DATA / IFLA_VLAN_ID:

# the message structure:

[ nlmsg fields ]
[ ifinfmsg fields ]
nla chain:
  [ IFLA_IFNAME ]
  [ IFLA_… ]
  [ IFLA_LINKINFO ]
  nla chain:
    [ IFLA_INFO_KIND ]
      ...
    [ IFLA_INFO_DATA ]
    nla chain:
      [ IFLA_VLAN_ID ]

和相应的代码(python 样本 pyroute2):

from pyroute2 import IPRoute
ip = IPRoute()
# assume `ifindex` contains VLAN interface index
nlmsg = ip.get_links(ifindex)[0]
vid = nlmsg.get_attr('IFLA_LINKINFO').\
    get_attr('IFLA_INFO_DATA').\
    get_attr('IFLA_VLAN_ID')
print(vid)

检查从 2.6.32 (RHEL6.5) 到 4.1.0-rc6 (F22) 的内核。

是的,您是对的 — 不应依赖接口名称作为 VLAN id 的来源。接口名称可以是任何字面意思。