A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Linux

Administração de Largura de Banda no Linux II

Dom

22

Abr

2007


18:09

(7 votos, média 4.14 de 5) 


Classificando pacotes com filtros

Para determinar qual das classes deve processar um pacote, a assim chamada 'cadeia de classificação' (classifier chain) é acionada toda vez que uma escolha precisa ser feita. Esta cadeia é composta por todos os filtros associados à qdisc com classe que precisa tomar a decisão.

Repetindo a árvore, que não é uma árvore:

                    raiz 1:
                      |
                    _1:1_
                   /  |  \
                  /   |   \
                 /    |    \
               10:   11:   12:
              /   \       /   \
           10:1  10:2   12:1  12:2

Quando um pacote entra numa fila, a cadeia de filtros é consultada em cada ramo para ver se há instruções relevantes. Um setup típico pode ter um filtro em 1:1 que direciona pacotes para 12: e um filtro em 12: que envia pacotes para 12:2.

Esta última regra também pode ser associada a 1:1, mas ganha-se em eficiência se os testes mais específicos estiverem em posições mais baixas na cadeia.

Aliás, é bom saber que não é possível filtrar um pacote 'para cima'. E mais uma coisa: com HTB, todos os filtros devem ser associados à raiz.

Repetindo: os pacotes só podem entrar na fila de cima para baixo! Quando saem da fila, sobem novamente na direção da interface. Eles NÃO saem pela parte de baixo da árvore para chegarem até o adaptador de rede!

Alguns exemplos de filtragem

Vamos começar com as coisas mais óbvias que, para nossa sorte, são bastante fáceis. Digamos que temos uma qdisc PRIO chamada '10:', que contém três classes. Queremos que todo o tráfego que chega e que sai da porta 22 tenha a banda com a prioridade mais alta. Neste caso, os filtros seriam:

# tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match \ 
  ip dport 22 0xffff flowid 10:1
# tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match \
  ip sport 80 0xffff flowid 10:1
# tc filter add dev eth0 protocol ip parent 10: prio 2 flowid 10:2

O que estes comandos dizem é: associar à eth0, nó 10:, um filtro de prioridade 1 u32 que separa apenas o que é destinado para a porta 22 - os pacotes filtrados devem ser enviados para a banda 10:1; na segunda linha, o mesmo é feito quando a origem é a porta 80; a última linha diz para enviar todo o resto para a banda 10:2, a próxima prioridade mais alta.

è preciso adicionar eth0 (ou qualquer outro nome que a interface tiver) porque cada interface possui um espaço de nomes de manipuladores próprio.

Para selecionar um endereço IP, use o seguinte:

# tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 \ 
  match ip dst 4.3.2.1/32 flowid 10:1
# tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 \
  match ip src 1.2.3.4/32 flowid 10:1
# tc filter add dev eth0 protocol ip parent 10: prio 2      \
  flowid 10:2

Isto coloca o tráfego para 4.3.2.1 e o tráfego vindo de 1.2.3.4 na fila com a prioridade mais alta - o restante vai para a fila com a segunda prioridade mais alta.

É possível concatenar critérios. Para casar o tráfego vindo de 1.2.3.4 através da porta 80, faça o seguinte:

# tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip src 4.3.2.1/32 \
  match ip sport 80 0xffff flowid 10:1

Os comandos de filtro mais usados

A maioria dos comandos a seguir começam com este preâmbulo:

# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 ..

Estas são as chamadas coincidências 'u32', as quais casam com QUALQUER parte do pacote.

  • Para o endereço de origem/destino: Máscara para a origem 'match ip src 1.2.3.0/24', máscara para o destino 'match ip dst 4.3.2.0/24'. Para separar um host único, use /32 ou omita a máscara.
  • Para a porta de origem/destino em todos os protocolos IP: Para a origem, 'match ip sport 80 0xffff'; para o destinao, 'match ip dport 80 0xffff'.
  • Para o protocolo IP (tcp, udp, icmp, gre, ipsec): Use os números citados no arquivo /etc/protocols. Por examplo, icmp é 1, neste caso 'match ip protocol 1 0xff'.
  • Para fwmark: Pode-se marcar os pacotes com ipchains ou iptables para que a marca fique preservada depois de roteamentos através das interfaces. Isto é muito útil para, por exemplo, modelar apenas o tráfego na eth1 que chegou através da eth0. A sintaxe é:
    # tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 6 fw flowid 1:1
    
    Observe que a filtragem não usa u32!
    Você pode colocar uma marca como esta:
    # iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6
    
    O número 6 é arbitrário.
    Se você não quer se preocupar com a sintaxe de filtro completa do tc, então use apenas iptables e aprenda apenas a selecionar com fwmark.
  • Para o campo TOS: Para selecionar tráfego interativo com um mínimo de retardo (delay)
    # tc filter add dev ppp0 parent 1:0 protocol ip prio 10 u32 \
         match ip tos 0x10 0xff \
         flowid 1:4
    
    Use 0x08 0xff para a massa (bulk) do tráfego.

Informações adicionais