1. Origin
My work is related to gateway products, and I often come into contact with the pppoe protocol, but I don’t know much about how ppp and pppoe are implemented. Finding related articles on the Internet mostly describes the specific content of the ppp/pppoe protocol and the large data flow process, but not too many details about the implementation of the pppoe driver and ppp driver code in the kernel. It happens to be watching Mao De Cao and Hu Ximing during this time. The teacher's "Linux Kernel Source Code Scenario Analysis", after reading the terminal driver in the kernel, I decided to study the content of the PPP/PPPOE driver carefully and record the gains during this period of time, so that I can read it later and share it with you .
2. About this article
This article will not involve the ppp protocol and the pppoe protocol itself, that is, it will not discuss the format of these messages such as LCP, PAP, CHAP, IPCP, PADI, etc. If you only want to understand the ppp and pppoe protocol itself, then this article The article is not for you.
If you want to understand the ppp and pppoe drivers, you want to know how the ppp program establishes the ppp network interface, and how the ppp network interface sends data through a specific network interface (such as eth0), and a specific network interface (such as eth0) receives After arriving at the data, how to send the data to the ppp network interface, then this article is just for you.
When reading this article, it is recommended to copy the flowchart of each part and save it in a document, and then look at the code against the flowchart.
3. Code link
ppp code download link http://mirrors.aliyun.com/ubuntu/pool/main/p/ppp/ppp_2.4.7.orig.tar.gz
Linux-2.4.0 code download link https://mirrors.edge.kernel.org/pub/linux/kernel/v2.4/linux-2.4.0.tar.gz
Four. Code analysis
1. Content preview
pppd command
ppp code to create ppp network interface
pppoe driver to establish channel
The ppp driver establishes the ppp network interface and associates with the channel established by pppoe
ppp network interface and ppp program receiving process
ppp program and ppp network interface package process
2.pppd command
pppd plugin /usr/lib/rp-pppoe.so nic-pon0.30 linkname internet nodefaultroute noipdefault noauth default-asyncmap hide-password nodetach usepeerdns mtu 1492 mru 1492 noaccomp nodeflate nopcomp novj novjccomp user aaa lcp-echo-interval 20 lcp-echo-failure 10 nopersist
3. ppp code to create ppp network interface
[ppp-2.4.7]main.c
[ppp-2.4.7]options.c
[ppp-2.4.7]options.c 中general_options
4. pppoe driver to establish a channel
the_channel->connect() is PPPOEConnectDevice, this function is relatively long, let’s look at it in sections
Linux code
In the above figure, proto[protocol]->create is pppoe_create, because the protocol is PX_PROTO_OE, which is registered in pppoe_init
Back to PPPOEConnectDevice function (continued 1)
In openInterface, a socket will be created and the interface will be bound, as shown in the following two figures
After the socket is successfully created, return to the PPPOEConnectDevice function and call the discovery() function to interact with the pppoe protocol
Then look at the PPPOEConnectDevice function (continued 2), the connect function will be called
The connect function will call the pppoe_connect in the kernel. This function is included in pppoe_ops and is set to sock->ops in pppoe_create, which is the parameter related to our conn->sessionSocket. This process can be seen above.
The ppp_register_channel function will generate struct channel *pch, set pch->chan to chan, and put pch in all_channels
5. The ppp driver establishes a ppp network interface and associates with the channel established by pppoe
Back to the function start_link of ppp's auth.c, the_channel->establish_ppp() is generic_establish_ppp
It should be noted that the fd in the function has changed. At the beginning, fd is the return value of the PPPOEConnectDevice function conn->sessionSocket, calling ioctl on it will go to linux
pppox_ioctl function, this function returns the index of the channel created by PPPOEConnectDevice[plugin.c in ppp code] function call connect
Then look at the actions of calling PPPIOCATTCHAN, make_ppp_unit and PPPIOCCONNECT for fd to "/dev/ppp" in generic_establish_ppp
Calling ioctl will call the ppp_ioctl function
When PPPIOCATTCHAN went back to find the channel, it was obvious that we found the channel created by pppoe in connect before
Make_ppp_unit in ppp will call PPPIOCNEWUNIT
When sending data through the network interface ppp0 (assuming this name), ppp_start_xmit will be called, and we will look at this function later.
The generic_establish_ppp function will then call PPPIOCCONNECT, and through ppp_connect_channel, the channel created by pppoe and
ppp network equipment is linked together
6. Ppp network interface and ppp program receiving process
Go back to the main function of ppp to see how the ppp program receives the data of the ppp protocol
Kernel receiving data process
Through the ppp_receive_nonmp_frame function, you can see that depending on whether the protocol of the received data packet is a ppp control packet or an ordinary network packet such as an ipv4 packet, different branches are taken. If it is a ppp protocol control packet, put it in ppp->file.rq , Our ppp program will receive this packet, if it is a normal network packet, it will enter the network protocol stack through netif_rx.
7. ppp program and ppp network interface packet sending process
This pch->chan->ops->start_xmit(pch->chan, skb) calls pppoe_xmit, then let’s see why it is pppoe_xmit
This channel is created through the pppoe socket and then calling the connect method. When created, po->chan.ops = &pppoe_chan_ops; so start_xmit is pppoe_xmit