(Mão na massa)
Vimos no post anterior as opções de marcações. Agora vamos ver como fazer e usar as marcações para dar tratamento diferenciado para o tráfego.
Classification
O primeiro passo é fazer a classificação (identificação) do tráfego, e para isso usamos o class-map.
No Cisco IOS usamos o MQC (composto por class-map, policy-map e service-policy) para configurar o QoS.
Como citado anteriormente, podemos especificar uma ACL ou olhar diretamente no pacote para fazer a classificação.
Exemplo de classificação usando class-map, onde identificaremos os seguintes tráfegos:
- Tráfego que der match na ACL ipv6SSH (TCP porta 22)
- Tráfego Telnet com marcação CS6
- Tráfego ICMP e ICMPv6
QoS#conf t QoS(config)#ipv6 access-list ipv6SSH QoS(config-ipv6-acl)# permit tcp any any eq 22 QoS(config-ipv6-acl)# permit tcp any eq 22 any QoS(config-ipv6-acl)#exit QoS(config)# QoS(config)#class-map match-all CLASSSSH QoS(config-cmap)# match access-group name ipv6SSH QoS(config-cmap)#class-map match-all CLASSTELNET QoS(config-cmap)# match protocol telnet QoS(config-cmap)# match dscp cs6 QoS(config-cmap)#class-map match-any CLASSICMP QoS(config-cmap)# match protocol icmp QoS(config-cmap)# match protocol ipv6-icmp QoS(config-cmap)#end QoS#
Note que temos dois tipos de class-map: match-all (padrão) e match-any. Quando temos a opção match-all, apenas se o pacote atender todas as especificações ele será selecionado.
No caso do match-any, como usado no class-map CLASSICMP, se o tráfego atender pelo menos um dos requisições ele já e classificado. Ou seja, se for icmp ou icmpv6 ele será classificado pelo CLASSICMP, enquanto que para ser classificado pelo CLASSTELNET o pacote precisar ser telnet e ter a marcação CS6.
Também é importante ressaltar que apesar de não ter sido configurado, temos a class-default, onde os demais pacotes serão enquadrados.
Marking
Agora que fizemos a classificação do nosso tráfego, precisamos tomar uma ação, e fazemos isso usando o comando policy-map.
As ações podem ser marcar o pacote, definir banda, escolher o tipo de fila, shape/policing,…. Mas por enquanto vamos fazer apenas a marcação.
Configurando o Policy-Map para:
- Marcar o tráfego SSH com CS6
- Marcar o ICMP com EF
- Todo o resto com DSCP 0
QoS#conf t QoS(config)#policy-map MARCA QoS(config-pmap)# class CLASSSSH QoS(config-pmap-c)# set dscp cs6 QoS(config-pmap-c)# class CLASSICMP QoS(config-pmap-c)# set dscp ef QoS(config-pmap-c)# class CLASSTELNET QoS(config-pmap-c)# class class-default QoS(config-pmap-c)# set dscp default QoS(config-pmap-c)#end QoS#
Observe que inserimos a class CLASSTELNET mas não tomamos nenhuma ação (marcação). Neste caso o tráfego vai passar sem ser alterado.
Vamos associar nosso policy-map à interface (no sentido inbound) e verificar a configuração.
QoS#conf t QoS(config)#int et0/0 QoS(config-if)#service-policy input MARCA QoS(config-if)#end QoS# QoS#show policy-map interface et0/0 Ethernet0/0 Service-policy input: MARCA Class-map: CLASSSSH (match-all) 11941 packets, 922918 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: access-group name ipv6SSH QoS Set dscp cs6 Packets marked 11941 Class-map: CLASSICMP (match-any) 4039 packets, 4059374 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: protocol icmp 0 packets, 0 bytes 30 second rate 0 bps Match: protocol ipv6-icmp 4039 packets, 4059374 bytes 30 second rate 0 bps QoS Set dscp ef Packets marked 4039 Class-map: CLASSTELNET (match-all) 2665 packets, 197384 bytes 30 second offered rate 0000 bps Match: protocol telnet Match: dscp cs6 (48) Class-map: class-default (match-any) 4 packets, 304 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: any QoS Set dscp default Packets marked 4 QoS#
Idealmente a marcação é feita o mais perto possível da origem do tráfego (normalmente por um switch). Após a marcação os demais elementos da rede ficam encarregados de garantir o mesmo tratamento para o tráfego com a mesma marcação.
Também pode acontecer do dispositivo final (um telefone IP, por exemplo) fazer a marcação nos seus pacotes, mas é importante tomar medidas para evitar que alguém passe a enviar tráfego marcado e assim ser tratado com prioritário (um usuário poderia fazer com que sua máquina envie tráfego com marcação EF, e os roteadores passariam a priorizar este tráfego).
Assim a melhor opção é configurar a marcação nos switches, onde você define que tráfego receberá qual marcação (ou confiar apenas na marcação que vier de dispositivos confiáveis).
Congestion Management
O gerenciamento de congestionamento permite determinarmos a ordem em que pacotes são enviados por uma interface com base nas prioridades atribuídas a esses pacotes, e envolve a criação de filas, atribuição de pacotes a essas filas e agendamento para transmissão.
Resumindo… classificamos, marcamos e agora vamos dar o tratamento diferenciado com base na marcação.
Considera-se congestionamento quando as filas em hardware estão cheias
Por padrão, quando configuramos uma classe ela trabalha no modo FIFO – First In First Out. Ou seja, primeiro pacote que entra é o primeiro que sai, sendo que cada classe está sujeita ao limite de velocidade especificado para o momento de congestionamento. Podemos no entanto mudar o tipo de fila para WFQ – Weighted Fair Queueing (ou CBWFQ- Class Based Weighted Fair Queueing já que estamos usando o modelo de configuração usando classes).
O CBWFQ associa um peso (a conta leva em consideração o IPP) para cada flow, e os flows com pesos menores são encaminhados primeiro.
Vamos criar outro policy-map, onde:
- ICMP deverá ter 128 Kbps, e ser colocado na fila prioritária (LLC)
- SSH deverá ter 10% da banda
- Telnet deverá ter 20% da banda
- Configurar a class-default para usar WFQ
QoS#conf t QoS(config)#policy-map QUEUES QoS(config-pmap)# class CLASSICMP QoS(config-pmap-c)# priority 128 QoS(config-pmap-c)# class CLASSSSH QoS(config-pmap-c)# bandwidth percent 10 QoS(config-pmap-c)# class CLASSTELNET QoS(config-pmap-c)# bandwidth percent 20 QoS(config-pmap-c)# class class-default QoS(config-pmap-c)# fair-queue QoS(config-pmap-c)#end QoS#
Importante notar que:
-
quando colocamos bandwidth percent estamos reservando uma porcentagem com base no comando bandwitdth que foi aplicado na interface, e não na velocidade da porta (neste exemplo a interface et0/1 do roteador QoS foi configurada com o comando bandwitdh 256 Bkps).
-
Se primeiro configuramos as classes com o comando bandwidth e depois mudamos o bandwidth na interface, as políticas não são atualizadas.
-
Se não houver nenhuma configuração de bandwidth na interface, é considerado o valor real/físico.
-
Podemos especificar o valor em Kbps (ao invés de percent) quando usamos a opção bandwidth, assim como fizemos com o comando priority.
-
Além das opções priority e bandwidth ainda temos o comando bandwidth remain percent, que reserva a porcentagem especificada desconsiderando os valores já alocados para outras classes.
-
Todas as classes configuradas com bandwidth precisam ser configuradas no mesmo padrão. Ou usamos todas com bandwidth Kbps, ou com bandwidth percent ou com bandwidth remaining percent. Mas podemos usar um classe com priority Kbps e outra com priority percent.
- Podemos ter mais de uma class configurada como LLC, mas os pacotes serão colocados em uma única fila prioritária.
-
Quando a class-default não tem banda configurada ela recebe a banda não usada.
-
Por padrão a class-default tem 1% da banda.
-
A soma das velocidades configuradas não pode exceder 100%.
Neste modelo o tráfego tem sua banda garantida quando ocorre a concorrência (congestionamento), e até por isso o nome Congestion Management. No entanto o ICMP (neste exemplo) pode usar a banda total caso as outras aplicações não estejam consumindo o link. O mesmo serve para o Telnet, SSH e os demais tráfegos que estão usando a class default.
Também é bom ressaltar que o comando priority habilita o Low Latency Queuing, e os pacotes que estão nesta fila tem prioridade (são tirados da fila em software e colocados na fila em hardware antes dos pacotes que estão nas demais classes).
Congestion Avoidance
Tudo muito bem, tudo muito bom, mas…
Mesmo marcando, classificando e definindo banda por classe (fila) em dado momento o tráfego pode ser maior do que o permitido (ou maior do que a interface suporta). E aqui entra o Congestion Avoidance.
Temos duas técnicas para “evitar” congestionamento.
-
Tail Drop: Trata todo o tráfego igualmente e não diferencia entre classes de serviço. Quando a fila de saída está cheia os pacotes são descartados até que o congestionamento seja eliminado e a fila não esteja mais cheia.
-
WRED – Weighted Random Early Detection: Opção bem mais evoluída, que descarta pacotes antes da fila encher. Pacotes com menor prioridade começam a ser descartados antes, enquanto pacotes prioritários só são dropados posteriormente.
Além de considerar a prioridade dos pacotes, foi comprovado que dropar alguns pacotes antes da fila encher traz um resultado melhor do que dropar mais pacotes quando a fila já está cheia.
Este comportamento é explicado pela forma que o TCP trabalha. Quando ocorre perda de pacotes o TCP diminui a velocidade dos dados enviados (TCP congestion window, slow start), e quando ocorre uma grande perda de pacotes, que é o caso quando usamos o Tail Drop, o TCP diminui ainda mais a velocidade.
Com o WRED podemos definir limites para cada classe, e pacotes menos prioritários começam a ser dropados antes.
Lembram da marcação AF que falamos no post anterior? Então, por padrão o IOS já tem um profile para drop de pacotes com base na marcação AF.
Usando o profile pré definido, os pacotes AFx1 começam a ser descartados quando tivermos 33 pacotes na fila, enquanto que o roteador só descartará pacotes EF quando tiver 37 pacotes na fila.
Também é possível mudar o padrão e definir níveis diferentes para o drop por marcação. E bom lembrar que após atingir o threshould máximo todos os pacotes são dropados, agindo como o Tail Drop.
Complementando nossa configuração, vamos habilitar o WRED class default.
QoS#conf t QoS(config)#policy-map QUEUES QoS(config-pmap-c)#random-detect dscp-based QoS(config-pmap-c)#end QoS#
E usando o comando show policy-map interface et0/1 podemos ver o efeito da configuração.
QoS#show policy-map interface et0/1 Ethernet0/1 Service-policy output: QUEUES queue stats for all priority classes: Queueing queue limit 64 packets (queue depth/total drops/no-buffer drops) 0/0/0 (pkts output/bytes output) 4087/4064650 Class-map: CLASSICMP (match-any) 4087 packets, 4063502 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: protocol icmp 0 packets, 0 bytes 30 second rate 0 bps Match: protocol ipv6-icmp 4087 packets, 4063502 bytes 30 second rate 0 bps Priority: 128 kbps, burst bytes 3200, b/w exceed drops: 0 Class-map: CLASSSSH (match-all) 11941 packets, 922918 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: access-group name ipv6SSH Queueing queue limit 64 packets (queue depth/total drops/no-buffer drops) 0/0/0 (pkts output/bytes output) 11941/922918 bandwidth 10% (25 kbps) Class-map: CLASSTELNET (match-all) 2665 packets, 197384 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: protocol telnet Match: dscp cs6 (48) Queueing queue limit 64 packets (queue depth/total drops/no-buffer drops) 0/0/0 (pkts output/bytes output) 2665/197384 bandwidth 20% (51 kbps) Class-map: class-default (match-any) 716 packets, 81297 bytes 30 second offered rate 0000 bps, drop rate 0000 bps Match: any Queueing queue limit 64 packets (queue depth/total drops/no-buffer drops/flowdrops) 0/0/0/0 (pkts output/bytes output) 716/81297 Fair-queue: per-flow queue limit 16 packets Exp-weight-constant: 9 (1/512) Mean queue depth: 0 packets dscp Transmitted Random drop Tail/Flow drop Minimum Maximum Mark pkts/bytes pkts/bytes pkts/bytes thresh thresh prob default 716/81297 0/0 0/0 20 40 1/10 QoS#
Não tivemos tráfego suficiente para gerar drops, mas veja que na class-default estamos usando fair-queue, de acordo com o que foi configurado.
Também podemos usar o comando sem a opção dscp-based, mas neste caso o descarte é feito com base no IPP.
Referências:
-
CCIE Routing and Switching v5.0, Volume 2
Até a próxima.