Linux STREAMS (LiS) |
||
|
LiS Drivers |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
DL_INFO_REQ |
Causes LDL to return a DL_INFO_ACK. If the stream has not been attached to a device then the returned values will consist of default values. If the stream has been attached then information will be returned that pertains the the underlying Linux network device. |
DL_PHYS_ADDR_REQ |
Causes LDL to return a DL_PHYS_ADDR_ACK (or DL_ERROR_ACK). The response will contain the current physical address of the Linux network device. The option to retrieve the factory address is not implemented and will always produce a DL_ERROR_ACK response. |
DL_ATTACH_REQ |
The stream must be in the DL_UNATTACHED state for this primitive to succeed. The dl_ppa field specifies the device number of the Linux network device to attach in its low order bits. In the LDL_FRAME_MASK bits, the dl_ppa specifies the framing type to use with the device. The valid framing types are: LDL_FRAME_EII, LDL_FRAME_802_2, LDL_FRAME_802_3, LDL_FRAME_SNAP and LDL_FRAME_RAW_LLC. The device number is usually obtained by issuing an LDL_FINDPPA ioctl. This ioctl takes a network device mnemonic, such as "etho", as an argument and produces a number suitable for use as the dl_ppa value in a DL_ATTACH_REQ. If the attach succeeds, LDL returns a DL_OK_ACK and sets the state of the stream to DL_UNBOUND. It returns a DL_ERROR_ACK if it fails. |
DL_DETACH_REQ |
Causes LDL to detach from the Linux network device. The stream must be in the DL_UNBOUND state for this primitive to be valid. If the detach succeeds, LDL returns a DL_OK_ACK and sets the state of the stream to DL_UNATTACHED. It returns a DL_ERROR_ACK if it fails. |
DL_BIND_REQ |
Causes LDL to bind an address to the stream. The stream must be in the DL_UNBOUND state for this primitive to succeed. The bound address is used in demultiplexing frames received from the Linux network driver. The SAP conveyed in the DL_BIND_REQ is used to select those received frames that are sent upstream on a particular stream. If the bind succeeds LDL returns a DL_OK_ACK and sets the state of the stream to DL_IDLE. If it fails then a DL_ERROR_ACK is sent upstream. |
DL_UNBIND_REQ |
Causes LDL to unbind all SAPs from the stream. The stream must be in the DL_IDLE state for this primitive to succeed. If the unbind succeeds, LDL returns a DL_OK_ACK and sets the state of the stream to DL_UNBOUND. If it fails then a DL_ERROR_ACK is sent upstream. |
DL_SUBS_BIND_REQ |
Causes LDL to add an additional SAP to the list of SAPs associated with the stream. The stream must be in the DL_IDLE state for this primitive to succeed. If the subs-bind succeeds, LDL returns a DL_SUBS_BIND_ACK. If it fails then a DL_ERROR_ACK is sent upstream. |
DL_SUBS_UNBIND_REQ |
Causes LDL to remove the given SAP from the list of SAPs associated with the stream. The stream must be in the DL_IDLE state for this primitive to succeed. If the subs-unbind succeeds, LDL returns a DL_OK_ACK. If it fails then a DL_ERROR_ACK is sent upstream. The state of the stream is left in the DL_IDLE state in either case. |
DL_PROMISCON_REQ |
The intent of this primitive is to set the Linux network device into the so-called "promiscuous" mode of operation. However, it is unimplemented. |
DL_PROMISCOFF_REQ |
This primitive would undo the effect of a DL_PROMISCON_REQ. However, it is unimplemented. |
DL_UNITDATA_REQ |
This primitive is used to send data to the Linux network driver. The destination address is used to set the physical address of the receiver of the data. The stream must be in the DL_IDLE state for this primitive to succeed. If the stream is operating in raw mode then the address field is ignored and it is assumed that the client has completely formatted the frame for transmission by the Linux network driver. If this primitive fails, a DL_UDERROR_IND is sent upstream. There is no response in the case of success. |
M_DATA |
An M_DATA is an acceptable alternative to a DL_UNITDATA_REQ for sending data on a raw-mode stream. If the data transmission operation fails, a DL_UDERROR_IND is sent upstream. There is no response in the case of success. |
For data received from the Linux network driver, LDL forwards a copy
of the received data in a DL_UNITDATA_IND
DLPI message to each client whose stream is attached to the particular
network driver and who has a SAP bound to the stream that matches the
SAP information in the received frame. Note that for non-raw frame
operations that the MAC header is stripped from the received frame prior
to forwarding it to the client. The address of the sender is retained
in the address field of the DL_UNITDATA_IND
primitive.
The LDL driver implements the following ioctls.
The user codes these ioctls as type I_STR and passes a structure
of type struct strioctl
to the driver. The ic_cmd field of this structure is decoded
according to the following table. the ic_dp and ic_len
fields delimit an argument structure which is also passed to the driver.
The argument structure differs for each type of ic_cmd.
ic_cmd value |
Argument Structure |
Description |
LDL_SETFLAGS |
IN/OUT: |
Used to set internal option flags for the open stream. See ldl.c source for details. |
LDL_FINDPPA |
IN: char[] |
The agrument is an ASCII string representing a network device mnemonic such as "eth0." If such a device can be found then the argument is overwritten with a long word whose numerical value can be used as the dl_ppa field of a DL_ATTACH_REQ. |
LDL_GETNAME |
IN: None |
This ioctl returns the ASCII string form of the network device mnemonic for the stream. |
Ole Husgaard <sparre@login.dknet.dk>
/dev/loop_clone (clone
device)
/dev/loop.1
/dev/loop.2
This driver is used by LiS and the strtst utility to assist in the regression testing of LiS. It connects two streams together in a manner similar to that of a pipe. Messages written into one stream can be read back from the other.
The driver can be operated as a clone device
with the two streams being connected via ioctls. A number of ioctls
exist that tailor the operation of the driver. The user codes these
ioctls as type I_STR and passes a structure of type struct
strioctl to the driver. The ic_cmd field of this structure
is decoded according to the following table. the ic_dp
and ic_len fields delimit an argument structure which is also
passed to the driver. The argument structure differs for each type
of ic_cmd.
ic_cmd value |
Argument Structure |
Description |
LOOP_SET |
IN: int |
Argument is the minor device number of the loop device to use for the other end of the connection. If the loop-around device had been opened by a directed open, such as to /dev/loop.1, then the minor device number is known from the device node. If it was opened via the /dev/loop_clone device then the minor device can be discovered via the LOOP_GET_DEV ioctl. |
LOOP_PUTNXT |
None |
Set the driver into a mode in which it will perform a direct putnext call on the other stream rather than the default behavior of using the service queue to forward the message. |
LOOP_MSGLVL |
IN: int |
Set to the number of messages to queue in the service queue before forwarding to the other stream. Zero means forward immediately. |
LOOP_TIMR |
IN: int |
Set the number of "ticks" to hold messages before forwarding them to the other stream. |
LOOP_MARK |
IN: int |
Set the MSGMARK flag for each of the next n messages before forwarding them to the other stream. |
LOOP_GET_DEV |
OUT: int |
Return the minor device number of this stream. Useful for finding out the minor number of a clone device. |
LOOP_BUFCALL |
None |
Use the bufcall mechanism to allocate a buffer for copying the next message. |
LOOP_CONCAT |
IN: int |
Concatenate this many messages into a single message and then forward on the other stream. One concatenation resets this value to zero and the ioctl needs to be issued again to repeat the behavior. |
LOOP_COPY |
None |
From this point on, copy messages rather than passing them through to the other stream. |
David Grothe <dave@gcom.com> plus others originally.
/dev/mux_clone (clone
device)
/dev/minimux.1
/dev/minimux.2
This driver is used by LiS in its testing procedures. It is a small multiplexing driver that allows cascaded multiplexors to be built and torn down. The driver uses a pair of ioctls to establish connectivity between upper streams and lower streams. This allows control over how data flows through the multiplexor.
Both of these ioctls are coded as type I_STR and pass a structure
of type struct strioctl to the driver. The ic_cmd
field of this structure is decoded according to the following table.
the ic_dp and ic_len fields delimit an argument structure
which is also passed to the driver. The argument structure may differ
for each type of ic_cmd.
ic_cmd value |
Argument Structure |
Description |
MINIMUX_UP |
IN: int |
The argument is a muxid that was returned from an I_LINK ioctl. This ioctl causes the lower stream indicated by the muxid to be connected to this stream. This is unidirectional linkage and only affects the upstream flow of messages. |
MINIMUX_DOWN |
IN: int |
The argument is a muxid that was returned from an I_LINK ioctl. This ioctl causes this stream to be connected to the lower stream indicated by the muxid. This is unidirectional linkage and only affects the downstream flow of messages. |
David Grothe <dave@gcom.com>
/dev/printk
This driver accepts messages written to it and prints them from the kernel using the kernel's printk function. It is used by the LiS test software to keep messages from LiS and messages from the test program in sequence.
David Grothe <dave@gcom.com>
/dev/sad
The STREAMS Administrative Driver manages the autopush function of LiS. Using ioctls the system administrator can provide a list of modules that are to be automatically pushed onto a given device when that device is opened. The controls are specified via the strapush structure which is defined in <sys/sad.h>.
The ioctl used by the user is of the form:
ioctl(fd, command, arg)
Where fd is the file descriptor of the file that is open to the sad driver, command and arg are described in the following table.
Command |
Argument |
Description |
---|---|---|
SAD_SAP |
struct strapush * |
Set the list of autopushed modules according to the sap_cmd and other arguments contained within the strapush structure. |
SAD_GAP |
struct strapush * |
Get the list of configured autopushed modules associated with the indicated major and minor device number. The sad driver fills in this structure with the names of the modules and the applicable range of minor device numbers. |
SAD_VML |
struct str_list * |
Validates a list of pushable module names to verify that they are installed in LiS. The str_list structure is defined in the file <sys/stropts.h>. |
The strapush structure used by
the SAD_SAP and SAD_GAP
ioctls contains the following fields.
Field |
Description |
|
---|---|---|
unsigned sap_cmd |
This is the autopush command to be executed. The values are as follows. |
|
SAP_ONE |
Configure one minor device of the driver indicated by sap_major. |
|
SAP_RANGE |
Configure a range of minor devices of the driver indicated by sap_major. The range runs from sap_minor to sap_lastminor, inclusively. |
|
SAP_ALL |
Configure all minor devices of the driver indicated by sap_major. |
|
SAP_CLEAR |
Undo all autopush configuration for the driver indicated by sap_major. |
|
major_t sap_major |
The major device number of the driver which is being configured for autopush. |
|
minor_t sap_minor |
The minor device being configured, or the first of a range. |
|
minor_t sap_lastminor |
The last minor device of a range to be configured. |
|
unsigned sap_npush |
Number of modules to be pushed when the indicated device is opened. |
|
char sap_list[MAXAPUSH][FMNAMESZ+1] |
List of module names to be pushed, or list of modules names returned to user. |
The ioctl function call returns zero upon success or -1 on failure. Upon failure errno is set to the error number describing the failure, usually either EFAULT or EINVAL.
Note that the sad driver is a standard AT&T STREAMS function. More comprehensive documentation for this driver can be found in the SVR4 Programmer's Guide: STREAMS.
Ole Husgaard <sparre@login.dknet.dk>
connld
The connld module provides a means to generate multiple unique STREAMS-based pipes from a single existing pipe end. connld may only be pushed (via the STREAMS I_PUSH ioctl) onto a STREAMS-based pipe. When first pushed, connld does nothing; on each subsequent open(2), connld will generate a unique STREAMS-based pipe. One end of each new pipe replaces the original pipe end from the perspective of the open call. The other end of each new pipe is sent, effectively as if by the I_SENDFD ioctl, to the other end of the original pipe, ostensibly to be received by a subsequent I_RECVFD ioctl operation.
The intent of connld is to provide a means to generate unique pipes which separately and independently connect client processes to a server process. The point of access for such clients is expected to be a path name known to all such clients and to which a pipe end may be connected (via fattach(3)) by the server process. The server establishes the original pipe, pushes connld onto the client end, and then listens via I_RECVFD for new connections on the server end. A client wishing to connect to the server will open(2) the path name representing the client end, and can determine via isastream(3) whether or not the server process is active and attached. If it is, the open() call returns one end of a unique new pipe that thus connects the client to the server.
Such a server is responsible both for accepting new connections via I_RECVFD on the original pipe, and for communicating with clients so connected via the received pipe ends. It would also be reasonable for such a server process to invalidate the point of access by calling fdetach(3) before terminating.
It should be noted that the poll(2) primitive may be used to indicate when an M_PASSFP representing a newly passed file is available on the original server pipe end. This is reflected by the POLLIN status setting in the events and revents fields of a pollfd structure. Moreover, any attempt to read an M_PASSFP message via the data-receiving primitives (i.e., read(2), getmsg(3), and getpmsg(3)) will fail with errno(3) returning an EBADMSG indication without discarding the message.
Even so, it should be reasonable to expect only M_PASSFP messages will be received on the original server pipe end, since it is not possible to carry on normal data traffic which has connld on one end, since connld does not support such traffic.
The use of connld can be made entirely free-standing by attaching well-known paths to both ends of the original pipe. The relevant capabilities are implemented in LiS so that the original creator of the pipe can close both ends after attaching paths to them, and the process of passing file descriptors can still be carried out via new open()'s as long as both ends remain attached.
fattach(3), fattach(8), fdetach(3), fifo(4), fifo(9),
pipe(3), STREAMS(4)
Unix System V Release 4 (SVR4)
John Boyd, protologos LLC. <jaboydjr@netwalk.com>
ip_strms
This module is pushed onto an open stream to a driver which implements the DLPI STREAMS protocol. It provides an interface between the DLPI driver below and the Linux IP module above. The effect is to be able to use a STREAMS DLPI driver as a network interface below Linux TCP/IP.
The ip_strms module monitors DLPI primitives sent from above on the stream file and shuttles them between the process which pushed the module onto the stream and the DLPI driver below. The ip_strms module will also allow data to be exchanged between the stream user and the DLPI driver until such time as the stream is logically attached to IP as a network driver.
In order to attach the stream to IP, the user process issues an ioctl of type SIOCSIFNAME. This ioctl causes ip_strms to register itself as a network driver of the given name. From that point onward data, in the form of M_DATA messages or of DL_UNITDATA_IND messages, are forwarded upstream to IP rather than to the stream user. Likewise, data messages received from IP are forwarded downstream to the DLPI driver as DL_UNITDATA_REQ messages. Downstream messages are completely formatted for the transmission medium and should be processed accordingly by the DLPI driver below.
After attaching to IP, the stream user must continue to remain in execution, holding the stream open. If the stream closes then ip_strms will detach from IP. Also, if the stream user sends a SIOCSIFNAME ioctl with an empty name then ip_strms will detach from IP.
The interfaces attached to IP will appear in the output of the netstat and ifconfig commands. An "ifconfig" down operation on the interface will also cause a detach from IP.
The application level program which manages the connection between a DLPI driver and TCP/IP should be coded to implement the following steps.
Open a stream to the DLPI driver. This can be a clone open.
Execute an I_PUSH ioctl on "ip_strms."
Send the DLPI attach and bind primitives downstream.
Execute an SIOCSIFNAME ioctl with the desired interface name. After this succeeds the DLPI driver will be connected to TCP/IP as a network driver via the ip_strms module.
Perform any needed ifconfig or route commands for the interface.
Sleep indefinitely keeping the stream open. Killing the process will cause the stream to be detached from IP.
David Grothe <dave@gcom.com>
pipemod
The pipemod module has the relatively simple task of reversing the sense of the FLUSH flag bits in M_FLUSH messages sent in STREAMS-based fifos and pipes. This must happen at the midpoint of a fifo or pipe, so that FLUSHR becomes FLUSHW, and FLUSHW becomes FLUSHR. pipemod does this, and has no other function.
To be used appropriately, then, pipemod must be the first module pushed onto a pipe end or a fifo, but it is only necessary on one end of a pipe.
pipemod is not needed if flush handling need not be supported, or if its function is supported by other means.
fifo(9), pipe(3), fifo(4), STREAMS(4)
Unix System V Release 4 (SVR4)
John Boyd, protologos LLC. <jaboydjr@netwalk.com>
relay relay2
These are two names for the same module. All the module does is forward STREAMS messages along on the stream using putnext. These modules are used in the testing of LiS but are not otherwise useful. One could use the source code as a starting point for coding a pushable STREAMS module.
David Grothe <dave@gcom.com>
timod
This is a primitive version of the standard AT&T SVR4 timod module. Its function is to convert user level ioctls to TLI primitives downstream.
Since there is no TLI Provider code within LiS, the timod module could be considered to be well ahead of its time.
Ole Husgaard <sparre@login.dknet.dk>
tirdwr
This is a primitive version of the standard AT&T SVR4 tirdwr module. Its function is to convert user level reads and writes to appropriate TLI protocol downstream.
Since there is no TLI Provider code within LiS, the tirdwr module could be considered to be well ahead of its time.
Ole Husgaard <sparre@login.dknet.dk>