1. Origine
Mon travail est lié aux produits de passerelle, et je suis souvent en contact avec le protocole pppoe, mais je ne sais pas grand-chose sur la façon dont ppp et pppoe sont implémentés. La recherche d'articles connexes sur Internet décrit principalement le contenu spécifique du protocole ppp / pppoe et le processus de flux de données volumineux, mais pas trop de détails sur l'implémentation du pilote pppoe et du code du pilote ppp dans le noyau. De Cao et Hu Ximing pendant cette période. L'analyse du scénario du code source du noyau Linux de l'enseignant, après avoir lu le pilote du terminal dans le noyau, j'ai décidé d'étudier attentivement le contenu du pilote PPP / PPPOE et d'enregistrer les gains pendant cette période de temps, afin que je puisse le lire plus tard et le partager avec vous.
2. À propos de cet article
Cet article n'impliquera pas le protocole ppp et le protocole pppoe lui-même, c'est-à-dire qu'il ne discutera pas du format de ces messages tels que LCP, PAP, CHAP, IPCP, PADI, etc. Si vous voulez seulement comprendre les ppp et pppoe protocole lui-même, alors cet article L'article n'est pas pour vous.
Si vous voulez comprendre les pilotes ppp et pppoe, vous voulez savoir comment le programme ppp établit l'interface réseau ppp, et comment l'interface réseau ppp envoie des données via une interface réseau spécifique (telle que eth0), et une interface réseau spécifique ( comme eth0) reçoit Après avoir atteint les données, comment envoyer les données à l'interface réseau ppp, cet article est fait pour vous.
Lors de la lecture de cet article, il est recommandé de copier l'organigramme de chaque partie et de l'enregistrer dans un document, puis de regarder le code par rapport à l'organigramme.
3. Lien de code
lien de téléchargement du code ppp http://mirrors.aliyun.com/ubuntu/pool/main/p/ppp/ppp_2.4.7.orig.tar.gz
Lien de téléchargement de code Linux-2.4.0 https://mirrors.edge.kernel.org/pub/linux/kernel/v2.4/linux-2.4.0.tar.gz
4. Analyse du code
1. Aperçu du contenu
commande pppd
code ppp pour créer une interface réseau ppp
pilote pppoe pour établir le canal
Le pilote ppp établit l'interface réseau ppp et s'associe au canal établi par pppoe
interface réseau ppp et processus de réception du programme ppp
programme ppp et processus de package d'interface réseau ppp
Commande 2.pppd
plugin pppd /usr/lib/rp-pppoe.so nic-pon0.30 nom de lien noeud internetfaultroute noipdefault noauth default-asyncmap hide-password nodetach usepeerdns mtu 1492 mru 1492 noaccomp nodeflate nopcomp novj novjccomp utilisateur aaa lcp-écho-écho intervalle 20 -failure 10 nopersist
3. code ppp pour créer une interface réseau ppp
[ppp-2.4.7] main.c
[ppp-2.4.7] options.c
[ppp-2.4.7] options.c 中 general_options
4. pilote pppoe pour établir un canal
the_channel-> connect () est PPPOEConnectDevice, cette fonction est relativement longue, regardons-la dans les sections
Code Linux
Dans la figure ci-dessus, proto [protocole] -> create est pppoe_create, car le protocole est PX_PROTO_OE, qui est enregistré dans pppoe_init
Retour à la fonction PPPOEConnectDevice (suite 1)
Dans openInterface, un socket sera créé et l'interface sera liée, comme le montrent les deux figures suivantes
Une fois le socket créé avec succès, revenez à la fonction PPPOEConnectDevice et appelez la fonction discovery () pour interagir avec le protocole pppoe
Ensuite, regardez la fonction PPPOEConnectDevice (suite 2), la fonction de connexion sera appelée
La fonction connect appellera pppoe_connect dans le noyau. Cette fonction est incluse dans pppoe_ops et est définie sur sock-> ops dans pppoe_create, qui est le paramètre lié à notre conn-> sessionSocket. Ce processus peut être vu ci-dessus.
La fonction ppp_register_channel générera struct channel * pch, définira pch-> chan sur chan et placera pch dans all_channels
5. Le pilote ppp établit une interface réseau ppp et s'associe au canal établi par pppoe
De retour à la fonction start_link de l'auth.c de ppp, the_channel-> Establ_ppp () est generic_establish_ppp
Il faut noter que le fd dans la fonction a changé. Au début, fd est la valeur de retour de la fonction PPPOEConnectDevice conn-> sessionSocket, et appeler ioctl dessus ira à linux
fonction pppox_ioctl, cette fonction retourne l'index du canal créé par PPPOEConnectDevice [plugin.c en code ppp] appel de la fonction connect
Ensuite, regardez les actions d'appeler PPPIOCATTCHAN, make_ppp_unit et PPPIOCCONNECT pour fd vers "/ dev / ppp" dans generic_establish_ppp
L'appel de ioctl appellera la fonction ppp_ioctl
Lorsque PPPIOCATTCHAN est retourné chercher le canal, il était évident que nous avions trouvé le canal créé par pppoe dans connect avant
Make_ppp_unit dans ppp appellera PPPIOCNEWUNIT
Lors de l'envoi de données via l'interface réseau ppp0 (en prenant ce nom), ppp_start_xmit sera appelé, et nous examinerons cette fonction plus tard.
La fonction generic_establish_ppp appellera alors PPPIOCCONNECT, et via ppp_connect_channel, le canal créé par pppoe et
les équipements de réseau ppp sont reliés entre eux
6. Interface réseau Ppp et processus de réception du programme ppp
Revenez à la fonction principale de ppp pour voir comment le programme ppp reçoit les données du protocole ppp
Processus de réception de données du noyau
Grâce à la fonction ppp_receive_nonmp_frame, vous pouvez voir que selon que le protocole du paquet de données reçu est un paquet de contrôle ppp ou un paquet réseau ordinaire tel qu'un paquet ipv4, différentes branches sont prises. S'il s'agit d'un paquet de contrôle de protocole ppp, mettez dans ppp-> file.rq, notre programme ppp recevra ce paquet, s'il s'agit d'un paquet réseau normal, il entrera dans la pile de protocoles réseau via netif_rx.
7. Processus d'envoi de paquets du programme ppp et de l'interface réseau ppp
Ce pch-> chan-> ops-> start_xmit (pch-> chan, skb) appelle pppoe_xmit, puis voyons pourquoi c'est pppoe_xmit
Ce canal est créé via le socket pppoe, puis en appelant la méthode connect. Lorsqu'il est créé, po-> chan.ops = & pppoe_chan_ops; donc start_xmit est pppoe_xmit