8. Informations Techniques

Contenu de cette section

Pour ceux d'entre vous qui souhaitent jouer avec les pilotes actuels, ou essayer de faire leur propre pilote pour une carte qui n'est actuellement pas supportée, ces informations peuvent se révéler utiles. Si vous n'entrez pas dans cette catégorie de personne, vous devriez peut-être sauter cette section.

8.1 Adresses testées

Lors des essais réalisés afin de déterminer quelle carte Ethernet est présente, les adresses suivantes sont automatiquement testées, en considérant que le type de la carte n'a pas été spécifié dans le noyau. Les noms de fichier qui suivent se trouvent dans /usr/src/linux/drivers/net/.


        3c501.c:        0x280, 0x300
        3c503.c:        0x300, 0x310, 0x330, 0x350, 0x250, 0x280, 0x2a0, 0x2e0
        3c505.c:        0x300, 0x280, 0x310
        3c507.c:        0x300, 0x320, 0x340, 0x280
        3c509.c:        port d'identification spécial
        apricot.c:      0x300
        at1700.c:       0x300, 0x280, 0x380, 0x320, 0x340, 0x260, 0x2a0, 0x240
        atp.c:          0x378, 0x278, 0x3bc
        depca.c         0x300, 0x200
        de600.c:        0x378
        de620.c:        0x378
        eexpress.c:     0x300, 0x270, 0x320, 0x340
        hp.c:           0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240
        hp-plus.c       0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340
        lance.c:        0x300, 0x320, 0x340, 0x360
        ne.c:           0x300, 0x280, 0x320, 0x340, 0x360
        ni52.c:         0x300, 0x280, 0x360, 0x320, 0x340
        ni65.c:         0x300, 0x320, 0x340, 0x360
        smc-ultra.c:    0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380
        wd.c:           0x300, 0x280, 0x380, 0x240

Il existe certaines cartes Ethernet, clones de la NE2000, qui sont des trous noirs attendant les pilotes qui font des détections automatiques. Alors que de nombreux clones NE2000 sont sûrs jusqu'au moment où ils sont activés, certains ne peuvent pas être réinitialisés dans un état sûr. Ces cartes Ethernet dangeureuses bloqueront tout accès d'E/S sur leurs `ports de données'. Les endroit typiquement dangeureux sont:


        Adresse de base configurée    Endroits dangeureux
        par cavalier sur la carte     (adresse de base + 0x10 - 0x1f)
                0x300 *                         0x310-0x317
                0x320                           0x330-0x337
                0x340                           0x350-0x357
                0x360                           0x370-0x377

* L'adresse 0x300 est l'endroit traditionnel où placer une carte Ethernet, mais c'est aussi un endroit populaire où mettre d'autres périphériques (souvent des contrôleurs SCSI). L'adresse 0x320 est souvent celle choisie ensuite, mais c'est mauvais pour la procédure de détection de l'AHA1542. L'adresse 0x360 est mauvaise, parce qu'elle est en conflit avec le port parallèle qui se trouve en 0x378. Si vous avez deux contrôleurs IDE, ou deux contrôleurs de disquettes, alors 0x360 est aussi un mauvais choix, car une carte NE2000 les démolira aussi.

Notez que les noyaux > 1.1.7x conservent un log de qui utilise quels ports d'E/S, et ne laisseront pas un pilote utiliser des ports d'E/S précédemment enregistrés par un autre pilote. Il peut en résulter que des procédures de détection échoueront sans rien dire. Vous pouvez voir qui utilise quels ports d'E/S en tapant cat /proc/ioports si vous avez activé le système de fichier proc.

Pour éviter ces cartes Ethernet menaçantes, voici ce que vous pouvez faire:

8.2 Écriture d'un pilote de carte

La seule chose indispensable pour utiliser une carte Ethernet sous Linux est le pilote approprié. Pour que cela soit possible, il est essentiel que le constructeur diffuse les informations techniques nécessaires à la programmation de ce pilote à destination du public sans que vous (ou quelqu'un d'autre) ne soyez obligé de leur vendre votre âme. Un bon indice des chances d'obtenir de la documentation (ou, si vous ne programmez pas, les chances que quelqu'un d'autre pourra écrire ce pilote dont vous avez vraiment, vraiment besoin) est la disponibilité du pilote en mode paquet Crynwr (nee Clarkson ). Russ Nelson dirige cette opération, et il a été d'un grand service par son aide au cours du développement de certain pilotes pour Linux. Vous pouvez essayer cette URL pour consulter le programme de Russ.

Pilote en mode paquet de Russ Nelson

Une fois la documentation obtenue, vous pouvez écrire un pilote pour votre carte et l'utiliser sous Linux (du moins en théorie). Rappelez-vous néanmoins que certains matériels anciens qui ont été créés pour des machines XT ne fonctionneront pas bien dans un environnement multitâche comme Linux. Leur utilisation entraînera des problèmes importants si votre réseau est raisonnablement chargé.

La plupart des cartes possèdent des pilotes pour des interfaces MS-DOS comme NDIS ou ODI, mais ceux-ci sont inutiles pour Linux. De nombreuses personnes ont suggéré de les intégrer directement ou de réaliser une traduction automatique, mais c'est quasiment impossible. Les pilotes MS-DOS s'attendent à travailler en mode 16 bits et à utiliser des `interruptions logicielles', deux notions incompatibles avec le noyau Linux. Cette incompatibilité est en faite un avantage, puisque certains pilotes pour Linux sont considérablement meilleurs que leur équivalent MS-DOS. Par exemple, la série des pilote `8390' utilise des zones tampon de transmissions en ping-pong, qui commencent seulement à apparaître dans le monde MS-DOS.

(Des zones tampon de transmissions en ping-pong signifie que l'on utilise au moins deux zones de la taille maximale d'un paquet pour transmettre les paquets. L'une des zones est chargée pendant que la carte est en train de transmettre l'autre. Le deuxième paquet est alors transmis dès que le premier est fini, etc. De cette manière, la plupart des cartes sont capables d'envoyer des paquets à la queue-leu-leu sur le câble.)

Bon. Donc vous avez décidé d'écrire un pilote pour la carte Ethernet Machin, puisque vous avez les informations nécessaires à sa programmation, et que personne ne l'a encore fait (.. ce sont les deux conditions principales ;-) ). Vous devriez commencer avec le squelette de pilote réseau qui est fourni avec la distribution source du noyau Linux. Il se trouve dans le fichier /usr/src/linux/drivers/net/skeleton.c dans tous les noyaux récents. Jetez aussi un coup d'oeil sur le `Kernel Hackers Guide' à l'URL suivante:

KHG

8.3 Inteface du pilote avec le noyau

Voici quelques notes sur les fonctions que vous devrez écrire si vous créez un nouveau pilote. Lisez-les en gardant le squelette de pilote décrit ci-dessus: cela simplifiera les choses.

Détection de la carte (Probe)

Appelée au démarrage pour vérifier l'existence de la carte. Meilleure si elle peut vérifier sans indiscrétion en lisant la mémoire, etc. Peut aussi lire les ports d'E/S. Ecrire au démarrage sur les ports d'E/S pour détecter la carte n'est pas bien parce que cela risque de tuer un autre périphérique. Certaines parties de l'initialisation du périphérique sont habituellement faites à ce niveau (allouer l'espace d'E/S, les IRQ, remplir les champs de dev->???, etc.) Vous avez besoin de savoir à quels ports d'E/S et à quelles zones mémoire la carte peut être configurée, comment autoriser l'utilisation de mémoire partagée (si besoin), comment sélectionner et mettre en oeuvre la génération d'interruptions, etc.

Gestionnaire d'interruptions (Interrupt handler)

Appelé par le noyau quand la carte déclenche une interruption. A la responsabilité de déterminer pourquoi la carte a déclenché l'interruption, et d'agir en conséquence. Les conditions habituelles d'interruption sont l'arrivée de données, la fin d'une transmission, l'indication de conditions d'erreur. Vous avez besoin de connaître les bits d'informations liés à une interruption afin de pouvoir agir en conséquence.

Fonction de transmission (Transmit function)

Est liée à dev->hard_start_xmit() et est appelée par le noyau quand ce dernier désire envoyer des données par l'intermédiaire du périphérique. Envoie les données sur la carte et déclenche la transmission. Vous avez besoin de savoir comment empaqueter les données et comment les faire parvenir sur la carte (copie en mémoire partagée, transfert sur les ports d'E/S, DMA?) et au bon endroit sur la carte. Puis vous devez savoir comment dire à la carte d'envoyer les données sur le câble, et (éventuellement) d'émettre une interruption quand ce sera fini. Quand le périphérique ne peut plus accepter de paquets supplémentaires, il doit armer le drapeau dev->tbusy. Quand de la place est devenue disponible, en général au cours d'une interruption de fin de transmission, dev->tbusy doit être désarmé et les niveaux supérieurs doivent être informés en utilisant mark_bh(INET_BH).

Fonction de réception (Receive function)

Appelée par le gestionnaire d'interruption du noyau quand la carte indique que des données sont disponibles. Récupère les données de la carte, les empaquete dans un sk_buff et informe le noyau de la présence des données en effectuant un netif_rx(sk_buff). Vouz devez savoir comment mettre en oeuvre le déclenchement d'interruptions à la réception de données, comment vérifier les bits d'information correspondant à la réception, et comment récupérer les données depuis la carte (de nouveau par mémoire partagée, ports d'E/S, DMA, etc.)

Fonction d'ouverture (Open function)

Est liée à dev->open. Est appelée par les couches réseau quand quelqu'un fait ifconfig eth0 up - cela doit mettre le périphérique en route et l'autoriser à recevoir et transmettre des données. Toute incantation spéciale liée à l'initialisation et qui n'aurait pas été réalisée dans la séquence de détection (autoriser la génération d'IRQ, etc.) viendra ici.

Fonction de fermeture (facultative) (Close function)

Met la carte dans un état sain quand quelqu'un effectue ifconfig eth0 down. Doit libérer les IRQ et les canaux DMA si le matériel le permet, et éteindre tout ce qui pourrait économiser de l'énergie (comme le transmetteur ).

Autres fonctions

Des choses comme une fonction de réinitialisation, afin que, si les choses se dégradent, le pilote puisse essayer de réinitialiser la carte en dernier recours. Généralement fait quand une transmission dépasse son temps maximal ou quelque chose du genre. Ou encore une fonction pour lire les registres qui contiennent les statistiques sur la carte, si elle en comporte.

8.4 Les interruptions et Linux

Il y a deux genres de gestionnaires d'interruptions sous Linux: les rapides et les lents. Vous décidez à quel type appartient celui que vous installez à l'aide des informations que vous passez à irqaction(). Les rapides, comme le gestionnaire d'interruption du port série, tournent avec _toutes_ les interruptions interdites. Les gestionnaires normaux, comme ceux des pilotes de cartes Ethernet, tournent avec les autres interruptions (que celle(s) qu'ils sont en train de gérer, NDT) autorisées.

La structure d'interruption est à deux niveaux. La partie `rapide' s'occupe des registres de périphérique, enlève les paquets, et éventuellement arme un drapeau. Après cela, et une fois que les interruptions ont été ré-autorisées, la partie lente est exécutée si le drapeau est armé.

Le drapeau entre les deux partie est armé par:

mark_bh(INET_BH);

En général ce drapeau est armé à l'intérieur de dev_rint() pendant une interruption de réception de paquet, et armé directement par le gestionnaire de périphérique pendant une interruption de fin de transmission.

Vous vous demandez peut-être pourquoi tous les gestionnaires d'interruption ne peuvent pas tourner en `mode normal' avec les autres interruptions autorisées. Ross Biro utilise le scénario suivant pour illustrer le problème:

La structure d'interruption `rapide' résoud ce problème en autorisant les gestionnaires d'interruption à durée limitée à s'exécuter sans risque de laisser leurs lignes d'interruption masquées par une autre demande d'interruption.

Une autre distinction entre les gestionnaires d'interruption rapides et lents est constituée par les arguments passés au gestionnaire. Un gestionnaire `lent' est défini comme



                static void
                handle_interrupt(int reg_ptr)
                {
                    int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
                    struct device *dev = irq2dev_map[irq];
                ...

Tandis qu'un gestionnaire rapide obtient directement le numéro de l'interruption:



                static void
                handle_fast_interrupt(int irq)
                {
                ...

Enfin, un aspect important des performances réseau est le temps de latence. La seule carte qui résoud vraiment ce problème est la 3c509, qui permet le déclenchement d'une interruption prédictive. Elle fournit un réglage du temps de réponse à une interruption afin que le pilote puisse régler précisément combien de temps à l'avance une interruption est générée.

8.5 Programmation des puces Intel (i82586 et i82593)

Ces puces sont utilisées dans bon nombre de cartes, plus précisément la 3c507 ('86), l'Intel EtherExpress 16 ('86), l'exos205t de Microdyne ('86), le Z-Note ('93), et la ni5210 de Racal-Interlan ('86).

Russ Nelson écrit: La plupart des cartes basées sur la 82586 peuvent réutiliser un peu de leur code. Plus, en fait, que les adapatateurs à base de 8390. Il n'existe que trois différences entre elles:

L'Intel EtherExpress 16 est une exception, car elle mappe la 82586 sur des adresses d'entrée/sortie. Oui, elle mappe sur des E/S. C'est plutôt hétéroclite, mais cela fonctionne.

Garrett Wollman avait fait un pilote AT&T pour BSD qui utilise le copyright BSD. La dernière version que j'ai (Septembre 92) n'utilise qu'un seul tampon de transmission. Vous pouvez et même devez faire mieux que ça si vous avez la mémoire qu'il faut. L'AT&T et la 3c507 l'ont; la ni5210 ne l'a pas.

Les gens de chez Intel m'ont donné une indication vraiment importante sur la façon de placer dans la file d'attente plusieurs paquets à transmettre. Vous mettez en place une liste de blocs (NOP-> XMIT-> NOP-> XMIT-> NOP-> XMIT-> début), puis vous mettez le pointeur `suivant' de chacun des blocs NOP vers eux-mêmes. Maintenant vous démarrez l'unité de commande sur cette chaîne. Elle va continuellement travailler sur le premier block NOP. Pour transmettre le paquet suivant, vous le déposez dans le block XMIT (transmit - transmission) suivant, et vous faites pointer le NOP précédent vers lui. De cette façon, vous n'avez pas besoin d'attendre que la transmission précédente soit finie, vous pouvez placer dans la file d'attente plusieurs paquets sans ambigüité sur le fait de savoir s'il va être accepté, et vous pouvez éviter le délai lié au démarrage de l'unité de commande.'

8.6 Informations techniques de 3Com

Si vous êtes intéressé(e) par l'écriture de pilotes pour les cartes 3Com, vous pouvez obtenir de la documentation technique de 3Com. Cameron a été suffisamment gentil pour nous dire comment y parvenir:

Les adaptateurs Ethernet de 3Com sont documentés pour les auteurs de pilotes dans nos `Références Techniques' (Technical References, TRs). Ces manuels décrivent les interfaces du programmeur avec la carte, mais elles ne parlent pas des diagnostics, des programmes d'installation, etc., que l'utilisateur final peut voir.

Le département marketing de la Division Adaptateur Réseaux (Network Adapter Division) est responsable de la diffusion des TRs. Pour que ce programme reste efficace, nous le centralisons dans une entité appelé `CardFacts'. CardFacts est un système téléphonique automatisé. Vous l'appelez avec un téléphone à fréquences vocales et il vous envoie des choses par télécopie. Pour obtenir un TR, appelez CardFacts au 408-727-7021.

(NDT: Cela ne fonctionne qu'aux Etats-Unis.) Demandez le formulaire de commande du développeur (Developer's Order Form), le document numéro 9070. Ayez votre numéro de fax sous la main lorsque vous appelez. Complétez le formulaire de commande et envoyez-le par télécopie au 408-764-5004. Les manuels sont expédiés par le service J+2 de Federal Express.

Après avoir obtenu un manuel, si vous ne parvenez toujours pas à savoir comment programmer la carte, essayez notre BBS `CardBoard' au 1-800-876-3266, et si vous ne pouvez pas le faire, écrivez à Andy_Chan@3Mail.3com.com et demandez-lui une autre solution. Si vous avez un problème vraiment bloquant auquel personne n'a encore trouvé de solution, le gars qui a besoin de le savoir est Steve_Lebus@3Mail.3com.com.

Il y a des gens ici qui pensent que nous sommes trop libéraux avec les manuels, et qui cherchent des preuves que le système est trop onéreux, ou prend trop de temps et d'effort. C'est pourquoi il est important d'essayer d'utiliser CardFacts avant que vous ne commenciez à appeler ou à envoyer des messages aux gens que j'ai nommés ici.

Il y a même des gens qui pensent que nous devrions être comme Diamond et Xircom, d'exiger un `partenariat' resserré avec les auteurs de pilotes pour empêcher que des pilotes de faibles performances ne soient écrits. Jusqu'à présent, les consommateurs de 3Com ont été très bons sur ce point, et il n'y a pas de problème avec le niveau de demande que nous avons obtenu. Nous avons besoin que votre coopération et votre retenue continuent pour le conserver ainsi.

        Cameron Spitzer, 408-764-6339
        3Com NAD
        Santa Clara
        travail: camerons@nad.3com.com
        maison:  cls@truffula.sj.ca.us

8.7 Notes sur les cartes basées sur la puce PCnet / LANCE d'AMD

La puce LANCE (Local Area Network Controller for Ethernet, Contrôleur Réseau Local pour Ethernet) d'AMD constituait l'offre initiale, et a depuis été remplacée par la puce `PCnet-ISA', aussi connue en tant que 79C960. La 79C960, une puce relativement récente d'AMD, est le coeur de nombreuses nouvelles cartes qui sont produites aujourd'hui. Notez que le nom `LANCE' est resté, et certaines personnes se réfèrent à la nouvelle puce en utilisant l'ancien nom. Dave Roberts de la Division des Produits Réseaux (Network Products Division) d'AMD a été suffisamment gentil pour nous fournir les informations suivantes concernant cette puce:

`En ce qui concerne l'architecture elle-même, AMD l'a développée à l'origine et l'a réduite à une seule puce -- la PCnet(tm)-ISA -- il y a plus d'un an. Elle se vend comme des petits pains depuis.

Fonctionnellement, elle est équivalente à une NE1500. Le jeu de registres est identique à celui de la vieille LANCE avec les additions de l'architecture 1500/2100. Les vieux pilotes 1500/2500 fonctionneront avec la PCnet-ISA. L'architecture NE1500 et NE2100 est la même à la base. Initialement Novell l'a appelé la 2100, mais ensuite a essayé de distinguer entre cartes coax et 10Base-T. Tout ce qui était purement 10Base-T devait être numéroté dans l'intervalle 1500. C'est la seule différence.

De nombreuses sociétés offrent des produits basés sur la PCnet-ISA, y compris HP, Racal-Datacom, Allied Telesis, Boca Research, Kingston Technology, etc. Les cartes sont à la base les mêmes, excepté que certains constructeurs ont ajouté des fonctionnalités `sans-cavaliers' (`jumperless') qui permettent à la carte d'être configurée par logiciel. La plupart n'en ont pas. AMD offre un paquetage de conception standard pour une carte qui utilise la PCnet-ISA et de nombreux fabricants utilisent notre conception sans changement. Cela signifie que n'importe qui souhaitant écrire des pilotes pour la plupart des cartes basées sur la puce PCnet-ISA peut se contenter d'obtenir la documentation technique auprès d'AMD. Appelez notre centre de distribution documentaire au (800)222-9323 et demandez la documentation de l'Am79C960, PCnet-ISA. Elle est gratuite.

Un moyen rapide de comprendre si la carte est une carte `brute' est simplement de la regarder. Si elle est brute, elle doit juste comporter une grosse puce, un quartz, une petite PROM d'adresse IEEE, éventuellement un support pour une ROM de démarrage, et un connecteur (1, 2 ou 3, selon les options de média offertes). Notez que s'il s'agit d'une carte coax, elle comportera aussi quelques composants pour le transceiver, mais ils devraient être près du connecteur et éloignés de la PCnet-ISA.'

Des informations concernant la puce LANCE se trouvent aussi dans le fichier lance.c qui est inclus dans le noyau standard.

Une note pour les bidouilleurs potentiels de cartes est que différentes implémentations de la LANCE effectuent le `redémarrage' de différentes façons. Certaines reprennent où elles s'étaient arrêtées dans l'anneau, et d'autres démarrent directement au début de l'anneau, comme si elles venaient d'être initialisées. C'est important lorsque vous mettez en place la liste pour le multicast.

8.8 Multicast et Mode `Promiscuous'

Une des autres choses sur lesquels Donald a travaillé est l'implémentation des points d'entrée pour le multicast et le mode `promiscuous'. Tous les pilotes ISA publiés (c'est-à-dire pas les pilotes au stade `alpha') supportent aujourd'hui le mode promiscuous.

Donald écrit: `Au début je prévoyais de le faire lors de l'implémentation soit de /dev/* soit de l'interface DDI, mais ce n'était pas vraiment la bonne façon de faire. Nous ne devons activer les modes multicast ou promiscuous que lorsque quelque chose souhaite regarder les paquets, et le désactiver quand cette application est finie, rien de tout cela n'étant vraiment lié à la mise en route ou à l'arrêt de la partie matérielle.

Je commencerai par parler du mode `promiscuous', qui est conceptuellement facile à implémenter. Pour la plupart des matériels, vous n'avez qu'à positionner un bit de registre, et à partir de ce moment-là vous obtenez tous les paquets qui passent sur le fil. Bon, ce n'est pas vraiment aussi simple que cela; pour certains matériels vous devez arrêter la carte (en perdant potentiellement quelques paquets), la reconfigurer, puis la réactiver. C'est dégoûtant et risqué, mais la solution alternative semble être d'obliger toutes les applications à s'enregistrer avant que vous ne démarriez la carte Ethernet au moment du démarrage du noyau.

Ok, ça c'est facile, donc je passe à quelque chose qui n'est pas aussi évident: le multicast. On peut le réaliser de deux façons:

  1. Utiliser le mode promiscuous, et un filtre de paquet comme le filtre de paquet de Berkeley (Berkeley packet filter, BPF). Le BPF est un langage à pile de recherche de motifs (pattern matching stack), avec lequel vous écrivez un programme qui extrait les adresses qui vous intéressent. Son avantage est qu'il est très général et programmable. Son inconvénient est qu'il n'existe pas de moyen général pour le noyau d'éviter d'avoir à mettre en route le mode promiscuous et de passer chaque paquet qui circule sur le fil à travers tous les filtres de paquets qui se sont enregistrés. Consultez  Le Berkeley Packet Filter pour plus d'informations.
  2. Utiliser le filtre multicast que la plupart des puces Ethernet possèdent.

Je devine que je devrais donner une liste de ce que quelques cartes ou puces Ethernet fournissent:

        
        Puce/carte  Promiscuous  Filtre Multicast
        -----------------------------------------
        Seeq8001/3c501  Oui     Filtre binaire (1)
        3Com/3c509      Oui     Filtre binaire (1)
        8390            Oui     Hashage a six bits Autodin II (2) (3)
        LANCE           Oui     Hashage a six bits Autodin II (2) (3)
        i82586          Oui     Hashage a six bits Autodin II cache (2) (4)
        

  1. Ces cartes prétendent avoir un filtre, mais il s'agit d'un simple oui/non `accepte tous les paquets multicast', ou `n'accepte aucun paquet multicast'.
  2. AUTODIN II est le polynôme standard de contrôle Ethernet (somme de contrôle/checksum CRC). Dans ce principe, les adresses multicast sont hashées et recherchées dans une table de hashage. Si le bit correspondant est activé, ce paquet est accepté. Les paquets Ethernet sont conçus de telle façon que la partie matérielle pour réaliser ceci est triviale -- vous mémorisez juste (habituellement) six bits du circuit CRC (qui est nécessaire de toute façon pour la vérification d'erreur) après les six premiers octets (l'adresse de destination), et vous les utilisez comme index dans la table de hashage (six bits -- une table de 64-bits).
  3. Ces puces utilisent le hashage à six bits, et nécessitent que la table soit calculée et chargée par l'hôte. Cela signifie que le noyau doit comprendre le code pour le CRC.
  4. Le 82586 utilise le hashage à six bits de façon interne, mais il calcule la table de hashage lui-même à partir d'une liste d'adresses multicast à accepter.

Notez qu'aucune de ces puces ne réalise un filtrage parfait, et nous avons encore besoin d'un module de niveau intermédiaire pour réaliser le filtrage final. Notez aussi que dans chaque cas nous devons conserver une liste complète des adresses multicast acceptées pour recalculer la table de hashage quand elle change.

Ma première approche du support de niveau intermédiaire est détaillée dans l'esquisse de pilote skeleton.c.

Cela ressemble à ce qui suit:


        #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 mode, receive all packets
           num_addrs -- 0       Normal mode, clear multicast list
           num_addrs > 0        Multicast mode, receive normal and
                MC packets, and do best-effort filtering.
         */
        /* Positionne ou vide le filtre multicast pour cet adaptateur.
           num_addrs -- -1    Mode promiscuous, reçoit tous les paquets
           num_addrs -- 0     Mode normal, efface la liste multicast
           num_addrs > 0      Mode multicast, reçoit les paquets normaux
                et les paquets multicast, et filtre du mieux possible.
         */
        static void
        set_multicast_list(struct device *dev, int num_addrs, void *addrs)
        {
        ...

Tous commentaires, critiques, etc. sont les bienvenus.''

8.9 Le filtre de paquet de Berkeley (Berkeley Packet Filter -- BPF)

L'idée générale pour les développeurs est que la fonctionnalité du BPF ne doit pas être fournie par le noyau, mais doit se trouver dans une librairie de compatibilité (dont on espère qu'elle servira peu).

Pour ceux qui ne seraient pas au courant: BPF (le Berkeley Packet Filter) est un mécanisme destiné à spécifier aux couches réseau du noyau quels paquets vous intéressent. Il est implémenté sous la forme d'un interpréteur d'un langage à pile spécialisé construit dans un niveau bas du code réseau. Une application passe un programme écrit dans ce langage au noyau, et le noyau exécute le programme sur chaque paquet entrant. Si le noyau possède plusieurs applications BPF, chaque programme est exécuté sur chaque paquet.

Le problème est qu'il est difficile de déduire quel type de paquet intéresse réellement l'application à partir du programme de filtrage, donc la solution est de toujours exécuter le filtre. Imaginez un programme qui enregistre un programme BPF pour extraire un flux à faible taux de données envoyé à une adresse multicast. La plupart des cartes Ethernet possèdent un filtre d'adresses multicast implémenté sous la forme d'une table de hashage à 64 entrées qui ignore la plupart des paquets multicast non souhaités, donc les capacités existent pour faire de cette opération une opération peu coûteuse en ressources. Mais avec le BPF, le noyau doit passer l'interface en mode promiscuous, recevoir _tous_ les paquets, et les passer à travers ce filtre. C'est un travail, à propos, qu'il est très difficile de comptabiliser dans le processus qui a demandé les paquets.


Chapitre suivant, Chapitre Précédent

Table des matières de ce chapitre, Table des matières générale

Début du document, Début de ce chapitre