svinota/pyroute2

Creating a vlan interface with protocol other then 801.2Q

Closed this issue · 9 comments

Hi,

I have tried to create a QinQ interfaces.
I haven't found a way to control the IFLA_VLAN_PROTOCOL with the current api.
I have tried:
a.link("add", ifname="test", vlan_id=23, kind="vlan", link=4, protocol=0x88a8)
and many variations on the protocol key (vlan_protocol, proto, and more..)
The bash command that works is:
ip link add link lag0 elag0.24 type vlan proto 802.1ad id 24

Am I missing something or this feature is not supported?

Should work like that (at least, it works for me):

with IPRoute() as ipr:
    # link to create vlan on:
    idx = ipr.link_lookup(ifname="lag0")[0]
    # create the vlan
    ipr.link("add",
             ifname="elag0.24",
             kind="vlan",
             vlan_id=24,
             link=idx,
             vlan_protocol=0x88a8)

If it doesn't work, please let me know.

Hi,
Thanks for the quick response.
I made a mistake in my example, the default is 0x88a8 and it does not change.
I have tried to add to with protocol 0x8100 and it did not work.
The value in the link data is ('IFLA_VLAN_PROTOCOL', 33024) instead of ('IFLA_VLAN_PROTOCOL', 34984)

Extending the example above:

with IPRoute() as ipr:
    # link to create vlan on:
    idx_h = ipr.link_lookup(ifname="lag0")[0]
    # create the s-vlan, 802.1ad -- 0x88a8
    ipr.link("add",
             ifname="elag0.24",
             kind="vlan",
             vlan_id=24,
             link=idx_h,
             vlan_protocol=0x88a8)
    # look up s-vlan link index
    # a race condition is possible here, as the RTNL protocol
    # is asynchronous and the link("add") call exits before the
    # link is created actually; to deal with it, one can use IPDB,
    # but it is out of the scope of the question
    idx_s = ipr.link_lookup(ifname="elag0.24")[0]
    # create the c-vlan, 802.1q -- 0x8100
    ipr.link("add",
             ifname="elag0.24.300",
             kind="vlan",
             vlan_id=300,
             link=idx_s,
             vlan_protocol=0x8100)

Thereafter two interfaces will be available: elag0.24 (802.1ad) and elag0.24.300 (802.1q)

The task for me: add common interface-specific attributes section to the docs (vlan, vxlan, gre, …)

I ran your example on docker container on Linux Controller 4.2.0-27-generic #32~14.04.1-Ubuntu SMP Fri Jan 22 15:32:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux .
both interfaces created with 0x88a8. (('IFLA_VLAN_PROTOCOL', 33024))
By the way s-tag is 0x8100 and it should be created first.

`
{'__align': (),
'attrs': [('IFLA_IFNAME', 'elag0.24'),
('IFLA_TXQLEN', 0),
('IFLA_OPERSTATE', 'DOWN'),
('IFLA_LINKMODE', 0),
('IFLA_MTU', 1400),
('IFLA_GROUP', 0),
('IFLA_PROMISCUITY', 0),
('IFLA_NUM_TX_QUEUES', 1),
('IFLA_NUM_RX_QUEUES', 1),
('IFLA_LINK', 4),
('IFLA_CARRIER', 1),
('IFLA_QDISC', 'noop'),
('IFLA_CARRIER_CHANGES', 0),
('IFLA_MAP', {'dma': 0, 'base_addr': 0, 'irq': 0, 'mem_end': 0, 'port': 0, 'mem_start': 0}),
('IFLA_ADDRESS', '12:12:12:12:12:18'),
('IFLA_BROADCAST', 'ff:ff:ff:ff:ff:ff'),
('IFLA_STATS', {'rx_over_errors': 0, 'tx_window_errors': 0, 'tx_aborted_errors': 0, 'rx_compressed': 0, 'tx_carrier_errors': 0, 'collisions': 0, 'tx_packets': 0, 'tx_dropped': 0, 'rx_packets': 0, 'rx_length_errors': 0, 'rx_missed_errors': 0, 'tx_bytes': 0, 'rx_frame_errors': 0, 'rx_dropped': 0, 'rx_crc_errors': 0, 'rx_bytes': 0, 'tx_errors': 0, 'rx_fifo_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'multicast': 0, 'rx_errors': 0, 'tx_compressed': 0}),
('IFLA_STATS64', {'rx_over_errors': 0, 'tx_window_errors': 0, 'tx_aborted_errors': 0, 'rx_compressed': 0, 'tx_carrier_errors': 0, 'collisions': 0, 'tx_packets': 0, 'tx_dropped': 0, 'rx_packets': 0, 'rx_length_errors': 0, 'rx_missed_errors': 0, 'tx_bytes': 0, 'rx_frame_errors': 0, 'rx_dropped': 0, 'rx_crc_errors': 0, 'rx_bytes': 0, 'tx_errors': 0, 'rx_fifo_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'multicast': 0, 'rx_errors': 0, 'tx_compressed': 0}),
('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'vlan'), ('IFLA_INFO_DATA', {'attrs': [('IFLA_VLAN_PROTOCOL', 33024), ('IFLA_VLAN_ID', 24), ('IFLA_VLAN_FLAGS', {'mask': 4294967295, 'flags': 1})]})]}),
('IFLA_AF_SPEC', {'attrs': [('AF_INET', {'igmpv2_unsolicited_report_interval': 10000, 'accept_source_route': 1, 'send_redirects': 1, 'arpfilter': 0, 'tag': 0, 'forwarding': 1, 'proxy_arp': 0, 'arp_ignore': 0, 'arp_accept': 0, 'accept_redirects': 1, 'log_martians': 0, 'proxy_arp_pvlan': 0, 'secure_redirects': 1, 'igmpv3_unsolicited_report_interval': 1000, 'noxfrm': 0, 'route_localnet': 0, 'src_vmark': 0, 'nopolicy': 0, 'force_igmp_version': 0, 'shared_media': 1, 'promote_secondaries': 0, 'dummy': 65656, 'mc_forwarding': 0, 'accept_local': 0, 'medium_id': 0, 'bootp_relay': 0, 'rp_filter': 1, 'arp_announce': 0, 'arp_notify': 0}), ('AF_INET6', {'attrs': [('IFLA_INET6_FLAGS', 0), ('IFLA_INET6_CACHEINFO', {'retrans_time': 1000, 'max_reasm_len': 65535, 'tstamp': 35260758, 'reachable_time': 20448}), ('IFLA_INET6_CONF', {'disable_ipv6': 0, 'accept_source_route': 0, 'router_probe_interval': 60000, 'force_tllao': 0, 'forwarding': 0, 'max_desync_factor': 600, 'accept_ra': 1, 'max_addresses': 16, 'accept_dad': 1, 'accept_ra_rt_info_max_plen': 0, 'optimistic_dad': 0, 'accept_ra_rtr_pref': 1, 'ndisc_notify': 0, 'temp_prefered_lft': 86400, 'mc_forwarding': 0, 'use_tempaddr': 0, 'accept_ra_defrtr': 1, 'accept_ra_pinfo': 1, 'router_solicitations': 3, 'proxy_ndp': 0, 'dad_transmits': 1, 'router_solicitation_delay': 1000, 'temp_valid_lft': 604800, 'force_mld_version': 0, 'mtu': 1400, 'regen_max_retry': 3, 'accept_redirects': 1, 'router_solicitation_interval': 4000, 'hop_limit': 64, 'autoconf': 1}), ('IFLA_INET6_STATS', {'innoroutes': 0, 'reasmfails': 0, 'inhdrerrors': 0, 'inmcastoctets': 0, 'reasmtimeout': 0, 'intoobigerrors': 0, 'outbcastpkts': 0, 'num': 36, 'indiscards': 0, 'ect1pkts': 0, 'fragcreates': 0, 'noectpkts': 0, 'inaddrerrors': 0, 'intruncatedpkts': 0, 'outoctets': 0, 'inbcastpkts': 0, 'fragoks': 0, 'outmcastpkts': 0, 'outmcastoctets': 0, 'inpkts': 0, 'csumerrors': 0, 'outdiscards': 0, 'inunknownprotos': 0, 'inmcastpkts': 0, 'indelivers': 0, 'outpkts': 0, 'outbcastoctets': 0, 'outforwdatagrams': 0, 'cepkts': 0, 'fragfails': 0, 'inoctets': 0, 'inbcastoctets': 0, 'reasmreqds': 0, 'ect0pkts': 0, 'outnoroutes': 0, 'reasmoks': 0}), ('IFLA_INET6_ICMP6STATS', {'outerrors': 0, 'csumerrors': 0, 'inmsgs': 0, 'num': 6, 'inerrors': 0, 'outmsgs': 0}), ('IFLA_INET6_TOKEN', '::'), ('IFLA_INET6_ADDR_GEN_MODE', 0)]})]})],
'change': 0,
'event': 'RTM_NEWLINK',
'family': 0,
'flags': 4098,
'header': {'error': None,
'flags': 2,
'length': 1224,
'pid': 2585670545,
'sequence_number': 255,
'type': 16},
'ifi_type': 1,
'index': 11},

{'__align': (),
'attrs': [('IFLA_IFNAME', 'elag0.24.300'),
('IFLA_TXQLEN', 0),
('IFLA_OPERSTATE', 'DOWN'),
('IFLA_LINKMODE', 0),
('IFLA_MTU', 1400),
('IFLA_GROUP', 0),
('IFLA_PROMISCUITY', 0),
('IFLA_NUM_TX_QUEUES', 1),
('IFLA_NUM_RX_QUEUES', 1),
('IFLA_LINK', 11),
('IFLA_CARRIER', 1),
('IFLA_QDISC', 'noop'),
('IFLA_CARRIER_CHANGES', 0),
('IFLA_MAP', {'dma': 0, 'base_addr': 0, 'irq': 0, 'mem_end': 0, 'port': 0, 'mem_start': 0}),
('IFLA_ADDRESS', '12:12:12:12:12:18'),
('IFLA_BROADCAST', 'ff:ff:ff:ff:ff:ff'),
('IFLA_STATS', {'rx_over_errors': 0, 'tx_window_errors': 0, 'tx_aborted_errors': 0, 'rx_compressed': 0, 'tx_carrier_errors': 0, 'collisions': 0, 'tx_packets': 0, 'tx_dropped': 0, 'rx_packets': 0, 'rx_length_errors': 0, 'rx_missed_errors': 0, 'tx_bytes': 0, 'rx_frame_errors': 0, 'rx_dropped': 0, 'rx_crc_errors': 0, 'rx_bytes': 0, 'tx_errors': 0, 'rx_fifo_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'multicast': 0, 'rx_errors': 0, 'tx_compressed': 0}),
('IFLA_STATS64', {'rx_over_errors': 0, 'tx_window_errors': 0, 'tx_aborted_errors': 0, 'rx_compressed': 0, 'tx_carrier_errors': 0, 'collisions': 0, 'tx_packets': 0, 'tx_dropped': 0, 'rx_packets': 0, 'rx_length_errors': 0, 'rx_missed_errors': 0, 'tx_bytes': 0, 'rx_frame_errors': 0, 'rx_dropped': 0, 'rx_crc_errors': 0, 'rx_bytes': 0, 'tx_errors': 0, 'rx_fifo_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'multicast': 0, 'rx_errors': 0, 'tx_compressed': 0}),
('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'vlan'), ('IFLA_INFO_DATA', {'attrs': [('IFLA_VLAN_PROTOCOL', 33024), ('IFLA_VLAN_ID', 300), ('IFLA_VLAN_FLAGS', {'mask': 4294967295, 'flags': 1})]})]}),
('IFLA_AF_SPEC', {'attrs': [('AF_INET', {'igmpv2_unsolicited_report_interval': 10000, 'accept_source_route': 1, 'send_redirects': 1, 'arpfilter': 0, 'tag': 0, 'forwarding': 1, 'proxy_arp': 0, 'arp_ignore': 0, 'arp_accept': 0, 'accept_redirects': 1, 'log_martians': 0, 'proxy_arp_pvlan': 0, 'secure_redirects': 1, 'igmpv3_unsolicited_report_interval': 1000, 'noxfrm': 0, 'route_localnet': 0, 'src_vmark': 0, 'nopolicy': 0, 'force_igmp_version': 0, 'shared_media': 1, 'promote_secondaries': 0, 'dummy': 65656, 'mc_forwarding': 0, 'accept_local': 0, 'medium_id': 0, 'bootp_relay': 0, 'rp_filter': 1, 'arp_announce': 0, 'arp_notify': 0}), ('AF_INET6', {'attrs': [('IFLA_INET6_FLAGS', 0), ('IFLA_INET6_CACHEINFO', {'retrans_time': 1000, 'max_reasm_len': 65535, 'tstamp': 35260758, 'reachable_time': 35464}), ('IFLA_INET6_CONF', {'disable_ipv6': 0, 'accept_source_route': 0, 'router_probe_interval': 60000, 'force_tllao': 0, 'forwarding': 0, 'max_desync_factor': 600, 'accept_ra': 1, 'max_addresses': 16, 'accept_dad': 1, 'accept_ra_rt_info_max_plen': 0, 'optimistic_dad': 0, 'accept_ra_rtr_pref': 1, 'ndisc_notify': 0, 'temp_prefered_lft': 86400, 'mc_forwarding': 0, 'use_tempaddr': 0, 'accept_ra_defrtr': 1, 'accept_ra_pinfo': 1, 'router_solicitations': 3, 'proxy_ndp': 0, 'dad_transmits': 1, 'router_solicitation_delay': 1000, 'temp_valid_lft': 604800, 'force_mld_version': 0, 'mtu': 1400, 'regen_max_retry': 3, 'accept_redirects': 1, 'router_solicitation_interval': 4000, 'hop_limit': 64, 'autoconf': 1}), ('IFLA_INET6_STATS', {'innoroutes': 0, 'reasmfails': 0, 'inhdrerrors': 0, 'inmcastoctets': 0, 'reasmtimeout': 0, 'intoobigerrors': 0, 'outbcastpkts': 0, 'num': 36, 'indiscards': 0, 'ect1pkts': 0, 'fragcreates': 0, 'noectpkts': 0, 'inaddrerrors': 0, 'intruncatedpkts': 0, 'outoctets': 0, 'inbcastpkts': 0, 'fragoks': 0, 'outmcastpkts': 0, 'outmcastoctets': 0, 'inpkts': 0, 'csumerrors': 0, 'outdiscards': 0, 'inunknownprotos': 0, 'inmcastpkts': 0, 'indelivers': 0, 'outpkts': 0, 'outbcastoctets': 0, 'outforwdatagrams': 0, 'cepkts': 0, 'fragfails': 0, 'inoctets': 0, 'inbcastoctets': 0, 'reasmreqds': 0, 'ect0pkts': 0, 'outnoroutes': 0, 'reasmoks': 0}), ('IFLA_INET6_ICMP6STATS', {'outerrors': 0, 'csumerrors': 0, 'inmsgs': 0, 'num': 6, 'inerrors': 0, 'outmsgs': 0}), ('IFLA_INET6_TOKEN', '::'), ('IFLA_INET6_ADDR_GEN_MODE', 0)]})]})],
'change': 0,
'event': 'RTM_NEWLINK',
'family': 0,
'flags': 4098,
'header': {'error': None,
'flags': 2,
'length': 1228,
'pid': 2585670545,
'sequence_number': 255,
'type': 16},
'ifi_type': 1,
'index': 12}]
`

First, let's be clear on definitions and values

  • 802.1ad == 0x88a8 == 34984, «external» tag, s-tag
  • 802.1q == 0x8100 == 33024, «internal» tag, c-tag

The creation/untagging scheme:

host interface (lag0) → s-vlan (elag0.s) → c-vlan (elag0.s.c)

As in your example, both interfaces are created with IFLA_VLAN_PROTOCOL == 0x8100 == 802.1q

Obviously, something went wrong — elag0.s should be 0x88a8 == 802.1ad.

On my test kernels (>= 4.10) everything goes ok:

[(x.get_attr('IFLA_IFNAME'),
  x.get_attr('IFLA_LINKINFO').get_attr('IFLA_INFO_DATA').get_attr('IFLA_VLAN_PROTOCOL'))
  for x in ip.get_links() if x.get_attr('IFLA_IFNAME').startswith('test.')]

[('test.25', 34984), ('test.25.300', 33024)]

So if it doesn't work for you, it may be a kernel issue, not the library. But to be sure I have to check it first, so give me some time to test it on Ubuntu with 4.2.0 kernel.

Yes I am sorry, I am bit out today, you are right on the definitions.
Its strange that it is a kernel problem because with the "ip link" it creates fine.

13: elag0.24@lag0: <BROADCAST,MULTICAST> mtu 1400 qdisc noop state DOWN mode DEFAULT group default
link/ether 12:12:12:12:12:18 brd ff:ff:ff:ff:ff:ff promiscuity 0
vlan protocol 802.1Q id 24 <REORDER_HDR>
14: elag0.24.300@elag0.24: <BROADCAST,MULTICAST,M-DOWN> mtu 1400 qdisc noop state DOWN mode DEFAULT group default
link/ether 12:12:12:12:12:18 brd ff:ff:ff:ff:ff:ff promiscuity 0
vlan protocol 802.1Q id 300 <REORDER_HDR>
15: elag0.25@lag0: <BROADCAST,MULTICAST> mtu 1400 qdisc noop state DOWN mode DEFAULT group default
link/ether 12:12:12:12:12:18 brd ff:ff:ff:ff:ff:ff promiscuity 0
vlan protocol 802.1ad id 25 <REORDER_HDR>

I have just checked it on a clean docker container running the latest ubuntu 14:04
and the same thing happens.

I would really appreciate if you check it out,
Thanks in advance.

Yep, sure. Thanks for the feedback. I'm checking it right now, and I believe we fix it soon.

I would expect no surprises as it is x86_64, but obviously something goes not as expected.

Thanks again for the bug record.

I still can not reproduce it on Ubuntu LTS 16.04

Could you please try to run the script attached (creates interfaces, requires CAP_NET_ADMIN)?

It should print something like that:

$ sudo python qinq.py 
qtest.50
	34984
qtest.50.120
	33024

qinq.zip