--- title: NSE rapport tags: NSE --- # Plan [TOC] --- 1. Tntroduction 2. Fonctionnement network device driver 17.2/3/4/5/6/7/8/13/ 3. Qu'est ce qu'on va monitorer 4. Comment on va monitorer # Auteurs Jeremy Delbarre - jeremy.delbarre@epita.fr Moemoea Fiérin - moemoea.fierin@epita.fr Tristan Martin - tristan.martin@epita.fr Joffrey Chambon - joffrey.chambon@epita.fr # Introduction Pour comparer les networks devices drives il est nécessaire de comprendre leur fonctionnement. Un device driver est un programme qui intéragit directement avec le matériel de la machine (Schéma 1). Ils sont essentiels puisque se sont eux qui gèrent la communication entre le kernel et le matériel. Leur effacité ainsi que leur sécurité est donc très importante. ![Schéma 1 : Structure d'un noyau Linux](https://i.imgur.com/HnktkY7.png) #### Schéma 1 : Structure d'un noyau Linux Les devices sous Linux sont divisés en trois catégories principales: block, character et network devices. 1. Block Device : devices qui traitent des chunks de données qui sont accessibles aléatoirement. Par exemple : disques, accessibles dans un ordre arbitraire. 2. Character device : devices qui reçoivent et envoient des données dans l'ordre, sous forme de flux d'octets. Par exemple : clavier, écran, imprimante, souris. 3. Network device : ils sont similaires aux character device puisqu'ils traitent les données dans l'ordre d'arrivée. Cependant, ils ont des caractéristiques différentes de ceux-ci (telles qu'un délai très variable, un taux d'erreur variable, des protocoles réseau complexes, etc). Ces drivers reçoivent des paquets venant de n'importe quel processus de manière asynchrone. De ce fait, Linux les traite comme une classe à part entière. Par exemple : Ethernet, Wifi. Dans cette étude, nous ne nous intéresseront qu'à la partie network driver. # Fonctionnement d'un network device driver ## Fonctionnement de la stack réseau Linux Le schéma suivant montre l'infrastructure globale des réseaux sur linux nous nous attarderons surtout sur la base d'un Ethernet Adapter ![](https://i.imgur.com/J5LBvZh.png) #### Schéma 2: Pile réseau de Linux Le kernel Linux gère toute la pile réseau de la couche transport à la couche physique. Lorsque l'utilisateur souhaite accéder à une page web, le kernel va une utiliser une même structure de donnée (sk_buff) qui va permettre ## Enregistrement des network devices Le fonctionnement des enregistrements pour des network devices est différent des deux autres étant donné qu'il n'y a pas de numéros de version. Pour cela, le kernel va donc utiliser des structures net_device qui seront alloué par le système avec la fonction alloc_netdev dans laquelle on pourra préciser la fonction d'initialisation ainsi que la taille de la structure. ## Initialisation des network devices Pour avoir toutes les informations sur les devices le kernel va utilisé une structure net_dev. cette dernière contients toutes les informations nécessaire pour faire fonctionner le device network. Peut etre ajouter des détails sur la struct net_dev ## Ouverture et fermeture des network devices Pour pouvoir envoyer des paquets l'interface va d'abord devoir l'ouvrir et lui assigner une adresse. Pour ouvrir une nouvelle interface il va falloir utiliser une fonction open. En plus des taches habituelle a l'ouverture d'une device driver, cette fonction devra copier l'adresse MAC de la carte réseau dans le champ dev_addr. En plus de cela, la fonction va créer la queue pour transmettre les paquets. Ce n'est qu'une fois ceci fait que l'envoie et la réception de données pourront commencer. Pour la fonction stop c'est globalement l'inverse de la fonction open. Cette dernière va fermer la queue de transmission de donnée et donc empêcher l'envoi et la réception de paquet sur cette interface. ## Envoi des paquets La tâche essentielle d'un driver est de transmettre et de receptionner les données. La transmission fait référence à l'acte d'envoyer un paquet sur une liaison réseau. Chaque fois que le noyau a besoin de transmettre un paquet de données, il va appeller la méthode hard_start_transmit du pilote pour placer les données dans la file d'attente sortante. Chaque paquet géré par le noyau est contenu dans une structure sk_buff. Prenons l'exemple d'un Ping. Celui-ci utilise UDP pour transmettre un paquet ECHO_REQUEST. 1. ping va utiliser la fonction syscall sendto(). Les données vont être copier depuis l'AS user du ping vers un sk_buff dans l'AS du noyau. 2. UDP va encapsuler la donnée avec son header respectif. Puis il va envoyer ces données encapsulés à la couche IP via la fonction send(). 3. IP encapsule à son tour les données reçus puis appelle la fonction hard_xmit_start() prevenant du driver Ethernet. 4. Le driver va alors copier le paquet reçu depuis le sk_buff vers le buffer TX dans le NIU (voir Schéma 2). 5. Une fois la transmission terminée, la NIU envoie une interruption matérielle au pilote Ethernet ## Réception des paquets Le systeme de réception est plus complexe que l'envoi car il a deux modes possible pour la gestion de la réception (interrupt et polled). Dans le mode interrupt, il y a deux interruption possible: lorsque un paquet arrive et lorsque la transmission d'un paquet est arrivé. Ce mode est assez lent c'est pourquoi sur les drivers les plus récent le mode poll est ajouté. Cela va permettre de limiter le nombre d'interruption du processeur ## socket buffer # Notes sur les network device driver Pour gérer les devices, le kernel va utiliser la struct net_device qui sera initialisée avec la fonction alloc_netdev. Tous les drivers possèdent une fonction d'ouverture et de fermeture du driver. La fonction open chargera les interfaces pour que celles-ci puissent commencer à recevoir des paquets (démarrage de la queue). La fonction close sera chargée de fermer la queue lorsque l'on souhaite arrêter l'interface. Une fois l'interface ouverte, on peut commencer à gérer des paquets. Pour cela le kernel va utiliser la struct sk_buff. Les paquets a envoyés sont stockées dans de la mémoire dédiée. Si cette mémoire est pleine, le driver va prévenir le kernel avec la fonction netif_stop_queue et pourra être redémarré avec netif_wake_queue. Pour gérer les erreurs sur le réseau, les drivers vont utiliser un système de timeout. Si ce dernier est dépassé, le driver va alors lancer la fonction tx_timeout pour essayer de régler le problème. Lors de l'envoi des paquets le driver va souvent fragmenter le paquet. Si le paquet est fragmenté la variable data contient un pointeur vers le premier fragment. Tous les paquets seront alors envoyés au hardware puis reconstruit en un paquet. Pour la reception des paquets, c'est un peu plus compliqué. Il existe deux modes : poll et interrupt. Le mode interrupt va notifier le cpu lorsqu'il reçoit un nouveau paquet ou lorsque tous les paquets ont étaient traités. Le driver va alors traiter les paquets apres notification. Le mode poll permet de ne plus attendre la notification et de les traiter directement après la réception. # Comparaison : E1000 vs E1000E Pour effectuer cette comparaison, nous avons utilisé l'outil iperf3 sur des VMs. Nous avons utilisé 4 configurations différentes pour ces tests (Pilote serveur-pilote client) : * E1000-E1000 * E1000-E1000E * E1000E-E1000 * E1000E-E1000E Nous avons également fait varier la MSS (Maximum segment size) pour observer les variations de performance de ces drivers. 4 paliers de MSS ont été utilisé (aucune limite, 1000, 500, 200) ![](https://i.imgur.com/7PC09af.png) ![](https://i.imgur.com/4f82sHn.png) ![](https://i.imgur.com/zhwBt0S.png) ![](https://i.imgur.com/cgwKbXp.png) On peut constater que le pilote E1000E affiche des performances supérieures par rapport au pilote E1000 quelque soit la configuration de test. # Bibliography - [Linux Network Device Drivers: an Overview](http://students.iitmandi.ac.in/~tag/csdoc/Linux_Network_Device_Drivers_Overview_2020.pdf) - [Linux device driver strategies in network designs](https://www.embedded.com/linux-device-driver-strategies-in-network-designs/) - [Writing a Network device driver - Part 1](https://tldp.org/LDP/LG/issue93/bhaskaran.html) - [How do Linux drivers work and where do I find them? (esp. NIC driver)](https://unix.stackexchange.com/questions/11127/how-do-linux-drivers-work-and-where-do-i-find-them-esp-nic-driver) - [Writing Network Device Drivers for Linux](https://linuxgazette.net/156/jangir.html) - [Network Performance Monitoring And Tuning In Linux](https://www.opensourceforu.com/2016/10/network-performance-monitoring/) - [Linux Device Drivers – network driver](https://ufal.mff.cuni.cz/~jernej/2018/docs/predavanja15.pdf) - [Understanding Linux Network Device Driver and NAPI Mechanism](https://courses.engr.illinois.edu/cs423/sp2014/Lectures/LinuxDriver.pdf) - [How Do Linux Kernel Drivers Work?](https://www.youtube.com/watch?v=juGNPLdjLH4) - [Performances des cartes virtuelles(parl e1000e)](https://www.virtualementvotre.ch/blog/2014/11/17/performances-des-cartes-virtuelles/) - [Livre Linux Device Driver Book](https://owncloud.delbarre.net/index.php/s/YDJEP4bdyRPObI8) - [Monitoring des devices drivers](https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/#network-device-driver)