/*
* 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
*/
/*
*/
/*
* Main door handler functions used by ipmgmtd to process the different door
* call requests, issued by the library libipadm.so.
*/
#include <alloca.h>
#include <pwd.h>
#include <auth_attr.h>
#include <secdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include <libnvpair.h>
#include "ipmgmt_impl.h"
/* Handler declaration for each door command */
typedef struct ipmgmt_door_info_s {
/* maps door commands to door handler functions */
{ 0, 0, NULL },
};
/*
* The main server procedure function that gets invoked for any of the incoming
* door commands. Inside this function we identify the incoming command and
* invoke the right door handler function.
*/
/* ARGSUSED */
void
{
int i;
for (i = 0; i_ipmgmt_door_info_tbl[i].idi_cmd != 0; i++) {
if (i_ipmgmt_door_info_tbl[i].idi_cmd ==
infop = &i_ipmgmt_door_info_tbl[i];
break;
}
}
goto fail;
}
/* check for solaris.network.interface.config authorization */
if (door_ucred(&cred) != 0) {
goto fail;
}
if ((int)uid < 0) {
goto fail;
}
NULL) {
goto fail;
}
goto fail;
}
}
/* individual handlers take care of calling door_return */
return;
fail:
}
/*
* Handles the door command IPMGMT_CMD_GETPROP. It retrieves the persisted
* property value for the given property.
*/
static void
{
}
/*
* Handles the door command IPMGMT_CMD_SETPROP. It persists the property value
* for the given property in the DB.
*/
static void
{
int err;
goto fail;
goto fail;
}
goto fail;
pargp->ia_aobjname)) != 0)
goto fail;
goto fail;
fail:
}
/*
* Helper function for ipmgmt_setaddr_handler().
* It converts the nvlist_t, `nvl', to aobjmap node `nodep'.
*/
static int
{
uint_t n;
int err = 0;
/*
* Retrieve all the information needed to build '*nodep' from
* nvlist_t nvl.
*/
&aobjname)) != 0 ||
return (err);
}
&plen) != 0)
return (EINVAL);
if (plen != 0) {
IPADM_NVP_IPNUMADDR, &addr6, &n) != 0)
return (EINVAL);
} else {
}
}
/*
* populate the `*nodep' with retrieved values.
*/
sizeof (nodep->am_aobjname));
if (addrtype == IPADM_ADDR_IPV6_ADDRCONF) {
}
/*
* Do not store logical interface number in persistent store as it
* takes different value on reboot. So remove it from `nvl'.
*/
return (0);
}
/*
* Handles the door command IPMGMT_CMD_SETADDR. It adds a new address object
* node to the list `aobjmap' and then persists the address information in the
* DB.
*/
static void
{
char *nvlbuf;
int err = 0;
goto ret;
goto ret;
if (flags & IPMGMT_INIT)
else
goto ret;
}
if (flags & IPMGMT_PERSIST) {
}
ret:
}
/*
* Handles the door commands that modify the `aobjmap' structure.
*
* IPMGMT_CMD_ADDROBJ_LOOKUPADD - places a stub address object in `aobjmap'
* after ensuring that the namespace is not taken. If required, also
* generates an `aobjname' for address object for the library to use.
* IPMGMT_CMD_LIF2ADDROBJ - given a logical interface, return address object
* associated with that logical interface.
* IPMGMT_CMD_AOBJNAME2ADDROBJ - given an address object name return logical
* interface associated with that address object.
*/
static void
{
void *rvalp;
int err = 0;
rsize = sizeof (ipmgmt_aobjop_rval_t);
sizeof (node.am_aobjname));
/* no logical number is associated with this addrobj yet */
/* The address object is not persisted yet. */
if (err == 0) {
sizeof (aobjrval.ir_aobjname));
}
break;
rsize = sizeof (ipmgmt_retval_t);
sizeof (node.am_aobjname));
break;
case IPMGMT_CMD_ADDROBJ_ADD:
rsize = sizeof (ipmgmt_retval_t);
break;
}
sizeof (node.am_aobjname));
/* The address object is not persisted. */
break;
rsize = sizeof (ipmgmt_aobjop_rval_t);
if (aobjname[0] == '\0') {
break;
}
continue;
/*
* For an auto-configured interface, return
* the lifnum that has the link-local on it.
* Other logical interfaces were created for
* prefixes and dhcpv6 addresses and do not
* have am_ifid set.
*/
head->am_linklocal) {
break;
}
}
break;
}
break;
case IPMGMT_CMD_LIF2ADDROBJ:
rsize = sizeof (ipmgmt_aobjop_rval_t);
if (ifname[0] == '\0') {
break;
}
break;
}
}
break;
}
sizeof (aobjrval.ir_aobjname));
break;
default:
rsize = sizeof (ipmgmt_retval_t);
}
}
/*
* Given an interface name and family, deletes all the address objects
* associated with it.
*/
void
{
continue;
}
flags == IPMGMT_ACTIVE) {
/*
* If the addres is present in both active and
* persistent store, and if we are performing
* a temporary delete, we update the node to
* indicate that the address is only present in
* persistent store and we proceed. Otherwise
* we always delete the node from aobjmap.
*/
} else {
else
}
if (db_op == IPADM_DB_DELETE)
}
}
/*
* Handles the door command IPMGMT_CMD_SETIF. It persists the interface
* information in the DB.
*/
static void
{
}
/*
* Handles the door command IPMGMT_CMD_RESETIF. For the given interface,
* deletes all the persisted interface configuration. It also deletes, from
* `aobjmap', all the address objects configured on the given interface.
*/
static void
{
int err = 0;
if (flags & IPMGMT_PERSIST)
if (flags & IPMGMT_ACTIVE)
flags);
}
/*
* Handles the door command IPMGMT_CMD_RESETADDR. For the given addrobj
* deletes all the persisted addrobj configuration. It also deletes the
* corresponding node, from `aobjmap'.
*/
static void
{
int err = 0;
if (flags & IPMGMT_PERSIST)
if (flags & IPMGMT_ACTIVE) {
sizeof (node.am_aobjname));
/*
* am_lnum is used only for IPv6 autoconf case, since there
* can be multiple nodes with the same aobjname.
*/
}
}
/*
* Handles the door command IPMGMT_CMD_GETADDR. It retrieves the persisted
* address for a given `gargp->ia_aobjname'. If it is not defined then it
* retrieves all the addresses configured on `gargp->ia_ifname'. The
* "ipadm show-addr addrobj" or "ipadm show-addr <ifname>/\*" will call this
* handler through library.
*/
static void
{
int err = 0;
goto fail;
/*
* If there is atleast one entry in the nvlist,
* do not return error.
*/
err = 0;
}
if (err != 0)
goto fail;
NV_ENCODE_NATIVE)) != 0) {
goto fail;
}
/*
* We cannot use malloc() here because door_return never returns, and
* memory allocated by malloc() would get leaked. Use alloca() instead.
*/
NV_ENCODE_NATIVE, 0)) != 0) {
goto fail;
}
return;
fail:
}
/*
* Handles the door command IPMGMT_CMD_RESETPROP. It deletes the property line
* from the DB.
*/
static void
{
}
/*
* Handles the door command IPMGMT_CMD_GETIF. It retrieves the name of all the
* persisted interfaces and the IP protocols (IPv4 or IPv6) they support.
*/
static void
{
/*
* If there is atleast one entry in the nvlist,
* do not return error.
*/
err = 0;
}
if (err != 0) {
return;
}
/* allocate sufficient buffer to return the interface info */
++count;
/*
* copy the interface info to buffer allocated on stack. The reason
* we do this is to avoid memory leak, as door_return() would never
* return
*/
for (i = 0; i < count; i++) {
}
}
/*
* Handles the door command IPMGMT_CMD_INITIF. It retrieves all the persisted
* interface configuration (interface properties and addresses), for all those
* interfaces that need to be initialized.
*/
static void
{
int err;
if (err != 0)
goto fail;
goto fail;
/*
* If there is atleast one entry in the nvlist,
* do not return error.
*/
err = 0;
}
if (err != 0)
goto fail;
goto fail;
/*
* We cannot use malloc() here because door_return never returns, and
* memory allocated by malloc() would get leaked. Use alloca() instead.
*/
NV_ENCODE_NATIVE, 0)) != 0) {
goto fail;
}
return;
fail:
}
int
{
int err = 0;
goto ret;
}
goto ret;
goto ret;
goto ret;
ret:
return (err);
}