Numeração de classe / filtro do Linux TC

12

Atualmente, estou trabalhando em uma solução de modelagem de tráfego para empresas no nível ISP e cheguei a um problema interessante (tipo de filosofia).

Observando o número de pontos de extremidade que o sistema deve manipular (que é de aproximadamente 20k), fiquei um pouco preocupado com o que aconteceria quando eu precisasse definir políticas / modelar o tráfego de mais usuários. Como atualmente estou usando a árvore de modelagem HFSC (consulte tc-hfsc, geralmente a mesma coisa, porém mais legal, como HTB mais conhecido) para toda a rede, eu precisaria usar mais ClassIDs (obviamente, pelo menos um para cada usuário no rede). O problema que descobri foi que os TC ClassIDs são meio limitados - são números de 16 bits, o que me dá um máximo possível de 64k usuários modelados por esta solução.

Da mesma forma, se eu quiser gerenciar filtros de TC com eficiência (por exemplo, não usar a técnica 'flush all'), preciso poder excluir ou modificar entradas de filtro individuais. (Estou usando algo semelhante à tabela de hash do LARTC [1]). Novamente, o único método que parece estar trabalhando com isso é numerar todos os filtros usando prioridades individuais (tc filter add dev ... prio 1). Não há outro parâmetro que possa ser usado para esse fim e, infelizmente, o prio também é apenas de 16 bits.

Minha pergunta é a seguinte: Existe algum bom método para ampliar o "espaço identificador" disponível, como clsid de 32 bits para o comando 'tc class' e prioridades de 32 bits (ou quaisquer outros identificadores de modificação) para 'tc filter' comando?

Muito obrigado,

-mk

(espero que isso não vá para o cenário "64k usuários devem ser suficientes para todos" ...)

exa
fonte
Todos esses valores são armazenados no espaço do kernel. Para aumentá-los, você precisará recompilar os utilitários do kernel e do espaço do usuário. Você já tentou usar o kernel de 64 bits? Eles podem ser definidos como 32 bits lá.
Hubert Kario
O kernel de 64 bits usa os mesmos tamanhos. Por exemplo, o número do filtro é um número inteiro u32 que consiste na parte superior (protocolo) e na parte inferior (prio), obviamente 16 bits. Os IDs de classe são codificados como u16. Provavelmente vou tentar perguntar a alguém no LKML.
exa
1
mesmo usando hash para seus filtros, você terá muitos problemas de IO se estiver usando tantos filtros (acho que para upstream e downstream). Passei muito tempo e tive que corrigir a implementação de filas no kernel para que as coisas funcionassem com o ksoftirqd. Usei um adesivo de um cara chamado Simon Lodal que conheci no LARTC há 4 anos. Dê uma olhada no patch dele mail-archive.com/[email protected]/msg16279.html . Você pode tentar enviar um e-mail para ele, porque ele sempre tem uma versão muito atualizada (contra o último kernel) com ele.
Pabluez
@Pabluez Muito obrigado, tentarei tirar o melhor proveito disso.
exa
1
Eu acho que seu requisito é válido, mas como Pabluez escreveu, isso certamente envolve muitas alterações no kernel. Não quero dizer "você está fazendo errado", mas encorajo você a verificar o fluxo aberto, onde as partes inferiores do manuseio de pacotes são feitas no nível do comutador e o policiamento é feito no software personalizado, presumivelmente executando no espaço do usuário. Não sei se ele atende às suas necessidades, mas certamente vale a pena investigar.
AndreasM

Respostas:

2

Eu acho que você não deve colocar 64k usuários com classes e filtros upstream e downstream para cada um deles na mesma interface. Você pode repetir os manipuladores para cada interface que possui, portanto, adicione mais interfaces. Você precisará de um trabalho / servidor / NIC incrível para obter essas coisas. Se o servidor travar, você terá 64k usuários offline (e travará facilmente com essa quantidade de tráfego). Não esqueça que CADA pacote que passa pela sua placa de rede será verificado e classificado por um filtro e enviado a uma classe para a fila. Isso é muito trabalhoso para uma NIC de um gateway ISP com clientes de 64k. Principalmente com todo o fluxo de vídeo que temos hoje em dia (que é difícil colocar na fila adequadamente).

Pabluez
fonte
Estou garantindo a disponibilidade do serviço em outro nível, mas obrigado pela preocupação. Na verdade, com boas placas de rede, não é tão difícil ter um roteador Linux que possa encaminhar 10Gbits.
exa
Para a pergunta original, eu estava mais interessado em coisas como adicionar 5 classes diferentes para cada usuário, o que me permitiria fazer um trabalho QOS realmente bom (como lidar com fluxos e tráfego em tempo real separadamente), mas é impensável nas condições atuais (com o meu caso de uso atual de ~ 20k pontos de extremidade já estaria atrás do limite).
exa
1
ok, encaminhar 10Gbits não é problema, o problema é ter muitos filtros e classes de 64k * 2 (altos e baixos). No entanto, boa sorte: D
Pabluez
0

Você pode dividir a manipulação de tráfego em duas máquinas (usando uma terceira) em vez de manipular todo o tráfego em uma máquina. O tráfego pode ser roteado simplesmente com base no endereço IP de origem. Portanto, você terá 10 mil usuários de maneira ideal se puder dividir o (s) intervalo (s) de IPs igualmente.

Obviamente, você pode usar mais de duas máquinas, se necessário. Eu acho que isso pode ser melhor do que corrigir o kernel do Linux e fazer alguns outros hacks. Em resumo, a modelagem do tráfego será distribuída em várias máquinas. O nó central apenas encaminhará o tráfego para o nó de processamento correto.

Khaled
fonte