Linux Switchdev estilo Mellanox

Esta es una transcripción de un discurso pronunciado en Yandex NextHop 2020 - video al final de la página






Saludos. Mi nombre es Alexander Zubkov, quiero hablarles sobre Linux Switchdev, qué es y cómo vivimos con él en Qrator Labs.







Hemos estado usando Switchdev en conmutadores Mellanox durante aproximadamente 2-3 años. Los conmutadores basados ​​en Mellanox Spectrum se clasifican como "caja blanca", lo que significa que puede poner diferentes sistemas operativos en estos conmutadores. Por lo general, el proveedor proporciona algún SDK para esto y los sistemas operativos utilizan este SDK para interactuar con el conmutador. Y en el caso de los conmutadores Mellanox, hay un sistema operativo del propio Mellanox, hay Cumulus. También se admite SAI (Switch Abstraction Interface): este es un intento de crear un SDK estándar para diferentes conmutadores, que ya está siendo utilizado, a su vez, por el sistema operativo SONiC. Y, por supuesto, Switchdev es compatible con conmutadores Mellanox.







Switchdev es una infraestructura de este tipo en el kernel de Linux que le permite crear un mapeo de la configuración de red habitual del kernel en sí al panel de datos, al hardware de su conmutador; esto se llama descarga. La imagen muestra que el rosa es el controlador del conmutador y el azul es la API y las utilidades para configurar el espacio de usuario. Switchdev actúa aquí como un intermediario: para el espacio de usuario representa el modelo de conmutador, para el conductor proporciona la infraestructura para organizar esta pantalla.







Usamos un conjunto de funciones bastante estándar en los conmutadores Mellanox: enrutamiento, ECMP, en general, nada inusual. Todo esto se apoya con la posibilidad de descargar a la línea de datos. Lo único que falta es el enrutamiento basado en políticas: no hay soporte en el controlador Mellanox.







El controlador Mellanox reside en un kernel básico de Linux con soporte Switchdev, no se necesitan parches ni controladores binarios adicionales. Prácticamente puede tomar el kernel de su distribución favorita o compilar el kernel vainilla usted mismo y usarlo. El firmware del conmutador lo actualiza el propio controlador; solo necesita insertar el archivo correspondiente, que generalmente se encuentra en el paquete de firmware de linux o algo similar.







Para configurar el conmutador en sí, por supuesto, se utilizan grandes cantidades de utilidades estándar de Linux. También se utiliza un conjunto de iproute2, ethtool, LLDP-daemon para QoS. Y sysctl para algunas opciones.







Para vrf en Linux, existen ambos espacios de nombres de red. Pero también existe el llamado subsistema vrf: difiere de los espacios de nombres de red. En este caso, todas sus interfaces están en el mismo espacio de nombres, cuando trabaja con vrf. Y para controlar el enrutamiento, hay una regla especial en la regla ip, que determina a qué vrf pertenece el paquete y, de acuerdo con esto, lo dirige a una tabla de enrutamiento específica. Para configurar esto, vrf en Linux, se crea una interfaz especial del tipo vrf y esta tabla está vinculada a ella durante la creación. Y además, si desea agregar alguna interfaz a su vrf, entonces, usando el comando ip link, configura este dispositivo especial como la interfaz maestra para su interfaz.Y dado que todas estas interfaces están en el mismo espacio de nombres, entonces puede especificar explícitamente una interfaz de otra vrf a la ruta y así hacer rutas entre las interfaces.







Por ejemplo, tenemos una tarea en la que el enrutamiento basado en políticas ayudaría: recibimos tráfico del enlace ascendente y queremos dirigirlo total e incondicionalmente a algunos nodos de filtrado. En Cisco o Arista, haríamos mapas de ruta de políticas o alguna política de servicio, en Linux y la regla de IP puede hacerlo, pero en Linux todo esto, desafortunadamente, no se descargará.







Y tenemos que dar la vuelta. Por ejemplo, hemos creado una función de este tipo, hemos dividido vrf en dos partes, es decir, en una parte, en la parte exterior hay una interfaz con nuestro enlace ascendente y en la parte interior hay interfaces con nuestros nodos de filtrado.







Y así es como se ve el enrutamiento. En el vrf interno, tenemos un conjunto de rutas más o menos estándar, es decir, tenemos rutas internas allí y una ruta predeterminada a través de nuestro enlace ascendente. Y ya en la interfaz externa, solo tenemos una ruta predeterminada, pero se encuentra a través de nuestros nodos de filtrado. Por lo tanto, obtuvimos un pseudo enrutamiento basado en políticas para interfaces. Todo el tráfico que llega a través de la interfaz de enlace ascendente se enruta por una ruta diferente.







Y, en general, cuando configura un conmutador en Switchdev, generalmente debe configurar primero los puertos, luego el enlace, luego conectarse al puente, luego a vlans, vrfs y al final de la dirección y las rutas. Esto está dictado principalmente por la estructura misma de las interfaces en Linux: cómo debe configurar todo, bueno, hay algunas otras restricciones que no le permiten cambiar arbitrariamente la configuración. Es decir, este es un trabajo bastante lúgubre, que en nuestra empresa fue realizado inicialmente por un gran script de inicio que configuraba todo esto. Pero, por supuesto, a veces tenemos que hacer cambios en tiempo de ejecución, en producción.







A veces es doloroso, porque hay que resolver esta estructura casi a mano: desmontar algunas interfaces, volver a montarlas, y todo esto está plagado de errores, por supuesto. Cuando trabaja en Cisco, cambia la configuración y el shell se encargará de todo, y luego se está realizando algún tipo de trabajo de bajo nivel.







Bueno, gracias por el hecho de que tenemos Perl; escribimos un script mlxrtr que toma dicha configuración y genera conjuntos de comandos para configurar la red y todo lo demás. Y también admite cambios, si realiza algún cambio, leerá su configuración actual en Linux y verá qué se debe hacer para llevarla al estado que desea.







Inicialmente, si ejecuta esta configuración, generará un conjunto de comandos de este tipo para usted, y también descarté los mismos.











Hay bastantes comandos, pero en general, si lo tiene en su script de inicio, entonces puede ser más o menos compatible.







Por ejemplo, si necesita cambiar un puerto a otro enlace, entonces necesita desconectar este puerto del enlace anterior, desconectar el enlace nuevo del puente, luego conectar el puerto a ese enlace, luego devolver el enlace al puente, reconfigurar los vlans en él - en en general, un trabajo bastante aburrido y es desagradable hacerlo con las manos, por supuesto. El guión hace todo esto por sí solo.







Más lejos. ACL es configurable ... puede usar iptables, pero no se descargará; solo puede usarlo para filtrar el tráfico del avión de control. Y si desea filtrar en la línea de datos, debe usar el filtro tc en el caso de Switchdev. Y aquí vale la pena tener en cuenta que el filtro tc ya filtrará no solo el tráfico enrutado, sino también el que está conmutado. Y también el filtro tc solo se puede colgar en puertos físicos, por lo que si trabaja con vlans, debe realizar construcciones más complejas aquí. Pero hay características interesantes allí, por ejemplo, puede colgar un bloque de este tipo en varias interfaces y buscarán a tientas (en el sentido de compartir) un filtro común. También hay un operador goto en las reglas tc, que también es bastante bueno y le permite hacer acls no lineales, a diferencia de Cisco o Arista.







Aquí también tenemos una utilidad para configurar acl - mlxacl. Principalmente trabajamos con vlans en el tercer nivel y la utilidad funciona de tal manera que para cada vlan crea una cadena separada y en la cadena principal simplemente coincide con vlans y va a la cadena correspondiente para este vlan.







Aquí, también, hay un ejemplo de tal configuración; tales comandos son el resultado. Hay menos de ellos que en el caso de la configuración del conmutador en sí, porque una regla se asigna a aproximadamente un comando, lo que no es tan difícil.







Pero si tiene que hacer algún cambio, en este caso, eliminé una regla y la utilidad hace todo de tal manera que reescribe todas las cadenas que han cambiado, después de lo cual vuelve a numerar en la cadena cero - principal - para que se refieran a nuevas cadenas. Y está claro que en este caso se podría solucionar, con trabajo manual, en un solo equipo.







Pero para esto, primero debemos mirar el estado actual y así es como se ve la salida del filtro tc: es bastante difícil trabajar con él.







Cuando trabajas con todo esto, la gente que pasa te mira así. Por lo tanto, escribimos esta utilidad, mlxacl, primero, porque era mucho más doloroso trabajar con ella, y luego palabra por palabra y para el resto de las configuraciones también escribimos la utilidad.







Estas utilidades, de las que te hablé, las publicamos en público en Gitlab; puedes usarlas. Tienen licencia del MIT y, por lo tanto, están disponibles gratuitamente.







Naturalmente, sin garantía alguna. Este es un par de scripts de Perl (anticipándose a sus preguntas, porque conozco Perl y simplemente funciona), relativamente pequeños, casi sin dependencias, utiliza un par de módulos de Perl que están en la distribución estándar de Perl y las utilidades de Linux, por supuesto.







Por último, si has trabajado un poco con una consola serie, con puertos COM, quiero darte algunos consejos. Por ejemplo, si alguien pensó que era una forma de salir de Vim, casi lo adivinó.







Para algunas BIOS, esto es el equivalente a Ctrl + Alt + Supr, ya que lo perciben a través del puerto serie. Es decir, si su cargador de arranque se cuelga, por ejemplo, y necesita reiniciar el conmutador de alguna manera, puede usar.



Además, cuando se trata del kernel, naturalmente intercepta el trabajo con el teclado, así que aquí es mejor que su kernel SysRq acepte comandos; de lo contrario, será difícil reiniciar el conmutador. Y en el caso de SysRq, cuando trabajas con un teclado y un terminal normal, allí se usa PrintScreen, y en el caso de una consola serial, con un puerto COM, necesitas enviar una señal de interrupción especial - en minicom es Ctrl + F, en pantalla ' e Ctrl + A, Ctrl + B y luego cree una tecla SysRq especial.



Y para ingresar a la BIOS en el momento del arranque, en la BIOS del conmutador, por supuesto, porque de hecho, como en una computadora normal, hay una BIOS a través de la cual generalmente se inicia, puede presionar Ctrl + B.



Eso es todo lo que quería contarte brevemente. Si tienes alguna pregunta, estaré encantado de responderte.







Versión en inglés de la publicación.



All Articles