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: %dn", 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: %dn", 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?
Advertisement
Answer
It’s all about 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) */
Thus through the native netlink API it could be done such a way:
/* 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:%un", *(unsigned short *)((char *) rta + NLA_HDRLEN)); break; }