6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * CDDL HEADER START
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The contents of this file are subject to the terms of the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Common Development and Distribution License (the "License").
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * You may not use this file except in compliance with the License.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * or http://www.opensolaris.org/os/licensing.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * See the License for the specific language governing permissions
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and limitations under the License.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * When distributing Covered Code, include this CDDL HEADER in each
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If applicable, add the following below this CDDL HEADER, with the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * fields enclosed by brackets "[]" replaced with your own identifying
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * information: Portions Copyright [yyyy] [name of copyright owner]
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * CDDL HEADER END
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Main door handler functions used by ipmgmtd to process the different door
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * call requests, issued by the library libipadm.so.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <alloca.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <pwd.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <auth_attr.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <secdb.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <stdlib.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <stdio.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <string.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <strings.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <errno.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <assert.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <libnvpair.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include "ipmgmt_impl.h"
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* Handler declaration for each door command */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailtypedef void ipmgmt_door_handler_t(void *argp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipmgmt_door_handler_t ipmgmt_getaddr_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getprop_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getif_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_initif_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_resetaddr_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_setif_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_resetif_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_resetprop_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_setaddr_handler,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_setprop_handler;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailtypedef struct ipmgmt_door_info_s {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t idi_cmd;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t idi_set;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_door_handler_t *idi_handler;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail} ipmgmt_door_info_t;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* maps door commands to door handler functions */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipmgmt_door_info_t i_ipmgmt_door_info_tbl[] = {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_SETPROP, B_TRUE, ipmgmt_setprop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_SETIF, B_TRUE, ipmgmt_setif_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_SETADDR, B_TRUE, ipmgmt_setaddr_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_GETPROP, B_FALSE, ipmgmt_getprop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_GETIF, B_FALSE, ipmgmt_getif_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_GETADDR, B_FALSE, ipmgmt_getaddr_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_RESETIF, B_TRUE, ipmgmt_resetif_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_RESETADDR, B_TRUE, ipmgmt_resetaddr_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_RESETPROP, B_TRUE, ipmgmt_resetprop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_INITIF, B_TRUE, ipmgmt_initif_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_ADDROBJ_LOOKUPADD, B_TRUE, ipmgmt_aobjop_handler },
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram { IPMGMT_CMD_ADDROBJ_SETLIFNUM, B_TRUE, ipmgmt_aobjop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_ADDROBJ_ADD, B_TRUE, ipmgmt_aobjop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_AOBJNAME2ADDROBJ, B_FALSE, ipmgmt_aobjop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { IPMGMT_CMD_LIF2ADDROBJ, B_FALSE, ipmgmt_aobjop_handler },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail { 0, 0, NULL },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail};
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The main server procedure function that gets invoked for any of the incoming
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * door commands. Inside this function we identify the incoming command and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * invoke the right door handler function.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailvoid
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t n_desc)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_door_info_t *infop = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t retval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int i;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ucred_t *cred = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (i = 0; i_ipmgmt_door_info_tbl[i].idi_cmd != 0; i++) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (i_ipmgmt_door_info_tbl[i].idi_cmd ==
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ((ipmgmt_arg_t *)(void *)argp)->ia_cmd) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail infop = &i_ipmgmt_door_info_tbl[i];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (infop == NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_log(LOG_ERR, "Invalid door command specified");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = EINVAL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (infop->idi_set) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uid_t uid;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct passwd pwd;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char buf[1024];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (door_ucred(&cred) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = errno;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_log(LOG_ERR, "Could not get user credentials.");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uid = ucred_getruid(cred);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((int)uid < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = errno;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_log(LOG_ERR, "Could not get user id.");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) ==
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = errno;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_log(LOG_ERR, "Could not get password entry.");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pwd.pw_name) != 1) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = EPERM;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_log(LOG_ERR, "Not authorized for operation.");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ucred_free(cred);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* individual handlers take care of calling door_return */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail infop->idi_handler((void *)argp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ucred_free(cred);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail retval.ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&retval, sizeof (retval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_GETPROP. It retrieves the persisted
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * property value for the given property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_getprop_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_prop_arg_t *pargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getprop_rval_t rval, *rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(pargp->ia_cmd == IPMGMT_CMD_GETPROP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_err = ipmgmt_db_walk(ipmgmt_db_getprop, pargp, IPADM_DB_READ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (rvalp->ir_err == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(rvalp->ir_pval, pargp->ia_pval,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (rvalp->ir_pval));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)rvalp, sizeof (*rvalp), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_SETPROP. It persists the property value
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for the given property in the DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_setprop_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_prop_arg_t *pargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_dbwrite_cbarg_t cb;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvl = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(pargp->ia_cmd == IPMGMT_CMD_SETPROP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pargp->ia_module[0] != '\0' &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_add_string(nvl, IPADM_NVP_PROTONAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pargp->ia_module)) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pargp->ia_ifname[0] != '\0' &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_add_string(nvl, IPADM_NVP_IFNAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pargp->ia_ifname)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pargp->ia_aobjname[0] != '\0' &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_add_string(nvl, IPADM_NVP_AOBJNAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pargp->ia_aobjname)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_add_string(nvl, pargp->ia_pname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pargp->ia_pval)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cb.dbw_nvl = nvl;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cb.dbw_flags = pargp->ia_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_update, &cb, IPADM_DB_WRITE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(nvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rval.ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Helper function for ipmgmt_setaddr_handler().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * It converts the nvlist_t, `nvl', to aobjmap node `nodep'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic int
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipmgmt_nvl2aobjnode(nvlist_t *nvl, ipmgmt_aobjmap_t *nodep)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname = NULL, *ifname = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int32_t lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvladdr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_storage addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t n;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af = AF_UNSPEC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_type_t addrtype = IPADM_ADDR_NONE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Retrieve all the information needed to build '*nodep' from
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * nvlist_t nvl.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &aobjname)) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_lookup_string(nvl, IPADM_NVP_IFNAME, &ifname)) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_lookup_int32(nvl, IPADM_NVP_LIFNUM, &lnum)) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (err);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addrtype = IPADM_ADDR_STATIC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (nvlist_exists(nvl, IPADM_NVP_DHCP)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addrtype = IPADM_ADDR_DHCP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addrtype = IPADM_ADDR_STATIC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (nvlist_lookup_nvlist(nvl, IPADM_NVP_INTFID, &nvladdr) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint8_t *addr6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t plen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addrtype = IPADM_ADDR_IPV6_ADDRCONF;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_lookup_uint32(nvladdr, IPADM_NVP_PREFIXLEN,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &plen) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (EINVAL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (plen != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_lookup_uint8_array(nvladdr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_NVP_IPNUMADDR, &addr6, &n) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (EINVAL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bcopy(addr6, &sin6->sin6_addr, n);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&sin6->sin6_addr, sizeof (sin6->sin6_addr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * populate the `*nodep' with retrieved values.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(nodep->am_ifname, ifname, sizeof (nodep->am_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(nodep->am_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (nodep->am_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nodep->am_lnum = lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nodep->am_family = af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nodep->am_atype = addrtype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addrtype == IPADM_ADDR_IPV6_ADDRCONF) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nodep->am_linklocal = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nodep->am_ifid = addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nodep->am_next = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Do not store logical interface number in persistent store as it
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * takes different value on reboot. So remove it from `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_exists(nvl, IPADM_NVP_LIFNUM))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) nvlist_remove(nvl, IPADM_NVP_LIFNUM, DATA_TYPE_INT32);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_SETADDR. It adds a new address object
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * node to the list `aobjmap' and then persists the address information in the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_setaddr_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_setaddr_arg_t *sargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjmap_t node;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvl = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *nvlbuf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nvlsize = sargp->ia_nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t flags = sargp->ia_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlbuf = (char *)argp + sizeof (ipmgmt_setaddr_arg_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_unpack(nvlbuf, nvlsize, &nvl, NV_ENCODE_NATIVE)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & (IPMGMT_ACTIVE|IPMGMT_INIT)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = i_ipmgmt_nvl2aobjnode(nvl, &node)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPMGMT_INIT)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_flags = (IPMGMT_ACTIVE|IPMGMT_PERSIST);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_flags = flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = ipmgmt_aobjmap_op(&node, ADDROBJ_ADD)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPMGMT_PERSIST) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_dbwrite_cbarg_t cb;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cb.dbw_nvl = nvl;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cb.dbw_flags = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_add, &cb, IPADM_DB_WRITE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailret:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(nvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rval.ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door commands that modify the `aobjmap' structure.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPMGMT_CMD_ADDROBJ_LOOKUPADD - places a stub address object in `aobjmap'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * after ensuring that the namespace is not taken. If required, also
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * generates an `aobjname' for address object for the library to use.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPMGMT_CMD_ADDROBJ_ADD - add/update address object in `aobjmap'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPMGMT_CMD_LIF2ADDROBJ - given a logical interface, return address object
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * associated with that logical interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPMGMT_CMD_AOBJNAME2ADDROBJ - given an address object name return logical
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * interface associated with that address object.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_aobjop_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_arg_t *largp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_rval_t aobjrval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail void *rvalp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t rsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjmap_t node;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *ifname = largp->ia_ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname = largp->ia_aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int32_t lnum = largp->ia_lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af = largp->ia_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_type_t atype = largp->ia_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjmap_t *head;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (largp->ia_cmd) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPMGMT_CMD_ADDROBJ_LOOKUPADD:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rsize = sizeof (ipmgmt_aobjop_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &aobjrval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&node, sizeof (node));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(node.am_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (node.am_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(node.am_ifname, ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (node.am_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_family = af;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram node.am_atype = atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* no logical number is associated with this addrobj yet */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_lnum = -1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* The address object is not persisted yet. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_flags = IPMGMT_ACTIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_aobjmap_op(&node, ADDROBJ_LOOKUPADD);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(aobjrval.ir_aobjname, node.am_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (aobjrval.ir_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram case IPMGMT_CMD_ADDROBJ_SETLIFNUM:
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram rsize = sizeof (ipmgmt_retval_t);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram rvalp = &rval;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram bzero(&node, sizeof (node));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram (void) strlcpy(node.am_aobjname, aobjname,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sizeof (node.am_aobjname));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram (void) strlcpy(node.am_ifname, ifname,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sizeof (node.am_ifname));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram node.am_family = af;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram node.am_lnum = lnum;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram err = ipmgmt_aobjmap_op(&node, ADDROBJ_SETLIFNUM);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPMGMT_CMD_ADDROBJ_ADD:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rsize = sizeof (ipmgmt_retval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname[0] == '\0' || ifname[0] == '\0' || lnum == -1 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af == AF_UNSPEC) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = EINVAL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&node, sizeof (node));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(node.am_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (node.am_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(node.am_ifname, ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (node.am_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_atype = atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_lnum = lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_family = af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* The address object is not persisted. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_flags = IPMGMT_ACTIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_aobjmap_op(&node, ADDROBJ_ADD);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPMGMT_CMD_AOBJNAME2ADDROBJ:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rsize = sizeof (ipmgmt_aobjop_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &aobjrval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&aobjrval, sizeof (aobjrval));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname[0] == '\0') {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = EINVAL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_rdlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head = aobjmap.aobjmap_head;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (; head; head = head->am_next) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(head->am_aobjname, aobjname) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For an auto-configured interface, return
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the lifnum that has the link-local on it.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Other logical interfaces were created for
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * prefixes and dhcpv6 addresses and do not
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * have am_ifid set.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (head->am_atype != IPADM_ADDR_IPV6_ADDRCONF ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_linklocal) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (head == NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ENOENT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(aobjrval.ir_ifname, head->am_ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (aobjrval.ir_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_lnum = head->am_lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_family = head->am_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_flags = head->am_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_atype = head->am_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (head->am_atype == IPADM_ADDR_IPV6_ADDRCONF &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_linklocal)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_ifid = head->am_ifid;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPMGMT_CMD_LIF2ADDROBJ:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rsize = sizeof (ipmgmt_aobjop_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &aobjrval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&aobjrval, sizeof (aobjrval));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifname[0] == '\0') {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = EINVAL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_rdlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head = aobjmap.aobjmap_head;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (; head; head = head->am_next) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(head->am_ifname, ifname) == 0 &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_lnum == lnum &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_family == af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (head == NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ENOENT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(aobjrval.ir_aobjname, head->am_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (aobjrval.ir_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_atype = head->am_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjrval.ir_flags = head->am_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rsize = sizeof (ipmgmt_retval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = EINVAL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ((ipmgmt_retval_t *)rvalp)->ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)rvalp, rsize, NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Given an interface name and family, deletes all the address objects
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * associated with it.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailvoid
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipmgmt_delif_aobjs(char *ifname, sa_family_t af, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjmap_t *head, *next, *prev;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_db_op_t db_op;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prev = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_wrlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head = aobjmap.aobjmap_head;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (; head; head = next) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail next = head->am_next;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(head->am_ifname, ifname) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_family != af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prev = head;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (head->am_flags == (IPMGMT_ACTIVE|IPMGMT_PERSIST) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags == IPMGMT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the addres is present in both active and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persistent store, and if we are performing
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * a temporary delete, we update the node to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * indicate that the address is only present in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persistent store and we proceed. Otherwise
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * we always delete the node from aobjmap.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_flags &= ~IPMGMT_ACTIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail head->am_lnum = -1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail db_op = IPADM_DB_WRITE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail db_op = IPADM_DB_DELETE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (prev == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjmap.aobjmap_head = next;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prev->am_next = next;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) ipmgmt_persist_aobjmap(head, db_op);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (db_op == IPADM_DB_DELETE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(head);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_SETIF. It persists the interface
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * information in the DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_setif_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan rval.ir_err = ipmgmt_persist_if(argp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_RESETIF. For the given interface,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * deletes all the persisted interface configuration. It also deletes, from
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `aobjmap', all the address objects configured on the given interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_resetif_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_if_arg_t *rargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_if_cbarg_t cbarg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t flags = rargp->ia_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_family = rargp->ia_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_ifname = rargp->ia_ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPMGMT_PERSIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_resetif, &cbarg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_DB_DELETE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPMGMT_ACTIVE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipmgmt_delif_aobjs(rargp->ia_ifname, rargp->ia_family,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rval.ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_RESETADDR. For the given addrobj
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * deletes all the persisted addrobj configuration. It also deletes the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * corresponding node, from `aobjmap'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_resetaddr_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_addr_arg_t *rargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjmap_t node;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t flags = rargp->ia_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_resetaddr_cbarg_t cbarg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_aobjname = rargp->ia_aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPMGMT_PERSIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_resetaddr, &cbarg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_DB_DELETE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPMGMT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&node, sizeof (node));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(node.am_aobjname, rargp->ia_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (node.am_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * am_lnum is used only for IPv6 autoconf case, since there
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * can be multiple nodes with the same aobjname.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_lnum = rargp->ia_lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail node.am_flags = flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) ipmgmt_aobjmap_op(&node, ADDROBJ_DELETE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rval.ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_GETADDR. It retrieves the persisted
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address for a given `gargp->ia_aobjname'. If it is not defined then it
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * retrieves all the addresses configured on `gargp->ia_ifname'. The
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * "ipadm show-addr addrobj" or "ipadm show-addr <ifname>/\*" will call this
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * handler through library.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_getaddr_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t buflen, onvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *buf, *onvlbuf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getaddr_arg_t *gargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getaddr_cbarg_t cbarg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_get_rval_t rval, *rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_ifname = gargp->ia_ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_aobjname = gargp->ia_aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_ocnt = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_alloc(&cbarg.cb_onvl, NV_UNIQUE_NAME, 0) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_getaddr, &cbarg, IPADM_DB_READ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == ENOENT && cbarg.cb_ocnt > 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If there is atleast one entry in the nvlist,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * do not return error.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_size(cbarg.cb_onvl, &onvlsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail NV_ENCODE_NATIVE)) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buflen = onvlsize + sizeof (ipmgmt_get_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We cannot use malloc() here because door_return never returns, and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * memory allocated by malloc() would get leaked. Use alloca() instead.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf = alloca(buflen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail onvlbuf = buf + sizeof (ipmgmt_get_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_pack(cbarg.cb_onvl, &onvlbuf, &onvlsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail NV_ENCODE_NATIVE, 0)) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(cbarg.cb_onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = (ipmgmt_get_rval_t *)(void *)buf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_nvlsize = onvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return(buf, buflen, NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(cbarg.cb_onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)rvalp, sizeof (*rvalp), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_RESETPROP. It deletes the property line
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * from the DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_resetprop_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_prop_arg_t *pargp = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(pargp->ia_cmd == IPMGMT_CMD_RESETPROP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rval.ir_err = ipmgmt_db_walk(ipmgmt_db_resetprop, pargp,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_DB_DELETE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_GETIF. It retrieves the name of all the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persisted interfaces and the IP protocols (IPv4 or IPv6) they support.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_getif_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getif_arg_t *getif = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getif_rval_t *rvalp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_retval_t rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getif_cbarg_t cbarg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_if_info_t *ifp, *rifp, *curifp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int i, err = 0, count = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t rbufsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(getif->ia_cmd == IPMGMT_CMD_GETIF);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&cbarg, sizeof (cbarg));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_ifname = getif->ia_ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_getif, &cbarg, IPADM_DB_READ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == ENOENT && cbarg.cb_ifinfo) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If there is atleast one entry in the nvlist,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * do not return error.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rval.ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)&rval, sizeof (rval), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* allocate sufficient buffer to return the interface info */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (ifp = cbarg.cb_ifinfo; ifp != NULL; ifp = ifp->ifi_next)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ++count;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rbufsize = sizeof (*rvalp) + count * sizeof (*ifp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = alloca(rbufsize);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(rvalp, rbufsize);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_ifcnt = count;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rifp = rvalp->ir_ifinfo;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifp = cbarg.cb_ifinfo;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * copy the interface info to buffer allocated on stack. The reason
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * we do this is to avoid memory leak, as door_return() would never
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * return
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (i = 0; i < count; i++) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rifp = rvalp->ir_ifinfo + i;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) bcopy(ifp, rifp, sizeof (*rifp));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rifp->ifi_next = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curifp = ifp->ifi_next;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(ifp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifp = curifp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)rvalp, rbufsize, NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Handles the door command IPMGMT_CMD_INITIF. It retrieves all the persisted
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * interface configuration (interface properties and addresses), for all those
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * interfaces that need to be initialized.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic void
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipmgmt_initif_handler(void *argp)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_initif_arg_t *initif = argp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t buflen, nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *buf = NULL, *onvlbuf, *invlbuf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_get_rval_t rval, *rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_initif_cbarg_t cbarg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(initif->ia_cmd == IPMGMT_CMD_INITIF);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&cbarg, sizeof (cbarg));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail invlbuf = (char *)argp + sizeof (ipmgmt_initif_arg_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlsize = initif->ia_nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_unpack(invlbuf, nvlsize, &cbarg.cb_invl, NV_ENCODE_NATIVE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cbarg.cb_family = initif->ia_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_alloc(&cbarg.cb_onvl, NV_UNIQUE_NAME, 0) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipmgmt_db_walk(ipmgmt_db_initif, &cbarg, IPADM_DB_READ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == ENOENT && cbarg.cb_ocnt > 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If there is atleast one entry in the nvlist,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * do not return error.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_size(cbarg.cb_onvl, &nvlsize, NV_ENCODE_NATIVE)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buflen = nvlsize + sizeof (ipmgmt_get_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We cannot use malloc() here because door_return never returns, and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * memory allocated by malloc() would get leaked. Use alloca() instead.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf = alloca(buflen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail onvlbuf = buf + sizeof (ipmgmt_get_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_pack(cbarg.cb_onvl, &onvlbuf, &nvlsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail NV_ENCODE_NATIVE, 0)) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(cbarg.cb_invl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(cbarg.cb_onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = (ipmgmt_get_rval_t *)(void *)buf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_nvlsize = nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return(buf, buflen, NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(cbarg.cb_invl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(cbarg.cb_onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp->ir_err = err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) door_return((char *)rvalp, sizeof (*rvalp), NULL, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhanint
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhanipmgmt_persist_if(ipmgmt_if_arg_t *sargp)
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan{
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan ipadm_dbwrite_cbarg_t cb;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan uint32_t flags = sargp->ia_flags;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan nvlist_t *nvl = NULL;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan int err = 0;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan char strval[IPMGMT_STRSIZE];
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if (!(flags & IPMGMT_PERSIST) || sargp->ia_family == AF_UNSPEC ||
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan sargp->ia_ifname[0] == '\0') {
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan err = EINVAL;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan goto ret;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan }
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0)) != 0)
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan goto ret;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if ((err = nvlist_add_string(nvl, IPADM_NVP_IFNAME,
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan sargp->ia_ifname)) != 0)
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan goto ret;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan (void) snprintf(strval, IPMGMT_STRSIZE, "%d", sargp->ia_family);
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if ((err = nvlist_add_string(nvl, IPADM_NVP_FAMILY, strval)) != 0)
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan goto ret;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan cb.dbw_nvl = nvl;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan cb.dbw_flags = 0;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan err = ipmgmt_db_walk(ipmgmt_db_add, &cb, IPADM_DB_WRITE);
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhanret:
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan nvlist_free(nvl);
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan return (err);
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan}