VLAN con GNU/Linux

per Victor Carceler darrera modificació 2020-04-02T12:53:41+02:00
Las Virtual LAN permiten fraccionar un switch físico en varios switches virtuales, lo que permite configurar una estructura de red lógica con independencia de ciertos parámetros físicos. El standar 802.1q está plenamente soportado por GNU/Linux.

Introducción

Una red de área local suele estar compuesta por uno o varios conmutadores. Hace tiempo que los concentradores han dejado de ser elementos de construcción de las LANs. Cuando se utilizaban, fragmentar el dominio de colisión de la LAN era con frecuencia un objetivo a alcanzar para mejorar el rendimiento de la red. Actualmente las VLANs se utilizan para fragmentar el dominio de difusión y conseguir una configuración de red lógica independiente del cableado físico.

Es posible dividir una LAN formada por muchos conmutadores en diferentes VLAN que se comportan como pequeñas LANs independientes. Si en algún momento es necesario trasladar un equipo de una estancia a otra, se puede reconfigurar la VLAN para que el equipo siga estando en la misma VLAN independientemente de que ahora se encuentre conectado a un conmutador diferente. Todo ello sin hacer cambios en el cableado físico.

Los equipos de red que pueden trabajar con VLANs soportan el estandar IEEE802.1Q. Además, algunos equipos también son capaces de trabajar con los protocolos propietarios ISL de Cisco o VLT de 3Com, pero estos protocolos han perdido vigencia en favor de 802.1Q.

Funcionamiento del estandar IEEE802.1Q

Cuando un conmutador soporta el protocolo 802.1Q es posible definir diferentes VLANs. Cada VLAN está identificada por un número entero comprendido entre 1 y 4095, además cada VLAN podrá tener una cadena descriptiva. Los identificadores numéricos de las VLANs tienen validez en toda la red de conmutadores.

Inicialmente la configuración de un conmutador sólo define una VLAN (con id 1) que se extiende a todos los puertos. A través de la interfaz de administración es posible definir nuevas VLANs. Si por ejemplo, en un conmutador de 24 puertos se define la VLAN 2 y se incluyen en dicha VLAN los puertos [21-24] nos encontraremos con que el conmutador se comportará como dos conmutadores virtuales:

  • Un conmutador virtual con los puertos [1-20] en la VLAN 1
  • Un conmutador virtual con los puertos [21-24] en la VLAN 2

Cuando los puertos sólo se encuentran en una VLAN el conmutador no necesita modificar las tramas, pues nunca hay ambiguedad.

En el ejemplo anterior el tráfico de los cuatro últimos puertos no se mezcla con el tráfico del resto de puertos. Si la configuración anterior se aplica a dos conmutadores físicos (A y B), y ambos conmutadores se conectan utilizando dos cables (uno conectando el puerto 1 de ambos conmutadores y otro conectando el puerto 24 de ambos conmutadores) se habrá conseguido que los equipos de la VLAN 1 se puedan comunicar entre sí (ocurrirá lo mismo para la VLAN 2) independientemente de que se encuentren conectados a A o B.

Cuando en un puerto no se modifican las tramas se dice que es un puerto sin etiquetar (untagged).

Trunking y puertos etiquetados:

En el ejemplo anterior, dos VLAN y dos conmutadores físicos, se han utilizado dos enlaces, uno para cada VLAN, para asegurar la conexión. Cada enlace es independiente, de manera que al retirar el latiguillo que conecta el primer puerto de A con B se pierde la conexión entre las estaciones de la VLAN 1 conectadas a A y las de B (las estaciones de la VLAN 2 seguirán estando conectadas entre sí). En ocasiones puede ser deseable conectar todas las VLANs de dos conmutadores con un solo enlace.

Cuando un enlace transporta tráfico perteneciente a varias VLANs se está haciendo trunking. En este caso es necesario modificar todas las tramas que transporta el enlace, agregando una etiqueta, para poder identificar la VLAN a la que pertenece la trama. Cuando un puerto pertenece a varias VLANs se dice que es un puerto etiquetado (tagged).

El estandar 802.1Q define etiquetas de 4 bytes que se añaden a la cabecera de las tramas que se transmiten por un puerto etiquetado. De esta forma, cuando llega al conmutador de destino este sabe por qué puertos la debe propagar. Cuando se propague por un puerto no etiquetado se eliminará la etiqueta de 4 bytes y la trama recuperará su formato original.

Normalmente las estaciones de red están conectadas a puertos no etiquetados del conmutador, sólo se utilizan los puertos etiquetados para los enlaces trunk entre dos conmutadores. Pero en ocasiones, cuando un servidor que sólo tiene un adaptador de red físico debe estar conectado a diferentes VLANs es posible conectar el servidor a un puerto etiquetado del conmutador. De este modo, si en el adaptador de red del servidor se configuran VLANs, se habrá conseguido la misma topologia de red que se hubiese conseguido con varios adaptadores de red físicos por una fracción de su coste. Evidentemente el SO del servidor ha de soportar 802.1Q, lo que no es ningún problema para GNU/Linux.

RESUMIENDO:

  1. Un puerto no etiquetado sólo puede pertenecer a una VLAN, no existe ambiguedad sobre el tráfico que se envia/recibe.
  2. Un puerto que pertenece a varias VLANs es un puerto etiquetado. En este caso es necesario añadir una etiqueta de 4 bytes a cada trama.
  3. En un puerto no etiquetado se puede conectar cualquier host.
  4. En un puerto etiquetado se debe conectar un host con soporte para VLANs.

VLANs con 802.1Q en GNU/Linux

Hace tiempo que el núcleo Linux incluye soporte para 802.1Q, de hecho si está utilizando el nucleo precompilado de cualquier distribución de GNU/Linux muy probablemente este soporte esté incluido.

La herramienta de usuario para el administrador es vconfig y se encuentra en el paquete vlan-utils en el caso de Mandriva o vlan en el caso de Debian y derivados. Una vez instalado, y cargado el modulo 8021q si fuese necesario, es posible utilizar vconfig para crear adaptadores de red virtuales conectados a diferentes VLANs.

Así, por ejemplo podemos crear un adaptador de red virtual para eth0 que estará conectado a la VLAN 2:

[root@localhost network-scripts]# modprobe 8021q
[root@localhost network-scripts]# vconfig
Expecting argc to be 3-5, inclusive. Was: 1

Usage: add [interface-name] [vlan_id]
rem [vlan-name]
set_flag [interface-name] [flag-num] [0 | 1]
set_egress_map [vlan-name] [skb_priority] [vlan_qos]
set_ingress_map [vlan-name] [skb_priority] [vlan_qos]
set_name_type [name-type]

* The [interface-name] is the name of the ethernet card that hosts
the VLAN you are talking about.
* The vlan_id is the identifier (0-4095) of the VLAN you are operating on.
* skb_priority is the priority in the socket buffer (sk_buff).
* vlan_qos is the 3 bit priority in the VLAN header
* name-type: VLAN_PLUS_VID (vlan0005), VLAN_PLUS_VID_NO_PAD (vlan5),
DEV_PLUS_VID (eth0.0005), DEV_PLUS_VID_NO_PAD (eth0.5)
* bind-type: PER_DEVICE # Allows vlan 5 on eth0 and eth1 to be unique.
PER_KERNEL # Forces vlan 5 to be unique across all devices.
* FLAGS: 1 REORDER_HDR When this is set, the VLAN device will move the
ethernet header around to make it look exactly like a real
ethernet device. This may help programs such as DHCPd which
read the raw ethernet packet and make assumptions about the
location of bytes. If you don't need it, don't turn it on, because
there will be at least a small performance degradation. Default
is OFF.
[root@localhost network-scripts]# vconfig add eth0 2
Added VLAN with VID == 2 to IF -:eth0:-
[root@localhost network-scripts]# ifconfig eth0.2 192.168.20.20 up
[root@localhost network-scripts]# ifconfig eth0.2
eth0.2 Link encap:Ethernet HWaddr 00:C0:26:27:0B:D8
inet addr:192.168.20.20 Bcast:192.168.20.255 Mask:255.255.255.0
inet6 addr: fe80::2c0:26ff:fe27:bd8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:1494 (1.4 KiB)

[root@localhost network-scripts]#

La notación por defecto supone que el adaptador de red virtual tendrá el nombre del adaptador de red físico con sufijo ".id_vlan" (por ejemplo, eth0.2 es el adaptador virtual de eth0 que está en la VLAN 2). A partir de este punto, el adaptador de red virtual se puede utilizar como cualquier otra targeta de red. Por ejemplo se puede configurar su dirección de red con el comando ifconfig.

Incluso es posible definir alias sobre la interfaz virtual:

[root@localhost network-scripts]# ifconfig eth0.2:0 192.168.20.21 up
[root@localhost network-scripts]# ifconfig
br0 Link encap:Ethernet HWaddr 00:00:00:00:00:00
inet6 addr: fe80::200:ff:fe00:0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:4140 (4.0 KiB)

eth0 Link encap:Ethernet HWaddr 00:C0:26:27:0B:D8
inet addr:192.168.100.101 Bcast:192.168.100.255 Mask:255.255.255.0
inet6 addr: fe80::2c0:26ff:fe27:bd8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4805 errors:0 dropped:0 overruns:0 frame:0
TX packets:9140 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3171548 (3.0 MiB) TX bytes:1196180 (1.1 MiB)
Interrupt:11 Base address:0xc000

eth0.2 Link encap:Ethernet HWaddr 00:C0:26:27:0B:D8
inet addr:192.168.20.20 Bcast:192.168.20.255 Mask:255.255.255.0
inet6 addr: fe80::2c0:26ff:fe27:bd8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:25 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:3995 (3.9 KiB)

eth0.2:0 Link encap:Ethernet HWaddr 00:C0:26:27:0B:D8
inet addr:192.168.20.21 Bcast:192.168.20.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1


eth1 Link encap:Ethernet HWaddr 00:90:D1:06:60:87
inet6 addr: fe80::290:d1ff:fe06:6087/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 b) TX bytes:2628 (2.5 KiB)
Interrupt:10 Base address:0xec00

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:1544 errors:0 dropped:0 overruns:0 frame:0
TX packets:1544 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:85904 (83.8 KiB) TX bytes:85904 (83.8 KiB)

[root@localhost network-scripts]#

Problemas con la MTU

Prácticamente la única cuestión que puede dar problemas al utilizar VLANs es la MTU. Puesto que los paquetes etiquetados crecen en 4 bytes, es posible que con algunos drivers con bugs, la fragmentación del tráfico no funcione de la manera esperada. Lo que puede crear conexiones que no tengan problema con paquetes pequeños pero se nieguen a transmitir paquetes grandes.

Para detectar este problema es posible utilizar el comando ping con la opción -s que permite indicar el tamaño del paquete a transmitir. Debe comprobarse la comunicación en los dos sentidos, y si se observa que por ejemplo no hay ningún problema con paquetes pequeños pero con paquetes de 1700Bytes o más si hay problemas debe reducirse la MTU de la interfaz. Un tamaño razonable de MTU es 1400 bytes.

Configurando las VLANs en cada arranque

En un servidor evidentemente querrá que las VLANs se configuren automáticamente cada vez que se reinicien las interficies de red. Para ello es necesario hacer uso de los scripts de arranque que utiliza su distribución. Por ejemplo, en el caso de Mandriva en el directorio /etc/sysconfig/network-scripts se incluyen los scripts que controlan los diferentes adaptadores de red sean físicos o virtuales.

Listado de /etc/sysconfig/network-scripts en Valinor:

  ,           ,
/ \ Welcome to Valinor
((__-^^-,-^^-__))
`-_---' `---_-' Free software for a free society
`--|o` 'o|--' do you want to be free ?
\ ` /
): :( valinor.iespuigcastellar.xeill.net
:o_o:
"-"
[vcarceler@valinor ~]$ cd /etc/sysconfig/network-scripts/
[vcarceler@valinor network-scripts]$ ls
hostname.d/ ifcfg-lo@ ifdown.d/ ifdown-sit* ifup.d/ ifup-plusb* ifup-sit* network-functions
ifcfg-eth0* ifcfg-sit0* ifdown-ipv6* ifdown-sl* ifup-ipv6* ifup-post* ifup-sl* network-functions-ipv6
ifcfg-eth0.1* ifdown@ ifdown-post* ifup@ ifup-ipx* ifup-ppp* ifup-wireless* wireless.d/
ifcfg-eth0.14* ifdown-aliases* ifdown-ppp* ifup-aliases* ifup-plip* ifup-routes* init.ipv6-global*
[vcarceler@valinor network-scripts]$


El contenido de los ficheros que configuran eth0.1 y eth0.14 es:

ifcfg-eth0.1 ifcfg-eth0.14
DEVICE=eth0.1
BOOTPROTO=static
IPADDR=192.168.0.6
NETMASK=255.255.255.0
NETWORK=192.168.0.0
BROADCAST=192.168.0.255
ONBOOT=yes
METRIC=10
MII_NOT_SUPPORTED=no
USERCTL=no
IPV6INIT=no
IPV6TO4INIT=no
PEERDNS=yes
DEVICE=eth0.14
BOOTPROTO=static
IPADDR=192.168.14.6
NETMASK=255.255.255.0
NETWORK=192.168.14.0
BROADCAST=192.168.14.255
ONBOOT=yes
MII_NOT_SUPPORTED=yes
PEERDNS=yes
 

En Galadriel es posible encontrar más ejemplos:

ifcfg-eth0.1 ifcfg-eth0.1:0 ifcfg-eth0.14
BOOTPROTO=static
DEVICE=eth0.1
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
IPADDR=192.168.0.8
NETWORK=192.168.0.0
ONBOOT=yes
PEERDNS=yes
MTU="1400"
BOOTPROTO=static
DEVICE=eth0.1:0
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
IPADDR=192.168.0.5
NETWORK=192.168.0.0
ONBOOT=yes
PEERDNS=yes
MTU="1400"
BOOTPROTO=static
DEVICE=eth0.14
NETMASK=255.255.255.0
BROADCAST=192.168.14.255
IPADDR=192.168.14.8
NETWORK=192.168.14.0
ONBOOT=yes
MTU="1400"

Más información: