/*
* 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 <stdio.h>
#include <door.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <libintl.h>
#include <libdllink.h>
#include <libdlvnic.h>
#include <libdlvlan.h>
#include <liblldp.h>
#include <liblldp_lldpd.h>
extern char *lldp_alloc_fmri(const char *, const char *);
/*
* Make a door call to the server and checks if the door call succeeded or not.
* `is_varsize' specifies that the data returned by lldpd daemon is of
* variable size and door will allocate buffer using mmap(). In such cases
* we re-allocate the required memory and assign it to `rbufp', copy the data
* to `rbufp' and then call munmap() (see below).
*
* It also checks to see if the server side procedure ran successfully by
* checking for lr_err. Therefore, for some callers who just care about the
* return status, should set `rbufp' to NULL and set `rsize' to 0.
*/
static int
{
}
if (door_fd == -1)
return (errno);
return (errno);
}
/*
* if the caller is expecting the result to fit in specified
* buffer then return failure.
*/
if (!is_varsize)
/*
* The size of the buffer `*rbufp' was not big enough
* and the door itself allocated buffer, for us. We will
* hit this, on several occasion as for some cases
* we cannot predict the size of the return structure.
* Reallocate the buffer `*rbufp' and memcpy() the contents
* to new buffer.
*/
if (err == 0) {
void *newp;
/* allocated memory will be freed by the caller */
} else {
}
}
/* munmap() the door buffer */
} else {
}
return (err);
}
/*
* Makes a door call to the server and `rbufp' is not re-allocated. If
* the data returned from the server can't be accomodated in `rbufp'
* that is of size `rsize' then an error will be returned.
*/
int
{
}
/*
* Makes a door call to the server and `rbufp' always points to a
* re-allocated memory and should be freed by the caller. This should be
* used by callers who are not sure of the size of the data returned by
* the server.
*/
int
{
}
/*
* Caller frees nvlist memory.
*/
{
int err = 0;
char *buf;
/* link validation will be done by the daemon */
return (LLDP_STATUS_NOMEM);
sizeof (*rval))) != 0) {
goto ret;
}
} else if (rval->lmr_listsz > 0) {
}
ret:
return (lldp_errno2status(err));
}
/*
* agent
*/
{
int status;
if (status != LLDP_STATUS_OK)
return (status);
continue;
break;
}
}
ret:
return (status);
}
/* Get LLDP agent stats */
/* ARGSUSED */
{
int err;
/* link validation will be done by the daemon */
if (err != 0)
return (lldp_errno2status(err));
return (LLDP_STATUS_OK);
}
char *
{
char *fmri;
/* If the limit is unknown, then use an arbitrary value */
max_fmri = 1024;
}
return (fmri);
}
/* Call into LLDP to notify of an event. */
{
int err;
if (event != DL_VIRTUAL_LINK_UPDATE)
return (LLDP_STATUS_NOTSUP);
/*
* if LLDP daemon is not installed or is not online then
* there is nothing to do.
*/
LLDP_SVC_DEFAULT_INSTANCE)) == NULL) {
return (LLDP_STATUS_NOMEM);
}
return (LLDP_STATUS_OK);
}
return (LLDP_STATUS_BADVAL);
}
/* Nothing to do for an update */
if (operation == DLMGMT_DLS_VLINK_MODIFY)
return (LLDP_STATUS_OK);
return (lldp_errno2status(err));
}
const char *
{
const char *s;
switch (status) {
case LLDP_STATUS_OK:
s = "ok";
break;
case LLDP_STATUS_EXIST:
s = "object already exists";
break;
case LLDP_STATUS_BADARG:
s = "invalid argument";
break;
case LLDP_STATUS_FAILED:
s = "operation failed";
break;
case LLDP_STATUS_TOOSMALL:
s = "buffer size too small";
break;
case LLDP_STATUS_NOTSUP:
s = "operation not supported";
break;
case LLDP_STATUS_PROPUNKNOWN:
s = "property unknown";
break;
case LLDP_STATUS_BADVAL:
s = "invalid value";
break;
case LLDP_STATUS_NOMEM:
s = "insufficient memory";
break;
case LLDP_STATUS_LINKINVAL:
s = "invalid link";
break;
case LLDP_STATUS_LINKBUSY:
s = "link already in use";
break;
case LLDP_STATUS_PERSISTERR:
s = "persistence of configuration failed";
break;
case LLDP_STATUS_BADRANGE:
s = "invalid range";
break;
case LLDP_STATUS_DISABLED:
s = "LLDP not enabled on port";
break;
case LLDP_STATUS_TEMPONLY:
s = "change cannot be persistent";
break;
case LLDP_STATUS_NOTFOUND:
s = "object not found";
break;
case LLDP_STATUS_PERMDENIED:
s = "Permission denied";
break;
default:
s = "<unknown error>";
break;
}
return (buf);
}
/*
* Convert a unix errno to a lldp_status_t.
* We only convert errnos that are likely to be encountered. All others
* are mapped to LLDP_STATUS_FAILED.
*/
{
switch (err) {
case 0:
return (LLDP_STATUS_OK);
case ESRCH:
return (LLDP_STATUS_DISABLED);
case EACCES:
case EPERM:
return (LLDP_STATUS_PERMDENIED);
case ENOENT:
return (LLDP_STATUS_NOTFOUND);
case EINVAL:
return (LLDP_STATUS_BADARG);
case EEXIST:
return (LLDP_STATUS_EXIST);
case ENOSPC:
return (LLDP_STATUS_TOOSMALL);
case ENOMEM:
return (LLDP_STATUS_NOMEM);
case ENOTSUP:
return (LLDP_STATUS_NOTSUP);
case ENODATA:
return (LLDP_STATUS_PERSISTERR);
case EBUSY:
return (LLDP_STATUS_LINKBUSY);
default:
return (LLDP_STATUS_FAILED);
}
}