c - 通过netlink获取VLAN接口(interface)的真实设备

标签 c linux linux-kernel netlink vlan

我需要获取real_dev给定 VLAN 接口(interface)的(例如 ID)。

我使用 libnl 编写了一些测试片段:

int main(void) {
     struct nl_sock *sock;
     struct nl_cache *cache;
     char iface[] = "eno1.10";
     //char iface[] = "eno1";

     if (!(sock = nl_socket_alloc())) {
          perror("nl_socket_alloc");
          return -1; 
     }

     if (nl_connect(sock, NETLINK_ROUTE) < 0) {
          perror("nl_connect");
          nl_socket_free( sock );
          return -1; 
     }

     if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache) < 0) {
          perror("rtnl_link_alloc_cache");
          nl_socket_free( sock );
          nl_close( sock );
          return -1; 
     }
     {   
          int ifindex; 
          struct rtnl_link *link = NULL;

          if (!(ifindex = rtnl_link_name2i(cache, iface))) {
               perror("rtnl_link_name2i");
               return -1; 
          }
          printf("ind: %d\n", ifindex);

          if (!(link = rtnl_link_get(cache, ifindex))) {
               perror("rtnl_link_get");
               return -1; 
          }

          if (rtnl_link_is_vlan(link)) {
               puts("It's VLAN link");

               /* alas it's not about the 'real' device */
               printf("master: %d\n", rtnl_link_get_master(link));
          } else
               puts("It's 'real' link");
     }   

     return 0;
}

所以我有一些接口(interface) ID,我可以检查它是否是 VLAN 接口(interface),但我不知道如何获取 VLAN 所连接的接口(interface)。 看来libnl的API并没有提供这种可能性。

有没有办法通过libnl native netlink API获取VLAN的“父”接口(interface)ID?

最佳答案

这都是关于IFLA_LINK :

/* IFLA_LINK.
   For usual devices it is equal ifi_index.
   If it is a "virtual interface" (f.e. tunnel), ifi_link
   can point to real physical interface (f.e. for bandwidth calculations),
   or maybe 0, what means, that real media is unknown (usual
   for IPIP tunnels, when route to endpoint is allowed to change)
 */

因此,通过原生 netlink API 可以通过以下方式完成:

/* some preparation code */
struct rtattr *rta = IFLA_RTA(msg);
int len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*msg));
for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len))
    if (rta->rta_type == IFLA_LINK) {
        printf("Real device ID:%u\n",
               *(unsigned short *)((char *) rta + NLA_HDRLEN));
        break;
    }

Full example on github .

关于c - 通过netlink获取VLAN接口(interface)的真实设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55758700/

相关文章:

c - DirectShow 数据复制太慢

将 C 结构实例复制到 Swift 后缺少成员

mysql - 在 Ubuntu Trusty 14.04 中启动时自动启动多个 MySQL 实例

linux - UDP 数据包丢弃 - INErrors 与 .RcvbufErrors

c - 不使用浮点寄存器的浮点常量(Linux内核模块)

c 结构关系

c++ - 无法打印 signed int 类型的大小

c - Ip 结构 C 参数

用于计算多个文件平均值的 Linux Bash 脚本

linux - 模块编译 : asm/linkage. h 文件未找到