Linux Switchdev estilo Mellanox

Esta é a transcrição de um discurso proferido no Yandex NextHop 2020 - vídeo no final da página






Saudações. Meu nome é Alexander Zubkov, quero falar sobre o Linux Switchdev - o que é e como vivemos com ele no Qrator Labs.







Temos usado Switchdev em switches Mellanox por cerca de 2-3 anos. Os switches Mellanox Spectrum são classificados como “caixa branca”, o que significa que você pode colocar diferentes sistemas operacionais nesses switches. Normalmente, o fornecedor fornece algum SDK para isso e os sistemas operacionais usam esse SDK para interagir com o switch. E no caso dos switches Mellanox, existe um sistema operacional da própria Mellanox, existe o Cumulus. SAI (Switch Abstraction Interface) também é suportado - esta é uma tentativa de criar um SDK padrão para diferentes switches, que já é usado, por sua vez, pelo sistema operacional SONiC. E, claro, Switchdev é suportado por switches Mellanox.







Switchdev é uma infraestrutura no kernel Linux que permite a você construir um mapeamento das configurações de rede usuais do próprio kernel para o datapane, para o hardware de seu switch - isso é chamado de descarregamento. A imagem mostra que rosa é o driver da chave e azul é a API e utilitários para configurar o espaço do usuário. Switchdev aqui atua como um intermediário: para o espaço do usuário ele representa o modelo do switch, para o driver ele fornece a infraestrutura para organizar esta exibição.







Usamos um conjunto de funções razoavelmente padrão em switches Mellanox: roteamento, ECMP, em geral, nada incomum. Tudo isso é suportado com a possibilidade de offload para a linha de dados. A única coisa que falta é o roteamento baseado em políticas - não há suporte no driver Mellanox.







O driver Mellanox reside em um kernel Linux básico com suporte Switchdev - ou seja, não são necessários patches ou drivers binários adicionais. Você pode praticamente pegar o kernel de sua distro favorita ou compilar você mesmo o kernel vanilla e usá-lo. O firmware no switch é atualizado pelo próprio driver - você só precisa inserir o arquivo correspondente, que geralmente está contido no pacote de firmware do linux ou algo semelhante.







Para configurar o próprio switch, é claro, utilitários Linux padrão são usados ​​em grandes quantidades. Um conjunto de iproute2, ethtool, LLDP-daemon para QoS também é usado. E sysctl para algumas opções.







Para vrf no Linux, existem dois namespaces de rede. Mas também existe o chamado subsistema vrf - ele difere dos namespaces de rede. Nesse caso, todas as suas interfaces estão no mesmo namespace - ao trabalhar com vrf. E para controlar o roteamento, existe uma regra especial na regra ip, que determina a qual vrf o pacote pertence e, de acordo com isso, o direciona para uma tabela de roteamento específica. Para configurar isso - vrf no Linux - uma interface especial do tipo vrf é criada e esta tabela é ligada a ela durante a criação. Além disso, se você deseja adicionar alguma interface ao seu vrf, usando o comando ip link, você define este dispositivo especial como a interface principal para sua interface.E, como todas essas interfaces estão no mesmo namespace, você pode especificar explicitamente uma interface de outro vrf para a rota e, assim, fazer rotas entre as interfaces.







Por exemplo, temos uma tarefa na qual o roteamento baseado em políticas ajudaria - recebemos tráfego do uplink e queremos direcioná-lo completa e incondicionalmente para alguns nós de filtragem. Em Cisco ou Arista, faríamos mapas de rota de política ou alguma política de serviço, no Linux e regra de ip você pode fazer - mas no Linux tudo isso, infelizmente, não será descarregado.







E temos que nos virar. Por exemplo, criamos esse recurso - dividimos o vrf em duas partes, ou seja, em uma parte - na parte externa, há uma interface com nosso uplink, e na parte interna, há interfaces com nossos nós de filtragem.







E é assim que o roteamento se parece. No vrf interno, temos um conjunto de rotas mais ou menos padrão - ou seja, temos rotas internas e uma rota padrão por meio de nosso uplink. E já na interface externa, temos apenas uma rota padrão, mas ela encontra-se através de nossos nós de filtragem. Assim, obtivemos um pseudo Roteamento Baseado em Políticas para interfaces. Todo o tráfego que passa pela interface de uplink é roteado por uma rota diferente.







E, em geral, quando você configura um switch no Switchdev, você geralmente tem que primeiro configurar as portas, depois o bond, então conectar à bridge, então vlans, vrfs e no final do endereço e das rotas. Isso é ditado principalmente pela própria estrutura de interfaces no Linux - como você deve configurar tudo, bem, existem algumas outras restrições que não permitem que você altere as configurações arbitrariamente. Ou seja, este é um trabalho um tanto enfadonho, que em nossa empresa foi inicialmente realizado por um grande script de inicialização que configurou tudo isso. Mas, é claro, às vezes precisamos fazer alterações em tempo de execução, na produção.







Às vezes é doloroso, porque você tem que resolver essa estrutura quase à mão - desmontar algumas interfaces, remontá-las, e tudo isso está repleto de erros, é claro. Quando você trabalha na Cisco, você altera as configurações e o shell cuidará de tudo, e então algum tipo de trabalho de baixo nível está sendo feito.







Bem, obrigado pelo fato de termos Perl - escrevemos um script mlxrtr que pega essa configuração e gera conjuntos de comandos para configurar a rede e tudo mais. E também suporta mudanças - se você fizer alguma mudança, ele lerá sua configuração atual no Linux e verá o que precisa ser feito para trazê-lo ao estado desejado.







Inicialmente, se você executar esta configuração irá gerar tal conjunto de comandos para você, e eu também joguei fora os mesmos.











Existem alguns comandos, mas em geral, se você os tiver em seu script de inicialização, então pode ser mais ou menos suportado.







Por exemplo, se você precisa mudar uma porta para outro vínculo, então você precisa desconectar esta porta do vínculo antigo, desconectar o novo vínculo da ponte, em seguida, conectar a porta a esse vínculo, em seguida, retornar o vínculo para a ponte, reconfigurar as vlans nela - em em geral, um trabalho bastante enfadonho e desagradável de fazer com as mãos, claro. O script faz tudo isso sozinho.







Mais longe. ACL é configurável ... você pode usar iptables, mas não será descarregado - você só pode usá-lo para filtrar o tráfego do plano de controle. E se você quiser filtrar na linha de dados, então você precisa usar o filtro tc no caso de Switchdev. E aqui vale lembrar que o filtro tc já vai filtrar não só o tráfego roteado, mas também o que é trocado. E também o filtro tc só pode ser pendurado em portas físicas, então se você trabalha com vlans, você precisa fazer construções mais complexas aqui. Mas existem recursos interessantes lá, por exemplo, você pode pendurar tal bloco em várias interfaces e eles irão atrapalhar (no sentido de compartilhar) um filtro comum. Há também um operador goto nas regras tc, que também é muito legal e permite que você faça acls não lineares, ao contrário de Cisco ou Arista.







Aqui também temos um utilitário para configurar acl - mlxacl. Trabalhamos principalmente com vlans no terceiro nível e o utilitário funciona de tal forma que para cada vlan ele cria uma cadeia separada e na cadeia principal ele simplesmente combina vlans e vai para a cadeia correspondente para esta vlan.







Aqui também há um exemplo de tal configuração - esses comandos são o resultado. Há menos deles do que no caso da configuração do próprio switch, porque uma regra é mapeada para aproximadamente um comando - o que não é tão difícil.







Mas se você tiver que fazer alguma alteração - neste caso, eu apaguei uma regra e o utilitário faz tudo de uma forma que reescreve todas as cadeias que foram alteradas, após o que ele renumera na cadeia principal zero para que se refiram a novas cadeias. E é claro que neste caso seria possível, com trabalho manual, resolvê-lo em um comando.







Mas para isso precisamos primeiro olhar para o estado atual e é assim que a saída do filtro tc se parece - é muito difícil trabalhar com isso.







Quando você trabalha com tudo isso, as pessoas que passam te olham assim. Portanto, escrevemos este utilitário - mlxacl - primeiro, porque era muito mais doloroso trabalhar com ele, e depois palavra por palavra e para o resto das configurações também escrevemos o utilitário.







Esses utilitários, dos quais eu falei, nós os postamos publicamente no Gitlab - você pode usá-los. Eles são licenciados pelo MIT e, portanto, disponíveis gratuitamente.







Naturalmente, sem nenhuma garantia. Este é um par de scripts Perl (antecipando suas perguntas - porque eu conheço Perl e ele simplesmente funciona), relativamente pequeno, quase sem dependências - ele usa alguns módulos Perl que estão na distribuição Perl padrão e utilitários Linux, é claro.







Por fim, se você trabalhou um pouco com um console serial, com portas COM, quero dar um conselho. Por exemplo, se alguém pensou que era uma maneira de sair do Vim, você quase adivinhou.







Para alguns BIOS, isso equivale a Ctrl + Alt + Del, visto que eles o percebem através da porta serial. Ou seja, se seu bootloader travar, por exemplo, e você precisar reiniciar o switch de alguma forma, você pode usar.



Além disso, quando se trata do kernel, ele naturalmente intercepta o trabalho com o teclado, então é melhor que seu kernel SysRq aceite comandos - caso contrário, será difícil reiniciar o switch. E no caso do SysRq, quando você trabalha com o teclado e um terminal regular, o PrintScreen é usado lá, e no caso de um console serial, com uma porta COM, você precisa enviar um sinal de break especial - no minicom é Ctrl + F, na tela ' e Ctrl + A, Ctrl + B e, em seguida, crie uma tecla SysRq especial.



E para entrar na bios na hora da inicialização - na bios do switch, é claro, porque na verdade, como em um computador normal, há uma bios através da qual ele normalmente inicializa - você pode pressionar Ctrl + B.



Isso é tudo que eu queria dizer rapidamente. Se você tiver alguma dúvida, ficarei feliz em responder.







Versão em inglês da publicação.



All Articles