|
|
**INTRODUCCIÓN**
|
|
|
|
|
|
|
|
|
En estos escenarios de ejemplo vamos a arrancar una topología con mininet y un controlador SDN de forma independiente.
|
|
|
|
|
|
En las topologías de mininet usadas hasta ahora, los switches arrancaban en el espacio de nombres raíz, así como el controlador. De esta forma los switches siempre podían conectarse al controlador, a traves de la interfaz de loopback (localhost). El problema es que en escenarios reales los switches no siempre pueden conectarse con el controlador, porque se encuentra en una máquina diferente y para que puedan conectarse con el controlador, la red que les une debe permitirlo.
|
|
|
|
|
|
En ocasiones hay dos infraestructuras de red diferentes entre los switches y el controlador: una para enviar los mensajes del plano de control y que el controlador pueda configurar los flujos OpenFlow en los switchs y otra diferente que usarán los switches para reenviar el tráfico de los usuarios (plano de datos). Sin embargo, esto implica un mayor despliegue ya que debería existir una "red de control" para que los switches puedan comunicarse con el controlador y una "red de datos" para que los switches puedan reenviar el tráfico de datos.
|
|
|
|
|
|
Por este motivo, hay veces que resulta interesante usar la misma red del plano de control para el plano de datos. El problema es que como la configuración la realiza el controlador, es necesario que el switch se conecte con el controlador para que la red, tanto para el plano de control como para el de datos, funcione. Pero ¿cómo se va a conectar el switch con el controlador si la red no funciona?
|
|
|
|
|
|
La idea es partir de una mínima configuración inicial que permita al switch comunicarse con el controlador, para que una vez que se establezca la conexión TCP y se intercambien los mensajes OpenFlow, el controlador pueda definir por completo el comportamiento del switch.
|
|
|
|
|
|
Nosotros vamos a usar un controlador que instalará reglas en los switches que introducen una cabecera adicional llamada NSH (entre la cabecera Ethernet e IP) donde va definido el camino que seguirá el paquete desde el switch al controlador o a la inversa. Este camino es la secuencia de puertos de salida en cada uno de los switches por los que es necesario que atraviese el paquete para llegar al destino. Cada switch que genere un paquete debe añadir esta cabecera y los switches que tengan que reenviar ese paquete consultarán esa cabecera para decidir la interfaz por la que tienen que reenviar ese paquete.
|
|
|
|
|
|
Para poder emular este escenario, haremos que los switches estén ejecutándose en diferentes espacios de nombres, por eso, vamos a crear 'hosts' en mininet que llamaremos: s0, s1, s2, etc que representarán los switches en diferentes espacios de nombres. Para ello, vamos a:
|
|
|
1. Crear un escenario con 'hosts' que representan switches, usando un fichero de topología de mininet;
|
|
|
2. Arrancar el controlador en el switch s0
|
|
|
3. Ejecutar un script que arranque los switches en cada uno de esos espacios de nombres. A partir de ese momento los switches intentarán establecer una conexión TCP con el controlador.
|
|
|
|
|
|
En la carpeta '$HOME/OF-in-band-control-plane/testbed/scenarios_ether/' se encuentra el software que vamos a utilizar. Las diferentes topologías de mininet están a partir de esa carpeta dentro del directorio 'scenarios'. Los scripts generales para crear switches y destruirlos se encuentran en la carpeta 'scripts' y el programa controlador se llama 'InBandController.py'. Echa un vistazo a la carpeta scenarios, donde podrás ver diferentes configuraciones para arrancar namespaces y conectarlos, fíjate que en ninguno se crean switches tal y como mininet los crea. Por eso, es necesario una vez arrancada la topología, ejecutar scripts de arranque que iniciar/parar switches. En cada una de las carpetas que hay en 'scenarios' hay 3 archivos: el escenario de mininet 'scenario_*.py' y después un script para arrancar los switches de ese escenario 'start_scenario_*.sh' y un script para detener los switches 'stop_scenario_*.sh'.
|
|
|
|
|
|
Todos los escenarios están configurados para arrancar diferentes networks namespaces para cada switch llamados 's0', 's1', 's2', etc. En el espacio de nombres 's0' arrancaremos el controlador y el switch raíz. En el resto de los espacios de nombres sólo arrancaremos un switch en cada uno de ellos.
|
|
|
|
|
|
|
|
|
|
|
|
**ESCENARIO ÁRBOL**
|
|
|
|
|
|
|
|
|
Vamos a arrancar un escenario sencillo para probar, el escenario se encuentra definido en el fichero $HOME/OF-in-band-control-plane/testbed/scenarios_ether/scenarios/arbol. En la siguiente figura se muestra cómo están conectados los switches de s0 a s4 de este escenario. Aunque también tenemos conectados dos hosts (h2 y h3) estos todavía no intervienen porque lo que queremos hacer es establecer un plano de control entre los switches y el controlador que se ejecutará en s0 (los números que aparecen junto a cada enlace son los números de puerto de cada switch que se usan en ese enlace):
|
|
|
|
|
|
1 1 2 1 2 1 2 1
|
|
|
s0 ----------- s1 -------------- s2 -------------- s3 ------------ h2
|
|
|
10.0.0.1 \ 3 10.0.0.2
|
|
|
\
|
|
|
\ 1 2 1
|
|
|
-------------- s4 ------------- h3
|
|
|
10.0.0.3
|
|
|
|
|
|
Entramos en la carpeta '$HOME/OF-in-band-control-plane/testbed/scenarios_ether' y desde allí comenzamos a lanzar el escenario:
|
|
|
1. Arranque de escenario de mininet:
|
|
|
sudo python3 ./scenarios/arbol/scenario_arbol.py
|
|
|
2. Dentro de mininet arrancaremos un terminal para s0 y activaremos el entorno sdnenv para encontrar los paquetes necesarios de python que necesita el controlador:
|
|
|
s0~:> source /home/sdnwifi/sdnenv/bin/activate
|
|
|
Observarás que el prompt ha cambiado, mostrando (sdnenv) al principio, ahora podemos lanzar el controlador que tiene su salida redirigida a un fichero '/tmp/salida':
|
|
|
s0~:> ryu-manager --verbose InBandController.py --config-file ./params-controller-s0.conf > /tmp/salida 2>&1
|
|
|
3. Desde un terminal diferente (fuera de mininet) usaremos el siguiente script que crea los switches en los espacios de nombres y les proporciona un mínimo de configuración (script reglas-switch.sh):
|
|
|
sudo ./scenarios/arbol/start_scenario_arbol.sh
|
|
|
|
|
|
El escenario está arrancado.
|
|
|
Para comprobar que los switches se han conectado al controlador, podemos hacer una búsqueda en el fichero de trazas que está escribiendo el controlador (/tmp/salida) y buscar la cadena "IS MANAGED":
|
|
|
sudo grep "IS MANAGED " /tmp/salida
|
|
|
|
|
|
Deberá aparecer una línea por cada switch que se ha conectado con el controlador y al cuál el controlador le ha instalado los flujos OpenFlow.
|
|
|
|
|
|
|
|
|
Las direcciones IP que se han configurado en cada uno de los switches son:
|
|
|
s0: 10.0.0.1
|
|
|
s1: 10.0.0.101
|
|
|
s2: 10.0.0.102
|
|
|
s3: 10.0.0.103
|
|
|
s4: 10.0.0.104
|
|
|
|
|
|
Como se muestra en la siguiente figura, el puerto 1 de s0 está conectado al puerto 1 de s1, el puerto 2 de s1 está conectado al puerto 1 de s2 y el puerto 3 de s1 está conectado al puerto 1 de s4, y así el resto de conexiones representadas.
|
|
|
|
|
|
1 1 2 1 2 1 2 1
|
|
|
s0 ----------- s1 --------------- s2 -------------- s3 ------------ h2
|
|
|
\ 3 10.0.0.2
|
|
|
Controlador \
|
|
|
\ 1
|
|
|
-------- s4 ------------- h3
|
|
|
1 2 10.0.0.3
|
|
|
|
|
|
|
|
|
En este escenario, cuando los switches estén conectados al controlador, el camino que instalará en los paquetes el switch s0 para alcanzar s3 será:
|
|
|
- Camino s0-s1-s2-s3 y para ello meterá en la cabecera adicional: '122'. Es decir, el paquete sale por el puerto 1 de s0, despues por el puerto 2 de s1 y después por el puerto 2 de s2 para llegar a s3.
|
|
|
|
|
|
El camino que meterá s3 para alcanzar el controlador será:
|
|
|
- Camino s3-s2-s1-s0 y para ello meterá en la cabecera adicional: '111'. Es decir, el paquete sale por el puerto 1 de s3, despues por el puerto 1 de s2 y después por el puerto 1 de s1 para llegar a s0.
|
|
|
|
|
|
Los paquetes que genere s0, saldrán de s0 con el camino puesto y por tanto el resto de switches consultarán la cabecera adicional y reenviarán por dicho puerto, además de quitar del camino ese puerto de salida.
|
|
|
|
|
|
|
|
|
Para ver los flujos instalados en un switch, se puede abrir un terminal de ese switch y allí ejecutar el comando 'dumpAllFlows.sh' añadiendo el nombre del switch. Por ejemplo, para ver los flujos de s3, abriremos una ventana de s3 y ejecutaremos:
|
|
|
s3:~> ./dumpAllFlows.sh s3
|
|
|
|
|
|
Aquí saldrán muchos flujos que el controlador ha creado en s1, pero si nos fijamos en los flujos que hay instalados en la tabla 2 veremos que hay uno en concreto que es el que introduce la cabecera NSH para los paquetes que van desde s1 al controlador. Para ver los flujos de la tabla 2:
|
|
|
s3:~> ./dumpAllFlows.sh s3 | grep table_id=2
|
|
|
|
|
|
El switch s0 es el switch raíz y debe comunicarse con el resto de los switches de la topología, por eso, este switch debe tener en su tabla 2 un flujo por cada uno de los switches para introducir el camino para llegar a cada uno de ellos. Lo puedes ver si ejecutas:
|
|
|
s0:~> ./dumpAllFlows.sh s0 | grep table_id=2
|
|
|
|
|
|
Para ver el tráfico que genera cada switch, podemos usar wireshark, arrancado desde el terminal de un switch podrá capturar el tráfico en cualquiera de sus interfaces. Recuerda que el puerto 1 de s1, por ejemplo, es su interfaz s1-eth0, el puerto 2 de ese switch es s1-eth1 y así sucesivamente.
|
|
|
|
|
|
Como primera aproximación al funcionamiento, podrías arrancar wireshark por ejemplo en s3-eth0 antes de arrancar el controlador, para ver qué mensajes se capturan en esa interfaz y permiten establecer la sesión OpenFlow entre s0 y s3. Fíjate que una vez que se haya configurado s3, los mensajes que salgan de s3 deberán llevar el grafo en la cabecera NSH, en el campo 'Context Header'. Puedes hacer capturas en todas las interfaces para ver cómo los caminos van cambiando en cada salto, cada switch debe eliminar el puerto de salida por el que envía un paquete.
|
|
|
|
|
|
|
|
|
Para interrumplir la ejecución del escenario, primero hay que interrumpir el controlador (pulsando Ctrl+C en la ventana de 's0' donde se está ejecutando el controlador y después hay que borrar las configuraciones de los switches, para ello desde un terminal de Linux hay que ejecutar:
|
|
|
sudo ./scenarios/arbol/stop_scenario_arbol.sh
|
|
|
|
|
|
Ahora ya se puede cerrar mininet.
|
|
|
|