Click here to load reader

Edgard Jamhour Mecanismos de QoS em Linux tc – Traffic Control Edgard Jamhour

  • View
    225

  • Download
    1

Embed Size (px)

Text of Edgard Jamhour Mecanismos de QoS em Linux tc – Traffic Control Edgard Jamhour

QoS Ethernet e VLANstc – Traffic Control
Edgard Jamhour
Este módulo descreve os principais mecanismos de QoS disponíveis no kernel do Linux.
Para utilizar esses mecanismos, é necessário criar uma política coerente de QoS, que determina como os pacotes recebidos serão classificados, tratados e encaminhados pelo S.O.
A configuração de QoS no linux é baseada no utilitário de comando de linha denominado tc (traffic control).
Existem algumas outras tentativas de construir outras interfaces de administração do QoS do Linux, mas a maioria delas usa o próprio tc para gerar as configurações de QoS. Por isso, esse módulo irá se focar apenas no uso do tc.
Algumas das figuras utilizadas nessa apostila foram extraídas do tutorial:
http://www.opalsoft.net/qos/DS.htm
Formatação de Tráfego
O Linux possui implementado em seu kernel um conjunto de algoritmos para controle de tráfego, genericamente denominados como TC (Traffic Control). Esses algoritmos permitem modificar a forma como os pacotes recebidos pelo sistema operacional são encaminhados pela rede.
Basicamente, o controle de tráfego é implementado através de dois mecanismos:
1) Pacotes são policiados na entrada. Através do policiamento, pacotes indesejáveis são descartados.
2) Pacotes são enfileirados na respectiva interface de saída. Os pacotes armazenados nas filas podem ser atrasados, marcados, descartados ou priorizados
As políticas de QoS do Linux são criadas de forma independente para cada interface do equipamento. Em qualquer caso, deve-se sempre levar em conta que o policiamento é feito para pacotes encaminhados para uma data interface e, o controle de tráfego propriamente dito, para os pacotes que são enviados pela interface.
Por exemplo, em um roteador, cada interface controla o QoS do tráfego em um único sentido. Se um roteador possui uma interface para a LAN interna e outra WAN para Internet, então as políticas de QoS na interface LAN controlam o que é transmitido para Internet (upload) e na interface WAN o que é recebido (download).
Para ter acesso as funções de controle de tráfego, o Linux disponibiliza um utilitário de comando de linha denominado tc. O tc permite criar uma política de QoS, que define a seqüência de algoritmos que são aplicados para tratamento do tráfego. A política de QoS é definida cascateando-se elementos lógicos que representam por quais etapas os pacotes serão encaminhados, antes de serem entregues a interface de saída.
Edgard Jamhour
Qdisc da classe
a) Queuing Disciplines = qdisc
b) Classes
c) Filters
utilizados para policiar e classificar os pacotes e atribuí-los as classes.
d) Policers
utilizados para evitar que o tráfego associado a cada filtro ultrapasse limites pré-definidos.
A figura ilustra uma estrutura típica para controle de tráfego.
Observe que as qdiscs são usadas em duas situações: a qdisc principal e as qdiscs associadas as classes. A qdisc principal é obrigatória. É ela quem define a estratégia geral de QoS implementada pelo tc e, em especial, de qual das classes o pacote será escolhido para envio. A função das qdiscs de classes é definir quais pacotes da classe estão prontos para serem transmitidos.
A quantidade de classes é variável e depende da quantidade de tratamentos diferenciados que serão implementados pelo tc. Por exemplo, se a política de QoS quer apenas diferenciar o tratamento de tráfego de VoIP e dados, bastariam apenas duas classes. Contudo, se a política quiser criar tratamentos diferenciados para os dados, mais classes precisarão ser criadas.
Os filtros são os classificadores. Sua função é encaminhar os pacotes para sua respectiva classe (por exemplo, pacotes de dados para uma classe e pacotes de VoIP para outra).
Edgard Jamhour
> tc qdisc add dev eth0
root handle 1:0
parent 1:0 classid 1:1
parent 1:0 classid 1:2
htb rate 300Kbit
A configuração da política de QoS é feita através de um script formado por uma seqüência de comandos tc. Cada comando tc é responsável por criar um dos elementos da política de controle de tráfego desejada.
O primeiro comando da figura cria a qdisc principal (root) associada a interface eth0. É importante observar que as políticas de controle de tráfego são específicas para cada uma das interfaces disponíveis no equipamento. Todas as qdiscs precisam ser identificadas por um número denominado handle. O identificador da qdisc tem sempre o formato N:0, onde N é um número inteiro qualquer. Todas as qdiscs são definidas por um tipo de algoritmo que define como o controle de tráfego é efetuado. No exemplo, htb (hierachical token bucket) é o algoritmo utilizado pela qdisc. O funcionamento do htb será discutido na seqüência deste módulo.
O segundo conjunto de comandos da figura cria duas classes com taxas diferentes. Observe que as classes são filhas da qdisc principal (conforme observado pelo atributo parent), e são do mesmo tipo htb. As classes do tipo htb exigem um parâmetro que define a taxa com que os pacotes armazenados em cada classe serão transmitidos. As classes são identificadas por um código classid. Esse código precisa seguir o seguinte formato específico: (handle do elemento pai):(código da classe). No exemplo, as classes são nomeadas como 1:1 e 1:2 porque elas são filhas da qdisc de handle 1:0. O número depois dos “:” pode ser qualquer, não precisando ser definidos em ordem. Contudo, não podem haver elementos de política com classid ou handle repetidos.
Edgard Jamhour
> tc qdisc add dev eth0 parent 1:1 handle 10:0
pfifo limit 10
pfifo limit 10
protocol ip u32 match ip protocol 0x06 0xff
flowid 1:1
protocol ip u32 match ip protocol 0x11 0xff
flowid 1:2
O primeiro conjunto de comandos na figura cria as qdiscs associadas a cada classe. Observe que cada qdisc é filha das classe a ela associada (conforme indicado pelo parâmetro parent). Novamente, as qdisc precisam ser identificadas por um handle que segue o formato N:0. As qdiscs de classe determinam em que ordem os pacotes já armazenados na fila serão removidos. Nesse caso, as qdiscs implementam uma simples política do tipo FIFO (First-In First-Out), criando um buffer com capacidade máxima de 10 pacotes.
O segundo conjunto de comandos cria os filtros. O tc permite utilizar dois tipos de filtros: o u32 e o iptables. Apesar de ser mais familiar, o uso do iptables junto com tc é menos recomendado, pois é necessário criar regras identificadas por índices com o iptables, e aportar esses índices usando o tc. Os filtros u32, por outro lado, podem ser definidos diretamente no comando tc. Os filtros u32 são definidos da seguinte forma:
protocol ip u32: indica que o filtro do tipo u32 será utilizado. Esses parâmetros são repetidos em todos os comandos tc que usam o filtro u32, independente da regra criada.
match ip <valor campo> <máscara>: indica qual o critério utilizado para classificar um pacote.
Geralmente, a regra é definida em termos dos campos do cabeçalho ip (ip de origem, ip de destino, tipo de protocolo, tos, dscp, etc) ou tcp/udp (porta de origem, porta de destino). No exemplo, o critério é baseado unicamente no campo protocol (tipo de protocolo) do cabeçalho IP. O código 0x06 corresponde ao TCP e o código 0x11 ao código UDP (conforme norma do IANA). O classificador u32 utiliza máscaras para todos os códigos dos campos, de forma similar ao que é feito com endereços IP. A máscara é usada da seguinte forma:
Se <campo do pacote> E-BINÁRIO <máscara> = <valor do campo> então o pacote é classificado pela regra, e encaminhado para o código da classe definido pelo flowid. Caso contrário, a próxima regra é testada.
Edgard Jamhour
Seqüência de filtros u32
Pacotes HTTP recebidos por 192.168.0.1/24 vão para classe 1:1. Os demais pacotes TCP recebidos por esse host vão para classe 1:2
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32
match ip protocol 0x06 0xff
match ip sport 80 0xfff
match ip dst 192.168.0.1/24
flowid 1:1
tc filter add dev eth0 parent 1:0 protocol ip prio 2 u32
match ip protocol 0x06 0xff
match ip dst 192.168.0.1/24
flowid 1:2
Os filtros u32 são analisados em seqüência, de forma semelhante as regras de um firewall. Geralmente, uma política de QoS pode definir filtros sobrepostos, como os da seguinte política:
"Pacotes HTTP recebidos por 192.168.0.1/24 vão para classe 1:1. Os demais pacotes TCP recebidos por esse host vão para classe 1:2".
Observe que todos os pacotes enviados a classe 1:1 são na verdade um subconjunto dos pacotes enviados a classe 1:2. Se o roteador testar se um pacote pertence a classe 1:2 primeiro, nenhum pacote será enviado a classe 1.1.
Para evitar que isso aconteça é necessário colocar os filtros em ordem, listando os filtros mais específicos antes dos mais genéricos.
Isso é feito utilizando o atributo prio disponível para os filtros u32. Os filtros de prio menor são testados sempre antes dos maiores. Se dois filtros tem o mesmo prio, provavelmente o último filtro a ser criado será testado primeiro. Contudo, é melhor nunca confiar nessa premissa, e utilizar o valor de prio para garantir uma ordem correta de interpretação dos filtros.
Edgard Jamhour
–s mostra as estatísticas do uso da qdisc/class/filter
tc qdisc del root dev eth0
limpa as regras de QoS
iplink show
mostra a classe default associada a interface
As políticas criadas pelo tc ficam em memória até que o computador seja reiniciado, pois os comandos tc são acumulativos. Isto é, quando um novo elemento é criado, os anteriores não são eliminados. É possível listar todos os elementos tc em memória através dos seguintes comandos:
tc [-s] qdisc show dev eth0: Mostra todas as qdiscs associadas a interface eth0. Se o atributo opcional [-s] for utilizado, as estatísticas associadas as qdiscs são mostradas. As estatísticas são muito dependentes do tipo de qdisc criada, mas geralmente contém a quantidade de pacotes que foi processada por cada qdisc.
tc [-s] class show dev eth0: Mostra todas as classes associadas a interface eth0. Se o atributo opcional [-s] for utilizado, as estatísticas associadas as classes são mostradas. Assim com as qdiscs, as estatísticas são muito dependentes do tipo de classe criada, e descrevem a quantidade de pacotes processada por cada classe.
tc [-s] class filter dev eth0: Mostra todas os filtros e policiadores associados a interface eth0. Se o atributo opcional [-s] for utilizado, as estatísticas associadas aos filtros são também mostradas. As estatísticas descrevem a quantidade de pacotes que foi classificada por cada filtro.
Geralmente é melhor criar um script com todos os comandos tc ao invés de digitá-los diretamente via console. Como os comandos são acumulativos, é necessário apagar todos os elementos da política antes de executar os script novamente. O seguinte comando deve ser incluído no início do script para garantir que apenas a política do script será utilizada pelo sistema operacional:
tc qdisc del root dev eth0
Normalmente, o Linux utiliza uma política do tipo FIFO default associada a cada interface. Essa política é sobreposta, sem necessidade de apagá-la, quando se cria uma nova classe “root”. Em alguns sistemas o comando iplink show permite ver a classe default associada a interface. O iplink, contudo, raramente é instalado pelas distribuições do Linux.
Edgard Jamhour
Queueing Disciplines
SFQ: Stochastic Fair Queuing
TBF: Token Bucket Flow
[CBQ: Class-Based Queueing] = OBSOLETA
HTB: Hierarquical Token Bucket
O efeito de uma política de QoS é determinada pelo tipo da queuing discipline (qdisc). Conforme dissemos, algumas qdiscs são utilizadas para controlar o escalonamento de múltiplas classes e outras para controlar a saída de tráfego de uma única classe.
As seguintes qdiscs são usadas para controlar o escalonamento de uma única classe:
FIFO (First In First Out): implementa a política First-In First-Out, que indica que os pacotes serão servidos na mesma ordem que chegaram.
SFQ (Stochastic Fair Queuing): procura equilibrar a quantidade de banda disponível para cada fluxo em uma fila.
TBF (Token Bucket Flow): permite controlar a taxa com que os pacotes de uma fila são servidos.
DS_MARK (Diff-Serv Marker): efetua a marcação dos campos DSCP dos pacotes para implementar a metodologia Diffserv.
RED (Random Early Detection): algoritmo de descarte preventivo para diminuir o tamanho da fila e, consequentemente, o atraso médio experimentado pelos pacotes
As seguintes qdiscs são usadas para controlar o escalonamento de múltiplas classes filhas:
PRIO (Priority Queue): coordena a ordem em que as filas são servidas segundo um esquema de prioridade (injusto).
CBQ: (Class-Based Queueing): coordena a ordem em que as filas são servidas segundo um esquema hierárquico.
HTB: (Hierarquical Token Bucket): coordena a ordem em que as filas são servidas segundo um esquema hierárquico. Substituto do CBQ
Todas as qdiscs acima está definidas para o kernel do Linux sem adição de patches, mas cada uma delas pode ser desabilitadas individualmente durante compilação do kernel.
Edgard Jamhour
> tc qdisc add dev eth0 root handle 1:0
pfifo limit 10
pfifo limit 10
A figura ilustra o princípio do algoritmo FIFO. A qdisc do tipo FIFO implementa um procedimento de encaminhamento em que os pacotes são servidos na mesma ordem em que chegam a interface do roteador ou a uma classe, independente do fluxo ao qual eles pertencem. Na abordagem FIFO, se forem misturados pacotes TCP e UDP em uma mesma fila, é possível que os pacotes UDP dominem o uso da banda, pois não existe forma de equilibrar a quantidade de banda alocada a cada fluxo.
As qdisc FIFO podem ser criadas como root (default) ou associadas as classes. O uso da FIFO como root é a implementação default da política QoS do Linux. A figura ilustra a criação da qdisc para as duas situações: o primeiro comando cria a classe como root e o segundo comando cria a qdisc FIFO como uma classe filha. Observe que essa qdisc solicita apenas um parâmetro, denominado limit, que determina a quantidade máxima de pacotes que podem aguardar na fila antes que sejam descartados.
Edgard Jamhour
prio
O qdisc do tipo PRIO controla o escalonamento de múltiplas classes filhas, sendo usada, usualmente, apenas como classe “root”. Essa qdisc cria automaticamente três classes: alta prioridade, média prioridade e baixa prioridade. O escalonamento implementado pela PRIO é uma priorização injusta, isto é, a classe de alta prioridade é servida enquanto tiver pacotes. A classe de média prioridade é servida apenas quando a classe de alta prioridade estiver vazia. A classe de baixa prioridade é servida apenas quando ambas as classes superiores estão vazias. Esse tipo de escalonamento é dito injusto pois pode fazer com que as classes menos prioritárias jamais sejam servidas.
A parte inferior da figura mostra como a qdisc é criada. Observe que a PRIO não solicita nenhum parâmetro. O comando cria uma política completa, já com as três classes e um qdisc fifo associada a cada classe, mas não cria os filtros. As classes são nomeadas de acordo com o código handle da qdisc. Por exemplo, se a qdisc PRIO tiver o código 1:0, a classe de alta prioridade será 1:1, a classe de média prioridade 1:2 e a classe de baixa prioridade 1:3. Para completar a política o administrador do sistema deve criar os filtros indicando quais políticas são alocadas para cada uma das classes.
Edgard Jamhour
prio
peakrate 1mbit minburst 1500
A qdisc do tipo TBF (Token Bucket Function) é usada para controlar a banda de uma única classe. Por exemplo, suponha que a qdisc principal seja do tipo PRIO, gerando as classes 1:1 (alta prioridade), 1:2 (média prioridade) e 1:3 (baixa prioridade). Como vimos, o escalonamento PRIO é injusto, pois as classes 1:2 e 1:3 podem nunca ser servidas, caso hajam muitos pacotes associados a classe 1:1.
Esse problema pode ser evitado, se uma qdisc TBF limitar a banda da classe 1:1. A seqüência de comandos para implementar essa política é ilustrada na figura. Observe que o primeiro comando cria as três classes e também as qdiscs do tipo FIFO associadas a cada classe (de forma automática). O segundo comando substitui a qdisc FIFO associada a classe 1:1 por outra do tipo TBF.
Os parâmetros usados pelo TBF são os seguintes:
rate: taxa média atribuída a classe
burst: tamanho do balde (em bytes), para controlar a duração das rajadas
latency: tempo máximo que um pacote pode ficar na fila aguardando uma ficha
peakrate: taxa de pico máxima das rajadas (em kbps ou mpbs)
minburst: quantidade mínimas de bytes contabilizada por pacote. Geralmente, utiliza-se o MTU de um quadro Ethernet (1500 bytes). Mesmo que um pacote com tenha tamanho inferior ao minburst, a quantidade de fichas consumidas do balde contabilizará o valor de minburst. Esse mecanismo é usado para evitar que um fluxo de pacotes pequenos seja tratado da mesma forma que poucos pacotes grandes. O primeiro caso consome mais recursos do roteador, e por isso é penalizado.
Edgard Jamhour
sfq perturb 10
sfq perturb 10
O algoritmo SFQ (Stochastic Fair Queuing) controla a forma como os pacotes de uma classe ou interface são encaminhados. Esse tipo de algoritmo cria automaticamente múltiplas filas para distribuir o fluxo de pacotes. Um fluxo de pacotes é determinado pela tupla (ip_origem:porta_origem – ip_destino:porta_destino). As filas SFQ são servidas um pacote de cada vez, utilizando a estratégia de round-robin, de maneira que a quantidade de banda atribuída a cada fila é equilibrada. A quantidade de filas SFQ nessa abordagem é variável, pois depende da quantidade de fluxos que atravessa uma interface ou uma classe do rotedor.
Esse algoritmo é controlado por dois parâmetros:
perturb: que determina o intervalo para recálculo do algoritmo de hashing, que readapta as filas para uma nova quantidade de fluxos. O valor recomendado para esse parâmetro é 10s.
quantum: determina a quantidade de pacotes removidos da fila SFQ por interação. O valor default é 1 = maximum sized packet (MTU-sized), o que determina que um pacote é enviado por completo de cada fila, cada vez que ela é servida.
Edgard Jamhour
htb rate rate ceil rate burst bytes
[ cburst bytes ] [ prio priority ]
Link
telnet
200.1.2.0/24
200.1.3.0/24
O algoritmo HTB permite estruturar uma hierarquia de divisão de bandas pela concatenação de classes. O HTB é considerado substituto do CBQ (Class Base Queuing), cuja implementação ineficiente não é considerada mais recomendada. Para criar uma política HTB, a classe root precisa ser do tipo htb, conforme indicado no primeiro comando da figura. Em seguida, cria-se um conjunto de classes usando o segundo comando. As classes possuem um conjunto de parâmetros utilizados para controlar a taxa de transmissão do tráfego que ela representa.
Os parâmetros da classe são os seguintes:
rate: taxa média garantida para classe e suas filhas
ceil: taxa máxima que pode ser emprestada da classe pai
burst: quantidade máxima de bytes que pode ser enviada na taxa ceil
cburst: quantidade máxima de bytes que pode ser enviada na taxa da interface (quando não houver limite imposto pela classe pai)
priority: ordenamento das classes. As classes de maior prioridade recebem o excesso de banda primeiro, reduzindo sua latência (prio 0 é a maior)
Para ilustrar como o HTB é utilizado considere o exemplo da figura. A política determina que um enlace de 3 Mbps deve ser dividido entre duas redes: A e B. A rede A recebeu 2 Mbps de banda garantida, e não pode ultrapassar esse limite, mesmo que haja banda disponível no enlace (pois rate é igual a ceil). A rede B possui 1 Mbps de banda garantida, e também não pode ultrapassar esse limite.
A banda da subrede A é dividida em aplicações de telnet, http e outras. As aplicações de telnet tem 200kbps garantidos, mas podem usar toda a banda da subrede caso as outras classes não estejam usando (pois o ceil é igual a capacidade total da subrede). O mesmo raciocínio se aplica para http e outros tipos de tráfego. Observe que o limite das classes filhas não pode ultrapassar o rate da classe pai.
Edgard Jamhour
Link
telnet
1:2
1:3
1:1
1:0
1:21
1:22
1:23
1:31
1:32
A fim de criar a hierarquia de classes, é necessário escolher os identificadores de cada classe que compõe a política. Como todas as classes são filhas da qdisc principal (identificada no exemplo pelo handle 1:0), todas as classes seguem a numeração 1:X. Um cuidado especial deve ser feito para indicar o relacionamento entre classes pais e filhas.
O script que ilustra a criação das classes para a política do desenho pode ser definido da seguinte forma:
#!/bin/bash
# cria a qdisc principal
# cria as classes para o link
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 3000 kbit
# cria as classes para as subredes
tc class add dev eth0 parent 1:1 classid 1:2 htb rate 2000 kbit ceil 2000 kbit
tc class add dev eth0 parent 1:1 classid 1:3 htb rate 1000 kbit ceil 1000 kbit
# cria as classes para dividir o tráfego da subrede A
tc class add dev eth0 parent 1:2 classid 1:21 htb rate 200 kbit ceil 2000 kbit
tc class add dev eth0 parent 1:2 classid 1:22 htb rate 800 kbit ceil 2000 kbit
tc class add dev eth0 parent 1:2 classid 1:23 htb rate 1000 kbit ceil 2000 kbit
# cria as classes para dividir o tráfego da subrede B
tc class add dev eth0 parent 1:3 classid 1:31 htb rate 500 kbit ceil 1000 kbit
tc class add dev eth0 parent 1:3 classid 1:32 htb rate 500 kbit ceil 1000 kbit
Edgard Jamhour
Link
telnet
qdisc
FIFO
qdisc
FIFO
qdisc
FIFO
qdisc
FIFO
qdisc
FIFO
1:2
1:3
1:1
1:0
1:21
1:22
1:23
1:31
1:32
210:0
220:0
230:0
310:0
320:0
Para completar a política é necessário incluir as qdisc para cada uma das classes folhas. Observe que apenas as classes folha (as mais inferiores na hierarquia) pode ser associadas as qdiscs. Associar uma qdisc a uma classe não folha, significa remover o pacote da fila antes que ele seja completamente classificado.
No exemplo todas as qdiscs das classes são do tipo FIFO. O script a seguir ilustra esse conceito.
# cria as qdiscs FIFO associada as classes folhas
tc qdisc add dev eth0 parent 1:21 handle 210:0 pfifo limit 10
tc qdisc add dev eth0 parent 1:22 handle 220:0 pfifo limit 10
tc qdisc add dev eth0 parent 1:23 handle 230:0 pfifo limit 10
tc qdisc add dev eth0 parent 1:31 handle 310:0 pfifo limit 10
tc qdisc add dev eth0 parent 1:32 handle 320:0 pfifo limit 10
Edgard Jamhour
HTB: Filtros
Link
telnet
1:2
1:3
1:1
1:0
1:21
1:22
1:23
1:31
1:32
210:0
220:0
230:0
310:0
320:0
Além das qdiscs é necessário definir os filtros que classificam os pacotes para cada classe. Novamente, são definidos filtros apenas para as classes folhas, que acumulam todas as regras de classificação das classes pai. Por exemplo, o filtro para classe de telnet da subrede A possui dois conjuntos de condições "match", uma para descriminar a subrede e outro para dizer caracterizar o tráfego de telnet.
Os filtros para o tráfego default (indicado como outros na figura), são implementados criando-se regra genéricas (sempre satisfeitas), mas de prioridade mais baixa. Por exemplo, na subrede A, pacotes que não se classificarem nas regras de prioridade 1 (telnet) ou 2 (htth), são classificados necessariamente na classe 3 (pois ela não tem restrição de porta). O script a seguir ilustra esse conceito.
# Cria os filtros para as classes folhas
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 \
match ip src 200.1.2.0/24 match ip dport 23 0xfff flowid 1:21
tc filter add dev eth0 parent 1:0 protocol ip prio 2 u32 \
match ip src 200.1.2.0/24 match ip dport 80 0xfff flowid 1:22
tc filter add dev eth0 parent 1:0 protocol ip prio 3 u32 \
match ip src 200.1.2.0/24 flowid 1:23
tc filter add dev eth0 parent 1:0 protocol ip prio 4 u32 \
match ip src 200.1.3.0/24 match ip dport 80 0xfff flowid 1:31
tc filter add dev eth0 parent 1:0 protocol ip prio 5 u32 \
match ip src 200.1.3.0/24 flowid 1:32
Edgard Jamhour
> tc qdisc add dev eth0 root handle 1:0
dsmark indices n default_index id
> tc class change dev eth0 classid 1:id
dsmark mask mask value value
new_DS = (old_DS & mask) | value
A qdisc DSMARK é utilizada para fazer a marcação ou remarcação do byte DS. Para criar uma política de marcação, é necessário criar uma qdisc root do tipo dsmark, conforme indicado no primeiro comando da figura. A qdisc dsmark é definida por dois parâmetros: indices e default_index. O parâmetro indices corresponde ao número de marcações distintas que serão feitas. Por exemplo, se indices=4, então poderão ser feitas até 4 marcações de pacotes com diferentes valores de DS (6 bits DSCP + 2bits ECN). O valor de indices deve ser múltiplo de 4, de forma que se forem necessários marcar 7 códigos distintos, será necessário utilizar índices=8.
A qdisc DSMARK cria automaticamente uma classe para receber os pacotes de cada um dos diferentes valores de DS que serão marcados. As classes são criadas de acordo com o handle da qdisc root, usando os códigos N:1, N:2, etc., onde N:0 é código da qdsic root. Essas classes não possuem marcação associada. Para definir como a marcação será feita, é necessário executar um comando "tc class change" para cada uma das classes de marcação da política, conforme indicado pelo segundo comando da figura. O comando "tc class change" é definido por dois parâmetro: mask e value.
O byte DS do pacote é marcado efetuando-se duas operações: um AND com o valor de mask e depois um OR com o valor de value, ou seja:
new_DS = (old_DS & mask) | value
Esse método é bastante flexível pois permite tanto efetuar a marcação com a remarcação do byte DS. Observe que para atribuir um valor ao byte DS de forma independente do seu conteúdo anterior, basta utilizar o valor 0x00 como mask.
Edgard Jamhour
Drop Precedence
DSCP em Hexa
DS em Hexa
A classes DSMARK alteram o valor do byte DS e não do campo DSCP. Convém recordar que o byte DS é composto por dois campos: 6 bits do código DSCP e 2 bits de notificação explícita de congestionamento (ECN). Atualmente, os bits ECN ainda são pouco usados, de forma que o uso principal do DSMARK é a marcação do campo DSCP. Como a DSMARK usa um valor em hexadecimal para os oito bits do byte DS, é preciso fazer uma manipulação de bits (um shift left de dois bits) para determinar qual o valor do DS corresponde a um dado código de DSCP.
A tabela na figura ilustra quais os valores devem ser usados no campo DS para obter cada um dos códigos DSCP correspondentes aos PHB's padronizados do Diffserv. A seguir são listados alguns exemplos de como definir os valores de mask e value para as classes DSMARK:
a) Setar todos os pacotes para AF23 independente do valor original:
mask 0x0 (b’00000000 ) value 0x58 (b’01011000 )
b) Setar todos os pacotes como AF12, preservando os bits ECN:
mask 0x3 (b’00000011 ) value 0x30 (b’00110000 )
c) Setar em 2 o 'drop precedence' de todos os pacotes
mask 0xe3 (b’11100011 ) value 0x10 (b’00010000)
d) Setar todos os pacotes para AF3, sem alterar os bites ECN e os bits de precedência.
mask 0x1f (b’00011111) value 0x60 (b’01100000)
Edgard Jamhour
Policiamento: Policing
Roteador de borda
Controle do excesso de tráfego e marcação para classe de core
Tráfego garantido: AF11
Tráfego excedente: AF12
Tráfego violado: DROP
Roteador de core
[reclassify | drop | continue]
Normalmente, as políticas do tipo DSMARK são utilizadas juntamente com políticas de policiamento. A razão para isso é que os pacotes pertencentes ao PHB AF (Assured Forwarded) não são classificados apenas de acordo com o tipo de tráfego, mas também de acordo com a quantidade de pacotes recebidos na classe. Por exemplo, alguns pacotes do tráfego de dados de um usuário podem ser marcados como AF11, AF12 ou descartados já na entrada do roteador, dependo se ele excedeu ou não a quantidade de tráfego garantida no seu contrato de SLA.
As políticas de policiamento são implementadas juntamente com os filtros incluindo-se a palavra reservada police no comandos tc filter, conforme indicado na figura. O policiamento é implementado de acordo com um filtro token bucket definido por uma taxa média (parâmetro rate, em kbps) e um tamanho de balde (burst, em kbytes). O último parâmetro especifica o que deve ser feito com os pacotes que excederem o burst. Três ações são possíveis:
drop: os pacotes são descartados
continue: procura-se uma outra regra para classificar o excesso de tráfego.
classify (apenas para CBQ): classifica o pacote como Best Effort.
Edgard Jamhour
Policiamento: Policing
balde 1
balde 2
e.g. AF12
e.g. 500 kbps
Uma política de marcação com múltiplas cores (por exemplo, AF11, AF12 e drop) é implementada cascateando-se filtros que tem o mesmo critério de classificação (isto é, os mesmos valores para os campos do cabeçalho IP ou TCP/UDP), mas com valores e ações de policiamento distintas. Por exemplo, a figura define a seguinte política: pacotes enviados pelo usuário até a taxa de 500 kbps são marcados como AF11, pacotes entre 500 kbps e 1000 kbps são marcados como AF12 e pacotes acima de 1 Mbps são descartados. Suponha que essa política se aplica a qualquer pacote enviado pelo usuário 192.168.1.2/32. O script que implementa essa política é definido a seguir:
#!/bin/bash
# Crias as classes dsmark
tc qdisc add dev eth0 handle 1:0 root dsmark indices 4
# Marcação em AF11
tc class change dev eth0 parent 1:0 classid 1:1 dsmark mask 0x0 value 0x28
# Marcação AF12
tc class change dev eth0 parent 1:0 classid 1:2 dsmark mask 0x0 value 0x30
# Filtro para classe AF11
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 \
match ip dst 192.168.1.2/32
# Filtro para classe AF12
tc filter add dev eth0 parent 1:0 protocol ip prio 2 u32
match ip dst 192.168.1.2/32
Edgard Jamhour
red limit <bytes> min <bytes> max <bytes> avpkt <bytes> \
burst <packets> probability <number> bandwidth <kbps> [ecn]
> tc qdisc add dev eth0 parent 1:1 handle 10:0 red ...
O principal objetivo deste algoritmo é limitar o tamanho das filas, controlando o atraso médio introduzido na transmissão de pacotes. Esse tipo de qdisc pode ser usado tanto em classes root (primeiro comando do exemplo), quanto para classes individuais (segundo comando do exemplo). Os parâmetros que controlam o comportamento dessa qdisc são os seguintes:
probability: probabilidade de descarte (de 0.0 a 1.0). Recomendado: 0.01 ou 0.02. Entre min e max, a probabilidade de descarte é proporcional ao tamanho médio da fila
max: tamanho médio da fila com probabilidade de descarte máxima. Esse valor é determinado pela fórmula: (largura de banda do enlace) * (atraso máximo desejado)
min: tamanho de fila médio que inicia o descarte. Valor recomendado: 1/3 * max
limit: tamanho máximo instantâneo da fila. Valor recomendado: >> max + burst ou 8 * max
burst: tolerância para tamanho instantâneo da fila. Valor recomendado: (min+min+max)/(3*avpkt).
avpkt: Tamanho médio do pacote em bytes
ecn: Explicit Congestion Notification. Corresponde ao bits menos significativos do byte DS. Quando ECN é usado, os pacotes abaixo de “limit” são marcados com ECN ao invés de descartados.
bandwidth: usado para calcular o tamanho médio da fila na ausência de tráfego (velocidade do link).
Edgard Jamhour
red limit 256000 min 12000 max 32000 avpkt 1000 \
burst 20 probability 0.02 bandwidth 512 ecn
sem descarte
descarte total para fila instantânea
Para ilustrar como os parâmetros do algoritmo de RED são calculados, considere a seguinte política associada a interface de um roteador com capacidade de 512 kbps. Deseja-se que os pacote sejam servidos com um atraso médio inferior a 0.5 s. O tamanho médio dos pacotes é 1 Kbyte.
Para calcular os parâmetros do RED, adota-se o seguinte procedimento:
a) Cálculo da capacidade do enlace em bytes/sec
<bandwidth> = 512 kbps ~ 512000 bps = 64000 bytes / sec
b) Cálculo do tamanho máximo da fila em bytes
Latência máxima desejada = 500 ms. Então:
<max> = 64000 bytes / sec * 0.5 sec = 32000 bytes
c) Tamanho da fila onde o descarte é iniciado:
<min> = ~ 1/3 <max> = 12000 bytes
d) Tamanho máximo instantâneo da fila
<limit> = ~ 8 * <max> = 256000 bytes.
e) Tamanho médio dos pacotes:
<avpkt> = 1000 bytes.
f) Tolerância para o tamanho instantâneo da fila em pacotes
<burst> = (2 * <min> + <max>) / (3 * <avpkt>)
= (2 * 12000 + 32000) / (3 * 1000) = 18.67 ~ 20.
Edgard Jamhour
Conclusão
O tc do linux apresenta um conjunto de algoritmos para controlar a forma como o tráfego é transmitido.
As políticas de QoS são feitas de forma independente para cada interface do computador/roteador
Os algoritmos de enfileiramento afetam apenas os pacotes que saem pela interface, e não os que entram.
Em um roteador, cada interface controla o QoS do tráfego em um único sentido.
Nesse módulo nós vimos o conjunto de mecanismos de QoS disponíveis no kernel do linux. Esses mecanismos são configurados através de políticas através do comando tc.
Existem um conjunto amplo de mecanismos disponíveis para QoS. Contudo, muitos desses mecanismos são usados em situações diferentes. Cabe ao administrador de rede selecionar o conjunto de mecanismos mais adequado para a política de QoS que deseja implementar.
Um cuidado especial deve ser tomado com o sentido do tráfego que se deseja controlar. As políticas de QoS são feitas de forma independente para cada interface do computador/roteador e afetam apenas os pacotes que saem pela interface, e não os que entram.
Se as políticas forem aplicadas a um servidor, por exemplo, elas irão afetar o download para o servidor e não o upload. A razão para isso é que não se pode controlar diretamente a quantidade de pacotes que chega apenas no seu destino, é preciso controlá-la na origem.