Drivers for Network Devices
Solaris network drivers are STREAMS-based. These types of drivers are covered in depth in STREAMS Programming Guide. This chapter discusses the Generic LAN driver (GLD), which is a kernel module encapsulating features common to most network drivers. The GLD implements much of the STREAMS and Data Link Provider Interface (DLPI) functionality for a Solaris network driver.
The GLD module is available for Solaris SPARC Platform Edition network drivers, as well as for Solaris Intel Platform Edition network drivers.
This chapter provides information on the following subjects:
For more information on GLDs, see the gld(7D), dlpi(7P), gld(9E), gld(9F), gld_mac_info(9S), gld_stats(9S) man pages.
Generic LAN Driver Overview
GLD is a multi-threaded, clonable, loadable kernel module providing support for Solaris local area network device drivers. Local area network (LAN) device drivers in Solaris are STREAMS-based drivers that use DLPI to communicate with network protocol stacks. These protocol stacks use the network drivers to send and receive packets on a local area network. A network device driver must implement and conform to the requirements imposed by the DDI/DKI specification, STREAMS specification, DLPI specification, and programmatic interface of the device itself.
GLD implements most STREAMS and DLPI functionality required of a Solaris LAN driver. Several Solaris network drivers are implemented using GLD.
A Solaris network driver implemented using GLD is made up of two distinct parts: a generic component that deals with STREAMS and DLPI interfaces, and a device-specific component that deals with the particular hardware device. The device-specific module indicates its dependency on the GLD module (which is found at /kernel/misc/gld) and registers itself with GLD from within the driver's attach(9E) function. After it is successfully loaded, the driver is DLPI-compliant. The device-specific part of the driver calls gld(9F) functions when it receives data or needs some service from GLD. GLD makes calls into the gld(9E) entry points of the device-specific driver through pointers provided to GLD by the device-specific driver when it registered itself with GLD. The gld_mac_info(9S) structure is the main data interface between GLD and the device-specific driver.
The GLD facility currently supports devices of type DL_ETHER (ISO 8802-3, IEEE 802.3 protocol), DL_TPR (IEEE 802.5, Token Passing Ring), and DL_FDDI (ISO 9314-2, Fibre Distributed Data Interface). GLD drivers are expected to process fully formed MAC-layer packets and should not perform logical link control (LLC) handling.
In some cases, you might need or want to implement a full DLPI-compliant driver without using the GLD facility. This is true for devices that are not ISO 8802-style (IEEE 802) LAN devices, or where you need a device type or DLPI service not supported by GLD.
Type DL_ETHER: Ethernet V2 and ISO 8802-3 (IEEE 802.3)
For devices designated type DL_ETHER, GLD provides support for both Ethernet V2 and ISO 8802-3 (IEEE 802.3) packet processing. Ethernet V2 enables a data link service user to access and use any of a variety of conforming data link service providers without special knowledge of the provider's protocol. A service access point (SAP) is the point through which the user communicates with the service provider.
Streams bound to SAP values in the range [0-255] are treated as equivalent and denote that the user wants to use 8802-3 mode. If the value of the SAP field of the DL_BIND_REQ is within this range, GLD computes the length (not including the 14-byte media access control (MAC) header) of each subsequent DL_UNITDATA_REQ message on that Stream and transmits 8802-3 frames having those lengths in the MAC frame header type fields. Such lengths never exceed 1500.
All frames received from the media that have a type field in the range [0-1500] are assumed to be 8802-3 frames and are routed up all open Streams that are in 8802-3 mode (those Streams bound to a SAP value in the [0-255] range). If more than one Stream is in 8802-3 mode, the incoming frame is duplicated and routed up each such Stream.
Streams bound to SAP values greater than 1500 (Ethernet V2 mode) receive incoming packets whose Ethernet MAC header type value exactly matches the value of the SAP to which the Stream is bound.
Types DL_TPR and DL_FDDI: SNAP Processing
For media types DL_TPR and DL_FDDI, GLD implements minimal SNAP (Sub-Net Access Protocol) processing for any Stream bound to a SAP value greater than 255. SAP values in the range [0-255] are LLC SAP values and are carried naturally by the media packet format. SAP values greater than 255 require a SNAP header, subordinate to the LLC header, to carry the 16-bit Ethernet V2-style SAP value.
SNAP headers are carried under LLC headers with destination SAP 0xAA. For outgoing packets with SAP values greater than 255, GLD creates an LLC+SNAP header that always looks like:
AA AA 03 00 00 00 XX XX |
where ``XX XX'' represents the 16-bit SAP, corresponding to the Ethernet V2 style ``type.'' This is the only class of SNAP header supported--non-zero OUI (organizational unique identifier) fields and LLC control fields other than 03 are considered to be LLC packets with SAP 0xAA. Clients wanting to use SNAP formats other than this one must use LLC and bind to SAP 0xAA.
Incoming packets are examined to ascertain whether they conform to the format shown above. Packets that conform to this format are matched to any Streams bound to the packet's 16-bit SNAP type, as well as being considered to match the LLC SNAP SAP 0xAA.
Packets received for any LLC SAP are passed up all Streams that are bound to an LLC SAP, as described for media type DL_ETHER.
Type DL_TPR: Source Routing
For type DL_TPR devices, GLD implements minimal support for source routing. Source routing enables a station that is sending a packet across a bridged medium to specify (in the packet MAC header) routing information that determines the route that the packet will take through the network.
Functionally, the source routing support provided by GLD learns routes, solicits and responds to requests for information about possible multiple routes, and selects among available routes. It adds Routing Information Fields to the MAC headers of outgoing packets and recognizes such fields in incoming packets.
GLD's source routing support does not implement the full Route Determination Entity (RDE) specified in Section 9 of ISO 8802-2 (IEEE 802.2). However, it can interoperate with any such implementations that might exist in the same (or a bridged) network.
Style 1 and Style 2 DLPI Providers
GLD implements both Style 1 and Style 2 DLPI providers. A physical point of attachment (PPA) is the point at which a system attaches itself to a physical communication medium. All communication on that physical medium funnels through the PPA. The Style 1 provider attaches the Stream to a particular PPA based on the major/minor device that has been opened. The Style 2 provider requires the DLS (data link service) user to explicitly identify the desired PPA using DL_ATTACH_REQ. In this case, open(9E) creates a Stream between the user and GLD, and DL_ATTACH_REQ subsequently associates a particular PPA with that Stream. Style 2 is denoted by a minor number of zero. If a device node whose minor number is not zero is opened, Style 1 is indicated and the associated PPA is the minor number minus 1. In both Style 1 and Style 2 opens, the device is cloned.
Implemented DLPI Primitives
GLD implements several DLPI primitives. The DL_INFO_REQ primitive requests information about the DLPI Stream. The message consists of one M_PROTO message block. GLD returns device-dependent values in the DL_INFO_ACK response to this request, based on information the GLD-based driver specified in the gldm_mac_info(9S) structure passed to gld_register(). However, GLD returns the following values on behalf of all GLD-based drivers:
Service mode is DL_CLDLS -- GLD implements connectionless-mode service
Provider style is DL_STYLE1 or DL_STYLE2, depending on how the Stream was opened
No optional Quality of Service (QOS) support is present and the QOS fields are zero
Note - Contrary to the DLPI specification, GLD returns the device's correct address length and broadcast address in DL_INFO_ACK even before the Stream has been attached to a PPA.
The DL_ATTACH_REQ primitive is used to associate a PPA with a Stream. This request is needed for Style 2 DLS providers to identify the physical medium over which the communication will transpire. Upon completion, the state changes from DL_UNATTACHED to DL_UNBOUND. The message consists of one M_PROTO message block. This request is not permitted when using the driver in Style 1 mode; Streams opened using Style 1 are already attached to a PPA by the time the open completes.
The DL_DETACH_REQ primitive requests to detach the PPA from the Stream. This is only allowed if the Stream was opened using Style 2.
The DL_BIND_REQ and DL_UNBIND_REQ primitives bind and unbind a DLSAP (data link service access point) to the Stream. The PPA associated with a Stream will have completed initialization before completion of the processing of the DL_BIND_REQ on that Stream. Binding multiple Streams to the same SAP is allowed; each such Stream receives a copy of any packets received for that SAP.
The DL_ENABMULTI_REQ and DL_DISABMULTI_REQ primitives enable and disable reception of individual multicast group addresses. An application or other DLS user is permitted to create or modify a set of multicast addresses on a per-Stream basis by iterative use of these primitives. The Stream must be attached to a PPA for these primitives to be accepted.
The DL_PROMISCON_REQ and DL_PROMISCOFF_REQ primitives enable and disable promiscuous mode on a per-Stream basis, either at a physical level or at the SAP level. The DL Provider routes all received messages on the media to the DLS user until either a DL_DETACH_REQ or a DL_PROMISCOFF_REQ is received or the Stream is closed. You can specify physical level promiscuous reception of all packets on the medium or of multicast packets only.
Note - The Stream must be attached to a PPA for these promiscuous mode primitives to be accepted.
The DL_UNITDATA_REQ primitive is used to send data in a connectionless transfer. Because this is an unacknowledged service, there is no guarantee of delivery. The message consists of one M_PROTO message block followed by one or more M_DATA blocks containing at least one byte of data.
The DL_UNITDATA_IND type is used when a packet is received and is to be passed upstream. The packet is put into an M_PROTO message with the primitive set to DL_UNITDATA_IND.
The DL_PHYS_ADDR_REQ primitive requests the MAC address currently associated with the PPA attached to the Stream. The address is returned by the DL_PHYS_ADDR_ACK primitive. When using Style 2, this primitive is only valid following a successful DL_ATTACH_REQ.
The DL_SET_PHYS_ADDR_REQ primitive changes the MAC address currently associated with the PPA attached to the Stream. This primitive affects all other current and future Streams attached to this device. Once changed, all Streams currently or subsequently opened and attached to this device will obtain this new physical address. The new physical address remains in effect until this primitive is used to change the physical address again or the driver is reloaded.
Note - The superuser is allowed to change the physical address of a PPA while other Streams are bound to the same PPA.
The DL_GET_STATISTICS_REQ primitive requests a DL_GET_STATISTICS_ACK response containing statistics information associated with the PPA attached to the Stream. Style 2 Streams must be attached to a particular PPA using DL_ATTACH_REQ before this primitive can succeed.