Configure an Ethernet interface as a QinQ VLAN trunk
To configure an Ethernet interface as an IEEE 802.1ad (QinQ) VLAN trunk.
802.1ad is a protocol for carrying VLAN traffic on an Ethernet. It is based upon 802.1Q, but allows for VLANs to be nested by adding two tags to each frame instead of one (a technique commonly known as VLAN stacking or Q-in-Q). This is useful when a network service provider and users of that service both wish to use VLANs. It also makes it possible to have more than the 4094 separate VLANs allowed by 802.1Q.
There are three ways in which a machine can be connected to a network carrying double-tagged 802.1ad traffic:
- via a untagged port, where both inner and outer VLANs are handled by the switch or switches (so the attached machine sees ordinary Ethernet frames);
- via a single-tagged (tunnel) port, where the outer VLAN only is handled by the switch (so the attached machine sees single-tagged 802.1Q VLAN frames); or
- via a double-tagged (trunk) port, where both inner and outer VLANs are handled by the attached machine (which sees double-tagged 802.1ad VLAN frames).
The advantage of a trunk or tunnel port is that it allows multiple VLANs to be carried by a single physical bearer. The disadvantage is that the machine in question must support the relevant VLAN protocol and be configured to use it. Typical practice is to use a tunnel or trunk for machines that need to talk to multiple VLANs and untagged ports for everything else. These instructions are applicable when you want to attach a Linux-based system to a double-tagged trunk port.
VLANs are numbered from 1 to 4094 inclusive (the values 0 and 4095 are reserved). Some manufacturers (including Cisco) additionally recommend that VLAN 1 be reserved for management purposes. When VLANs are nested using 802.1ad, the outer VLAN is known as the Service VLAN (S-VLAN) and the inner one the customer VLAN (C-VLAN). Physically, the S-VLAN tag appears first in the Ethernet frame and the C-VLAN tag second.
A standard implementation of 802.1ad uses EtherTypes of 0x8100 and 0x88a8 for the inner and outer VLANs respectively, however there are extant pre-standard QinQ implementations which use a different EtherType for the outer VLAN. Common choices are 0x8100 (the same as the inner VLAN) and 0x9100 (with the option of using 0x9200 if triple tagging is needed). At the time of writing Linux was able to support 0x88a8 or 0x8100 as the outer tag, but not 0x9100 or 0x9200.
Suppose you have a physical server which provides hosting for a number of virtual machines. The physical server has an Ethernet interface named
eth0 which is connected to an 802.1ad VLAN trunk which uses two levels of tagging. Each virtual machine has one or more virtual Ethernet interfaces which you want to bridge to particular VLANs carried by the trunk.
In order to attach a VLAN to a bridge you must first create a network interface corresponding to that VLAN. In the first instance you wish to do this for customer VLAN 371 inside service VLAN 24.
Support for 802.1Q on Linux-based systems is provided by the
8021q kernel module. As of kernel version 3.10 (released in June 2013), this includes support for 802.1ad. Single-tagged 802.1Q VLANs can be configured using the
vconfig command, but this does not support 802.1ad. The method described here therefore uses the
ip link command instead, which supports both 802.1Q and 802.1ad.
By itself a single
ip link command can remove only a single layer of tagging. Two such commands are therefore needed if there are two tags to be removed. The full procedure is as follows:
- Select the required service VLAN (S-VID = 24) from the service VLAN trunk (
eth0) and present this as a new network interface (named
eth0.24in this example).
- Select the required customer VLAN (C-VID = 371) from the customer VLAN trunk (
eth0.24) and present this as a second new network interface (named
eth0.24.371in this example).
- Ensure that both of the trunk interfaces (
eth0.24) are up.
The new interfaces have been named here after the VLAN or VLANs to which they refer. You are not required to follow this naming scheme, and can call the interfaces whatever you wish, however there are obvious benefits in using names which carry some useful meaning.
Be aware that this configuration method is non-persistent. If you need it to be applied automatically at boot time then you will need to make your own arrangements for that (which will depend on the particular GNU/Linux distribution you are using). The support provided for persistent 802.1Q VLANs on Debian-based systems (using
/etc/network/interfaces) did not extend to 802.1ad at the time of writing.
You want to select VLAN 24 from interface
eth0 and present it as
eth0.24. This can be achieved using the following command:
ip link add link eth0 eth0.24 type vlan proto 802.1ad id 24
By default, the
type vlan argument would create an 802.1Q VLAN tagged using an EtherType of 0x8100.
proto 802.1ad argument overrides this, causing the VLAN to be tagged using an EtherType of 0x88a8 (which is correct for a service VLAN).
You want to select VLAN 371 from interface
eth0.24 and present it as
eth0.24.371. This can be achieved using the following command:
ip link add link eth0.24 eth0.24.371 type vlan proto 802.1Q id 371
proto 802.1Q argument can be omitted, since this type of VLAN is the default, but it has been included here in the interests of clarity. The documentation is not clear as to whether an upper- or lower-case Q is preferred, but either will work. The resulting VLAN will be tagged using an EtherType of 0x8100 (which is correct for a customer VLAN).
A network interface must be in the up state for it to send or receive any data. Usually this is something which would happen as a routine part of putting the interface to use (for example, giving it an IP address), and for this reason you will probably not need to take any special action in respect of the interface used to present the VLAN (
eth0.24.371). However, activation of this interface does not automatically activate the trunk interfaces, so you will need to attend to these separately if any traffic is to pass.
Interfaces can be brought up using
ip link. Since the latter was used when creating the VLAN, it will also be used here. The required commands are:
ip link set eth0 up ip link set eth0.24 up
The full sequence of commands is:
ip link add link eth0 eth0.24 type vlan proto 802.1ad id 24 ip link add link eth0.24 eth0.24.371 type vlan proto 802.1Q id 371 ip link set eth0 up ip link set eth0.24 up
You can change the EtherType of the outer VLAN to 0x8100 using the obvious method:
ip link add link eth0 eth0.24 type vlan proto 802.1Q id 24 ip link add link eth0.24 eth0.24.371 type vlan proto 802.1Q id 371
As noted above, Linux did not support EtherType of 0x9100 or 0x9200 at the time of writing (kernel version 3.16.3).