(M)  s i s t e m a   o p e r a c i o n a l   m a g n u x   l i n u x ~/ · documentação · suporte · sobre

  Página seguinte Página anterior Índice

581. Modo Multicast e Indiscriminado

ethernet,modo multicast e indiscriminado Uma outra coisa que o Donald tem trabalhado é na implementação dos ganchos do modos multicast e indiscriminado. Todos os programas de controle ISA lançados (ex. não ALPHA) agora suportam o modo indiscriminado.

Donald escreve: `Primeiro eu estava planejando fazê-lo enquanto implementava tanto o /dev/* quanto a interface DDI, mas não é a maneira correta de fazer. Nós devemos só capacitar os modos multicast ou indiscriminado quando alguma coisa quiser olhar os pacotes, e fechá-los quando aquele aplicativo estiver terminado, nenhuma das maneiras está fortemente relacionada a quando o hardware é aberto ou lançado.

Começarei discutindo o modo indiscriminado, que é conceituadamente fácil de implementar. Para a maioria dos hardware você só tem que configurar um bit de registro, e a partir daí você consegue todos os pacotes na linha. Bem, é quase tão fácil, pois em alguns hardware você precisa fechar a placa (potencialmente derrubar alguns pacotes), reconfigurar, e então recapacitar a placa ethernet. Isto é trabalho sujo e arriscado, mas a alternativa parece ter todos os registros de aplicações antes de você abrir a placa ethernet na hora da inicialização.

OK, então isto é fácil, por isso vou mudar para algo que não é assim tão óbvio: Multicast. Ele pode ser feito de duas maneiras:

  1. Use o modo indiscriminado, e um filtro como o filtro de pacote de Berkeley (BPF). O BPF é uma linguagem de configuração da correspondência de pilha, onde você escreve um programa que escolhe os endereços que você está interessado. Sua vantagem é que é muito genérico e programável. Sua desvantagem é que não há uma maneira genérica para o kernel evitar ligar o modo indiscriminado e rodar todos os pacotes na linha através de todos os filtros de pacote registrados. Veja Filtro de Pacotes de Berkley para maiores informações.
  2. Usando o filtro embutido multicast que a maioria das placas e chips possuem.

Eu acho que eu deveria relacionar o que algumas placas/chips ethernet fornecem:

        
        Filtro  Multicast Indiscriminado chip/placa
        ----------------------------------------
        Seeq8001/3c501  Yes     Binary filter (1)
        3Com/3c509      Yes     Binary filter (1)
        8390            Yes     Autodin II six bit hash (2) (3)
        LANCE           Yes     Autodin II six bit hash (2) (3)
        i82586          Yes     Hidden Autodin II six bit hash (2) (4)
        

  1. Estas placas necessitam um filtro, mas é uma simples questão de sim/não para a aceitação de todos os pacotes multicast ou a aceitação de nenhum dos pacotes multicast.
  2. AUTODIN II é o padrão ethernet CRC (checksum) de polinômio. Neste esquema os endereços multicast são redefinidos e melhorados numa tabela hash. Se o bit correspondente estiver capacitado, este pacote é aceito. Os pacotes ethernet são dispostos por isso para o hardware fazer isto é comum - você só tranca seis bits (geralmente) do circuito CRC (necessário de qualquer maneira para a verificação de erro) depois dos primeiros seis octetos (o endereço de destino), e usa-os como um índice na tabela hash (tabela de 6 bits a 64 bits).
  3. Este chips usam o hash de 6 bits, e tem que ter a tabela computada e carregada pela máquina. Isto significa que o kernel deve incluir o código CRC.
  4. O 82586 usa o hash de 6 bits internamente, mas ele computa a tabela hash a partir de uma lista de endereços multicast para aceitar.

Note que nenhum destes chips fazem a filtragem perfeita, e nós ainda precisamos de um módulo de nível médio para fazer a filtragem final. Também note que em todos os casos nós temos que manter uma lista completa dos endereços multicast aceitos para recomputar a tabela hash quando ela muda.

Meu primeiro passo no suporte do nível do dispositivo está detalhado no resumo do programa de controle skeleton.c. Parece assim:

        #ifdef HAVE_MULTICAST
        static void set_multicast_list(struct device *dev, int num_addrs,
                         void *addrs);
        #endif
        .
        .
        
        ethercard_open() {
        ...
        #ifdef HAVE_MULTICAST
                dev->set_multicast_list = &set_multicast_list;
        #endif
        ...
        
        #ifdef HAVE_MULTICAST
        /* Set or clear the multicast filter for this adaptor.
           num_addrs -- -1      Promiscuous modo, receive all packets
           num_addrs -- 0       Normal modo, clear multicast list
           num_addrs > 0        Multicast modo, receive normal and
                MC packets, and do best-effort filtering.
         */
        static void
        set_multicast_list(struct device *dev, int num_addrs, void *addrs)
        {
        ...

Qualquer comentário, crítica, etc. será bem-vindo.'


Página seguinte Página anterior Índice