


Utiliser Netlink pour la communication entre l'espace utilisateur et l'espace noyau
En 2001, le comité ForCES IETF a officiellement réalisé des travaux de normalisation sur Netlink. Jamal Hadi Salim a proposé de définir Netlink comme un protocole de communication entre le composant moteur de routage d'un périphérique réseau et son composant de contrôle et de gestion. Cependant, sa suggestion n'a finalement pas été adoptée et a été remplacée par le modèle que nous voyons aujourd'hui : Netlink a été conçu comme un nouveau domaine de protocole, domaine.
Tobas, le père de Linux, a dit un jour "Linux est une évolution, pas une conception intelligente". Quel est le sens? En d'autres termes, Netlink suit également certains concepts de conception de Linux, c'est-à-dire qu'il n'existe pas de document de spécification ou de document de conception complet. Juste quoi? Vous savez --- "Lisez le putain de code source".
Bien sûr, cet article n'a pas pour but d'analyser le mécanisme d'implémentation de Netlink sur Linux, mais de partager avec vous les sujets de « Qu'est-ce que Netlink » et « Comment faire bon usage de Netlink ». Il vous suffit de lire les sources du noyau. code lorsque vous rencontrez des problèmes. Découvrez pourquoi.
Qu'est-ce que NetlinkPour comprendre Netlink, il faut saisir plusieurs points clés :
1. Sous-système de messagerie sans connexion pour les datagrammes
2. Implémenté sur la base de l'architecture commune BSD Socket
Concernant le premier point, il nous est facile de penser au protocole UDP. C'est formidable d'y penser. Il n'est pas déraisonnable de comprendre Netlink sur la base du protocole UDP. Tant que vous pouvez faire des parallèles et apprendre par analogie, être doué pour résumer et associer, et enfin réaliser le transfert de connaissances, c'est l'essence de l'apprentissage. Netlink peut réaliser une communication de données bidirectionnelle et asynchrone entre noyau->utilisateur et utilisateur->noyau. Il prend également en charge la communication de données entre deux processus utilisateur et même entre deux sous-systèmes du noyau. Dans cet article, nous ne considérerons pas les deux derniers et nous concentrerons sur la manière d'implémenter la communication de données entre les utilisateurs <->
Lorsque vous avez vu le deuxième point, l'image suivante vous est-elle venue à l'esprit ? Si oui, cela signifie que vous avez la racine de la sagesse ; bien sûr, sinon, cela n’a pas d’importance, la racine de la sagesse peut grandir lentement, haha.
Nous utiliserons principalement socket(), bind(), sendmsg() lors de la pratique ultérieure de la programmation de socket Netlink
Les appels système tels queet recvmsg(), et bien sûr le mécanisme d'interrogation fourni par socket.
Type de communication NetlinkNetlink prend en charge deux types de méthodes de communication : unicast et multicast.
Unicast : souvent utilisé pour la communication de données 1:1 entre un processus utilisateur et un sous-système du noyau. L'espace utilisateur envoie des commandes au noyau, puis reçoit les résultats des commandes du noyau.
Multicast : souvent utilisé pour la communication de données 1:N entre un processus noyau et plusieurs processus utilisateur. Le noyau agit en tant qu'initiateur de la session et l'application de l'espace utilisateur en est le récepteur. Afin de réaliser cette fonction, le programme spatial du noyau créera un groupe de multidiffusion, puis tous les processus de l'espace utilisateur intéressés par les messages envoyés par le processus du noyau rejoindront le groupe pour recevoir les messages envoyés par le noyau. Comme suit :
La communication entre le processus A et le sous-système 1 est unicast, et la communication entre les processus B et C et le sous-système 2 est multicast. L'image ci-dessus nous transmet également un message. Les données transférées de l'espace utilisateur vers le noyau n'ont pas besoin d'être mises en file d'attente, c'est-à-dire que l'opération est terminée de manière synchrone, tandis que les données transférées de l'espace noyau vers l'espace utilisateur doivent être mises en file d'attente, ce qui est asynchrone ; Comprendre cela peut nous éviter bien des détours lors du développement de modules applicatifs basés sur Netlink. Si vous envoyez un message au noyau et avez besoin d'obtenir certaines informations dans le noyau, telles qu'une table de routage ou d'autres informations, si la table de routage est trop volumineuse, alors lorsque le noyau vous renvoie des données via Netlink, vous pouvez penser à comment le recevoir. Problèmes de données, après tout, vous avez vu la file d'attente de sortie, vous ne pouvez pas fermer les yeux.
Format de message NetlinkLe message Netlink se compose de deux parties : l'en-tête du message et la charge utile, et l'intégralité du message Netlink est aligné sur 4 octets et généralement transmis dans l'ordre des octets de l'hôte. L'en-tête du message est fixé à 16 octets, et la longueur du corps du message est variable :
L'en-tête du message est défini dans le fichier
Cliquez (ici) pour réduire ou ouvrir
- struct nlmsghdr
- {
- __u32 nlmsg_len; /* Longueur du message y compris l'en-tête */
- __u16 nlmsg_type; /* Contenu du message */
- __u16 nlmsg_flags; /* Drapeaux supplémentaires */
- __u32 nlmsg_seq; /* Numéro de séquence */
- __u32 nlmsg_pid; /* Processus d'envoi PID */
- };
Explication et explication des attributs de chaque membre dans l'entête du message :
nlmsg_len : La longueur du message entier, en octets. Inclut l'en-tête du message Netlink lui-même.
nlmsg_type : le type de message, c'est-à-dire s'il s'agit d'un message de données ou de contrôle. Actuellement (version 2.6.21 du noyau) Netlink ne prend en charge que quatre types de messages de contrôle, comme suit :
NLMSG_NOOP - message vide, ne faites rien
NLMSG_ERROR - Indique que le message contient une erreur
NLMSG_DONE - Si le noyau renvoie plusieurs messages via la file d'attente Netlink, le dernier message de la file d'attente est de type NLMSG_DONE et l'attribut nlmsg_flags de tous les messages restants a le bit NLM_F_MULTI défini pour être valide.
NLMSG_OVERRUN-Pas encore utilisé.
nlmsg_flags : informations descriptives supplémentaires jointes au message, telles que NLM_F_MULTI mentionné ci-dessus. L'extrait est le suivant :
Tant que vous savez que nlmsg_flags a plusieurs valeurs, quant au rôle et à la signification de chaque valeur, vous pouvez certainement trouver la réponse via Google et le code source, je n'entrerai donc pas dans les détails ici. Toutes les valeurs du noyau 2.6.21 précédent :
nlmsg_seq : numéro de séquence du message. Étant donné que Netlink est orienté vers les datagrammes, il existe un risque de perte de données, mais Netlink fournit un mécanisme garantissant que les messages ne sont pas perdus, permettant aux développeurs de programmes de l'implémenter en fonction de leurs besoins réels. Les numéros de séquence de message sont généralement utilisés conjointement avec les messages de type NLM_F_ACK. Si l'application de l'utilisateur doit s'assurer que chaque message qu'elle envoie est reçu avec succès par le noyau, elle a besoin que le programme utilisateur définisse lui-même le numéro de séquence lors de l'envoi du message, et le noyau reçoit le message. Extrayez ensuite le numéro de série, puis définissez le même numéro de série dans le message de réponse envoyé au programme utilisateur. Un peu similaire au mécanisme de réponse et de confirmation de TCP.
Remarque : lorsque le noyau envoie activement un message de diffusion à l'espace utilisateur, ce champ dans le message est toujours 0.
nlmsg_pid : lorsqu'un canal d'échange de données est établi via Netlink entre un processus de l'espace utilisateur et un certain sous-système dans l'espace du noyau, Netlink attribuera une identification numérique unique à chacun de ces canaux. Sa fonction principale est de corréler les messages de requête et les messages de réponse de l'espace utilisateur. Pour le dire franchement, s'il y a plusieurs processus utilisateur dans l'espace utilisateur et plusieurs processus dans l'espace noyau, Netlink doit fournir un mécanisme pour garantir que l'interaction des données entre chaque paire de processus de communication espace « utilisateur-noyau » est cohérente.
C'est-à-dire que lorsque les processus A et B obtiennent des informations du sous-système 1 via Netlink, le sous-système 1 doit garantir que les données de réponse renvoyées au processus A ne seront pas envoyées au processus B. Il convient principalement aux scénarios dans lesquels les processus de l'espace utilisateur obtiennent des données de l'espace noyau. Normalement, lorsqu'un processus de l'espace utilisateur envoie un message au noyau, il attribue généralement l'ID de processus du processus actuel à cette variable via l'appel système getpid(). Autrement dit, le processus de l'espace utilisateur le fait lorsqu'il l'espère. obtenir une réponse du noyau. Ce champ est défini sur 0 pour les messages activement envoyés du noyau vers l'espace utilisateur.
Corps du message NetlinkLe corps du message de Netlink adopte le format TLV (Type-Length-Value) :
Chaque attribut de Netlink est représenté par struct nlattr{} dans le fichier
Message d'indication d'erreur fourni par Netlink
Contenu Lorsqu'une erreur se produit lors de la communication entre les applications de l'espace utilisateur et les processus de l'espace noyau via Netlink, Netlink doit informer l'espace utilisateur de ces erreurs. Netlink encapsule le message d'erreur séparément,Cliquez (ici) pour réduire ou ouvrir
- struct nlmsgerr
- {
- int error; //Code d'erreur standard, défini dans le fichier d'en-tête errno.h. Cela peut être expliqué en utilisant perror()
- struct nlmsghdr msg; //Indique quel message a déclenché la valeur d'erreur dans la structure
- };
1. Mémoire épuisée;
2. Débordement de tampon dans le processus de réception de l'espace utilisateur. Les principales raisons d'un dépassement de tampon peuvent être les suivantes : le processus de l'espace utilisateur s'exécute trop lentement ou la file d'attente de réception est trop courte ;
Si Netlink ne peut pas transmettre correctement le message au processus de réception dans l'espace utilisateur, alors le processus de réception dans l'espace utilisateur renverra une erreur de mémoire insuffisante (ENOBUFS) lors de l'appel du système recvmsg(). Cela doit être noté. En d'autres termes, la situation de débordement de tampon ne sera pas envoyée dans l'appel système sendmsg() depuis user->kernel. La raison a déjà été mentionnée. Veuillez y réfléchir vous-même.
Bien sûr, si le blocage de la communication par socket est utilisé, il n'y a aucun danger caché d'épuisement de la mémoire. Pourquoi ? Accédez rapidement à Google et recherchez ce qu’est un socket bloquant. Si vous apprenez sans réfléchir, vous serez en vain ; si vous réfléchissez sans apprendre, vous serez en danger.
Structure d'adresse de NetlinkDans l'article de blog TCP, nous avons mentionné la structure d'adresse et la structure d'adresse standard utilisées dans le processus de programmation Internet. Leur relation avec la structure d'adresse Netlink est la suivante :
La définition et la description détaillées de struct sockaddr_nl{} sont les suivantes :
Cliquez (ici) pour réduire ou ouvrir
- struct sockaddr_nl
- {
- sa_family_t nl_family; /*Ce champ est toujours AF_NETLINK */
- unsigned short nl_pad; /* Actuellement non utilisé, rempli de 0*/
- __u32 nl_pid; /* processus pid */
- __u32 nl_groups; /* masque de groupes multicast */
- };
nl_pid : Cet attribut est l'ID du processus d'envoi ou de réception de messages. Comme nous l'avons dit précédemment, Netlink peut non seulement réaliser une communication dans l'espace utilisateur-noyau, mais également permettre une communication en temps réel entre deux processus dans l'espace utilisateur, ou entre deux processus dans l'espace utilisateur. espace du noyau. Lorsque cet attribut vaut 0, il s'applique généralement aux deux situations suivantes :
Premièrement, la destination que nous voulons envoyer est le noyau, c'est-à-dire que lors de l'envoi de l'espace utilisateur à l'espace noyau, nl_pid dans la structure d'adresse Netlink que nous construisons est généralement défini sur 0. Une chose que je dois vous expliquer ici est que dans la spécification Netlink, le nom complet du PID est Port-ID (32 bits) et sa fonction principale est d'identifier de manière unique un canal de socket basé sur Netlink. Normalement, nl_pid est défini sur l'ID de processus du processus en cours. Cependant, dans le cas où plusieurs threads d'un processus utilisent le socket netlink en même temps, le paramètre nl_pid est généralement implémenté comme suit :
Cliquez (ici) pour réduire ou ouvrir
- pthread_self() <<16 |
nl_groups : si un processus de l'espace utilisateur souhaite rejoindre un groupe de multidiffusion, il doit exécuter l'appel système bind(). Ce champ précise le
masque du numéro de groupe multicast que l'appelant souhaite rejoindre (notez qu'il ne s'agit pas du numéro de groupe, nous expliquerons ce champ en détail plus tard). Si ce champ est à 0, cela signifie que l'appelant ne souhaite rejoindre aucun groupe de multidiffusion. Pour chaque protocole appartenant au domaine protocolaire Netlink, jusqu'à 32 groupes de multidiffusion peuvent être pris en charge (car la longueur de nl_groups est de 32 bits), et chaque groupe de multidiffusion est représenté par un bit.
Concernant les points de connaissances restants de Netlink, nous les aborderons plus tard lorsqu'ils seront utiles lors de séances pratiques.Pas terminé, à suivre...
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Les principales différences entre Centos et Ubuntu sont: l'origine (Centos provient de Red Hat, pour les entreprises; Ubuntu provient de Debian, pour les particuliers), la gestion des packages (Centos utilise Yum, se concentrant sur la stabilité; Ubuntu utilise APT, pour une fréquence de mise à jour élevée), le cycle de support (CentOS fournit 10 ans de soutien, Ubuntu fournit un large soutien de LT tutoriels et documents), utilisations (Centos est biaisé vers les serveurs, Ubuntu convient aux serveurs et aux ordinateurs de bureau), d'autres différences incluent la simplicité de l'installation (Centos est mince)

Comment utiliser Docker Desktop? Docker Desktop est un outil pour exécuter des conteneurs Docker sur les machines locales. Les étapes à utiliser incluent: 1. Installer Docker Desktop; 2. Démarrer Docker Desktop; 3. Créer une image Docker (à l'aide de DockerFile); 4. Build Docker Image (en utilisant Docker Build); 5. Exécuter Docker Container (à l'aide de Docker Run).

Étapes d'installation de CentOS: Téléchargez l'image ISO et Burn Bootable Media; démarrer et sélectionner la source d'installation; sélectionnez la langue et la disposition du clavier; configurer le réseau; partitionner le disque dur; définir l'horloge système; créer l'utilisateur racine; sélectionnez le progiciel; démarrer l'installation; Redémarrez et démarrez à partir du disque dur une fois l'installation terminée.

CentOS a été interrompu, les alternatives comprennent: 1. Rocky Linux (meilleure compatibilité); 2. Almalinux (compatible avec CentOS); 3. Serveur Ubuntu (configuration requise); 4. Red Hat Enterprise Linux (version commerciale, licence payante); 5. Oracle Linux (compatible avec Centos et Rhel). Lors de la migration, les considérations sont: la compatibilité, la disponibilité, le soutien, le coût et le soutien communautaire.

Méthode de visualisation du processus docker: 1. Commande Docker CLI: Docker PS; 2. Commande CLI Systemd: Docker d'état SystemCTL; 3. Docker Compose CLI Commande: Docker-Compose PS; 4. Process Explorer (Windows); 5. / Répertoire proc (Linux).

Docker utilise les fonctionnalités du noyau Linux pour fournir un environnement de fonctionnement d'application efficace et isolé. Son principe de travail est le suivant: 1. Le miroir est utilisé comme modèle en lecture seule, qui contient tout ce dont vous avez besoin pour exécuter l'application; 2. Le Système de fichiers Union (UnionFS) empile plusieurs systèmes de fichiers, ne stockant que les différences, l'économie d'espace et l'accélération; 3. Le démon gère les miroirs et les conteneurs, et le client les utilise pour l'interaction; 4. Les espaces de noms et les CGROUP implémentent l'isolement des conteneurs et les limitations de ressources; 5. Modes de réseau multiples prennent en charge l'interconnexion du conteneur. Ce n'est qu'en comprenant ces concepts principaux que vous pouvez mieux utiliser Docker.

Dépannage des étapes pour la construction d'image Docker échouée: cochez la syntaxe Dockerfile et la version de dépendance. Vérifiez si le contexte de construction contient le code source et les dépendances requis. Affichez le journal de construction pour les détails d'erreur. Utilisez l'option - cibler pour créer une phase hiérarchique pour identifier les points de défaillance. Assurez-vous d'utiliser la dernière version de Docker Engine. Créez l'image avec --t [Image-Name]: Debug Mode pour déboguer le problème. Vérifiez l'espace disque et assurez-vous qu'il est suffisant. Désactivez SELINUX pour éviter les interférences avec le processus de construction. Demandez de l'aide aux plateformes communautaires, fournissez Dockerfiles et créez des descriptions de journaux pour des suggestions plus spécifiques.

Vs Code Système Exigences: Système d'exploitation: Windows 10 et supérieur, MacOS 10.12 et supérieur, processeur de distribution Linux: minimum 1,6 GHz, recommandé 2,0 GHz et au-dessus de la mémoire: minimum 512 Mo, recommandée 4 Go et plus d'espace de stockage: Minimum 250 Mo, recommandée 1 Go et plus d'autres exigences: connexion du réseau stable, xorg / wayland (Linux) recommandé et recommandée et plus
