DLPI(7P) | Protocols | DLPI(7P) |
#include <sys/dlpi.h>
The interface specifies access to the data link service provider in the form of M_PROTO and M_PCPROTO type STREAMS messages and does not define a specific protocol implementation. The interface defines the syntax and semantics of primitives exchanged between the data link user and the data link provider to attach a physical device with physical-level address to a stream, bind a datalink-level address to the stream, get implementation-specific information from the data link provider, exchange data with a peer data link user in one of three communication modes (connection, connectionless, acknowledged connectionless), enable/disable multicast group and promiscuous mode reception of datalink frames, get and set the physical address associated with a stream, and several other operations.
Solaris conforms to The Open Group Technical Standard for DLPI, Version 2. For free access to this specification, point your browser to www.opengroup.org/pubs/catalog/c811.htm. Solaris also provides extensions to the DLPI standard, as detailed in this man page.
typedef struct { t_uscalar_t dl_primitive; uint32_t dl_notifications; uint32_t dl_timelimit; } dl_notify_req_t;
The dl_primitive field must be set to DL_NOTIFY_REQ; the dl_timelimit field is reserved for future use and must be set to zero. The dl_notifications field is a bitmask containing the event types the consumer is interested in receiving, and must be zero or more of:
DL_NOTE_LINK_DOWN Notify when link has gone down DL_NOTE_LINK_UP Notify when link has come up DL_NOTE_PHYS_ADDR Notify when address changes DL_NOTE_SDU_SIZE Notify when MTU changes DL_NOTE_SPEED Notify when speed changes DL_NOTE_PROMISC_ON_PHYS Notify when DL_PROMISC_PHYS is set DL_NOTE_PROMISC_OFF_PHYS Notify when DL_PROMISC_PHYS is cleared
Consumers might find it useful to send a DL_NOTIFY_REQ message with no requested types to check if the DLPI provider supports the extension.
Upon receiving the DL_NOTIFY_REQ, the DLPI provider must generate a DL_NOTIFY_ACK, which is an M_PROTO message with the following payload:
typedef struct { t_uscalar_t dl_primitive; uint32_t dl_notifications; } dl_notify_ack_t;
The dl_primitive field must be set to DL_NOTIFY_ACK. The dl_notifications field must include any notifications that the provider supports, along with any other unrequested notifications that the provider supports. However, regardless of the notifications the provider supports, it is restricted to sending only DL_NOTIFY_IND messages (see below) that were requested in the DL_NOTIFY_REQ.
Since there are additional notification types which are not yet available for public use, DLPI consumers and providers must take care when inspecting and setting the dl_notifications field. Specifically, consumers must be careful to only request the above notification types, and providers must be careful to not include any unrecognized notification types in the dl_notifications field when constructing the DL_NOTIFY_ACK. In addition, DL_NOTIFY_IND's that are received with undocumented dl_notification or dl_data values must be ignored.
DLPI consumers might receive a DL_ERROR_ACK message (with dl_error_primitive set to DL_NOTIFY_REQ) in response to the initial DL_NOTIFY_REQ message. This message indicates that the DLPI provider does not support the DLPI notification extension. Otherwise, the DLPI consumer receives a DL_NOTIFY_ACK and should expect to receive DL_NOTIFY_IND messages for any types that it requested that were still set in it. The DL_NOTIFY_IND is an M_PROTO message with the following payload:
typedef struct { t_uscalar_t dl_primitive; uint32_t dl_notification; uint32_t dl_data; t_uscalar_t dl_addr_length; t_uscalar_t dl_addr_offset; } dl_notify_ind_t;
The dl_primitive field must be set to DL_NOTIFY_IND, and the dl_notification field must be set to the event type that has occurred (for example, DL_NOTE_LINK_DOWN). Only a single event type can be set in each DL_NOTIFY_IND.
For the DL_NOTE_SPEED event type, dl_data must be set to the current interface speed in kilobits per second. For the DL_NOTE_PHYS_ADDR event type, dl_data must be set to DL_CURR_PHYS_ADDR. For the DL_NOTE_SDU_SIZE event type, dl_data must be set to the current MTU in bytes. Otherwise, dl_data must be set to zero.
For the DL_NOTE_PHYS_ADDR event type, the dl_addr_length field must be set to the length of the address, and the dl_addr_offset field must be set to offset of the first byte of the address, relative to b_rptr (for example, if the address immediately follows the dl_notify_ind structure, dl_addr_offset is set to 'sizeof (dl_notify_ind)'). For all other event types, the dl_addr_length and dl_addr_offset fields must be set to zero by DLPI providers and ignored by DLPI consumers.
In addition to generating DL_NOTIFY_IND messages when a requested event has occurred, the DLPI provider must initially generate one or more DL_NOTIFY_IND messages to notify the DLPI consumer of the current state of the interface. For instance, if the consumer has requested DL_NOTE_LINK_UP | DL_NOTE_LINK_DOWN, the provider must send a DL_NOTIFY_IND containing the current state of the link (either DL_NOTE_LINK_UP or DL_NOTE_LINK_DOWN) after sending the DL_NOTIFY_ACK.
For the initial DL_NOTIFY_IND message, the DLPI provider is strongly recommended against sending DL_NOTE_LINK_DOWN, even if the interface is still initializing and is not yet ready to send or receive packets. Instead, either delaying the DL_NOTIFY_IND message until the interface is ready or optimistically reporting DL_NOTIFY_LINK_UP and subsequently reporting DL_NOTE_LINK_DOWN if the negotiation fails is strongly preferred. This prevents DL_NOTIFY_IND consumers from needlessly triggering network failover operations and logging error messages during network interface initialization.
The DLPI provider must continue to generate DL_NOTIFY_IND messages until it receives a new DL_NOTIFY_REQ message or the DLPI stream is detached (or closed). Further, a DLPI style 2 provider must keep track of the requested events after a DL_DETACH_REQ operation, and if a subsequent DL_ATTACH_REQ is received, it must send gratuitous DL_NOTIFY_IND messages to notify the consumer of the current state of the device, since the state might have changed while detached (or the consumer might have simply discarded its previous state).
Passive Consumers of Aggregated Links
The DL_PASSIVE_REQ primitive is an M_PROTO message containing the following payload:
typedef struct { t_uscalar_t dl_primitive; } dl_passive_req_t;
Issuing this primitive allows the consumer of a DLPI link to coexist with a link aggregation that also uses the link. Such a consumer is considered passive.
Consumers that don't use this primitive while an aggregation is using the link receive DL_SYSERR/EBUSY when issuing the following DLPI primitives:
DL_BIND_REQ DL_ENABMULTI_REQ DL_PROMISCON_REQ DL_AGGR_REQ DL_UNAGGR_REQ DL_CONTROL_REQ DL_SET_PHYS_ADDR_REQ
A consumer that has not issued a DL_PASSIVE_REQ and has successfully issued one of the above primitives is considered active.
The creation of a link aggregation using dladm(1M) fails if one of the links included in the aggregation has an active consumer, but succeeds if the links do not have any DLPI consumers or only passive consumers.
Raw Mode
Native Mode
Margin
Unless raw mode is enabled, a DLPI stream bound to a VLAN data-link behaves no differently than a traditional DLPI stream. As with non-VLAN data-link access, data must be sent to a DLPI provider without link-layer headers (which are added by the provider) and received data is passed to interested DLPI consumers without link-layer headers. As a result, DLPI consumers not require special-case logic to implement VLAN access.
Because all VLAN traffic is sent with SAP 0x8100, VLAN traffic not filtered at the physical (DL_PROMISC_PHYS) level is also visible if a DLPI consumer enables promiscuous mode of a stream at the DL_PROMISC_SAP level. As mentioned earlier, these packets are received starting with their VLAN headers if raw mode is not enabled.
The priority value can be set on either a per-stream or per-packet basis. DLPI consumers can specify the per-stream priority using the DL_UDQOS_REQ request (the priority value remains unchanged until the next DL_UDQOS_REQ) and also specify the per-packet priority value using the b_band field of a M_DATA message or the dl_priority field of a DL_UNITDATA_REQ.
On the transmit-side, DLPI consumers must send the packets down to the DLPI providers without the VLAN headers (but with the Ethernet headers) unless certain QoS support is required. If QoS support is needed, the packet can have the VLAN header to indicate the priority value, however its VLAN ID must be zero. The DLPI providers then insert the VLAN tags or encode the VLAN tags using the priority value specified in the VLAN headers and send the packets.
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
Interface Stability (Notification support/Passive mode behavior) | Committed |
The DLPI provider name must be between 1 and 16 characters in length, though names between 3 and 8 characters are preferred. The DLPI provider name can consist of any alphanumeric character (a-z, A-Z, 0-9), and the underscore (_). The first and last character of the DLPI provider name cannot be a digit.
The PPA must be a number between 0 and 4294967294 inclusive. Leading zeroes are not permitted.
April 9, 2016 | OmniOS |