/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdio.h>
#include <libdevinfo.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <libintl.h>
#include <net/if_types.h>
#include <libdllink.h>
#include <libdladm.h>
#include <libdlib.h>
#include <libdladm_impl.h>
#include <libinetutil.h>
#include <zone.h>
/*
* IP over IB administration API; see PSARC/2010/085
*/
/*
* Function prototypes
*/
/*
* Convert a error status returned by the IP over IB kernel driver to a
* valid dladm status.
*/
static dladm_status_t
{
switch (err) {
case 0:
return (DLADM_STATUS_OK);
case IBD_INVALID_PORT_INST:
return (DLADM_STATUS_INVALID_PORT_INSTANCE);
case IBD_PORT_IS_DOWN:
return (DLADM_STATUS_PORT_IS_DOWN);
case IBD_PKEY_NOT_PRESENT:
return (DLADM_STATUS_PKEY_NOT_PRESENT);
case IBD_PARTITION_EXISTS:
return (DLADM_STATUS_PARTITION_EXISTS);
case IBD_INVALID_PKEY:
return (DLADM_STATUS_INVALID_PKEY);
case IBD_NO_HW_RESOURCE:
return (DLADM_STATUS_NO_IB_HW_RESOURCE);
return (DLADM_STATUS_INVALID_PKEY_TBL_SIZE);
default:
return (DLADM_STATUS_FAILED);
}
}
static dladm_status_t
{
return (DLADM_STATUS_OK);
if (iocp->ioc_status == 0)
return (dladm_errno2status(errno));
}
/*
* Get the active configuration information for the partition given by
* the 'linkid'.
*/
static dladm_status_t
{
/*
* The ioc_linkid here will contain the data link id of the IB partition
* object.
*/
if (status != DLADM_STATUS_OK)
goto bail;
/*
* On return from the ioctl ioc_linkid field contains the IB port's
* linkid.
*/
/*
* If the IP over IB driver reports that this partition was created
* forcibly, then set the force create flag.
*/
if (ioc.ioc_force_create)
bail:
return (status);
}
/*
* Get the configuration information about the IB partition 'linkid' from the
* persistent configuration.
*/
static dladm_status_t
{
/* Get the IB partition's datalink ID */
goto done;
return (status);
/*
* Get the name of the IB Phys link over which IB partition was
* created.
*/
sizeof (linkover));
if (status != DLADM_STATUS_OK) {
goto done;
} else {
/* Get the IB Phys link's datalink ID */
goto done;
}
/* Get the IB partition's P_Key */
sizeof (uint64_t));
if (status != DLADM_STATUS_OK)
goto done;
if (class != DATALINK_CLASS_PART) {
goto done;
}
/*
* If the FFORCE field is set in the persistent configuration database
* set the force create flag in the partition attributes.
*/
sizeof (boolean_t));
if (status != DLADM_STATUS_OK) {
if (status != DLADM_STATUS_NOTFOUND)
goto done;
}
done:
return (status);
}
/*
* Get the configuration information for the IB partition given by the datalink
* ID 'linkid'. Based on the 'flags' field the information is either from the
* active system (DLADM_OPT_ACTIVE) or from the persistent configuration
* database.
*/
{
if (flags == DLADM_OPT_ACTIVE)
else if (flags == DLADM_OPT_PERSIST)
else
return (DLADM_STATUS_BADARG);
}
/*
* Get the configuration information for the IB Phys link given by the datalink
* ID 'linkid'.
*/
/* ARGSUSED */
{
/*
* We need to get the device name of the IB Phys link to get the
* correct instance number of the IP over IB driver instance.
*/
!= DLADM_STATUS_OK)
return (DLADM_STATUS_BADARG);
/*
* Get the instance number of the IP over IB driver instance which
* represents this IB Phys link.
*/
return (DLADM_STATUS_FAILED);
/*
* The ioc_linkid here will contain IB port linkid here. We make the
* first ioctl call to get the P_Key table size for this HCA port.
*/
ioc.ioc_pkey_tbl_sz = 0;
if (status != DLADM_STATUS_OK)
return (status);
/*
* Now allocate the memory for the P_Key table based on the table size
* return by the ioctl.
*/
goto bail;
}
/*
* Call the ioctl again to get the P_Key table and other IB Phys link
* attributes.
*/
if (status != DLADM_STATUS_OK)
goto bail;
return (status);
bail:
return (status);
}
/*
* Free the memory allocated for the IB HCA port's P_Key table by
* dladm_ib_info library call.
*/
void
{
}
/*
* Call into the IP over IB driver to create a partition object.
*/
static dladm_status_t
{
/* IB Physical datalink ID */
/* IB Partition datalink ID */
!= 0);
}
/*
* Create an entry in the dladm persistent configuration database for the
* partition specified by pattr.
*/
{
if (status != DLADM_STATUS_OK)
return (status);
/*
* Get the name of the IB Phys link over which this partition was
* created.
*/
if (status != DLADM_STATUS_OK)
return (status);
/* Store IB Phys link name (linkover) */
linkover);
if (status != DLADM_STATUS_OK)
return (status);
/* Store the IB Partitions P_Key */
DLADM_TYPE_UINT64, &u64);
if (status != DLADM_STATUS_OK)
return (status);
/* Store the force create flag. */
if (status != DLADM_STATUS_OK)
goto done;
}
if (status != DLADM_STATUS_OK)
return (status);
done:
return (status);
}
/*
* Create a new IB Partition datalink of name 'pname' over the IB Physical link
* given in 'physlinkid' with the P_key 'pkey' and return the datalink ID in
* 'partlinkid'. If the 'force' option is set in the 'flags' argument, the
* partition will be created even if the P_Key 'pkey' does not exist or if the
* HCA port represented by the IB Phys link is down. If the 'temporary' flag is
* set, then the configuration information is not added to the persistent
* database.
*/
{
int i;
flags &= ~DLADM_OPT_FORCE;
/*
* Get the media type of the Phys link datalink ID provided and
* make sure that it is Infiniband media DL_IB)
*/
return (status);
return (dladm_errno2status(ENOTSUP));
/*
* Get the instance number of the IP over IB driver instance which the
* IB Phys link 'physlinkid' over which we will be creating our IB
* partition.
*/
return (status);
return (DLADM_STATUS_FAILED);
return (status);
/*
* Create the IB partition object.
*/
if (status != DLADM_STATUS_OK)
goto done;
/*
* If the persist flag is set then write this partition information
* to the persistent configuration.
*/
if (status != DLADM_STATUS_OK)
goto done;
}
/*
* If the name-value pair list of properties were provided set those
* properties over the datalink.
*/
if (status != DLADM_STATUS_OK)
break;
}
}
done:
if (status != DLADM_STATUS_OK) {
if (conf_set)
if (part_created)
(void) i_dladm_part_delete(handle,
flags);
}
if (partlinkid != NULL)
return (status);
}
{
}
/*
* Call into the IP over IB driver to delete the IB partition and free up all
* the resources allocated for it.
*/
static dladm_status_t
{
if (status != DLADM_STATUS_OK)
return (status);
return (DLADM_STATUS_OK);
}
/*
* Delete an IB partition if 'flags' contains the active flag. Update the
* persistent configuration if 'flags' contains the persist flag.
*/
{
if (flags == 0)
return (DLADM_STATUS_BADARG);
/*
* Make sure that the datalinkid provided is an IB partition class
* datalink ID.
*/
!= DLADM_STATUS_OK))
return (DLADM_STATUS_BADARG);
if (class != DATALINK_CLASS_PART)
return (DLADM_STATUS_BADARG);
if ((flags & DLADM_OPT_ACTIVE) != 0) {
if (status == DLADM_STATUS_OK ||
status == DLADM_STATUS_NOTFOUND) {
} else {
return (status);
}
}
if ((flags & DLADM_OPT_PERSIST) != 0) {
/*
* A partition could have been temporarily deleted in which
* case the delete of the active partition above would have
* failed. In that case, we update the status to be returned
* to that of the status returned for deleting the persistent
* database entry.
*/
if (status == DLADM_STATUS_NOTFOUND)
}
return (status);
}
/*
* Call into the IP over IB driver to create the active instances of one or all
* IB partitions present in the persistent configuration.
*/
/* ARGSUSED */
static int
{
/*
* plinkid is the IB partition datalink's ID. Get an handle to the
* persistent configuration entry for this datalink ID. If this datalink
* ID is not present in the persistent configuration return.
*/
return (status);
/*
* Get the name of the IB Phys link over which this partition was
* created.
*/
sizeof (linkover));
if (status != DLADM_STATUS_OK)
goto done;
NULL)) != DLADM_STATUS_OK)
goto done;
/*
* Get the phys attribute of the IB Phys link to get the device name
* associated with the phys link. We need this to get the IP over IB
* driver instance number.
*/
!= DLADM_STATUS_OK)
goto done;
/* Get the IB partition's P_key */
sizeof (u64));
if (status != DLADM_STATUS_OK)
goto done;
/*
* We always set the force flag during dladm_part_up because we want
* the partition creation to succeed even if the IB HCA port over which
* the partition is being created is still down. Since dladm_part_up
* is usually invoked during early boot sequence, it is possible under
* some IB subnet configurations for dladm_up_part to be called before
* the IB link negotiation is completed and port state is set to active
* and P_Key table is updated.
*/
/* IB Phys link's datalink ID. */
/* IB Partition's datalink ID. */
return (DLADM_WALK_CONTINUE);
/* Create the active IB Partition object. */
done:
return (DLADM_WALK_CONTINUE);
}
/*
* Bring up one or all IB partition(s) present in the persistent configuration
* database. If we need to bring up one IB Partition, its datalink ID is
* provided in 'linkid'.
*/
/* ARGSUSED */
{
if (linkid == DATALINK_ALL_LINKID) {
return (DLADM_STATUS_OK);
} else {
return (status);
}
}
/*
* Call into the IP over IB driver to delete the IB partition. Persistent
* configuration is not changed.
*/
static int
{
return (DLADM_WALK_CONTINUE);
}
/*
* Bring down one or all active IB partition(s). If we need to bring down one
* IB Partition, its datalink ID is provided in 'linkid'. Persistent
* configuration and linkid mapping in dlmgmtd is not removed. Downed IB
* partition(s) can be brought up with dladm_part_up().
*/
/* ARGSUSED */
{
if (linkid == DATALINK_ALL_LINKID) {
} else {
}
return (status);
}