tc u32 - como combinar protocolos L2 em kernels recentes?

12

Eu tenho um bom shaper, com filtragem de hash, construído em uma ponte linux. Em resumo, br0conexões externale internalinterfaces físicas, os pacotes marcados com VLAN são conectados "de forma transparente" (quero dizer, não há interfaces VLAN).

Agora, diferentes kernels fazem isso de maneira diferente. Posso estar errado com as faixas exatas de verificações do kernel, por favor me perdoe. Obrigado.

2.6.26

Então, no debian, 2.6.26 e superior (até 2.6.32, eu acredito) --- isso funciona:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

Aqui, o "kernel" corresponde a dois bytes no campo "protocolo" com 0x8100, mas conta o início do pacote ip como uma "posição zero" (desculpe pelo meu inglês, se não sou claro).

2.6.32

Novamente, no debian (eu não construí o kernel vanilla), 2.6.32-5 --- isso funciona:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 at 20 flowid 1:200

Aqui, o "kernel" corresponde ao mesmo para o protocolo, mas conta o deslocamento desde o início do cabeçalho do protocolo --- eu tenho que adicionar 4 bytes para compensar (20, não 16 para o endereço dst). Tudo bem, parece mais lógico, quanto a mim.

3.2.11, o mais recente estável agora

Isso funciona --- como se não houvesse nenhuma tag 802.1q:

tc filter add dev internal protocol ip parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

O problema é que não consegui encontrar uma maneira de corresponder a tag 802.1q até agora.

Correspondência da tag 802.1q no passado

Eu poderia fazer isso antes da seguinte maneira:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 match u16 0x0ed8 0x0fff at -4 flowid 1:300

Agora eu sou incapaz de combinar 802.1q tag com at 0, at -2, at -4, at -6ou assim. O principal problema que tenho zero número de acessos - esse filtro não está sendo verificado, "protocolo errado", em outras palavras.

Por favor, alguém me ajude :-)

Obrigado!

browniano
fonte

Respostas:

4

A tag VLAN foi retirada do skb nos kernels recentes. Tente algo parecido com isto para fazer uma correspondência meta no skb:

tc filter add dev internal protocol all parent 1:0 prio 100 basic match 'meta(vlan mask 0xfff eq 0x0ed8)' flowid 1:300
Thusitha
fonte
Uma tentativa de adicionar um filtro raiz para o protocol alldá-me RTNETLINK answers: Invalid argument(kernel 3.3.4 aqui). Vou testar isso com kernels mais recentes. Obrigado.
brownian
Isso funcionou para mim com o debian wheezy kernel 3.2.0. Adicionei outra resposta com todos os detalhes.
Nick Craig-Wood
3

Eu tive que fazer exatamente isso. Descobri que a resposta sugerida por Thusitha era a maneira correta de fazer isso para novos kernels.

Testado com o kernel Debian wheezy 3.2.0-4 e o iproute (de onde vem o comando tc) versão 20120521-3 + b3

Aqui está o script completo, as tc filterlinhas sendo quase exatamente as especificadas por @Thusitha

function qos() {
    if="$1"
    vlan1="$2"
    vlan2="$3"

    # delete previous
    tc qdisc del dev $if root >/dev/null 2>&1
    tc qdisc del dev $if ingress >/dev/null 2>&1

    # Root HTB for $if
    tc qdisc add dev $if root handle 1: htb r2q 1 default 1

    # Root class to borrow from
    tc class add dev $if parent 1: classid 1:1 htb quantum 1000000 rate 500mbit ceil 500mbit burst 64k prio 2
    tc qdisc add dev $if parent 1:1 handle 101 sfq perturb 10

    # class for vlan1
    tc class add dev $if parent 1:1 classid 1:106 htb quantum 1000000 rate 1.00mbit ceil 1.00mbit burst 6k
    tc qdisc add dev $if parent 1:106 handle 107 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan1})" flowid 1:106

    # class for vlan2
    tc class add dev $if parent 1:1 classid 1:108 htb quantum 1000000 rate 1.00mbit ceil 10.00mbit burst 6k
    tc qdisc add dev $if parent 1:108 handle 108 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan2})" flowid 1:108

}

qos eth1 1234 1235
qos eth2 2345 2346
Nick Craig-Wood
fonte
Estranho, protocol allme deu um erro no kernel da baunilha. Eu deveria conferir mais. Obrigado.
brownian
1

Eu recomendaria usar o wireshark para capturar o que está passando pela interface como visível no espaço do usuário e usá-lo para escrever o filtro. Gostaria de saber se, talvez, a interface esteja removendo as tags VLAN por algum motivo (apesar de estar configurada para fazer a ponte transparente). Talvez esteja adicionando tags extras ou algo assim?

Falcon Momot
fonte
Não, definitivamente não está removendo a tag VLAN - tudo funciona (o tráfego é alterado através de troncos nos switches de hardware), exceto os filtros no shaper. Vou olhar mais de perto, no entanto. Eu olhei para o recurso de descarregamento de tags VLAN, mas esses drivers não são capazes de executar descarregamentos de vídeos.
browniano
tcpdumpmostra IDs de vlan em todas as interfaces bridgee portas.
brownian
Agora, meu bom shaper funciona no kernel 3.3.4 do linux, tudo funciona muito bem, exceto a filtragem de tags 8021q (eu posso viver sem ele). O problema permanece sem solução. Obrigado mesmo assim.
brownian 21/05
1

Você pode marcar pacotes vlan com ebtables .

# mark packets according to the vlan id
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 1 -j mark --mark-set 1
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 5 -j mark --mark-set 2

Em seguida, aplique a modelagem com base nas marcações. ebtables e iptables compartilham a mesma marcação.

Ainda não fiz isso. Portanto, é um palpite.

rhasti
fonte
Duvido que funcione sem problemas no link de 10Gb ... Gostaria de evitar qualquer tabela *. Obrigado pela sugestão de qualquer maneira.
browniano
@ brownian você acha que fazer exatamente a mesma filtragem no iproute2 terá melhor desempenho? É o mesmo kernel, o mesmo caminho de código, os mesmos algoritmos. Contanto que você não faça algo acidentalmente como ativar o rastreamento de conexão, não verá diferença. * As tabelas podem afetar o desempenho porque podem fazer muitas coisas complexas. Mas isso não significa que ele vai .
usar o seguinte comando
@tylerl Desde que eu realmente têm de filtro com iproute2 (centenas de clientes na mesma VLAN, um grupo de filtros de hashes) - qualquer outra verificação extra para cada pacote irá afetar o desempenho, eu não acredito.
brownian
0

Tente desativar a reorder_hdropção na interface vlan. Se a opção Reordenar cabeçalho estiver ativada, as tags dos quadros serão removidas. Verifique por comando ip -d link list dev vlan_iface.

Homem maligno
fonte
1
Por favor, você pode esclarecer quando é removido e quando é inserido novamente? Quero dizer, um quadro marcado entra na ponte linux e o deixa de outra interface - quando / onde essas manipulações de tags ocorrem e quando / onde os tcfiltros são chamados? Você tem um link para um mapa ou algo assim? Obrigado!
brownian 24/05
Por favor, outro pensamento: qual interface vlan você quer dizer? Essa ponte não possui uma interface vlan (escrevi "Quero dizer, não há interfaces VLAN") no primeiro parágrafo.
brownian 25/05