⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp_generic.txt

📁 linux 内核源代码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
		PPP Generic Driver and Channel Interface		----------------------------------------			    Paul Mackerras			   paulus@samba.org			      7 Feb 2002The generic PPP driver in linux-2.4 provides an implementation of thefunctionality which is of use in any PPP implementation, including:* the network interface unit (ppp0 etc.)* the interface to the networking code* PPP multilink: splitting datagrams between multiple links, and  ordering and combining received fragments* the interface to pppd, via a /dev/ppp character device* packet compression and decompression* TCP/IP header compression and decompression* detecting network traffic for demand dialling and for idle timeouts* simple packet filteringFor sending and receiving PPP frames, the generic PPP driver calls onthe services of PPP `channels'.  A PPP channel encapsulates amechanism for transporting PPP frames from one machine to another.  APPP channel implementation can be arbitrarily complex internally buthas a very simple interface with the generic PPP code: it merely hasto be able to send PPP frames, receive PPP frames, and optionallyhandle ioctl requests.  Currently there are PPP channelimplementations for asynchronous serial ports, synchronous serialports, and for PPP over ethernet.This architecture makes it possible to implement PPP multilink in anatural and straightforward way, by allowing more than one channel tobe linked to each ppp network interface unit.  The generic layer isresponsible for splitting datagrams on transmit and recombining themon receive.PPP channel API---------------See include/linux/ppp_channel.h for the declaration of the types andfunctions used to communicate between the generic PPP layer and PPPchannels.Each channel has to provide two functions to the generic PPP layer,via the ppp_channel.ops pointer:* start_xmit() is called by the generic layer when it has a frame to  send.  The channel has the option of rejecting the frame for  flow-control reasons.  In this case, start_xmit() should return 0  and the channel should call the ppp_output_wakeup() function at a  later time when it can accept frames again, and the generic layer  will then attempt to retransmit the rejected frame(s).  If the frame  is accepted, the start_xmit() function should return 1.* ioctl() provides an interface which can be used by a user-space  program to control aspects of the channel's behaviour.  This  procedure will be called when a user-space program does an ioctl  system call on an instance of /dev/ppp which is bound to the  channel.  (Usually it would only be pppd which would do this.)The generic PPP layer provides seven functions to channels:* ppp_register_channel() is called when a channel has been created, to  notify the PPP generic layer of its presence.  For example, setting  a serial port to the PPPDISC line discipline causes the ppp_async  channel code to call this function.* ppp_unregister_channel() is called when a channel is to be  destroyed.  For example, the ppp_async channel code calls this when  a hangup is detected on the serial port.* ppp_output_wakeup() is called by a channel when it has previously  rejected a call to its start_xmit function, and can now accept more  packets.* ppp_input() is called by a channel when it has received a complete  PPP frame.* ppp_input_error() is called by a channel when it has detected that a  frame has been lost or dropped (for example, because of a FCS (frame  check sequence) error).* ppp_channel_index() returns the channel index assigned by the PPP  generic layer to this channel.  The channel should provide some way  (e.g. an ioctl) to transmit this back to user-space, as user-space  will need it to attach an instance of /dev/ppp to this channel.* ppp_unit_number() returns the unit number of the ppp network  interface to which this channel is connected, or -1 if the channel  is not connected.Connecting a channel to the ppp generic layer is initiated from thechannel code, rather than from the generic layer.  The channel isexpected to have some way for a user-level process to control itindependently of the ppp generic layer.  For example, with theppp_async channel, this is provided by the file descriptor to theserial port.Generally a user-level process will initialize the underlyingcommunications medium and prepare it to do PPP.  For example, with anasync tty, this can involve setting the tty speed and modes, issuingmodem commands, and then going through some sort of dialog with theremote system to invoke PPP service there.  We refer to this processas `discovery'.  Then the user-level process tells the medium tobecome a PPP channel and register itself with the generic PPP layer.The channel then has to report the channel number assigned to it backto the user-level process.  From that point, the PPP negotiation codein the PPP daemon (pppd) can take over and perform the PPPnegotiation, accessing the channel through the /dev/ppp interface.At the interface to the PPP generic layer, PPP frames are stored inskbuff structures and start with the two-byte PPP protocol number.The frame does *not* include the 0xff `address' byte or the 0x03`control' byte that are optionally used in async PPP.  Nor is thereany escaping of control characters, nor are there any FCS or framingcharacters included.  That is all the responsibility of the channelcode, if it is needed for the particular medium.  That is, the skbuffspresented to the start_xmit() function contain only the 2-byteprotocol number and the data, and the skbuffs presented to ppp_input()must be in the same format.The channel must provide an instance of a ppp_channel struct torepresent the channel.  The channel is free to use the `private' fieldhowever it wishes.  The channel should initialize the `mtu' and`hdrlen' fields before calling ppp_register_channel() and not changethem until after ppp_unregister_channel() returns.  The `mtu' fieldrepresents the maximum size of the data part of the PPP frames, thatis, it does not include the 2-byte protocol number.If the channel needs some headroom in the skbuffs presented to it fortransmission (i.e., some space free in the skbuff data area before thestart of the PPP frame), it should set the `hdrlen' field of theppp_channel struct to the amount of headroom required.  The genericPPP layer will attempt to provide that much headroom but the channelshould still check if there is sufficient headroom and copy the skbuffif there isn't.On the input side, channels should ideally provide at least 2 bytes ofheadroom in the skbuffs presented to ppp_input().  The generic PPPcode does not require this but will be more efficient if this is done.Buffering and flow control--------------------------The generic PPP layer has been designed to minimize the amount of datathat it buffers in the transmit direction.  It maintains a queue oftransmit packets for the PPP unit (network interface device) plus aqueue of transmit packets for each attached channel.  Normally thetransmit queue for the unit will contain at most one packet; theexceptions are when pppd sends packets by writing to /dev/ppp, andwhen the core networking code calls the generic layer's start_xmit()function with the queue stopped, i.e. when the generic layer hascalled netif_stop_queue(), which only happens on a transmit timeout.The start_xmit function always accepts and queues the packet which itis asked to transmit.Transmit packets are dequeued from the PPP unit transmit queue andthen subjected to TCP/IP header compression and packet compression(Deflate or BSD-Compress compression), as appropriate.  After thispoint the packets can no longer be reordered, as the decompressionalgorithms rely on receiving compressed packets in the same order thatthey were generated.If multilink is not in use, this packet is then passed to the attachedchannel's start_xmit() function.  If the channel refuses to takethe packet, the generic layer saves it for later transmission.  Thegeneric layer will call the channel's start_xmit() function againwhen the channel calls  ppp_output_wakeup() or when the corenetworking code calls the generic layer's start_xmit() functionagain.  The generic layer contains no timeout and retransmissionlogic; it relies on the core networking code for that.If multilink is in use, the generic layer divides the packet into oneor more fragments and puts a multilink header on each fragment.  Itdecides how many fragments to use based on the length of the packetand the number of channels which are potentially able to accept afragment at the moment.  A channel is potentially able to accept afragment if it doesn't have any fragments currently queued up for itto transmit.  The channel may still refuse a fragment; in this casethe fragment is queued up for the channel to transmit later.  Thisscheme has the effect that more fragments are given to higher-bandwidth channels.  It also means that under light load, the genericlayer will tend to fragment large packets across all the channels,thus reducing latency, while under heavy load, packets will tend to betransmitted as single fragments, thus reducing the overhead offragmentation.SMP safety----------The PPP generic layer has been designed to be SMP-safe.  Locks areused around accesses to the internal data structures where necessaryto ensure their integrity.  As part of this, the generic layerrequires that the channels adhere to certain requirements and in turnprovides certain guarantees to the channels.  Essentially the channelsare required to provide the appropriate locking on the ppp_channelstructures that form the basis of the communication between thechannel and the generic layer.  This is because the channel providesthe storage for the ppp_channel structure, and so the channel isrequired to provide the guarantee that this storage exists and isvalid at the appropriate times.The generic layer requires these guarantees from the channel:* The ppp_channel object must exist from the time that  ppp_register_channel() is called until after the call to  ppp_unregister_channel() returns.* No thread may be in a call to any of ppp_input(), ppp_input_error(),  ppp_output_wakeup(), ppp_channel_index() or ppp_unit_number() for a  channel at the time that ppp_unregister_channel() is called for that  channel.* ppp_register_channel() and ppp_unregister_channel() must be called

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -