Vlan interface details using NETLINK

2.8k views Asked by At

I understand that new interface addition can be detected using RTE_NEWLINK message type in NETLINK. Netlink sends a message with which we can get index and name of the interface using (if_indextoname & if_nametoindex).

My question is , if we add a VLAN interface, it sends a message with interface name (example: eth1.10). Does this vlan number only be available in interface name or is it available anywhere inside NL_MSG structure. I dont want to parse interface name and get VLAN number

I executed the below code and added a vlan sub interface, but couldn't find vlan information from attribute structures. It didnt print anything even though RTM_NEWLINK detected the new interface. Please correct me if i am looking for VLAN information at a wrong place in code.

 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
1

There are 1 answers

8
svinota On BEST ANSWER

The vlan info is available in RTM_NEWLINK messages: 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 ]

and the corresponding code (python sample with 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)

Checked on kernels from 2.6.32 (RHEL6.5) to 4.1.0-rc6 (F22).

And yes, you're right — one should not rely on the interface name as the source of VLAN id. The interface name can be literally any.