Digital UNIX provides the dlb STREAMS pseudodriver, which is a partial implementation of the Data Link Provider Interface (DLPI).
This chapter describes the dlb STREAMS pseudodriver and the basics of DLPI. A PostScript copy of the DLPI specification ( dlpi.ps) is located in the /usr/share/doclib/dlpi directory.
Note
You must have the OSFPGMK200 subset installed to access the DLPI specification online.
Figure 2-1 highlights the data link interfaces and shows their relationship to the rest of the network programming environment.
Note
The dlb STREAMS pseudodriver supports a subset of DLPI primitives. See Section 2.4 for a list of the supported primitives.
The data link interface is the boundary between the network and data link layers of the OSI reference model. A network application, or data link service user (DLS user), uses the services of the data link interface. A driver, pseudodriver, or data link service provider (DLS provider), provides the services to the data link layer.
DLPI specifies a STREAMS kernel-level service interface that maps to the OSI reference model. It defines an interface to the services of the data link layer and provides a definition of service primitives that make up the interface.
Figure 2-2 shows the components of DLPI. The DLS user communicates with the DLS provider using request/response primitives; the DLS provider communicates with the DLS user with indication/confirmation primitives.
The primitives that Digital UNIX supports are listed in Section 2.4.
DLPI supports three modes of communication:
Enables a DLS user to establish a data link connection, transfer data over that connection, reset the link, and release the connection when the conversation has terminated.
The connection service establishes a data link connection between a local DLS user and a remote DLS user for the purpose of sending data. Only one data link connection is allowed on each Stream.
Enables a DLS user to transfer units of data to peer DLS users without incurring the overhead of establishing and releasing a connection. The connectionless service does not, however, guarantee reliable delivery of data units between peer DLS users (for instance, lack of flow control may cause buffer resource shortages that result in data being discarded).
Once a Stream has been initialized using the local management services, it may be used to send and receive connectionless data units.
Note
Digital UNIX supports only the connectionless mode of communication.
Designed for general use for the reliable transfer of information between peer DLS users. These services are intended for applications that require acknowledgement of cross-LAN data unit transfer, but wish to avoid the complexity associated with the connection-mode services. Although the exchange service is connectionless, in-sequence delivery is guaranteed for data sent by the initiating station.
This section describes the types of service, or phases of communication, supported by DLPI. Note that the types of service available depend on the mode of communication (connection, connectionless, acknowledged connectionless) between the DLS provider and the DLS user.
DLPI supports the following types of service:
The local management services apply to all three modes of communication supported by DLPI. They enable a DLS user to initialize a Stream that is connected to a DLS provider and to establish an identity with that provider. The local management services support the following:
Provides information about the DLPI Stream to the DLS user.
Assigns a physical point of attachment (PPA) to a Stream. See Section 2.3 for more information.
Associates a data link service access point (DLSAP) with a Stream.
The connection-mode services allow two DLS users to establish a data link connection between them to exchange data, and to reset the link and release the connection when the conversation is through. The connection-mode services support the following:
Establishes a data link connection between a local DLS user and a remote DLS user for the purposes of sending data.
Provides for the exchange of user data in either direction or both directions simultaneously. Data is sent in logical groups called data link service data units (DLSDUs) and is guaranteed to be delivered in the order in which it was sent.
Enables either the DLS user or DLS provider to break an established connection.
Allows a DLS user to resynchronize the use of a data link connection, or a DLS provider to report detected loss of data unrecoverable within the data link service.
The connectionless-mode services allow DLS users to exchange data without incurring the overhead of establishing and releasing a connection. The connectionless-mode services support the following:
Provides for the exchange of user data (DLSDU) in either direction or in both directions simultaneously.
Enables a DLS user to specify the quality of service it can expect for each invocation of the connectionless data transfer service.
Provides a means to notify a DLS user that a previously sent data unit either produced an error or could not be delivered. However, the error reporting service does not guarantee that an error indication will be issued for every undeliverable data unit.
The acknowledged connectionless-mode data transfer services are designed for general use for the reliable transfer of data between peer DLS users. These services are intended for applications that require acknowledgment of data transfer between local area networks, but wish to avoid using the connection mode services. In-sequence delivery is guaranteed for data sent by the initiating station. The following services are supported:
Provides for the exchange of DLSDUs which are acknowledged at the LLC sublayer.
Enables a DLS user to specify the quality of service it can expect for each invocation of the connectionless data transfer service.
Provides a means to notify a DLS user that a previously sent data unit either produced an error or could not be delivered. However, the error reporting service does not guarantee that an error indication will be issued for every undeliverable data unit.
Each DLPI user must establish an identity to communicate with other data link users. This identity consists of the following pieces of information:
This identifies the physical medium over which the DLS user communicates. The importance of identifying the physical medium is particularly evident on systems that are attached to multiple physical media. See Section 2.5 for information about identifying the available physical points of attachment (PPAs) on your system.
The DLS user must register with the DLS provider so that the provider can deliver protocol data units destined for that user.
The format of the DLSAP address is an unsigned character array containing the Medium Access Control (MAC) addresses followed by the bound Service Access Point (SAP). The SAP is usually two bytes in the case of Ethernet, or one byte in the case of ISO 8802-2 (IEEE 802.2). The one exception is when a HIERACHICAL DL_SUBS_BIND_REQ is processed. In that case, the DLSAP address consists of the MAC address, the SNAP SAP (0xAA), and a five-byte SNAP.
Figure 2-3 illustrates the components of this identification approach.
The PPA is the point at which a system attaches itself to a physical communications medium. All communication on that physical medium funnels through the PPA. On systems where a DLS provider supports more than one physical medium, the DLS user must identify the medium through which it will communicate. A PPA is identified by a unique PPA identifier.
DLPI defines the following two styles of DLS provider, which are distinguished by the way they enable a DLS user to choose a particular PPA:
This implementation of a style 1 driver allows the STREAMS clone open feature to be used for each PPA configured. Style 1 providers are appropriate when few PPAs are supported.
Digital UNIX supports only the style 2 provider because it is more suitable for supporting large numbers of PPAs.
Table 2-1 lists and describes the DLPI primitives that Digital UNIX supports in the dlb STREAMS pseudodriver. For a complete list of DLPI primitives see the DLPI specification in the /usr/share/doclib/dlpi/dlpi.ps file.
Primitive | Description |
DL_ATTACH_REQ | Requests that the DLS provider associate a physical point of attachment (PPA) with a Stream. Used on style 2 providers only. |
DL_BIND_REQ | Requests that the DLS provider bind a DLSAP to the Stream. The DLS user must identify the address of the DLSAP to be bound to the Stream. |
DL_BIND_ACK | Reports the successful bind of a DLSAP to a Stream, and returns the bound DLSAP address to the DLS user. Generated in response to a DL_BIND_REQ. |
DL_UNBIND_REQ | Requests that the DLS provider unbind the DLSAP that was bound by a previous DL_BIND_REQ from this Stream. |
DL_DETTACH_REQ | Requests the DLS provider disassociate a physical point of attachment (PPA) with a stream. |
DL_DISABMULTI_REQ | Request the DLS provider disable the multicast address. |
DL_ENABMULTI_REQ | Request the DLS provider enable a specific multicast address. (The current implementation of the DLB driver requires the state to be DL_IDLE.) |
DL_ERROR_ACK | Informs DLS user of a previously issued request which was invalid. |
DL_INFO_ACK | Response to DL_INFO_REQ primitive; conveys information about the DLPI stream. |
DL_INFO_REQ | Requests the DLS provider return information about the DLPI stream. |
DL_OK_ACK | Acknowledges to the DLS user that a previously issued request primitive was successfully received. |
DL_PHYS_ADDR_REQ | Requests that the DLS provider return either the default (factory) or current value of the physical address associated with the Stream, depending upon the value of the address type selected in the request. |
DL_PHYS_ADDR_ACK | Returns the value for the physical address to the link user in response to a DL_PHYS_ADDR_REQ. |
DL_SUBS_BIND_ACK | Is the positive response to a DL_SUBS_BIND_REQ from the DLS provider. |
DL_SUBS_BIND_REQ |
Requests the DLS provider bind a subsequent DLSAP to stream. There are
two
classes of subsequent bind requests: HIERACHICAL and PEER.
HIERACHICAL requests are only valid for SNAPs (see the IEEE 802.1 specification) and you must have bound to the SNAP sap (0xAA) with a DL_BINDS_REQ before issuing the DL_SUBS_BIND_REQ for the SNAP. The PEER request binds to additional saps but does not change the DLSAP address of the stream. |
DL_SUBS_UNBIND_REQ | Requests the DLS provider to unbind a sap which was previously bound by a DL_SUBS_BIND_REQ. |
DL_TEST_CON | Conveys that a DLSDU TEST response was received in response to a DL_TEST_REQ. |
DL_TEST_IND | Conveys to the DLS user that a TEST cmd DLSDU was received. |
DL_TEST_REQ | Requests the DLS provider to transmit a TEST cmd DLSDU on behalf of the DLS user. |
DL_TEST_RES | Requests the DLS provider to send a TEST response command on behalf of the DLS user. |
DL_UDERROR_IND | Informs DLS user that a previously sent DL_UNITDATA_REQ failed. |
DL_UNITDATA_REQ | Conveys one DLSDU from the DLS user to the DLS provider for transmission to a peer DLS user. |
DL_UNITDATA_IND | Conveys one DLSDU from the DLS provider to the DLS user. |
DL_XID_CON | Conveys that a XID DLSDU was received in response to a DL_XID_REQ. |
DL_XID_IND | Conveys to the DLS user that a XID DLSDU was received. |
DL_XID_REQ | Requests the DLS provider to transmit a XID DLSDU on behalf of the DLS user. |
DL_XID_RES | Requests the DLS provider to send a XID DLSDU on behalf of the DLS user. This is in repsonse to a DL_XID_RES. |
When compiled and run as root on a Digital UNIX system, the following program opens the STREAMS device /dev/streams/dlb and prints to the screen the PPAs available on the system. The PPA number should be passed in using the dl_ppa field of the DL_ATTACH_REQ DLPI primitive.
#include <sys/ioctl.h> #include <stropts.h> #include <errno.h> #include <fcntl.h># a.out
#define ND_GET ('N' << 8 + 0) #define BUFSIZE 256
main() { int i; int fd; char buf [BUFSIZE]; struct strioctl stri;
fd = open("/dev/streams/dlb", O_RDWR, 0); if (fd < 0) { perror("open"); exit(1); }
sprintf(buf, "dl_ifnames"); stri.ic_cmd = ND_GET; stri.ic_timout = -1; stri.ic_len = BUFSIZE; stri.ic_dp = buf;
if (ioctl(fd, I_STR, &stri) < 0) { perror("ioctl"); exit(1); }
printf("Valid PPA names on this system are:\n"); for (i=0; i<stri.ic_len; i++) { if (buf[i] == 0) printf(" "); else printf("%c",buf[i]); } printf("\n"); }