2

I need to obtain the real_dev (f.e. ID) of the given VLAN-inteface.

I wrote some test snippet using 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;
}

So I have some interface ID and I can check if it's a VLAN-interface, but I have no idea how to obtain the interface the vlan is attached to. It seems that libnl's API does not provide such possibility.

Is there a way to obtain the VLAN's "parent" interface ID through the libnl or the native netlink API?

4

1 回答 1

3

这都是关于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;
    }

github 上的完整示例

于 2019-04-26T10:21:16.650 回答