Получение реального устройства VLAN-интерфейса через netlink - PullRequest
2 голосов
/ 19 апреля 2019

Мне нужно получить real_dev (например, ID) данного VLAN-интерфейса.

Я написал несколько тестовых фрагментов, используя 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;
}

Итак, у меня есть идентификатор интерфейса , и я могу проверить, является ли это VLAN-интерфейсом, но я не знаю , как получитьинтерфейс, к которому подключен vlan .Похоже, что API libnl не предоставляет такой возможности.

Есть ли способ получить идентификатор "родительского" интерфейса VLAN через libnl или собственный API netlink ?

1 Ответ

1 голос
/ 26 апреля 2019

Это все о 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)
 */

Таким образом, с помощью нативного API netlink это можно сделать следующим образом:

/* 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;
    }
...