2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * Data-Link Provider Interface (Version 2) 2N/A * Rather than have libdlpi take the libdladm handle, 2N/A * open the handle here. 2N/A * Validate linkname and retrieve the DLPI provier name and PPA. 2N/A * Ensure flags values are sane. 2N/A /* Allocate a new dlpi_impl_t. */ 2N/A /* Copy linkname provided to the function. */ 2N/A /* Copy provider name. */ 2N/A * Special case: DLPI_SERIAL flag is set to indicate a synchronous 2N/A * serial line interface (see syncinit(1M), syncstat(1M), 2N/A * syncloop(1M)), which is not a DLPI link. 2N/A * The error code indicates not to continue the 2N/A * style-2 open. Change the error code back to 2N/A * DL_SYSERR, so that one would know the cause 2N/A * of failure from errno. 2N/A * We intentionally do not care if this request fails, as this 2N/A * indicates the underlying DLPI device does not support Native mode 2N/A * (pre-GLDV3 device drivers). 2N/A * NOTE: The version argument must be less than the max supported value 2N/A * and is used to determine the fields of the dlpi_info_t structure. See 2N/A /* Set QoS range parameters to default unsupported value. */ 2N/A /* Set QoS parameters to default unsupported value. */ 2N/A /* Check and save QoS selection information, if any. */ 2N/A /* Check and save QoS range information, if any. */ 2N/A /* Check and save physical address and SAP information. */ 2N/A /* Check and save broadcast address information, if any. */ 2N/A /* Information retrieved from the handle. */ 2N/A * This function parses 'linkname' and stores the 'provider' name and 'PPA'. 2N/A * We support opening links using the zone/link format. Before we parse 2N/A * the linkname and retreive the DLPI provider name and PPA we strip the 2N/A * zonename prefix (if any) and call dlpi_parselink to retrieve the DLPI 2N/A * provider name and PPA. 2N/A * Validate linkname and retrieve the DLPI provier name and PPA. 2N/A * This function takes a provider name and a PPA and stores a full linkname 2N/A * as 'linkname'. If 'provider' already is a full linkname 'provider' name 2N/A * is stored in 'linkname'. 2N/A * If 'sap' is DLPI_ANY_SAP, bind to SAP 2 on token ring, else 0 on 2N/A * other interface types (SAP 0 has special significance on token ring). 2N/A * Received a DLPI_BIND_ACK, now verify that the bound SAP 2N/A * is equal to the SAP requested. Some DLPI MAC type may bind 2N/A * to a different SAP than requested, in this case 'boundsap' 2N/A * returns the actual bound SAP. For the case where 'boundsap' 2N/A * is NULL and 'sap' is not DLPI_ANY_SAP, dlpi_bind fails. 2N/A * This function is invoked by dlpi_enabmulti() or dlpi_disabmulti() and 2N/A * This function is invoked by dlpi_promiscon() or dlpi_promiscoff(). Based 2N/A * on the value of 'op', promiscuous mode is turned on/off at the specified 2N/A /* Received DL_PHYS_ADDR_ACK, store the physical address and length. */ 2N/A /* Set priority to default priority range. */ 2N/A /* Use SAP value if specified otherwise use bound SAP value. */ 2N/A * Since `daddrp' only has the link-layer destination address, 2N/A * we must prepend or append the SAP (according to dli_sapbefore) 2N/A * to make a full DLPI address. 2N/A * If handle is in raw mode ignore everything except total message 2N/A * If DLPI link provides source address, store source address in 2N/A * 'saddrp' and source length in 'saddrlenp', else set saddrlenp to 0. 2N/A * If destination address requested, check and save destination 2N/A /* Register notification information. */ 2N/A /* Insert notification node at head */ 2N/A /* Walk the notifyentry list to find matching id. */ 2N/A /* Delete node if callbacks are not being processed. */ 2N/A * Returns DLPI style stored in the handle. 2N/A * Note: This function is used for test purposes only. Do not remove without 2N/A * fixing the DLPI testsuite. 2N/A * This function attempts to open a device under the following namespaces: 2N/A * /dev/net/zone - if a data-link is specified with a zonename prefix 2N/A * /dev/net - if a data-link with the specified name exists 2N/A * /dev - if DLPI_DEVONLY is specified, or if there is no 2N/A * data-link with the specified name (could be /dev/ip) 2N/A * In particular, if DLPI_DEVIPNET is not specified, this function is used to 2N/A * open a data-link node, or "/dev/ip" node. It is usually be called firstly 2N/A * with style1 being B_TRUE, and if that fails and the return value is not 2N/A * DLPI_ENOTSTYLE2, the function will again be called with style1 being 2N/A * B_FALSE (style-1 open attempt first, then style-2 open attempt). 2N/A * If DLPI_DEVONLY is specified, both attempt will try to open the /dev node 2N/A * Otherwise, for style-1 attempt, the function will try to open the style-1 2N/A * /dev node if the give name is not a data-link name (e.g., it is /dev/ip). 2N/A * Note that the fallback and the subsequent style-2 attempt will not happen if: 2N/A * errno other than ENOENT, which means that the specific /dev/net or 2N/A * /dev/net/zone node exists, but the attempt fails for some other reason; 2N/A * 3. style-1 openning of the /dev/net node fails with ENOENT, but the name 2N/A * is a known device name or its VLAN PPA hack name. (for example, assuming 2N/A * ENOENT, but we should not fallback to open /dev/bge1000 in this case, 2N/A * as VLAN 1 over the bge0 device should be named as net1000. 2N/A * DLPI_ENOTSTYLE2 will be returned in case 2 and 3 to indicate not to proceed 2N/A * the second style-2 open attempt. 2N/A * This is not a valid style-1 name. It could be "ip" module 2N/A * for example. Fallback to open the /dev node. 2N/A * We don't fallback to open the /dev node when it returns 2N/A * error codes other than ENOENT. In that case, DLPI_ENOTSTYLE2 2N/A * is returned to indicate not to continue the style-2 open. 2N/A * We didn't find the /dev/net node. Then we check whether 2N/A * the given name is a device name or its VLAN PPA hack name 2N/A * of a known link. If the answer is yes, and this link 2N/A * supports vanity naming, then the link (or the VLAN) should 2N/A * also have its /dev/net node but perhaps with another vanity 2N/A * name (for example, when bge0 is renamed to net0). In this 2N/A * case, although attempt to open the /dev/net/<devname> fails, 2N/A * we should not fallback to open the /dev/<devname> node. 2N/A /* open libdladm handle rather than taking it as input */ 2N/A * Open a style 1 link. PPA is implicitly attached. 2N/A * Open a style 2 link. PPA must be explicitly attached. 2N/A * Special case: DLPI_SERIAL flag (synchronous serial lines) is not a 2N/A * DLPI link so attach and ignore rest. 2N/A * Succeeded opening the link and verified it is style2. Now attach to 2N/A * PPA only if DLPI_NOATTACH is not set. 2N/A * Verify with DLPI that the link is the expected DLPI 'style' device, 2N/A * dlpi_info sets the DLPI style in the DLPI handle. 2N/A * For DLPI style 2 providers, an explicit attach of PPA is required. 2N/A * Special case: DLPI_SERIAL flag (synchronous serial lines) 2N/A * is not a DLPI link so ignore DLPI style. 2N/A * Enable DLPI passive mode on a DLPI handle. We intentionally do not care 2N/A * if this request fails, as this indicates the underlying DLPI device does 2N/A * not support link aggregation (pre-GLDV3 device drivers), and thus will 2N/A * DLPI primitives like DL_BIND_REQ. For further info see dlpi(7p). 2N/A * Send a dlpi control message and/or data message on a stream. The inputs 2N/A * for this function are: 2N/A * dlpi_impl_t *dip: internal dlpi handle to open stream 2N/A * const dlpi_msg_t *dlreqp: request message structure 2N/A * void *databuf: data buffer 2N/A * size_t datalen: data buffer len 2N/A * int flags: flags to set for putmsg() 2N/A * Returns DLPI_SUCCESS if putmsg() succeeds, otherwise DL_SYSERR on failure. 2N/A * Get a DLPI control message and/or data message from a stream. The inputs 2N/A * for this function are: 2N/A * dlpi_impl_t *dip: internal dlpi handle 2N/A * int msec: timeout to wait for message 2N/A * dlpi_msg_t *dlreplyp: reply message structure, the message size 2N/A * member on return stores actual size received 2N/A * t_uscalar_t dlreqprim: requested primitive 2N/A * t_uscalar_t dlreplyprim:acknowledged primitive in response to request 2N/A * size_t dlreplyminsz: minimum size of acknowledged primitive size 2N/A * void *databuf: data buffer 2N/A * size_t *datalenp: data buffer len 2N/A * size_t *totdatalenp: total data received. Greater than 'datalenp' if 2N/A * actual data received is larger than 'databuf' 2N/A * Function returns DLPI_SUCCESS if requested message is retrieved 2N/A * otherwise returns error code or timeouts. If a notification arrives on 2N/A * the stream the callback is notified. However, error returned during the 2N/A * handling of notification is ignored as it would be confusing to actual caller 2N/A * dlreplyp and databuf can be NULL at the same time, to force a check 2N/A * for pending events on the DLPI link instance; dlpi_enabnotify(3DLPI). 2N/A * this will be true more so for DLPI_RAW mode with notifications 2N/A * The supplied DLPI_CHUNKSIZE sized buffers are large enough 2N/A * to retrieve all valid DLPI responses in one iteration. 2N/A * If MORECTL or MOREDATA is set, we are not interested in the 2N/A * remainder of the message. Temporary buffers are used to 2N/A * drain the remainder of this message. 2N/A * The special case we have to account for is if 2N/A * a higher priority messages is enqueued whilst handling 2N/A * this condition. We use a change in the flags parameter 2N/A * returned by getmsg() to indicate the message has changed. 2N/A * In the special case of higher priority 2N/A * message received, the low priority message 2N/A * received earlier is discarded, if no data 2N/A * or control message is left. 2N/A * Check if DL_NOTIFY_IND message received. If there is one, 2N/A * notify the callback function(s) and continue processing the 2N/A * requested message. 2N/A /* process properly-formed DL_NOTIFY_IND messages */ 2N/A * If we were expecting a data message, and we got one, set 2N/A * *datalenp. If we aren't waiting on a control message, then 2N/A * If we were expecting a control message, and the message 2N/A * we received is at least big enough to be a DLPI message, 2N/A * then verify it's a reply to something we sent. If it 2N/A * is a reply to something we sent, also verify its size. 2N/A * Common routine invoked by all DLPI control routines. The inputs for this 2N/A * dlpi_impl_t *dip: internal dlpi handle 2N/A * const dlpi_msg_t *dlreqp: request message structure 2N/A * dlpi_msg_t *dlreplyp: reply message structure 2N/A * size_t dlreplyminsz: minimum size of reply primitive 2N/A * int flags: flags to be set to send a message 2N/A * message. However, if DLPI notification has been enabled via 2N/A * dlpi_enabnotify(), DL_NOTIFY_IND messages are handled before handling 2N/A * expected messages. Otherwise, any other unexpected asynchronous messages will 2N/A /* Put the requested primitive on the stream. */ 2N/A /* Retrieve acknowledged message for requested primitive. */ 2N/A * If primitive is DL_ERROR_ACK, set errno. 2N/A "bad LSAP selector",
/* DL_BADSAP 0x00 */ 2N/A "DLSAP address in improper format or invalid",
/* DL_BADADDR 0x01 */ 2N/A "improper permissions for request",
/* DL_ACCESS 0x02 */ 2N/A "primitive issued in improper state",
/* DL_OUTSTATE 0x03 */ 2N/A "sequence number not from outstanding DL_CONN_IND",
2N/A /* DL_BADCORR 0x05 */ 2N/A "user data exceeded provider limit",
/* DL_BADDATA 0x06 */ 2N/A "requested service not supplied by provider",
2N/A /* DL_UNSUPPORTED 0x07 */ 2N/A "specified PPA was invalid",
/* DL_BADPPA 0x08 */ 2N/A "primitive received not known by provider",
/* DL_BADPRIM 0x09 */ 2N/A "QoS parameters contained invalid values",
2N/A /* DL_BADQOSPARAM 0x0a */ 2N/A "token used not an active stream",
/* DL_BADTOKEN 0x0c */ 2N/A "attempted second bind with dl_max_conind",
/* DL_BOUND 0x0d */ 2N/A "physical link initialization failed",
/* DL_INITFAILED 0x0e */ 2N/A "provider couldn't allocate alternate address",
/* DL_NOADDR 0x0f */ 2N/A "physical link not initialized",
/* DL_NOTINIT 0x10 */ 2N/A "previous data unit could not be delivered",
2N/A /* DL_UNDELIVERABLE 0x11 */ 2N/A "primitive is known but unsupported",
2N/A /* DL_NOTSUPPORTED 0x12 */ 2N/A "limit exceeded",
/* DL_TOOMANY 0x13 */ 2N/A "promiscuous mode not enabled",
/* DL_NOTENAB 0x14 */ 2N/A "other streams for PPA in post-attached",
/* DL_BUSY 0x15 */ 2N/A "automatic handling XID&TEST unsupported",
/* DL_NOAUTO 0x16 */ 2N/A "automatic handling of XID unsupported",
/* DL_NOXIDAUTO 0x17 */ 2N/A "automatic handling of TEST unsupported",
/* DL_NOTESTAUTO 0x18 */ 2N/A "automatic handling of XID response",
/* DL_XIDAUTO 0x19 */ 2N/A "automatic handling of TEST response",
/* DL_TESTAUTO 0x1a */ 2N/A "pending outstanding connect indications" /* DL_PENDING 0x1b */ 2N/A * libdlpi error codes. 2N/A "DLPI operation succeeded",
/* DLPI_SUCCESS */ 2N/A "invalid argument",
/* DLPI_EINVAL */ 2N/A "invalid DLPI linkname",
/* DLPI_ELINKNAMEINVAL */ 2N/A "DLPI link does not exist",
/* DLPI_ENOLINK */ 2N/A "bad DLPI link",
/* DLPI_EBADLINK */ 2N/A "invalid DLPI handle",
/* DLPI_EINHANDLE */ 2N/A "DLPI operation timed out",
/* DLPI_ETIMEDOUT */ 2N/A "unsupported DLPI version",
/* DLPI_EVERNOTSUP */ 2N/A "unsupported DLPI connection mode",
/* DLPI_EMODENOTSUP */ 2N/A "unavailable DLPI SAP",
/* DLPI_EUNAVAILSAP */ 2N/A "DLPI operation failed",
/* DLPI_FAILURE */ 2N/A "DLPI style-2 node reports style-1",
/* DLPI_ENOTSTYLE2 */ 2N/A "bad DLPI message",
/* DLPI_EBADMSG */ 2N/A "DLPI raw mode not supported",
/* DLPI_ERAWNOTSUP */ 2N/A "DLPI notification not supported by link",
2N/A /* DLPI_ENOTENOTSUP */ 2N/A "invalid DLPI notification type",
/* DLPI_ENOTEINVAL */ 2N/A "invalid DLPI notification id",
/* DLPI_ENOTEIDINVAL */ 2N/A "DLPI_IPNETINFO not supported" /* DLPI_EIPNETINFONOTSUP */ 2N/A * Each table entry comprises a DLPI/Private mactype and the description. 2N/A return (
"Unknown MAC Type");
2N/A * Each table entry comprises a DLPI primitive and the maximum buffer 2N/A * size needed, in bytes, for the DLPI message (see <sys/dlpi.h> for details). 2N/A * Refers to the dlpi_primsizes[] table to return corresponding maximum 2N/A * sap values vary in length and are in host byte order, build sap value 2N/A * by writing saplen bytes, so that the sap value is left aligned. 2N/A * Copy sap value to a buffer in host byte order. saplen is the number of 2N/A * Fill notification payload and callback each registered functions. 2N/A * Delete nodes if any was called while processing. 2N/A * libdlpi currently only supports notifications for 2N/A * DL_CURR_PHYS_ADDR. 2N/A /* Walk the notifyentry list to unregister marked entries. */ 2N/A * Find registered notification. 2N/A * Walk the list of notifications and deleted nodes marked to be deleted.