• Sonuç bulunamadı

2.2 ĠDARĠ PARA CEZASI KAVRAMI

2.2.3 Para Cezaları ÇeĢitleri

Os códigos apresentados até aqui são executados no nível do sistema operacional. Na implementação do Gatekeeper-ng buscou-se simplificar ao máximo o trabalho realizado pelo Kernel por questões de desempenho e portabilidade, seguindo a mesma prática adotada pelo Open vSwitch. O Kernel é responsável apenas por manter a monitoração da vazão de cada interface e de cada fluxo e enviar notificações de congestionamentos para o Controlador de Congestionamentos.

O tratamento das notificações de congestionamentos enviadas pelo Kernel é im- plementada à nível de usuário, no daemon do Open vSwitch, o ovs_vswitchd. Para que os datapaths, executados no nível do Kernel, possam se comunicar com o daemon, o Open vSwitch utiliza filas de notificações que são compartilhadas entre esses dois componentes do sistema, como apresentado na figura 3.3.

Ao invés de verificar continuamente os dados presentes no Kernel utilizando cha- madas de sistema, como era feito a cada D milissegundos na implementação anterior do Gatekeeper, o daemon do Open vSwitch registra tratadores de eventos junto ao seu componente que executa à nível de kernel, o openvswitch_mod, e passa a dormir, interrompendo a sua execução. Quando um desses eventos ocorre, o openvswitch_mod utiliza a fila de notificações para armazenar eventuais informações relacionadas ao evento e acorda o daemon. Após isso, as mensagens na fila de notificações são lidas pelo daemon, que realiza o tratamento desses eventos. Um exemplo de uso dessa inter- face na implementação original do Open vSwitch é a falta de uma regra de chaveamento na sua Tabela de Fluxos quando um pacote de um novo fluxo é recebido. Nesse caso o datapath precisa perguntar a um controlador OpenFlow o que fazer com esse fluxo, como bloquear, encaminhar para uma determinada porta ou então enfileirar os pacotes em uma fila específica. A comunicação entre o datapath e o controlador é intermediada pelo daemon ovs_vswitchd, que utiliza a interface de filas entre os níveis de Kernel e usuário para receber informações relativas ao novo fluxo. O Gatekeeper-ng utiliza essa mesma interface de comunicação para receber notificações do Kernel toda vez que ocorre um Monitor de Tráfego detecta um congestionamento.

Como daemon do Open vSwitch só é executado quando um evento ocorre, essa regra também se estende ao Controlador de Congestionamento do Gatekeeper-ng, que é implementado dentro desse processo. Essa é uma outra diferença entre essa versão do sistema e da versão anterior, cujo código a nível de usuário era executado a cada D milissegundos mesmo quando não existem fluxos de tráfego no switch virtual.

ções do switch virtual, como a interface de configuração das interfaces virtuais e dos datapaths, manutenção do banco de dados que armazena as informações referentes às configurações dos elementos de chaveamento virtual e o suporte aos canais de comuni- cação seguros entre controladores OpenFlow e datapaths. Todas essas funcionalidades são invocadas a partir do laço principal do daemon, apresentado na listagem de có- digo 3.3. Basicamente, o daemon realiza as configurações iniciais dos datapaths e inicia um laço infinito, que faz com que ele passe a dormir esperando por um evento e acorde para realizar eventuais tratamentos.

1 main ( ) { 2 . . . 3 while( ! e x i t i n g ) { 4 5 bridge_run ( ) ; 6 dp_run ( ) ; 7 netdev_run ( ) ; 8 9 s i g n a l _ w a i t ( s i g h u p ) ; 10 br i dg e _w a it ( ) ; 11 dp_wait ( ) ; 12 netdev_wait ( ) ; 13 p o l l _ b l o c k ( ) ; 14 } 15 . . . 16 }

Listing 3.3. Visão geral da implementação do daemon do Open vSwitch, ovs_vswitchd

De todos os fluxos de execução que têm início no laço infinito do daemon, a cha- mada de função importante para o Gatekeeper-ng é a bridge_run(). Essa função é o ponto de partida para a lógica básica de um switch que implementa a especificação OpenFlow, chamado pelo Open vSwitch de ofproto. A estrutura que armazena as va- riáveis referentes ao switch virtual, como endereço do controlador OpenFlow associado ao datapath e demais variáveis de configuração do switch, é a struct ofproto. Essa estrutura também foi alterada para abrigar as variáveis de controle do Gatekeeper-ng: o limite que indica qual é banda reservada para detecção de congestionamentos, ou headroom (identificada pelo limiar rx_threshold nas listagens de código); as estrutu- ras referentes aos sockets para comunicação entre Controladores de Congestionamentos instalados em outras máquinas físicas; e a estrutura do serviço de diretórios, que contém as informações referentes às VMs.

Na função ofproto_run(), apresentada na listagem de código 3.4, referente à execução do ofproto, foram inseridos os códigos relacionados ao Controlador de Con- gestionamentos do Gatekeeper-ng para o tratamento das mensagens de notificação advindas do Kernel, envio e recebimento de notificações de congestionamento de/para outros Controladores de Congestionamento e ajuste de taxas do Escalonador de Saída. O tratamento das notificações do Kernel é feito pela função handle_kernel_msg(), que verifica qual foi o tipo do evento enviado pelo Kernel e caso esse seja uma notifica- ção de congestionamento, realiza a leitura da Tabela de Fluxos utilizando a chamada de sistema ioctl() e executa a função gk_feedback() que irá determinar o destino da notificação de congestionamento. Nessa mesma listagem de código também estão as chamadas das funções para receber uma mensagem de congestionamento de um outro Controlador de Congestionamento, através chamada de sistema recvfrom() e no processamento dessa mensagem recebida, realizado pela função gk_recv_msg(). A comunicação entre os Controladores de Congestionamento é feita através de mensagens UDP.

1 /∗ From bri dge _run ( ) ∗/

2 ofproto_run ( struct o f p r o t o ∗p ) { 3 . . . 4 5 r e t = r e c v f r o m ( p−>r s o c k , buf , . . . ) ; 6 i f ( r e t > 0 ) { 7 gk_recv_msg ( p , buf ) ; 8 } 9 10 poll_fd_wait ( p−>r s o c k , POLLIN) ; 11 12 f o r ( ; ; ) { 13 r e t = d p i f _ r e c v ( p−>d p i f , buf ) ; 14 i f ( r e t ) 15 handle_kernel_msg ( p , buf ) ; 16 e l s e 17 break; 18 } 19 . . . 20 } 21

22 handle_kernel_msg ( struct o f p r o t o ∗p , struct o f p b u f ∗msg ) { 23 struct odp_flow ∗ f l o w s

24 switch ( msg−>r e a s o n ) { 25 . . .

26 case GK_CONGESTION:

27 n_flows = gk_get_flows ( p , &f l o w s ) ; 28 gk_feedback ( p , &f l o w s , n_flows ) ; 29 break;

30 } 31 . . . 32 }

Listing 3.4. Fluxos para chamadas de funções do Gatekeeper-ng, implementadas no ovs_vswitchd