14.3.5. Como funciona SCH_DSMARK
Essa qdisc aplicará os passos seguintes:
• Se tivermos declarado a opção set_tc_index no comando qdisc, o valor do campo DS será recuperado e armazenado dentro da variável skb->tc_index.
• O Classificador é invocado. O classificador será executado e retornará um class ID que será estocado na variável skb->tc_index. Se nenhum filtro matches for encontrado, consideramos a opção default_index para determinar o classId a estocar. Se nem set_tc_index e nem default_index foram declaradas os resultados podem ser imprevisível.
• Depois de ter sido enviado as qdiscs internas onde você pode reusar o resultado do filtro, o classid retornado pela qdisc interna é estocado em skb->tc_index. Nós usaremos esse valor no futuro para indexar uma tabela mask-value. O resultado final a atribuir ao pacote será o resultado dessa operação seguinte:
New_Ds_field = ( Old_DS_field & mask ) | value
• Portanto, novo valor resultará da operação "AND" entre os valores ds_field e mask e prosseguindo, esse resultado é submetido à operação "OR" com o parâmetro value. Veja o diagrama seguinte compreender todo esse processo:
skb->ihp->tos
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
| | ^
| -- If you declare set_tc_index, we set DS | | <-----May change
| value into skb->tc_index variable | |O DS field
| A| |R
+-|-+ +------+ +---+-+ Internal +-+ +---N|-----|----+
| | | | tc |--->| | |--> . . . -->| | | D| | |
| | |----->|index |--->| | | Qdisc | |---->| v | |
| | | |filter|--->| | | +---------------+ | ---->(mask,value) |
-->| O | +------+ +-|-+--------------^----+ / | (. , .) |
| | | ^ | | | | (. , .) |
| | +----------|---------|----------------|-------|--+ (. , .) |
| | sch_dsmark | | | | |
+-|------------|---------|----------------|-------|------------------+
| | | <- tc_index -> | |
| |(read) | may change | | <--------------Index to the
| | | | | (mask,value)
v | v v | pairs table
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->
skb->tc_index
Como fazer a marcação? Apenas alterando o mask e o value da classe que você deseja remarcar. Veja a próxima linha do código:
tc class change dev eth0 classid 1:1 dsmark mask 0x3 value 0xb8
Isso altera o par (mask,value) na tabela hash, para remarcar pacotes pertencentes a classe 1:1. Você precisa alterar “change” esses valores por causa do valores padrões que o par (mask,value) possuem inicialmente (veja a tabela abaixo).
Agora, explicaremos como o filtro TC_INDEX funciona e como ajusta nisso. Além do mais, o filtro TCINDEX pode ser usado em outras configurações além daquelas que inclui os serviços DS.
14.3.6. Filtro TC_INDEX
Esse é o comando básico para declarar um filtro TC_INDEX:
... tcindex [ hash SIZE ] [ mask MASK ] [ shift SHIFT ]
[ pass_on | fall_through ]
[ classid CLASSID ] [ police POLICE_SPEC ]
Prosseguindo, mostraremos o exemplo usado para explicar o modo de operação TC_INDEX. Preste atenção às palavras destacadas em itálico:
tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 set_tc_index
tc filter add dev eth0 parent 1:0 protocol ip prio 1 tcindex mask 0xfc shift 2
tc qdisc add dev eth0 parent 1:0 handle 2:0 cbq \
bandwidth 10Mbit cell 8 avpkt 1000 mpu 64
1: Classe de tráfego EF
tc class add dev eth0 parent 2:0 classid 2:1 cbq \
bandwidth 10Mbit rate 1500Kbit avpkt 1000 \
prio 1 bounded isolated allot 1514 weight 1 maxburst 10
2: Pacote qdisc fifo para o tráfego EF
(Esse código não está completo. É apenas um extrato do exemplo EFCBQ incluído na distribuição iproute2).
tc qdisc add dev eth0 parent 2:1 pfifo limit 5
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
handle 0x2e tcindex classid 2:1 pass_on
Antes de tudo, suponha que recebemos um pacote marcado como EF. Se você ler a RFC2598, verá que o valor recomendado de DSCP para tráfego EF é 101110. Isso significa que o campo DS será 10111000 (lembre-se que os bits menos significativos no byte TOS não são usados em DS) ou 0xb8 na codificação hexadecimal.
TC INDEX
FILTER
+---+ +-------+ +---+-+ +------+ +-+ +-------+
| | | | | | | |FILTER| +-+ +-+ | | | |
| |----->| MASK | -> | | | -> |HANDLE|->| | | | -> | | -> | |
| | . | =0xfc | | | | |0x2E | | +----+ | | | | |
| | . | | | | | +------+ +--------+ | | | |
| | . | | | | | | | | |
-->| | . | SHIFT | | | | | | | |-->
| | . | =2 | | | +----------------------------+ | | |
| | | | | | CBQ 2:0 | | |
| | +-------+ +---+--------------------------------+ | |
| | | |
| +-------------------------------------------------------------+ |
| DSMARK 1:0 |
+-------------------------------------------------------------------------+
O pacote que chega, então, é definido com o valor 0xb8 no campo DS. Como explicado antes, a qdisc dsmark identificada por 1:0 no exemplo, recupera o valor do campo DS e o armazena na variável skb->tc_index. O próximo passo no exemplo corresponderá ao filtro associado a essa qdisc (segunda linha no exemplo). Isso executará as operações seguintes:
Value1 = skb->tc_index & MASK
Key = Value1 >> SHIFT
No exemplo, MASK=0xFC e SHIFT=2.
Value1 = 10111000 & 11111100 = 10111000
Key = 10111000 >> 2 = 00101110 -> 0x2E in hexadecimal
O valor retornado corresponderá a um handle de filtro da qdisc interna (no exemplo, identificador 2:0). Se existir um filtro com esse id, condições de policiamento e metering serão verificadas (caso em que o filtro inclui isso) e o classid será retornado (nosso exemplo, classid 2:1) e armazenado na variável skb->tc_index.
Mas se nenhum filtro com esse identificador não for encontrado, o resultado dependerá da declaração do flag fall_through. Se existir, a chave valor é retornada como classid. Se não, um erro é retornado e o processo continua com o resto dos filtros. Tenha cuidado se você usar o flag fall_through; isso pode ser feito se uma relação simples existir entre valores da variável skb->tc_index e classid´s.
Os últimos parâmetros a comentar são hash e pass_on. O primeiro relaciona com o tamanho da tabela hash. O parâmetro pass_on será usado para indicar que se nenhum classid for encontrado que se iguale ao resultado desse filtro, será tentado o próximo filtro. A ação padrão é fall_through (olhe a tabela seguinte).
Finalmente, vejamos quais possíveis valores podem ser definidos a todos os parâmetros TCINDEX:
TC Name Value Default
-----------------------------------------------------------------
Hash 1...0x10000 Dependente de Implementação
Mask 0...0xffff 0xffff
Shift 0...15 0
Fall through / Pass_on Flag Fall_through
Classid Major:minor None
Police ..... None
Esse tipo de filtro é muito poderoso. É necessário explorar todas as possibilidades. Além disso, esse filtro não é somente usado em configurações DiffServ. Você pode usá-las com qualquer outro tipo de filtro.
Eu recomendo você olhar todos os exemplos DiffServ incluídos na distribuição iproute2. Eu prometo que tentarei complementar esse texto tão logo eu possa. Além do mais, tudo que eu tenho explicado é o resultado de um monte de testes. Eu agradeceria por você dizer-me se me equivoquei em algum ponto.
14.4. qdisc Ingress
Todas qdiscs discutidas até aqui são qdiscs egress. Cada interface, contudo, pode também ter uma qdisc ingress que não é usada para enviar pacotes pra fora do adaptador de rede. Em vez disso, ela permite você aplicar filtros tc a pacotes entrantes pela interface, não importando se os pacotes tiverem um destino local e nem se eles forem encaminhados.
Como os filtros tc contém uma implementação completa do Filtro Bucket Token, e também podem de bater com o estimador de fluxo do kernel, existe um monte de funcionalidades disponíveis. Isso efetivamente permite a você policiar o trafego entrante, antes que ele de fato entre na pilha IP.
14.4.1. Parâmetros & Uso
A qdisc ingress em si não exige qualquer parâmetros. Ela difere de outras qdiscs pelo fato de que ela não ocupa a root qdisc de um dispositivo. Vincule-a como aqui:
# tc qdisc add dev eth0 ingress
Isso permite você ter outra, a que envia, qdiscs sobre seu dispositivo além da qdisc ingress.
Para um exemplo esperto de como a qdisc ingress pode ser usada, veja o Cookbook.
Autores Originais dos textos:
Bert Hubert (Netherlabs BV)
bert.hubert@netherlabs.nl
Thomas Graf (Autor de Seção)
tgraf@suug.ch
Gregory Maxwell (Autor de Seção)
greg@linuxpower.cx
Remco van Mook (Autor de Seção)
remco@virtu.nl
Martijn van Oosterhout (Autor de Seção)
kleptog@cupid.suninternet.com
Paul B Schroeder (Autor de Seção)
paulsch@us.ibm.com
Jasper Spaans (Autor de Seção)
jasper@spaans.ds9a.nl
Pedro Larroy (Autor de Seção)
piotr@member.fsf.org
Bert Hubert (Netherlabs BV)
bert.hubert@netherlabs.nl
Thomas Graf (Autor de Seção)
tgraf@suug.ch
Gregory Maxwell (Autor de Seção)
greg@linuxpower.cx
Remco van Mook (Autor de Seção)
remco@virtu.nl
Martijn van Oosterhout (Autor de Seção)
kleptog@cupid.suninternet.com
Paul B Schroeder (Autor de Seção)
paulsch@us.ibm.com
Jasper Spaans (Autor de Seção)
jasper@spaans.ds9a.nl
Pedro Larroy (Autor de Seção)
piotr@member.fsf.org
Nenhum comentário:
Postar um comentário