19 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

4 comments:

Reggie P. said...

Nice and concise tutorial! Thanks for posting.

troy said...

Reggie P.,

I'm glad it was useful.

--troy

Anonymous said...

Hi Troy,

I am playing with Vlan configuration on CentOS 6.4

I have 2 interfaces, eth0 and eth1.

I have configured 2 VLAN interfaces eth0.20 and eth0.30 as

#file: ifcfg-eth0.20
#-------------

VLAN=yes
DEVICE=eth0.20
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR=192.168.20.1
GATEWAY=192.168.20.1
NETMASK=255.255.255.0
USERCTL=no


#file: ifcfg-eth0.30
#-------------
VLAN=yes
DEVICE=eth0.30
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR=192.168.30.1
GATEWAY=192.168.30.1
NETMASK=255.255.255.0
USERCTL=no

ifcfg-eth0 configuration is as mentioned in this post.

Then connected a desktop to interface eth0 port using LAN cable and assigned 192.168.30.2/24 IP.

When I try to ping 192.168.30.1 from 192.168.30.2 machine, It shows destination host unreachable. I am also not able to ping 192.168.30.2 from 192.168.30.1.

However ping -I eth0 192.168.30.2 works fine.

Please let me know how can I get the ping working from 192.168.30.1 to 192.168.30.2?

Any help in this regard will be very helpful.

Thank You,
Prasad

troy said...

Anonymous,

My first question would be whether iptables is configured (or some other packet filter) and if so, if there is a rule that is otherwise prohibiting ICMP. My next question is how eth0 and the rest of the other interfaces (if any) are configured, followed by what the routing table looks like. The only other thing I can say, just based on your currently presented configuration, is that "GATEWAY" is unnecessary here, especially if you are only using it for vlan local communication. Let me know if I can be of further assistance.

--troy