/keyboards/lightsaver/keymaps/rasmus/

anism for transporting PPP frames from one machine to another. A PPP channel implementation can be arbitrarily complex internally but has a very simple interface with the generic PPP code: it merely has to be able to send PPP frames, receive PPP frames, and optionally handle ioctl requests. Currently there are PPP channel implementations for asynchronous serial ports, synchronous serial ports, and for PPP over ethernet. This architecture makes it possible to implement PPP multilink in a natural and straightforward way, by allowing more than one channel to be linked to each ppp network interface unit. The generic layer is responsible for splitting datagrams on transmit and recombining them on receive. PPP channel API --------------- See include/linux/ppp_channel.h for the declaration of the types and functions used to communicate between the generic PPP layer and PPP channels. 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 the channel code, rather than from the generic layer. The channel is expected to have some way for a user-level process to control it independently of the ppp generic layer. For example, with the ppp_async channel, this is provided by the file descriptor to the serial port. Generally a user-level process will initialize the underlying communications medium and prepare it to do PPP. For example, with an async tty, this can involve setting the tty speed and modes, issuing modem commands, and then going through some sort of dialog with the remote system to invoke PPP service there. We refer to this process as `discovery'. Then the user-level process tells the medium to become a PPP channel and register itself with the generic PPP layer. The channel then has to report the channel number assigned to it back to the user-level process. From that point, the PPP negotiation code in the PPP daemon (pppd) can take over and perform the PPP negotiation, accessing the channel through the /dev/ppp interface. At the interface to the PPP generic layer, PPP frames are stored in skbuff 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 there any escaping of control characters, nor are there any FCS or framing characters included. That is all the responsibility of the channel code, if it is needed for the particular medium. That is, the skbuffs presented to the start_xmit() function contain only the 2-byte protocol 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 to represent the channel. The channel is free to use the `private' field however it wishes. The channel should initialize the `mtu' and `hdrlen' fields before calling ppp_register_channel() and not change them until after ppp_unregister_channel() returns. The `mtu' field represents the maximum size of the data part of the PPP frames, that is, it does not include the 2-byte protocol number. If the channel needs some headroom in the skbuffs presented to it for transmission (i.e., some space free in the skbuff data area before the start of the PPP frame), it should set the `hdrlen' field of the ppp_channel struct to the amount of headroom required. The generic PPP layer will attempt to provide that much headroom but the channel should still check if there is sufficient headroom and copy the skbuff if there isn't. On the input side, channels should ideally provide at least 2 bytes of headroom in the skbuffs presented to ppp_input(). The generic PPP code 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 data that it buffers in the transmit direction. It maintains a queue of transmit packets for the PPP unit (network interface device) plus a queue of transmit packets for each attached channel. Normally the transmit queue for the unit will contain at most one packet; the exceptions are when pppd sends packets by writing to /dev/ppp, and when the core networking code calls the generic layer's start_xmit() function with the queue stopped, i.e. when the generic layer has called netif_stop_queue(), which only happens on a transmit timeout. The start_xmit function always accepts and queues the packet which it is asked to transmit. Transmit packets are dequeued from the PPP unit transmit queue and then subjected to TCP/IP header compression and packet compression (Deflate or BSD-Compress compression), as appropriate. Af