Soluciones MPLS con GNU/Linux

Buenas!

Volvemos a nuestro querido mundo del networking, sobre la potencia absoluta que nos dan los entornos GNU/Linux y que tanta pasi√≥n nos despierta ūüėČ

Esta vez queremos comentar una de las principales novedades del kernel 4.3¬†que nos interesan mucho: el soporte de lo que se conoce como ¬ęlight weight tunnels¬Ľ¬†¬†(lwtunnel), en concreto, en el √°rea MPLS, que es la que nos interesa describir en este post.

Antes de esta release del Kernel, hubo un intento importante por parte de¬†Igor Maravińá, publicado en Github¬†junto con las herramientas de user space necesarias (principalmente: iproute2 parcheado¬†para soportar MPLS), se trat√≥ en la lista NETDEV del Kernel, y, posteriormente est√° muy comentado, casi de forma recurrente en lista de Quagga DEV.

MPLS en sí

El protocolo MPLS, en muchos casos considerado como de capa ¬ę2.5¬Ľ, se podr√≠a decir que es ¬†como un MUST BE en toda red grande, sobre todo ahora que fabricantes como Mikrotik¬†con soporte nativo ¬†MPLS e interoperable en su routerOS¬†venden devices a un precio muy asequible.

Existe m√ļltiples presentaciones coment√°ndolo en detalle, nosotros nos quedamos especialmente con esta presentaci√≥n de¬†Alex Vishnyakov¬†d√≥nde explican desde el punto de vista del ISP las ventajas de tener una red con soporte MPLS; y con esta otra presentaci√≥n resumen, que como intro es m√°s que suficiente.

Lo que nos aplica en este caso

¬ŅD√≥nde estamos en este post y para qu√©?

En este post no queremos entrar en el detalle de asuntos reservados ISP’s y/o carriers de tr√°nsito o similares con complejas t√©cnicas de Traffic Engineering. Nos centraremos exclusivamente en su soporte reciente nativo en Linux as√≠ como en alguna posibilidad moderna, de estas que nos gustan ;).

Principalmente hablamos desde la perspectiva de alguien que no es ¬ęNetwork Owner¬Ľ y que se construye su infraestructura con ingenier√≠as de routing sobre t√ļneles, mezclando ¬ęclouds¬Ľ de operadores e infraestructura propia, algo as√≠ como un Net Power User ūüôā (o un net cowboy obligado ūüėČ ).

Proof of concept!

Preparando el kernel

La versión mínima que tenemos que disponer es 4.3, Debian Jessie por defecto viene con 3.16. Así que tenemos dos opciones:

Si optamos por la compilación manual, debemos asegurarnos que al menos estas opciones están activadas (al hacer el clásico y casi olvidado ya make menuconfig): lwtunnel, mpls-iptunnel, mpls-gso y finalmente mpls-router.

Una vez descomprimido el fuente, ejecutado el make menuconfig, podemos crear paquetes DEB para instalarlos cómodamente:

fakeroot make-kpkg --initrd --revision=XXX.MPLS kernel_image

(podemos a√Īadir opciones -j para compilaci√≥n paralela).

Tras bootear con el new kernel podemos cargar mpls_router por ejemplo y ver:

root@zgor-mpls-02:~# lsmod | grep mpls
mpls_iptunnel          16384  0 
mpls_gso               16384  0 
mpls_router            24576  1 mpls_iptunnel

Este nuevo kernel nos expone un interface en /proc, siendo /proc/sys/net/mpls/conf/ dónde se define la activación o no global por interface.

 

Herramients de user space

Principalmente, necesitamos iproute2 con soporte MPLS para poder realizar configuraciones, descargable por ejemplo aquí.

La compilación no tiene misterior (./configure;make && make install).

Una vez instalado, vemos que ejecutando directamente ¬ęip¬Ľ obtenemos ya un output indicando soporte mpls:

Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns | l2tp | fou | tcp_metrics | token | netconf }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec |
                    -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}

y podemos, igualmente ejecutar por ejemplo:

ip -f mpls route show

d√≥nde ¬ę-f mpls¬Ľ es de address family MPLS, ni IPV4 ni IPV6, MPLS! Bienvenidos al mundo de los labels!

Ni routing por origen ni destino, decisi√≥n/¬Ľswitching¬Ľ por etiquetas ūüėČ

Hello World MPLS

De cara a tener un esquema mínimo de prueba, necesitamos al menos:

  • Ingress node (LER label edge router): Equipo que recibe tr√°fico y lo re-encamina hacia la red MPLS, encapsulado en MPLS.
  • Egress node (LER tambi√©n): Equipo recibe tr√°fico encapsulado en MPLS y finalmente elimina la parte MPLS y hace el delivery.

Es decir, partimos de un primer ejemplo sin tr√°nsito ni nada MPLS, casi que punto a punto y fin.

Para comenzar con este despliegue, la base, tan sencilla como:

esquema_helloworld

Es decir, un par de hosts conectados en una red cualquiera, con una direcci√≥n de loop a√Īadida (que hacemos se parezca a su NIC eth0 para que sea m√°s f√°cil verlo):

MPLS01:

root@zgor-mpls-01:~# ip address add dev lo 192.168.10.187/32

MPLS02:

root@zgor-mpls-02:~# ip address add dev lo 192.168.10.152/32

Con esto tenemos las loopbacks ready.

Para realizar el envío de tráfico MPLS Encapsulated:

MPLS01

root@zgor-mpls-01:~# ip route add 192.168.10.152/32 encap mpls 101 via 10.10.0.152

MPLS02:

root@zgor-mpls-02:~# ip route add 192.168.10.187/32 encap mpls 101 via 10.10.0.187

 

Llegados a este punto, podríamos intentar pingar, peroooo:

root@zgor-mpls-01:~# ping -I 192.168.10.187 192.168.10.152
PING 192.168.10.152 (192.168.10.152) from 192.168.10.187 : 56(84) bytes of data.
^C
--- 192.168.10.152 ping statistics ---
9 packets transmitted, 0 received, 100% packet loss, time 8022ms

Peroooooooooooooooooooo ¬ŅPorqu√© no llegan?!!!

Si capturamos tr√°fico, vemos el ICMP:

icmp

 

Entrando en detalle vemos:
layer25

Efectivamente! Se trata de un paquete ICMP, pero tiene un layer adicional entre l2(frame ethernet) y l3(ip), de ahí que mucha gente lo llame protocolo 2.5

¬ŅEntonces porque no llegan?¬†No llegan porque hace falta realizar la salida ! El LER final tiene que desencapsular !

Por tanto, como queremos que funcione tanto en ida como en vuelta:

MPLS01:

root@zgor-mpls-01:~# ip -f mpls route add 101 dev lo

MPLS02:

root@zgor-mpls-02:~# ip -f mpls route add 101 dev lo

Y finalmente:

root@zgor-mpls-01:~# ping -I 192.168.10.187 192.168.10.152
PING 192.168.10.152 (192.168.10.152) from 192.168.10.187 : 56(84) bytes of data.
64 bytes from 192.168.10.152: icmp_seq=1 ttl=63 time=0.577 ms
64 bytes from 192.168.10.152: icmp_seq=2 ttl=63 time=0.654 ms
64 bytes from 192.168.10.152: icmp_seq=3 ttl=63 time=0.636 ms
^C
--- 192.168.10.152 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.577/0.622/0.654/0.038 ms

 

Encaminando tr√°fico

En el lado de GNU/Linux, actuar como un LSR (Label Switch Router) es pr√°cticamente igual de sencillo que un LER:

ip -f mpls route add XXXX as YYY via inet 192.168.2.2

Dónde:

 

  • X es la etiqueta recibida
  • Y es la etiqueta sobre-escrita
  • 192.168.2.2 (ejemplo) es el nexthop al que mandar los paquetes MPLS recibidos con la etiqueta X y que ser√°n re-enviados con la etiqueta Y.

Y ya est√°! Con esto ya hemos transformado nuestra linux box en un LSR ūüôā

Transportando MPLS over OpenVPN !

¬ŅPor qu√© alguien puede querer hacer esto ? ūüėČ

Generalmente, como coment√°bamos al principio, MPLS est√° presente en las redes grandes y/o de ISPS’s, en las que finalmente se ha acabando transportando ATM over IP y caminos semejantes. Bajo la perspectiva de empresas usuarias de redes, salvo acuerdos de integraci√≥n en MPLS de ISP’s que act√ļen tb como Hoster’s y tengamos m√°quinas ah√≠ que querer integrar de una forma muy espec√≠fica, no parecen presentarse muchos casos de uso claros.¬†Uno que si vemos muy probable es el de interconnecting entre los diversos clouds, transportando MPLS over OpenVPN y siendo por tanto agn√≥sticos a lo que haya por de bajo, direccionamiento incluido ūüôā As√≠ podemos hacer uso interno de las bondades de cada tipo de cloud, o, si se da el caso y por tipos de proyecto/legislaci√≥n/X tenemos que estar si o si principalmente en una ūüėČ

esquema_multinube

Fight!

De cara a realizar el escenario mínimo de proof of concept, nos planteamos:

esquema_mplsopenvpn (1)

Lo que es la configuración:

MPLS01

# Activamos MPLS en eth0:
echo 1 > /proc/sys/net/mpls/conf/eth0/input

# Informamos al kernel de que 10.200.200.2 es via 10.10.0.152 con encapsulación MPLS (LABEL100)
ip route add 10.200.200.2/32 encap mpls 100 via 10.10.0.152 dev eth0

# Informamos al kernel que label 200 lo tiene que desencapsular y entregarlo en el device LO:
ip -f mpls route add 200 dev lo

MPLS02

Siendo ¬ęVPN¬Ľ el iface OpenVPN (importante, tiene que ser ‘tap’, no ‘tun’).

# Activamos MPLS en eth0 y VPN:
echo 1 > /proc/sys/net/mpls/conf/eth0/input
echo 1 > /proc/sys/net/mpls/conf/vpn/input

# Los paquetes MPLS con label 100 los encaminamos via 10.96.96.1 (extremo VPN (MPLS03))
ip -f mpls route add 100 as 100 via inet 10.10.0.122

# Los paquetes MPLS con label 200 los mandamos hacia MPLS01
ip -f mpls route add 200 as 200 via inet 10.10.0.187

MPLS03

# Activamos MPLS en eth0 y VPN:
echo 1 > /proc/sys/net/mpls/conf/eth0/input
echo 1 > /proc/sys/net/mpls/conf/vpn/input

# Los paquetes MPLS con label 100 los encaminamos via 10.96.96.1 (extremo VPN (MPLS04))
ip -f mpls route add 100 as 100 via inet 10.10.0.172

# Los paquetes MPLS con label 200 los mandamos hacia MPLS02
ip -f mpls route add 200 as 200 via inet 10.96.96.2

MPLS04

# Activamos MPLS en eth0:
echo 1 > /proc/sys/net/mpls/conf/eth0/input

# Informamos al kernel de que 192.168.10.152 es via 10.10.0.152 con encapsulación MPLS (LABEL100)
ip route add 10.200.200.1/32 encap mpls 200 via 10.10.0.122 dev eth0

# Informamos al kernel que label 200 lo tiene que desencapsular y entregarlo en el device LO:
ip -f mpls route add 100 dev lo

Una vez llegados a este punto, si pingamos desde MPLS04 con su origen loopback (el que usamos para MPLS):

root@zgor-mpls-04:~# ping -I 10.200.200.2 10.200.200.1
PING 10.200.200.1 (10.200.200.1) from 10.200.200.2 : 56(84) bytes of data.
64 bytes from 10.200.200.1: icmp_seq=1 ttl=61 time=1.69 ms

¬ŅPero, est√° realmente viajando por el interface VPN? Basta con capturar en MPLS02 por ejemplo:

root@zgor-mpls-02:~# tcpdump -n -v -i vpn
tcpdump: listening on vpn, link-type EN10MB (Ethernet), capture size 262144 bytes
16:41:22.911437 MPLS (label 200, exp 0, [S], ttl 63)
	IP (tos 0x0, ttl 64, id 6258, offset 0, flags [DF], proto ICMP (1), length 84)
    10.200.200.2 > 10.200.200.1: ICMP echo request, id 25860, seq 14, length 64
16:41:22.912246 MPLS (label 100, exp 0, [S], ttl 63)
	IP (tos 0x0, ttl 64, id 46459, offset 0, flags [none], proto ICMP (1), length 84)
    10.200.200.1 > 10.200.200.2: ICMP echo reply, id 25860, seq 14, length 64

 

Despedida y cierre!

Realmente, nos ha quedado un micro-post esta vez ūüôā La verdad es que de MPLS se puede hablar un rato largo y hay muchos mas ingredientes a meter en la cazuela: ¬ŅRouting din√°mico? Existe este¬†¬†Quagga de Renato Westphal¬† ¬†disponible con soporte LDPD. ¬†¬ŅInteroperabilidad? Con la facilidad que da RouterOS de ser instalado en una MV, montar un escenario piloto es realmente trivial.

Nada m√°s por el momento! Que teng√°is un buen inicio de verano!



¬ŅTe gusta este post? Es solo un ejemplo de c√≥mo podemos ayudar a tu empresa...
Sobre Gorka Gorrotxategi

CTO en Irontec, en el frente técnico desde un par de lustros ya, para todo lo que tenga que ver con Networking, VoIP y Sistemas, en ese orden :D) Desde @zetagor escribo algo, pero poco verbose la verdad

1 Comentario

¬ŅPor qu√© no comentas t√ļ tambi√©n?


  • Muy interesante lo de los MPLS, donde se pueden conseguir m√°s informaci√≥n al respecto, principalmente sobre aplicaciones concretas de esta.
    Gracias

    Tuanity Hace 7 a√Īos Responde


  • Excelente informacion , habras probado la parte interoperatividad ?

    Norman Hace 7 a√Īos Responde


  • Buenas Norman,

    Pues sinceramente, lo empezamos a montar, se monta f√°cil un entorno de test con Mikrotik-RouterOS, permiten descargar un IMG que en KVM(Proxmox, …) arranca f√°cilmente y puedes por tanto conectarle ifaces contra bridges virtuales con VM’s con MPLS Linux y tal. Lo dejamos montado, pero no acabamos de aterrizarlo, saltamos a otros frentes variopintos ūüėČ

    Gorka Gorrotxategi Hace 7 a√Īos Responde


  • Me podr√≠an ayudar, cada vez que intento hacer el encaminamiento recibo este error:
    RTNETLINK answers: Invalid argument

    Jose Luciano Hace 6 a√Īos Responde


  • Hola, muy bueno el post. He seguido todos los pasos pero me pasa que el ping no se me responde. Puedo notar que el ping llega al destino, pero este no responde el ping

    Rafael Hace 6 a√Īos Responde


Queremos tu opinión :)