/*
* 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 <assert.h>
#include <door.h>
#include <errno.h>
#include <fcntl.h>
#include <libdladm_impl.h>
#include <libdladm.h>
#include <libdlflow_impl.h>
#include <libdlflow.h>
#include <libdllink.h>
#include <libdlmgmt.h>
#include <libnwam.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <zone.h>
/*
* Table of data type sizes indexed by dladm_datatype_t.
*/
0, /* DLADM_TYPE_STR, use strnlen() */
sizeof (boolean_t), /* DLADM_TYPE_BOOLEAN */
sizeof (uint64_t) /* DLADM_TYPE_UINT64 */
};
static dladm_status_t
{
int door_fd;
/* The door descriptor is opened if it isn't already */
return (status);
/*
* Stale door descriptor is possible if dlmgmtd was re-started
* since last door_fd open so try re-opening door file.
*/
goto reopen;
}
}
if (status != DLADM_STATUS_OK)
return (status);
/*
* The size of the input rbuf is not big enough so that
* the door allocate the rbuf itself. In this case, return
* the required size to the caller.
*/
return (DLADM_STATUS_TOOSMALL);
return (DLADM_STATUS_FAILED);
}
}
/*
* Allocate a new linkid with the given name for the given zone.
* Return the new linkid.
*/
{
return (DLADM_STATUS_BADARG);
}
}
return (status);
}
/*
* Allocate a new linkid with the given name. Return the new linkid.
*/
{
}
/*
* Destroy the given link ID.
*/
{
}
/*
* Remap a given link ID to a new name.
*/
const char *link)
{
}
/*
* Make a given link ID active.
*/
{
}
/*
* Create a new link with the given name. Return the new link's handle
*/
{
return (DLADM_STATUS_BADARG);
}
return (status);
}
static dladm_status_t
{
&uint_attrval, sizeof (uint_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
return (DLADM_STATUS_OK);
}
static dladm_status_t
{
&uint_attrval, sizeof (uint_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
&uint_attrval, sizeof (uint_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK)
str_attrval, sizeof (str_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
str_attrval, sizeof (str_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
&uint_attrval, sizeof (uint_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
&uint_attrval, sizeof (uint_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
&uint_attrval, sizeof (uint_attrval));
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s == DLADM_STATUS_OK) {
}
return (s == DLADM_STATUS_NOTFOUND ? DLADM_STATUS_OK : s);
}
{
if (*ret_err != 0)
return (dladm_errno2status(errno));
/* get LINKOVER property, this is a must prop */
if (status != DLADM_STATUS_OK)
return (status);
/*
* returned status ignored, cause it is ok that the underline
* link is missing.
*/
/*
* Get flow_desc and mac_resource, these props don't have to
* set. So NOTFOUND is ok.
*/
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
&attr->fa_flow_desc);
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
}
if (status != DLADM_STATUS_OK)
return (status);
else
return (s == DLADM_STATUS_NOTFOUND ? DLADM_STATUS_OK : s);
}
/* get the flowconf who is next to the "flowname" flow */
{
if (*ret_err != 0)
return (dladm_errno2status(errno));
/* get LINKOVER property, this is a must prop */
sizeof (str_attrval));
if (status != DLADM_STATUS_OK)
return (status);
/*
* Get flow_desc and mac_resource, these props don't have to
* set. So NOTFOUND is ok.
*/
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
if (s != DLADM_STATUS_OK && s != DLADM_STATUS_NOTFOUND)
return (s);
}
if (status != DLADM_STATUS_OK)
return (status);
else
return (s == DLADM_STATUS_NOTFOUND ? DLADM_STATUS_OK : s);
}
{
return (DLADM_STATUS_BADARG);
return (status);
}
/*
* An active physical link reported by the dlmgmtd daemon might not be active
* anymore as this link might be removed during system shutdown. Check its
* real status by calling dladm_phys_info().
*/
{
if (status == DLADM_STATUS_NOTFOUND) {
/*
* No active status, this link was removed. Update its status
* in the daemon and delete all active linkprops.
*
* Note that the operation could fail. If it does, return
* failure now since otherwise dladm_set_linkprop() might
* call back to i_dladm_phys_status() recursively.
*/
return (status);
(*flagsp) &= ~DLMGMT_ACTIVE;
}
return (status);
}
/*
* Utility function to search for a zone ID in an array of zone IDs.
*/
{
int idx;
return (DLADM_STATUS_OK);
}
return (DLADM_STATUS_NOTFOUND);
}
static void
{
}
/*
* Walk each entry in the data link configuration repository and
* call fn on the linkid and arg. Caller must supply one of the
* two callback fns. The first callback fn is called for each
* datalink along with the datalink ID argument, the second callback
* is called with datalink ID and the name of the datalink.
*/
static dladm_status_t
{
return (DLADM_STATUS_BADARG);
return (DLADM_STATUS_BADARG);
if (linkid != DATALINK_ALL_LINKID) {
if (status == DLADM_STATUS_OK)
return (status);
}
do {
/*
* Done with walking. If no next datalink is found,
* return success.
*/
if (status == DLADM_STATUS_NOTFOUND)
break;
}
/*
* An active physical link reported by the dlmgmtd
* daemon might not be active anymore. Check its
* real status.
*/
continue;
}
/*
* Skip to next link now if we are only looking
* for active links.
*/
continue;
}
break;
continue;
}
/*
* If datalink is on loan to a NGZ then we have to call
* the callback twice, with and without a zonename prefix.
*/
/*
* First check if we should use the non-prefixed link
* name that is associated with the global zone.
*/
if ((zonecnt == 0 ||
break;
/*
* Next, check if we should use the prefixed link name
* that is loaned to the non-global zone.
*/
if ((zonecnt == 0 ||
break;
} else {
/*
* For all other datalinks first check if -z option was
* used the datalink is part of the given -z option
* zone list.
*/
if (zonecnt > 0 &&
zonelist) != DLADM_STATUS_OK)
continue;
break;
}
} while (linkid != DATALINK_INVALID_LINKID);
return (status);
}
/*
* Datalink walker function that requires the callback function to
* accept a datalink information structure. This walker should be
* used when printing out datalink names as datalinks in non-global
* zones are displayed in the global zone with a zonename prefix.
*/
{
}
/*
* Walk each physical device present on the system in order based on the
* relative locations of the physical devices, calling fn() and passing in
* argp. Walk is possible only for active config. DLADM_OPT_FORCE is
* supported but optional). Attributes are walked in order determined by
* their current relative physical locations.
*/
{
do {
/*
* Done with walking. If no next device is found,
* return success.
*/
if (status == DLADM_STATUS_NOTFOUND)
break;
}
/*
* "force" option is only needed for initial door call to
* refresh physical location data.
*/
switch (status) {
case DLADM_STATUS_OK:
argp) == DLADM_WALK_TERMINATE)
return (status);
break;
case DLADM_STATUS_NOTFOUND:
/* Device may have been removed */
break;
default:
return (status);
}
return (status);
}
/*
* Reinitialize physical links.
*/
{
if (phys_prefix == NULL) {
} else {
}
}
/*
* check if given flow exists
*/
{
if (name[0] == '\0')
return (DLADM_STATUS_BADARG);
if (status != DLADM_STATUS_OK)
return (status);
return (status);
}
/*
* Walk each entry in the data link configuration repository and
* call fn on the linkid and arg.
*/
{
}
/*
* Get a handle of a copy of the link configuration (kept in the daemon)
* for the given link so it can be updated later by dladm_write_conf().
*/
{
return (DLADM_STATUS_BADARG);
}
return (status);
}
/*
* Get the handle of a local snapshot of the link configuration. Note that
* any operations with this handle are read-only, i.e., one can not update
* the configuration with this handle.
*/
{
char *nvlbuf;
int err;
return (DLADM_STATUS_BADARG);
sz = sizeof (dlmgmt_getconfsnapshot_retval_t);
return (DLADM_STATUS_NOMEM);
goto again;
}
if (status != DLADM_STATUS_OK) {
return (status);
}
}
return (status);
}
/*
* Commit the given flow to the configuration repository so that it will
* persist across reboots.
*/
{
return (DLADM_STATUS_BADARG);
&sz));
}
/*
* Return the underlying links for the link represented by the conf object.
* The caller MUST free the string that is returned.
*/
static char *
{
/*
* Determine which property is used to store the underlying links for
* this link class.
*/
switch (class) {
case DATALINK_CLASS_PHYS:
case DATALINK_CLASS_ETHERSTUB:
case DATALINK_CLASS_BRIDGE:
case DATALINK_CLASS_IPTUN:
return (NULL);
case DATALINK_CLASS_AGGR:
break;
case DATALINK_CLASS_SIMNET:
prop = FSIMNETPEER;
break;
case DATALINK_CLASS_VLAN:
case DATALINK_CLASS_VNIC:
case DATALINK_CLASS_PART:
break;
default:
return (NULL);
}
/* Then, retrieve the links from that property */
!= DLADM_STATUS_OK)
return (NULL);
}
/*
* Commit the given link to the data link configuration repository so
* that it will persist across reboots.
*/
{
return (DLADM_STATUS_BADARG);
if (conf.ds_readonly)
return (DLADM_STATUS_DENIED);
/*
* If the door call to write the configuration is successful, send a
* door call to nwamd to read in this newly created configuration.
*/
if (status == DLADM_STATUS_OK) {
return (status);
/* find the links under this link for vnics, aggrs, etc. */
}
return (status);
}
/*
* Given a flow name and an attribute name, get the attribute value from
* flow configuration repository.
*/
{
return (DLADM_STATUS_BADARG);
return (status);
return (DLADM_STATUS_TOOSMALL);
return (DLADM_STATUS_OK);
}
/*
* Given a dladm_conf_t, get the specific configuration field
*
* If the specified dladm_conf_t is a read-only snapshot of the configuration,
* get a specific link propertie from that snapshot (nvl), otherwise, get
* the link protperty from the dlmgmtd daemon using the given confid.
*/
{
return (DLADM_STATUS_BADARG);
if (conf.ds_readonly) {
int err;
return (dladm_errno2status(err));
}
return (DLADM_STATUS_TOOSMALL);
} else {
return (DLADM_STATUS_BADARG);
return (status);
}
return (DLADM_STATUS_TOOSMALL);
}
return (status);
}
/*
* Get next property attribute from data link configuration repository.
* If last_attr is "", return the first property.
*/
/* ARGSUSED */
{
int err;
return (DLADM_STATUS_BADARG);
if (last_attr[0] == '\0')
break;
break;
}
return (DLADM_STATUS_NOTFOUND);
return (dladm_errno2status(err));
}
return (DLADM_STATUS_TOOSMALL);
return (DLADM_STATUS_OK);
}
/*
* Get the link ID that is associated with the given name.
*/
{
return (status);
}
/*
* An active physical link reported by the dlmgmtd daemon
* might not be active anymore. Check and set its real status.
*/
if (status != DLADM_STATUS_OK)
return (status);
}
DLADM_OPT_PERSIST : 0;
}
return (DLADM_STATUS_OK);
}
/*
* Get the link attributes including zoneid
*/
{
return (DLADM_STATUS_BADARG);
return (status);
}
return (DLADM_STATUS_TOOSMALL);
/*
* An active physical link reported by the dlmgmtd daemon
* might not be active anymore. Check and set its real status.
*/
if (status != DLADM_STATUS_OK)
return (status);
}
return (DLADM_STATUS_TOOSMALL);
}
DLADM_OPT_ACTIVE : 0;
DLADM_OPT_PERSIST : 0;
}
return (DLADM_STATUS_OK);
}
/*
* Get the link name that is associated with the given id.
*/
{
}
/*
* Set the given attr with the given attrval for the given flow.
*/
{
return (DLADM_STATUS_BADARG);
if (type == DLADM_TYPE_STR)
else
if (attrsz > MAXOBJATTRVALLEN)
return (DLADM_STATUS_TOOSMALL);
&sz));
}
/*
* Set the given attr with the given attrval for the given link.
*/
{
return (DLADM_STATUS_BADARG);
if (conf.ds_readonly)
return (DLADM_STATUS_DENIED);
if (type == DLADM_TYPE_STR)
else
if (attrsz > MAXOBJATTRVALLEN)
return (DLADM_STATUS_TOOSMALL);
}
/*
* Unset the given attr the given link.
*/
const char *attr)
{
return (DLADM_STATUS_BADARG);
if (conf.ds_readonly)
return (DLADM_STATUS_DENIED);
}
{
if (phys_prefix == NULL)
return (DLADM_STATUS_BADARG);
if (status == DLADM_STATUS_OK) {
}
return (status);
}
/*
* Remove the flow and its entry from the data link configuration
* repository.
*/
const char *root)
{
return (status);
}
/*
* Remove the given link ID and its entry from the data link configuration
* repository.
*/
{
/*
* If the door call to remove configuration is successful, send a door
* call to nwamd to remove the configuration.
*/
if (status == DLADM_STATUS_OK) {
return (status);
/* no need to determine what links are underneath */
}
return (status);
}
/*
* Free the contents of the link structure.
*/
void
{
if (conf.ds_readonly) {
} else {
return;
}
}
{
}
{
}
{
}
{
}
{
}