18 November 2010

VLAN Tagged Interfaces (Linux)

A while back, I wrote on how to setup VLAN tagged interfaces on Solaris
and FreeBSD.  Though I've also needed to set them up under Linux, I
never seemed to get around to writing up how to do so.  To remedy this,
the following are our setup details:
        HOST:           tux
        PROMPT:         tux [0]
        LINUX DISTRO:   CentOS 5.4 (Red Hat EL clone)
        INTERFACE:      eth0
        VLANs:          487 (7.7.4.0/23), 519 (10.19.3.0/24)
To get started, VLAN tagging (802.1q trunking) has been supported by Linux
for a while, first as a patch, then included in the kernel since 2.4.14.
Given that the following details the setup on CentOS 5.4, the specifics
for config retention through a reboot may be different for other distros.
The command line syntax should be about the same, though.  To ensure
that the Linux kernel supports VLAN tagging, check for the kernel module
(8021q), and if necessary, load it:
        tux [0] /sbin/lsmod | /bin/grep 8021q
        tux [1] /sbin/modprobe 8021q
        tux [0] /sbin/lsmod | /bin/grep 8021q
        8021q                  24649  0
In the above, since the first 'lsmod' didn't report the 8021q module,
we had loaded it via 'modprobe' and the second 'lsmod' verifies such.
It isn't explicitly necessary to load the module as configuration of
a VLAN tagged interface should take care of it.  The purpose above is
to simply identify kernel support for 802.1q trunking.  Assuming that the
network switch port that our interface is connected to has already been
configured to support VLAN trunking, we can add a couple of VLANs (487
and 519) to the network interface (eth0) on our host (tux):
        tux [0] /sbin/vconfig add eth0 487
        ERROR: trying to add VLAN #487 to IF -:eth0:-  error: Invalid argument
The error above is because interface 'eth0' is not up, so we'll need to
try again:
        tux [3] /sbin/ifconfig eth0 up
        tux [0] /sbin/vconfig add eth0 487
        Added VLAN with VID == 487 to IF -:eth0:-
        tux [0] /sbin/vconfig add eth0 519
        Added VLAN with VID == 519 to IF -:eth0:-
Now that the new interfaces are configured, we can identify them in
'ifconfig' output and configure them much like a normal interface:
        tux [0] /sbin/ifconfig -a | /bin/awk '/^eth0/ {print $1}'
        eth0
        eth0.487
        eth0.519
        tux [0] /sbin/ifconfig eth0.487 7.7.4.129 netmask 255.255.254.0 up
        tux [0] /sbin/ifconfig eth0.519 10.19.3.78 netmask 255.255.255.0 up
        tux [0] /sbin/ifconfig -a
        eth0      Link encap:Ethernet  HWaddr 08:00:27:9E:A8:A8
                  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                  RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                  TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
                  collisions:0 txqueuelen:1000
                  RX bytes:0 (0.0 b)  TX bytes:2736 (2.6 KiB)
                  Interrupt:169 Base address:0xd020

        eth0.487  Link encap:Ethernet  HWaddr 08:00:27:9E:A8:A8
                  inet addr:7.7.4.129  Bcast:7.7.5.255  Mask:255.255.254.0
                  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                  RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                  TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
                  collisions:0 txqueuelen:0
                  RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

        eth0.519  Link encap:Ethernet  HWaddr 08:00:27:9E:A8:A8
                  inet addr:10.19.3.78  Bcast:10.19.3.255  Mask:255.255.255.0
                  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                  RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                  TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
                  collisions:0 txqueuelen:0
                  RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
        <snip...>
As seen above, the supporting interface (eth0) doesn't need to be
configured, only brought up in order to support a trunked interface.
As an aside, Linux retains a listing of the VLAN interface name, the VLAN
ID, and the supporting device listed in file '/proc/net/vlan/config'.
Linux also retains various statistics regarding the VLAN interface
name (ex: eth0.487) in unique interface files in the same directory.
The following is a sample of this:
        tux [0] /bin/cat /proc/net/vlan/config
        VLAN Dev name    | VLAN ID
        Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD
        eth0.487       | 487  | eth0
        eth0.519       | 519  | eth0
        tux [0] /bin/cat /proc/net/vlan/eth0.487
        eth0.487  VID: 487       REORDER_HDR: 1  dev->priv_flags: 81
                 total frames received            0
                  total bytes received            0
              Broadcast/Multicast Rcvd            0

              total frames transmitted            0
               total bytes transmitted            0
                    total headroom inc            0
                   total encap on xmit            0
        Device: eth0
        INGRESS priority mappings: 0:0  1:0  2:0  3:0  4:0  5:0  6:0 7:0
        EGRESSS priority Mappings:
The only thing left now is to configure our bootup scripts to retain
our configuration:
        tux [0] cd /etc/sysconfig/network-scripts/
        tux [0] /bin/cat ifcfg-eth0
        # Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
        DEVICE=eth0
        BOOTPROTO=dhcp
        ONBOOT=no
        TYPE=Ethernet
        HWADDR=08:00:27:9e:a8:a8
The config file for 'eth0' gets updated to:
        tux [0] /bin/cat ifcfg-eth0
        DEVICE=eth0
        BOOTPROTO=none
        ONBOOT=yes
        TYPE=Ethernet
        HWADDR=08:00:27:9e:a8:a8
Additionally, after creating 'ifcfg-eth0.487', the contents are:
        tux [0] /bin/cat ifcfg-eth0.487 
        # vlan 487, 7.7.4.0/23 
        DEVICE=eth0.487
        ONBOOT=yes
        TYPE=Ethernet
        IPADDR=7.7.4.129
        NETWORK=7.7.4.0
        NETMASK=255.255.254.0
        BROADCAST=7.7.5.255
        VLAN=yes
And for interface 'eth0.519':
        tux [0] /bin/cat ifcfg-eth0.519
        # vlan 519, 10.19.3.0/24
        DEVICE=eth0.519
        ONBOOT=yes 
        TYPE=Ethernet
        IPADDR=10.19.3.78
        NETWORK=10.19.3.0
        NETMASK=255.255.255.0
        BROADCAST=10.19.3.255
        VLAN=yes