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/*
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy * Copyright (c) 2013 by Delphix. All rights reserved.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This file contains functions for address management such as creating
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * an address, deleting an address, enabling an address, disabling an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address, bringing an address down or up, setting/getting properties
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * on an address object and listing address information
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for all addresses in active as well as persistent configuration.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <sys/types.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <sys/socket.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <netdb.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <inet/ip.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <string.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <strings.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <assert.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <sys/sockio.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <errno.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <unistd.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <stropts.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <zone.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <netinet/in.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <arpa/inet.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <fcntl.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <ctype.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <dhcpagent_util.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <dhcpagent_ipc.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <ipadm_ndpd.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <libdladm.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <libdllink.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <libdliptun.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include <ifaddrs.h>
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#include "libipadm_impl.h"
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#define SIN6(a) ((struct sockaddr_in6 *)a)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail#define SIN(a) ((struct sockaddr_in *)a)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_create_addr(ipadm_handle_t, ipadm_addrobj_t,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_create_dhcp(ipadm_handle_t, ipadm_addrobj_t,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_delete_dhcp(ipadm_handle_t, ipadm_addrobj_t,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_get_db_addr(ipadm_handle_t, const char *,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *, nvlist_t **);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_op_dhcp(ipadm_addrobj_t, dhcp_ipc_type_t,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int *);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_validate_create_addr(ipadm_handle_t,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t, uint32_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_addr_persist_nvl(ipadm_handle_t, nvlist_t *,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_get_default_prefixlen(struct sockaddr_storage *,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t *);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t i_ipadm_get_static_addr_db(ipadm_handle_t,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic boolean_t i_ipadm_is_user_aobjname_valid(const char *);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback functions to retrieve property values from the kernel. These
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * functions, when required, translate the values from the kernel to a format
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * suitable for printing. They also retrieve DEFAULT, PERM and POSSIBLE values
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for a given property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_pd_getf_t i_ipadm_get_prefixlen, i_ipadm_get_addr_flag,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_get_zone, i_ipadm_get_broadcast;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback functions to set property values. These functions translate the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * values to a format suitable for kernel consumption, allocate the necessary
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * ioctl buffers and then invoke ioctl().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_pd_setf_t i_ipadm_set_prefixlen, i_ipadm_set_addr_flag,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_set_zone;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* address properties description table */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_prop_desc_t ipadm_addrprop_table[] = {
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { "broadcast", NULL, IPADMPROP_CLASS_ADDR, MOD_PROTO_NONE, 0,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail NULL, NULL, i_ipadm_get_broadcast },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { "deprecated", NULL, IPADMPROP_CLASS_ADDR, MOD_PROTO_NONE, 0,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_set_addr_flag, i_ipadm_get_onoff,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_get_addr_flag },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { "prefixlen", NULL, IPADMPROP_CLASS_ADDR, MOD_PROTO_NONE, 0,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_set_prefixlen, i_ipadm_get_prefixlen,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_get_prefixlen },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { "private", NULL, IPADMPROP_CLASS_ADDR, MOD_PROTO_NONE, 0,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_set_addr_flag, i_ipadm_get_onoff, i_ipadm_get_addr_flag },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { "transmit", NULL, IPADMPROP_CLASS_ADDR, MOD_PROTO_NONE, 0,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_set_addr_flag, i_ipadm_get_onoff, i_ipadm_get_addr_flag },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { "zone", NULL, IPADMPROP_CLASS_ADDR, MOD_PROTO_NONE, 0,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_set_zone, NULL, i_ipadm_get_zone },
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy { NULL, NULL, 0, 0, 0, NULL, NULL, NULL }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail};
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roystatic ipadm_prop_desc_t up_addrprop = { "up", NULL, IPADMPROP_CLASS_ADDR,
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail MOD_PROTO_NONE, 0, NULL, NULL, NULL };
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Helper function that initializes the `ipadm_ifname', `ipadm_aobjname', and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ipadm_atype' fields of the given `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailvoid
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_init_addr(ipadm_addrobj_t ipaddr, const char *ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *aobjname, ipadm_addr_type_t atype)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(ipaddr, sizeof (struct ipadm_addrobj_s));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr->ipadm_ifname, ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr->ipadm_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype = atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Determine the permission of the property depending on whether it has a
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * set() and/or get() callback functions.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_pd2permstr(ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t perm;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nbytes;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail perm = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pdp->ipd_set != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail perm |= MOD_PROP_PERM_WRITE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pdp->ipd_get != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail perm |= MOD_PROP_PERM_READ;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%c%c",
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ((perm & MOD_PROP_PERM_READ) != 0) ? 'r' : '-',
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ((perm & MOD_PROP_PERM_WRITE) != 0) ? 'w' : '-');
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nbytes >= *bufsize) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* insufficient buffer space */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *bufsize = nbytes + 1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_BUFS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Given an addrobj with `ipadm_aobjname' filled in, i_ipadm_get_addrobj()
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * retrieves the information necessary for any operation on the object,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * such as delete-addr, enable-addr, disable-addr, up-addr, down-addr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * refresh-addr, get-addrprop or set-addrprop. The information include
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the logical interface number, address type, address family,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the interface id (if the address type is IPADM_ADDR_IPV6_ADDRCONF) and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the ipadm_flags that indicate if the address is present in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * active configuration or persistent configuration or both. If the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is not found, IPADM_NOTSUP is returned.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_addrobj(ipadm_handle_t iph, ipadm_addrobj_t ipaddr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_arg_t larg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_rval_t rval, *rvalp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* populate the door_call argument structure */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_cmd = IPMGMT_CMD_AOBJNAME2ADDROBJ;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(larg.ia_aobjname, ipaddr->ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (larg.ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, &larg, sizeof (larg), (void **)&rvalp,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (rval), B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr->ipadm_ifname, rval.ir_ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_lifnum = rval.ir_lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype = rval.ir_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_af = rval.ir_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_flags = rval.ir_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (rval.ir_atype == IPADM_ADDR_IPV6_ADDRCONF) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) memcpy(&ipaddr->ipadm_intfid, &rval.ir_ifid,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_intfid));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Retrieves the static address (IPv4 or IPv6) for the given address object
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in `ipaddr' from persistent DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_static_addr_db(ipadm_handle_t iph, ipadm_addrobj_t ipaddr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *onvl;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *anvl = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvladdr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *name;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname = ipaddr->ipadm_aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *sname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af = AF_UNSPEC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Get the address line in the nvlist `onvl' from ipmgmtd daemon.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_db_addr(iph, NULL, aobjname, &onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Walk through the nvlist `onvl' to extract the IPADM_NVP_IPV4ADDR
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * or the IPADM_NVP_IPV6ADDR name-value pair.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(onvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(onvl, NULL)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvpair_value_nvlist(nvp, &anvl) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_exists(anvl, IPADM_NVP_IPV4ADDR) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_exists(anvl, IPADM_NVP_IPV6ADDR))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvp == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(anvl, NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp != NULL; nvp = nvlist_next_nvpair(anvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_IPV4ADDR) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_IPV6ADDR) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(af != AF_UNSPEC);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvpair_value_nvlist(nvp, &nvladdr) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_lookup_string(nvladdr, IPADM_NVP_IPADDRHNAME, &sname) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_set_addr(ipaddr, sname, af) != IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTFOUND);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For the given `addrobj->ipadm_lifnum' and `addrobj->ipadm_af', this function
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * fills in the address objname, the address type and the ipadm_flags.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_lif2addrobj(ipadm_handle_t iph, ipadm_addrobj_t addrobj)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_arg_t larg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_rval_t rval, *rvalp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_cmd = IPMGMT_CMD_LIF2ADDROBJ;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(larg.ia_ifname, addrobj->ipadm_ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (larg.ia_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_lnum = addrobj->ipadm_lifnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_family = addrobj->ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, &larg, sizeof (larg), (void **)&rvalp,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (rval), B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(addrobj->ipadm_aobjname, rval.ir_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (addrobj->ipadm_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addrobj->ipadm_atype = rval.ir_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addrobj->ipadm_flags = rval.ir_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Adds an addrobj to ipmgmtd daemon's aobjmap (active configuration).
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * with the given name and logical interface number.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This API is called by in.ndpd to add addrobjs when new prefixes or
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * dhcpv6 addresses are configured.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_add_aobjname(ipadm_handle_t iph, const char *ifname, sa_family_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *aobjname, ipadm_addr_type_t atype, int lnum)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_arg_t larg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_cmd = IPMGMT_CMD_ADDROBJ_ADD;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(larg.ia_ifname, ifname, sizeof (larg.ia_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(larg.ia_aobjname, aobjname, sizeof (larg.ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_atype = atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_lnum = lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_family = af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, &larg, sizeof (larg), NULL, 0, B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Deletes an address object with given name and logical number from ipmgmtd
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * daemon's aobjmap (active configuration). This API is called by in.ndpd to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * remove addrobjs when auto-configured prefixes or dhcpv6 addresses are
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * removed.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_delete_aobjname(ipadm_handle_t iph, const char *ifname, sa_family_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *aobjname, ipadm_addr_type_t atype, int lnum)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s aobj;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_init_addr(&aobj, ifname, aobjname, atype);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobj.ipadm_af = af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobj.ipadm_lifnum = lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_delete_addrobj(iph, &aobj, IPADM_OPT_ACTIVE));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Gets all the addresses from active configuration and populates the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address information in `addrinfo'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_active_addr_info(ipadm_handle_t iph, const char *ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t **addrinfo, uint32_t ipadm_flags, int64_t lifc_flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ifaddrs *ifap, *ifa;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t *curr, *prev = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ifaddrs *cifaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int sock;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char cifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in6 *sin6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *sep;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int lnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailretry:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *addrinfo = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Get all the configured addresses */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (getallifaddrs(AF_UNSPEC, &ifa, lifc_flags) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Return if there is nothing to process. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifa == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed struct sockaddr_storage data;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(cifname, ifap->ifa_name, sizeof (cifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lnum = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((sep = strrchr(cifname, ':')) != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *sep++ = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lnum = atoi(sep);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifname != NULL && strcmp(cifname, ifname) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (!(ipadm_flags & IPADM_OPT_ZEROADDR) &&
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sockaddrunspec(ifap->ifa_addr) &&
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram !(ifap->ifa_flags & IFF_DHCPRUNNING))
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Allocate and populate the current node in the list. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((curr = calloc(1, sizeof (ipadm_addr_info_t))) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Link to the list in `addrinfo'. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (prev != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prev->ia_ifa.ifa_next = &curr->ia_ifa;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *addrinfo = curr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prev = curr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cifaddr = &curr->ia_ifa;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((cifaddr->ifa_name = strdup(ifap->ifa_name)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cifaddr->ifa_flags = ifap->ifa_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cifaddr->ifa_addr = malloc(sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (cifaddr->ifa_addr == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) memcpy(cifaddr->ifa_addr, ifap->ifa_addr,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cifaddr->ifa_netmask = malloc(sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (cifaddr->ifa_netmask == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) memcpy(cifaddr->ifa_netmask, ifap->ifa_netmask,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifap->ifa_flags & IFF_POINTOPOINT) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cifaddr->ifa_dstaddr = malloc(
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (cifaddr->ifa_dstaddr == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) memcpy(cifaddr->ifa_dstaddr, ifap->ifa_dstaddr,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (ifap->ifa_flags & IFF_BROADCAST) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cifaddr->ifa_broadaddr = malloc(
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (cifaddr->ifa_broadaddr == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) memcpy(cifaddr->ifa_broadaddr,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed ifap->ifa_broadaddr,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sizeof (struct sockaddr_storage));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Get the addrobj name stored for this logical interface. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_aobjname[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr.ipadm_ifname, cifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr.ipadm_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_lifnum = lnum;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed ipaddr.ipadm_af = ifap->ifa_addr->sa_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_lif2addrobj(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Find address type from ifa_flags, if we could not get it
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * from daemon.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) memcpy(&data, ifap->ifa_addr,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sizeof (struct sockaddr_in6));
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sin6 = SIN6(&data);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags = ifap->ifa_flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(curr->ia_aobjname, ipaddr.ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (curr->ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_atype = ipaddr.ipadm_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if ((flags & IFF_DHCPRUNNING) && (!(flags & IFF_IPV6) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_atype = IPADM_ADDR_DHCP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (flags & IFF_ADDRCONF) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_atype = IPADM_ADDR_IPV6_ADDRCONF;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_atype = IPADM_ADDR_STATIC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Populate the flags for the active configuration from the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ifa_flags'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(flags & IFF_UP)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_DUPLICATE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_state = IFA_DUPLICATE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_state = IFA_DOWN;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_cflags |= IA_UP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_RUNNING) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifap->ifa_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed sock = (ifap->ifa_addr->sa_family == AF_INET) ?
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail iph->iph_sock : iph->iph_sock6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCGLIFDADSTATE,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (caddr_t)&lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (errno == ENXIO) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail freeifaddrs(ifa);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_free_addr_info(*addrinfo);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto retry;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (lifr.lifr_dadstate == DAD_IN_PROGRESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_state = IFA_TENTATIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_state = IFA_OK;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_state = IFA_INACCESSIBLE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_UNNUMBERED)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_cflags |= IA_UNNUMBERED;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_PRIVATE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_cflags |= IA_PRIVATE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_TEMPORARY)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_cflags |= IA_TEMPORARY;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_DEPRECATED)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_cflags |= IA_DEPRECATED;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail freeifaddrs(ifa);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* On error, cleanup everything and return. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_free_addr_info(*addrinfo);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *addrinfo = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail freeifaddrs(ifa);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * From the given `name', i_ipadm_name2atype() deduces the address type
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and address family. If the `name' implies an address, it returns B_TRUE.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Else, returns B_FALSE and leaves the output parameters unchanged.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailboolean_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_name2atype(const char *name, sa_family_t *af, ipadm_addr_type_t *type)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t is_addr = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_IPV4ADDR) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *type = IPADM_ADDR_STATIC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_IPV6ADDR) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *af = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *type = IPADM_ADDR_STATIC;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_DHCP) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *type = IPADM_ADDR_DHCP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_INTFID) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *af = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *type = IPADM_ADDR_IPV6_ADDRCONF;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail is_addr = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (is_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Parses the given nvlist `nvl' for an address or an address property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The input nvlist must contain either an address or an address property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ainfo' is an input as well as output parameter. When an address or an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address property is found, `ainfo' is updated with the information found.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Some of the fields may be already filled in by the calling function.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The fields that will be filled/updated by this function are `ia_pflags',
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ia_sname' and `ia_dname'. Values for `ia_pflags' are obtained if the `nvl'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * contains an address property. `ia_sname', `ia_dname', and `ia_pflags' are
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * obtained if `nvl' contains an address.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_nvl2ainfo_common(nvlist_t *nvl, ipadm_addr_info_t *ainfo)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvladdr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *name;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *propstr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *sname, *dname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_type_t atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t is_addr = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (i_ipadm_name2atype(name, &af, &atype)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_nvlist(nvp, &nvladdr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail is_addr = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (IPADM_PRIV_NVP(name)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &propstr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (is_addr) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We got an address from the nvlist `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Parse `nvladdr' and populate relevant information
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in `ainfo'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (atype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_STATIC:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, "up") == 0 &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail strcmp(propstr, "yes") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ainfo->ia_pflags |= IA_UP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For static addresses, we need to get the hostnames.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_lookup_string(nvladdr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_NVP_IPADDRHNAME, &sname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ainfo->ia_sname, sname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ainfo->ia_sname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_lookup_string(nvladdr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_NVP_IPDADDRHNAME, &dname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ainfo->ia_dname, dname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ainfo->ia_dname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * dhcp and addrconf address objects are always
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * marked up when re-enabled.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ainfo->ia_pflags |= IA_UP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_FAILURE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We got an address property from `nvl'. Parse the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * name and the property value. Update the `ainfo->ia_pflags'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for the flags.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, "deprecated") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(propstr, IPADM_ONSTR) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ainfo->ia_pflags |= IA_DEPRECATED;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, "private") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(propstr, IPADM_ONSTR) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ainfo->ia_pflags |= IA_PRIVATE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Parses the given nvlist `nvl' for an address or an address property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The input nvlist must contain either an address or an address property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ainfo' is an input as well as output parameter. When an address or an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address property is found, `ainfo' is updated with the information found.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Some of the fields may be already filled in by the calling function,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * because of previous calls to i_ipadm_nvl2ainfo_active().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Since the address object in `nvl' is also in the active configuration, the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * fields that will be filled/updated by this function are `ia_pflags',
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ia_sname' and `ia_dname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If this function returns an error, the calling function will take
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * care of freeing the fields in `ainfo'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_nvl2ainfo_active(nvlist_t *nvl, ipadm_addr_info_t *ainfo)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_nvl2ainfo_common(nvl, ainfo));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Parses the given nvlist `nvl' for an address or an address property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The input nvlist must contain either an address or an address property.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ainfo' is an input as well as output parameter. When an address or an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address property is found, `ainfo' is updated with the information found.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Some of the fields may be already filled in by the calling function,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * because of previous calls to i_ipadm_nvl2ainfo_persist().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * All the relevant fields in `ainfo' will be filled by this function based
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * on what we find in `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If this function returns an error, the calling function will take
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * care of freeing the fields in `ainfo'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_nvl2ainfo_persist(nvlist_t *nvl, ipadm_addr_info_t *ainfo)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvladdr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ifaddrs *ifa;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *name;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *ifname = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *propstr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_type_t atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t is_addr = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t size = sizeof (struct sockaddr_storage);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t plen = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_nvl2ainfo_common(nvl, ainfo);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_IFNAME) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &ifname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_AOBJNAME) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &aobjname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (i_ipadm_name2atype(name, &af, &atype)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_nvlist(nvp, &nvladdr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail is_addr = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &propstr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifa = &ainfo->ia_ifa;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ainfo->ia_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ainfo->ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifa->ifa_name == NULL && (ifa->ifa_name = strdup(ifname)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (is_addr) {
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed struct sockaddr_in6 data;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We got an address from the nvlist `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Parse `nvladdr' and populate `ifa->ifa_addr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ainfo->ia_atype = atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((ifa->ifa_addr = calloc(1, size)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (atype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_STATIC:
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed ifa->ifa_addr->sa_family = af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed ifa->ifa_addr->sa_family = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed data.sin6_family = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (i_ipadm_nvl2in6_addr(nvladdr, IPADM_NVP_IPNUMADDR,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed &data.sin6_addr) != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_lookup_uint32(nvladdr, IPADM_NVP_PREFIXLEN,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &plen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((ifa->ifa_netmask = malloc(size)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = plen2mask(plen, af, ifa->ifa_netmask)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) memcpy(ifa->ifa_addr, &data, sizeof (data));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_FAILURE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, "prefixlen") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If a prefixlen was found, update the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ainfo->ia_ifa.ifa_netmask'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((ifa->ifa_netmask = malloc(size)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Address property lines always follow the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * line itself in the persistent db. We must have
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * found a valid `ainfo->ia_ifa.ifa_addr' by now.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(ifa->ifa_addr != NULL);
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed err = plen2mask(atoi(propstr), ifa->ifa_addr->sa_family,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifa->ifa_netmask);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Retrieves all addresses from active config and appends to it the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * addresses that are found only in persistent config. In addition,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * it updates the persistent fields for each address from information
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * found in persistent config. The output parameter `addrinfo' contains
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * complete information regarding all addresses in active as well as
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persistent config.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_all_addr_info(ipadm_handle_t iph, const char *ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t **addrinfo, uint32_t ipadm_flags, int64_t lifc_flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvladdr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *onvl = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t *ainfo = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t *curr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t *last = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Get all addresses from active config. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_active_addr_info(iph, ifname, &ainfo, ipadm_flags,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lifc_flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Get all addresses from persistent config. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_db_addr(iph, ifname, NULL, &onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If no address was found in persistent config, just
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * return what we found in active config.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_NOTFOUND) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If nothing was found neither active nor persistent
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * config, this means that the interface does not exist,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * if one was provided in `ifname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ainfo == NULL && ifname != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_ENXIO);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *addrinfo = ainfo;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* In case of any other error, cleanup and return. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* we append to make sure, loopback addresses are first */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ainfo != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (curr = ainfo; IA_NEXT(curr) != NULL; curr = IA_NEXT(curr))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail last = curr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `onvl' will contain all the address lines from the db. Each line
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * could contain the address itself or an address property. Addresses
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and address properties are found in separate lines.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If an address A was found in active, we will already have `ainfo',
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and it is present in persistent configuration as well, we need to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * update `ainfo' with persistent information (`ia_pflags).
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For each address B found only in persistent configuration,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * append the address to the list with the address info for B from
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `onvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(onvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(onvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvpair_value_nvlist(nvp, &nvladdr) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_lookup_string(nvladdr, IPADM_NVP_AOBJNAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &aobjname) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (curr = ainfo; curr != NULL; curr = IA_NEXT(curr)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(curr->ia_aobjname, aobjname) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (curr == NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We did not find this address object in `ainfo'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This means that the address object exists only
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in the persistent configuration. Get its
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * details and append to `ainfo'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr = calloc(1, sizeof (ipadm_addr_info_t));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (curr == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail curr->ia_state = IFA_DISABLED;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (last != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail last->ia_ifa.ifa_next = &curr->ia_ifa;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ainfo = curr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail last = curr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Fill relevant fields of `curr' from the persistent info
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in `nvladdr'. Call the appropriate function based on the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ia_state' value.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (curr->ia_state == IFA_DISABLED)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_nvl2ainfo_persist(nvladdr, curr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_nvl2ainfo_active(nvladdr, curr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *addrinfo = ainfo;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* On error, cleanup and return. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(onvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_free_addr_info(ainfo);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *addrinfo = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that sets the property `prefixlen' on the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * object in `arg' to the value in `pval'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_set_prefixlen(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t af, uint_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_storage netmask;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err, s;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail unsigned long prefixlen, abits;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *end;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t ipaddr = (ipadm_addrobj_t)arg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_atype == IPADM_ADDR_DHCP)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail errno = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prefixlen = strtoul(pval, &end, 10);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (errno != 0 || *end != '\0')
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail abits = (af == AF_INET ? IP_ABITS : IPV6_ABITS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (prefixlen == 0 || prefixlen == (abits - 1))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed if ((err = plen2mask(prefixlen, af, (struct sockaddr *)&netmask)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail s = (af == AF_INET ? iph->iph_sock : iph->iph_sock6);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) memcpy(&lifr.lifr_addr, &netmask, sizeof (netmask));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* now, change the broadcast address to reflect the prefixlen */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (af == AF_INET) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * get the interface address and set it, this should reset
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the broadcast address.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that sets the given value `pval' to one of the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * properties among `deprecated', `private', and `transmit' as defined in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `pdp', on the address object in `arg'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_set_addr_flag(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t af, uint_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t on_flags = 0, off_flags = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t on;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t ipaddr = (ipadm_addrobj_t)arg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_atype == IPADM_ADDR_DHCP &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail strcmp(pdp->ipd_name, "deprecated") == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(pval, IPADM_ONSTR) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(pval, IPADM_OFFSTR) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(pdp->ipd_name, "private") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (on)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on_flags = IFF_PRIVATE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail off_flags = IFF_PRIVATE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(pdp->ipd_name, "transmit") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (on)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail off_flags = IFF_NOXMIT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on_flags = IFF_NOXMIT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(pdp->ipd_name, "deprecated") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (on)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on_flags = IFF_DEPRECATED;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail off_flags = IFF_DEPRECATED;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_PROP_UNKNOWN);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_set_flags(iph, lifname, af, on_flags, off_flags));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that sets the property `zone' on the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * object in `arg' to the value in `pval'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_set_zone(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t af, uint_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail zoneid_t zoneid;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int s;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * To modify the zone assignment such that it persists across
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * reboots, zonecfg(1M) must be used.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_PERSIST) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (flags & IPADM_OPT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* put logical interface into all zones */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(pval, "all-zones") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail zoneid = ALL_ZONES;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* zone must be ready or running */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((zoneid = getzoneidbyname(pval)) == -1)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail s = (af == AF_INET ? iph->iph_sock : iph->iph_sock6);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname((ipadm_addrobj_t)arg, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lifr.lifr_zoneid = zoneid;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(s, SIOCSLIFZONE, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that gets the property `broadcast' for the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * object in `arg'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_broadcast(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t valtype)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in *sin;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t ipaddr = (ipadm_addrobj_t)arg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nbytes = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t ifflags = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_flags & IPMGMT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_flags(iph, lifname, af, &ifflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ifflags & IFF_BROADCAST)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (valtype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_DEFAULT: {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_storage mask;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct in_addr broadaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t plen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail in_addr_t addr, maddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char val[MAXPROPVALLEN];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t valsz = MAXPROPVALLEN;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in *sin;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr->ipadm_flags & IPMGMT_ACTIVE)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Since the address is unknown we cannot
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * obtain default prefixlen
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_atype == IPADM_ADDR_DHCP ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_af == AF_INET6) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For the static address, we get the address from the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persistent db.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_static_addr_db(iph, ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin = SIN(&ipaddr->ipadm_static_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addr = sin->sin_addr.s_addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address object is active, we retrieve the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address from kernel.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(lifr.lifr_name, lifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(iph->iph_sock, SIOCGLIFADDR,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addr = (SIN(&lifr.lifr_addr))->sin_addr.s_addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For default broadcast address, get the address and the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * default prefixlen for that address and then compute the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * broadcast address.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_prefixlen(iph, arg, NULL, val, &valsz, af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail MOD_PROP_DEFAULT);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail plen = atoi(val);
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed if ((err = plen2mask(plen, AF_INET,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (struct sockaddr *)&mask)) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail maddr = (SIN(&mask))->sin_addr.s_addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail broadaddr.s_addr = (addr & maddr) | ~maddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", inet_ntoa(broadaddr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_ACTIVE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(lifr.lifr_name, lifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(iph->iph_sock, SIOCGLIFBRDADDR,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (caddr_t)&lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin = SIN(&lifr.lifr_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s",
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail inet_ntoa(sin->sin_addr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nbytes >= *bufsize) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* insufficient buffer space */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *bufsize = nbytes + 1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_BUFS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that retrieves the value of the property `prefixlen'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for the address object in `arg'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_prefixlen(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t valtype)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t ipaddr = (ipadm_addrobj_t)arg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int s;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t prefixlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nbytes;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t lifflags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_flags & IPMGMT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_flags(iph, lifname, af, &lifflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (lifflags & IFF_POINTOPOINT) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail s = (af == AF_INET ? iph->iph_sock : iph->iph_sock6);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(lifr.lifr_name, lifname, sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (valtype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_POSSIBLE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (af == AF_INET)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "1-30,32");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "1-126,128");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_DEFAULT:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_flags & IPMGMT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For static addresses, we retrieve the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * from kernel if it is active.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_default_prefixlen(
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &lifr.lifr_addr, &prefixlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if ((ipaddr->ipadm_flags & IPMGMT_PERSIST) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype == IPADM_ADDR_DHCP) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Since the address is unknown we cannot
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * obtain default prefixlen
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If not in active config, we use the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * from persistent store.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_static_addr_db(iph, ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_default_prefixlen(
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &ipaddr->ipadm_static_addr, &prefixlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%u", prefixlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_ACTIVE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prefixlen = lifr.lifr_addrlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%u", prefixlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nbytes >= *bufsize) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* insufficient buffer space */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *bufsize = nbytes + 1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_BUFS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that retrieves the value of one of the properties
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * among `deprecated', `private', and `transmit' for the address object
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in `arg'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_addr_flag(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t valtype)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t on = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t ifflags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nbytes;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t ipaddr = (ipadm_addrobj_t)arg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (valtype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_DEFAULT:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(pdp->ipd_name, "private") == 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail strcmp(pdp->ipd_name, "deprecated") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(pdp->ipd_name, "transmit") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_PROP_UNKNOWN);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_ACTIVE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address is present in active configuration, we
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * retrieve it from kernel to get the property value.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Else, there is no value to return.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_flags(iph, lifname, af, &ifflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(pdp->ipd_name, "private") == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = (ifflags & IFF_PRIVATE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(pdp->ipd_name, "transmit") == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = !(ifflags & IFF_NOXMIT);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(pdp->ipd_name, "deprecated") == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail on = (ifflags & IFF_DEPRECATED);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s",
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (on ? IPADM_ONSTR : IPADM_OFFSTR));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nbytes >= *bufsize) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* insufficient buffer space */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *bufsize = nbytes + 1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_NO_BUFS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Callback function that retrieves the value of the property `zone'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for the address object in `arg'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/* ARGSUSED */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_zone(ipadm_handle_t iph, const void *arg,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t valtype)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char zone_name[ZONENAME_MAX];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int s;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nbytes = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if (iph->iph_zoneid != GLOBAL_ZONEID) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * we are in global zone. See if the lifname is assigned to shared-ip
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * zone or global zone.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (valtype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_DEFAULT:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (getzonenamebyid(GLOBAL_ZONEID, zone_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (zone_name)) > 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", zone_name);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case MOD_PROP_ACTIVE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname((ipadm_addrobj_t)arg, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail s = (af == AF_INET ? iph->iph_sock : iph->iph_sock6);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(s, SIOCGLIFZONE, (caddr_t)&lifr) == -1)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (lifr.lifr_zoneid == ALL_ZONES) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", "all-zones");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (getzonenamebyid(lifr.lifr_zoneid, zone_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (zone_name)) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", zone_name);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nbytes >= *bufsize) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* insufficient buffer space */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *bufsize = nbytes + 1;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_BUFS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_prop_desc_t *
8887b57dc579de11464fc6c74163d2595ce073afGirish Moodalbaili_ipadm_get_addrprop_desc(const char *pname)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int i;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (i = 0; ipadm_addrprop_table[i].ipd_name != NULL; i++) {
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy if (strcmp(pname, ipadm_addrprop_table[i].ipd_name) == 0 ||
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy (ipadm_addrprop_table[i].ipd_old_name != NULL &&
299625c6492013aa7bd163862f0d181854f69b3cSebastien Roy strcmp(pname, ipadm_addrprop_table[i].ipd_old_name) == 0))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (&ipadm_addrprop_table[i]);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Gets the value of the given address property `pname' for the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * object with name `aobjname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_get_addrprop(ipadm_handle_t iph, const char *pname, char *buf,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t *bufsize, const char *aobjname, uint_t valtype)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (iph == NULL || pname == NULL || buf == NULL ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bufsize == NULL || *bufsize == 0 || aobjname == NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* find the property in the property description table */
8887b57dc579de11464fc6c74163d2595ce073afGirish Moodalbail if ((pdp = i_ipadm_get_addrprop_desc(pname)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_PROP_UNKNOWN);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For the given aobjname, get the addrobj it represents and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * retrieve the property value for that object.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_init_addr(&ipaddr, "", aobjname, IPADM_ADDR_NONE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((status = i_ipadm_get_addrobj(iph, &ipaddr)) != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr.ipadm_atype == IPADM_ADDR_IPV6_ADDRCONF)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = ipaddr.ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Call the appropriate callback function to based on the field
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * that was asked for.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (valtype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_OPT_PERM:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_pd2permstr(pdp, buf, bufsize);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_OPT_ACTIVE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr.ipadm_flags & IPMGMT_ACTIVE)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = pdp->ipd_get(iph, &ipaddr, pdp, buf, bufsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af, MOD_PROP_ACTIVE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_OPT_DEFAULT:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = pdp->ipd_get(iph, &ipaddr, pdp, buf, bufsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af, MOD_PROP_DEFAULT);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_OPT_POSSIBLE:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pdp->ipd_get_range != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = pdp->ipd_get_range(iph, &ipaddr, pdp, buf,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bufsize, af, MOD_PROP_POSSIBLE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf[0] = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_OPT_PERSIST:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_persist_propval(iph, pdp, buf, bufsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_INVALID_ARG;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Sets the value of the given address property `pname' to `pval' for the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address object with name `aobjname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_addrprop(ipadm_handle_t iph, const char *pname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *pval, const char *aobjname, uint_t pflags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char defbuf[MAXPROPVALLEN];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t defbufsize = MAXPROPVALLEN;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t reset = (pflags & IPADM_OPT_DEFAULT);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ipadm_check_auth())
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_EAUTH);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (iph == NULL || pname == NULL || aobjname == NULL || pflags == 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pflags == IPADM_OPT_PERSIST ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (pflags & ~(IPADM_COMMON_OPT_MASK|IPADM_OPT_DEFAULT)) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (!reset && pval == NULL)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* find the property in the property description table */
8887b57dc579de11464fc6c74163d2595ce073afGirish Moodalbail if ((pdp = i_ipadm_get_addrprop_desc(pname)) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_PROP_UNKNOWN);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pdp->ipd_set == NULL || (reset && pdp->ipd_get == NULL))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail if (!(pdp->ipd_flags & IPADMPROP_MULVAL) &&
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail (pflags & (IPADM_OPT_APPEND|IPADM_OPT_REMOVE))) {
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail return (IPADM_INVALID_ARG);
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail }
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For the given aobjname, get the addrobj it represents and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * set the property value for that object.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_init_addr(&ipaddr, "", aobjname, IPADM_ADDR_NONE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((status = i_ipadm_get_addrobj(iph, &ipaddr)) != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr.ipadm_flags & IPMGMT_ACTIVE))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_OP_DISABLE_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Persistent operation not allowed on a temporary object. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((pflags & IPADM_OPT_PERSIST) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail !(ipaddr.ipadm_flags & IPMGMT_PERSIST))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_TEMPORARY_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Currently, setting an address property on an address object of type
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_ADDR_IPV6_ADDRCONF is not supported. Supporting it involves
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in.ndpd retrieving the address properties from ipmgmtd for given
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address object and then setting them on auto-configured addresses,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * whenever in.ndpd gets a new prefix. This will be supported in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * future releases.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr.ipadm_atype == IPADM_ADDR_IPV6_ADDRCONF)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Setting an address property on an address object that is
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * not present in active configuration is not supported.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr.ipadm_flags & IPMGMT_ACTIVE))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = ipaddr.ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (reset) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If we were asked to reset the value, we need to fetch
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the default value and set the default value.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = pdp->ipd_get(iph, &ipaddr, pdp, defbuf, &defbufsize,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af, MOD_PROP_DEFAULT);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pval = defbuf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* set the user provided or default property value */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = pdp->ipd_set(iph, &ipaddr, pdp, pval, af, pflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If IPADM_OPT_PERSIST was set in `flags', we need to store
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * property and its value in persistent DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (pflags & IPADM_OPT_PERSIST) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_persist_propval(iph, pdp, pval, &ipaddr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Remove the address specified by the address object in `addr'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * from kernel. If the address is on a non-zero logical interface, we do a
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * SIOCLIFREMOVEIF, otherwise we set the address to INADDR_ANY for IPv4 or
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * :: for IPv6.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_delete_addr(ipadm_handle_t iph, ipadm_addrobj_t addr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int sock;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(addr, lifr.lifr_name, sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sock = (addr->ipadm_af == AF_INET ? iph->iph_sock : iph->iph_sock6);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addr->ipadm_lifnum == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Fake the deletion of the 0'th address by
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * clearing IFF_UP and setting it to as 0.0.0.0 or ::.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_set_flags(iph, addr->ipadm_ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail addr->ipadm_af, 0, IFF_UP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr.lifr_addr, sizeof (lifr.lifr_addr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lifr.lifr_addr.ss_family = addr->ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCSLIFADDR, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCSLIFDSTADDR, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (ioctl(sock, SIOCLIFREMOVEIF, (caddr_t)&lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Extracts the IPv6 address from the nvlist in `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_nvl2in6_addr(nvlist_t *nvl, char *addr_type, in6_addr_t *in6_addr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint8_t *addr6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t n;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_lookup_uint8_array(nvl, addr_type, &addr6, &n) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTFOUND);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(n == 16);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bcopy(addr6, in6_addr->s6_addr, n);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Used to validate the given addrobj name string. Length of `aobjname'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * cannot exceed IPADM_AOBJ_USTRSIZ. `aobjname' should start with an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * alphabetic character and it can only contain alphanumeric characters.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic boolean_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_is_user_aobjname_valid(const char *aobjname)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *cp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname == NULL || strlen(aobjname) >= IPADM_AOBJ_USTRSIZ ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail !isalpha(*aobjname)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (cp = aobjname + 1; *cp && isalnum(*cp); cp++)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (*cp == '\0');
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Computes the prefixlen for the given `addr' based on the netmask found using
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the order specified in /etc/nsswitch.conf. If not found, then the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * prefixlen is computed using the Classful subnetting semantics defined
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in RFC 791 for IPv4 and RFC 4291 for IPv6.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_default_prefixlen(struct sockaddr_storage *addr, uint32_t *plen)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af = addr->ss_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_storage mask;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in *m = (struct sockaddr_in *)&mask;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in6 *sin6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in *sin;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct in_addr ia;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t prefixlen = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case AF_INET:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin = SIN(addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ia.s_addr = ntohl(sin->sin_addr.s_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail get_netmask4(&ia, &m->sin_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail m->sin_addr.s_addr = htonl(m->sin_addr.s_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail m->sin_family = AF_INET;
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed prefixlen = mask2plen((struct sockaddr *)&mask);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case AF_INET6:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin6 = SIN6(addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prefixlen = 10;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prefixlen = 64;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *plen = prefixlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhanipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_resolve_addr(const char *name, sa_family_t af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_storage *ss)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct addrinfo hints, *ai;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int rc;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in6 *sin6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in *sin;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t is_mapped;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) memset(&hints, 0, sizeof (hints));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail hints.ai_family = af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail hints.ai_flags = (AI_ALL | AI_V4MAPPED);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rc = getaddrinfo(name, NULL, &hints, &ai);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (rc != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (rc == EAI_NONAME)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_BAD_ADDR);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_FAILURE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ai->ai_next != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* maps to more than one hostname */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail freeaddrinfo(ai);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_BAD_HOSTNAME);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* LINTED E_BAD_PTR_CAST_ALIGN */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail is_mapped = IN6_IS_ADDR_V4MAPPED(&(SIN6(ai->ai_addr))->sin6_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (is_mapped) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin = SIN(ss);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin->sin_family = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* LINTED E_BAD_PTR_CAST_ALIGN */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IN6_V4MAPPED_TO_INADDR(&(SIN6(ai->ai_addr))->sin6_addr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &sin->sin_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin6 = SIN6(ss);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin6->sin6_family = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bcopy(ai->ai_addr, sin6, sizeof (*sin6));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail freeaddrinfo(ai);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This takes a static address string <addr>[/<mask>] or a hostname
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and maps it to a single numeric IP address, consulting DNS if
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * hostname was provided. If a specific address family was requested,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * an error is returned if the given hostname does not map to an address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * of the given family. Note that this function returns failure
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * if the name maps to more than one IP address.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_addr(ipadm_addrobj_t ipaddr, const char *astr, sa_family_t af)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *prefixlenstr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t prefixlen = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *endp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We use (NI_MAXHOST + 5) because the longest possible
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * astr will have (NI_MAXHOST + '/' + {a maximum of 32 for IPv4
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * or a maximum of 128 for IPv6 + '\0') chars
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char addrstr[NI_MAXHOST + 5];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) snprintf(addrstr, sizeof (addrstr), "%s", astr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((prefixlenstr = strchr(addrstr, '/')) != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *prefixlenstr++ = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail errno = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prefixlen = strtoul(prefixlenstr, &endp, 10);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (errno != 0 || *endp != '\0')
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((af == AF_INET && prefixlen > IP_ABITS) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (af == AF_INET6 && prefixlen > IPV6_ABITS))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_resolve_addr(addrstr, af, &ipaddr->ipadm_static_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr->ipadm_static_aname, addrstr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_static_aname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_af = ipaddr->ipadm_static_addr.ss_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_static_prefixlen = prefixlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey/*
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * Gets the static source address from the address object in `ipaddr'.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * Memory for `addr' should be already allocated by the caller.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskeyipadm_status_t
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskeyipadm_get_addr(const ipadm_addrobj_t ipaddr, struct sockaddr_storage *addr)
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey{
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey if (ipaddr == NULL || ipaddr->ipadm_atype != IPADM_ADDR_STATIC ||
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey addr == NULL) {
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey return (IPADM_INVALID_ARG);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey }
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey *addr = ipaddr->ipadm_static_addr;
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey return (IPADM_SUCCESS);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Set up tunnel destination address in ipaddr by contacting DNS.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The function works similar to ipadm_set_addr().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The dst_addr must resolve to exactly one address. IPADM_BAD_ADDR is returned
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * if dst_addr resolves to more than one address. The caller has to verify
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * that ipadm_static_addr and ipadm_static_dst_addr have the same ss_family
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_dst_addr(ipadm_addrobj_t ipaddr, const char *daddrstr, sa_family_t af)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* mask lengths are not meaningful for point-to-point interfaces. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strchr(daddrstr, '/') != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_BAD_ADDR);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_resolve_addr(daddrstr, af,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &ipaddr->ipadm_static_dst_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr->ipadm_static_dname, daddrstr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_static_dname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Sets the interface ID in the address object `ipaddr' with the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in the string `interface_id'. This interface ID will be used when
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * ipadm_create_addr() is called with `ipaddr' with address type
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * set to IPADM_ADDR_IPV6_ADDRCONF.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_interface_id(ipadm_addrobj_t ipaddr, const char *interface_id)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_in6 *sin6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *end;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *cp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t prefixlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char addrstr[INET6_ADDRSTRLEN + 1];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL || interface_id == NULL ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype != IPADM_ADDR_IPV6_ADDRCONF)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(addrstr, interface_id, sizeof (addrstr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((cp = strchr(addrstr, '/')) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *cp++ = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin6 = &ipaddr->ipadm_intfid;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) == 1) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail errno = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail prefixlen = strtoul(cp, &end, 10);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (errno != 0 || *end != '\0' || prefixlen > IPV6_ABITS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sin6->sin6_family = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_intfidlen = prefixlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Sets the value for the field `ipadm_stateless' in address object `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_stateless(ipadm_addrobj_t ipaddr, boolean_t stateless)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype != IPADM_ADDR_IPV6_ADDRCONF)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_stateless = stateless;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Sets the value for the field `ipadm_stateful' in address object `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_stateful(ipadm_addrobj_t ipaddr, boolean_t stateful)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype != IPADM_ADDR_IPV6_ADDRCONF)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_stateful = stateful;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Sets the dhcp parameter `ipadm_primary' in the address object `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The field is used during the address creation with address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * type IPADM_ADDR_DHCP. It specifies if the interface should be set
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * as a primary interface for getting dhcp global options from the DHCP server.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_primary(ipadm_addrobj_t ipaddr, boolean_t primary)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL || ipaddr->ipadm_atype != IPADM_ADDR_DHCP)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_primary = primary;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Sets the dhcp parameter `ipadm_wait' in the address object `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This field is used during the address creation with address type
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_ADDR_DHCP. It specifies how long the API ipadm_create_addr()
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * should wait before returning while the dhcp address is being acquired
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * by the dhcpagent.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Possible values:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * - IPADM_DHCP_WAIT_FOREVER : Do not return until dhcpagent returns.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * - IPADM_DHCP_WAIT_DEFAULT : Wait a default amount of time before returning.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * - <integer> : Wait the specified number of seconds before returning.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_set_wait_time(ipadm_addrobj_t ipaddr, int32_t wait)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL || ipaddr->ipadm_atype != IPADM_ADDR_DHCP)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_wait = wait;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Creates a placeholder for the `ipadm_aobjname' in the ipmgmtd `aobjmap'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the `aobjname' already exists in the daemon's `aobjmap' then
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_ADDROBJ_EXISTS will be returned.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the libipadm consumer set `ipaddr.ipadm_aobjname[0]' to `\0', then the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * daemon will generate an `aobjname' for the given `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_lookupadd_addrobj(ipadm_handle_t iph, ipadm_addrobj_t ipaddr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_arg_t larg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_aobjop_rval_t rval, *rvalp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&larg, sizeof (larg));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_cmd = IPMGMT_CMD_ADDROBJ_LOOKUPADD;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(larg.ia_aobjname, ipaddr->ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (larg.ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(larg.ia_ifname, ipaddr->ipadm_ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (larg.ia_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail larg.ia_family = ipaddr->ipadm_af;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram larg.ia_atype = ipaddr->ipadm_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = &rval;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, &larg, sizeof (larg), (void **)&rvalp,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (rval), B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == 0 && ipaddr->ipadm_aobjname[0] == '\0') {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* copy the daemon generated `aobjname' into `ipadddr' */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(ipaddr->ipadm_aobjname, rval.ir_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (ipaddr->ipadm_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == EEXIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_ADDROBJ_EXISTS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram/*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * Sets the logical interface number in the ipmgmtd's memory map for the
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * address object `ipaddr'. If another address object has the same
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * logical interface number, IPADM_ADDROBJ_EXISTS is returned.
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaramipadm_status_t
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundarami_ipadm_setlifnum_addrobj(ipadm_handle_t iph, ipadm_addrobj_t ipaddr)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram{
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram ipmgmt_aobjop_arg_t larg;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram ipmgmt_retval_t rval, *rvalp;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram int err;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if (iph->iph_flags & IPH_IPMGMTD)
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan return (IPADM_SUCCESS);
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram bzero(&larg, sizeof (larg));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram larg.ia_cmd = IPMGMT_CMD_ADDROBJ_SETLIFNUM;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram (void) strlcpy(larg.ia_aobjname, ipaddr->ipadm_aobjname,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sizeof (larg.ia_aobjname));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram larg.ia_lnum = ipaddr->ipadm_lifnum;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram (void) strlcpy(larg.ia_ifname, ipaddr->ipadm_ifname,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sizeof (larg.ia_ifname));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram larg.ia_family = ipaddr->ipadm_af;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram rvalp = &rval;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram err = ipadm_door_call(iph, &larg, sizeof (larg), (void **)&rvalp,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sizeof (rval), B_FALSE);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (err == EEXIST)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (IPADM_ADDROBJ_EXISTS);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (ipadm_errno2status(err));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram}
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Creates the IPv4 or IPv6 address in the nvlist `nvl' on the interface
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ifname'. If a hostname is present, it is resolved before the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is created.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_enable_static(ipadm_handle_t iph, const char *ifname, nvlist_t *nvl,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *prefixlenstr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *upstr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *sname = NULL, *dname = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvaddr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *cidraddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *name;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* retrieve the address information */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_IPV4ADDR) == 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail strcmp(name, IPADM_NVP_IPV6ADDR) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_nvlist(nvp, &nvaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_AOBJNAME) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &aobjname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, IPADM_NVP_PREFIXLEN) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &prefixlenstr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (strcmp(name, "up") == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &upstr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvaddr, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvaddr, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_IPADDRHNAME) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &sname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(name, IPADM_NVP_IPDADDRHNAME) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &dname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(upstr, "yes") == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags |= IPADM_OPT_UP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* build the address object from the above information */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_init_addr(&ipaddr, ifname, aobjname, IPADM_ADDR_STATIC);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (prefixlenstr != NULL && atoi(prefixlenstr) > 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (asprintf(&cidraddr, "%s/%s", sname, prefixlenstr) == -1)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_set_addr(&ipaddr, cidraddr, af);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(cidraddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_set_addr(&ipaddr, sname, af);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (dname != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_set_dst_addr(&ipaddr, dname, af);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_create_addr(iph, &ipaddr, flags));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Creates a dhcp address on the interface `ifname' based on the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_ADDR_DHCP address object parameters from the nvlist `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_enable_dhcp(ipadm_handle_t iph, const char *ifname, nvlist_t *nvl)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int32_t wait;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t primary;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvdhcp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *name;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Extract the dhcp parameters */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_DHCP) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_nvlist(nvp, &nvdhcp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(name, IPADM_NVP_AOBJNAME) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &aobjname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvdhcp, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvdhcp, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_WAIT) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_int32(nvp, &wait);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(name, IPADM_NVP_PRIMARY) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_boolean_value(nvp, &primary);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Build the address object */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_init_addr(&ipaddr, ifname, aobjname, IPADM_ADDR_DHCP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_primary = primary;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (iph->iph_flags & IPH_INIT)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_wait = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_wait = wait;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram ipaddr.ipadm_af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_create_dhcp(iph, &ipaddr, IPADM_OPT_ACTIVE));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Creates auto-configured addresses on the interface `ifname' based on
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the IPADM_ADDR_IPV6_ADDRCONF address object parameters from the nvlist `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_enable_addrconf(ipadm_handle_t iph, const char *ifname, nvlist_t *nvl)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *stateful = NULL, *stateless = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t n;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint8_t *addr6 = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t intfidlen = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *name;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Extract the parameters */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_INTFID) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_nvlist(nvp, &nvaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(name, IPADM_NVP_AOBJNAME) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &aobjname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(nvaddr, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(nvaddr, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail name = nvpair_name(nvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_IPNUMADDR) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_uint8_array(nvp, &addr6, &n);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp(name, IPADM_NVP_PREFIXLEN) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_uint32(nvp, &intfidlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(name, IPADM_NVP_STATELESS) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &stateless);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (strcmp(name, IPADM_NVP_STATEFUL) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvpair_value_string(nvp, &stateful);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Build the address object. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_init_addr(&ipaddr, ifname, aobjname, IPADM_ADDR_IPV6_ADDRCONF);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (intfidlen > 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_intfidlen = intfidlen;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bcopy(addr6, &ipaddr.ipadm_intfid.sin6_addr.s6_addr, n);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_stateless = (strcmp(stateless, "yes") == 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_stateful = (strcmp(stateful, "yes") == 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_create_ipv6addrs(iph, &ipaddr, IPADM_OPT_ACTIVE));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Allocates `ipadm_addrobj_t' and populates the relevant member fields based on
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the provided `type'. `aobjname' represents the address object name, which
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is of the form `<ifname>/<addressname>'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The caller has to minimally provide <ifname>. If <addressname> is not
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * provided, then a default one will be generated by the API.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_create_addrobj(ipadm_addr_type_t type, const char *aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t *ipaddr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t newaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aname, *cp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char ifname[IPADM_AOBJSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifspec_t ifsp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *ipaddr = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname == NULL || aobjname[0] == '\0')
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strlcpy(ifname, aobjname, IPADM_AOBJSIZ) >= IPADM_AOBJSIZ)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((aname = strchr(ifname, '/')) != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *aname++ = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Check if the interface name is valid. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ifparse_ifspec(ifname, &ifsp))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Check if the given addrobj name is valid. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aname != NULL && !i_ipadm_is_user_aobjname_valid(aname))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((newaddr = calloc(1, sizeof (struct ipadm_addrobj_s))) == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the ifname has logical interface number, extract it and assign
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * it to `ipadm_lifnum'. Only applications with IPH_LEGACY set will do
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * this today. We will check for the validity later in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * i_ipadm_validate_create_addr().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifsp.ifsp_lunvalid) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_lifnum = ifsp.ifsp_lun;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail cp = strchr(ifname, IPADM_LOGICAL_SEP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *cp = '\0';
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(newaddr->ipadm_ifname, ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (newaddr->ipadm_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aname != NULL) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) snprintf(newaddr->ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (newaddr->ipadm_aobjname), "%s/%s", ifname, aname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (type) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_intfidlen = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_stateful = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_stateless = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_af = AF_INET6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_primary = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_wait = IPADM_DHCP_WAIT_DEFAULT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_af = AF_INET;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail case IPADM_ADDR_STATIC:
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail newaddr->ipadm_af = AF_UNSPEC;
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail newaddr->ipadm_static_prefixlen = 0;
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail break;
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail default:
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail status = IPADM_INVALID_ARG;
8b88711aa8fd0a7b5c9ea1947bc568831e46190cGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail newaddr->ipadm_atype = type;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *ipaddr = newaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(newaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey/*
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * Returns `aobjname' from the address object in `ipaddr'.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskeyipadm_status_t
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskeyipadm_get_aobjname(const ipadm_addrobj_t ipaddr, char *aobjname, size_t len)
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey{
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey if (ipaddr == NULL || aobjname == NULL)
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey return (IPADM_INVALID_ARG);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey if (strlcpy(aobjname, ipaddr->ipadm_aobjname, len) >= len)
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey return (IPADM_INVALID_ARG);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey return (IPADM_SUCCESS);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey}
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Frees the address object in `ipaddr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailvoid
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_destroy_addrobj(ipadm_addrobj_t ipaddr)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Retrieves the logical interface name from `ipaddr' and stores the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * string in `lifname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailvoid
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_addrobj2lifname(ipadm_addrobj_t ipaddr, char *lifname, int lifnamesize)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_lifnum != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) snprintf(lifname, lifnamesize, "%s:%d",
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_ifname, ipaddr->ipadm_lifnum);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) snprintf(lifname, lifnamesize, "%s",
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_ifname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Checks if a non-zero static address is present on the 0th logical interface
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * of the given IPv4 or IPv6 physical interface. For an IPv4 interface, it
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * also checks if the interface is under DHCP control. If the condition is true,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the output argument `exists' will be set to B_TRUE. Otherwise, `exists'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is set to B_FALSE.
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan *
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * Note that *exists will not be initialized if an error is encountered.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_addr_exists_on_if(ipadm_handle_t iph, const char *ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af, boolean_t *exists)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int sock;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* For IPH_LEGACY, a new logical interface will never be added. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (iph->iph_flags & IPH_LEGACY) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *exists = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (af == AF_INET) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sock = iph->iph_sock;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (lifr.lifr_flags & IFF_DHCPRUNNING) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *exists = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sock = iph->iph_sock6;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCGLIFADDR, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed *exists = !sockaddrunspec((struct sockaddr *)&lifr.lifr_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram/*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * Adds a new logical interface in the kernel for interface
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * `addr->ipadm_ifname', if there is a non-zero address on the 0th
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * logical interface or if the 0th logical interface is under DHCP
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * control. On success, it sets the lifnum in the address object `addr'.
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaramipadm_status_t
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundarami_ipadm_do_addif(ipadm_handle_t iph, ipadm_addrobj_t addr)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram{
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram ipadm_status_t status;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram boolean_t addif;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram struct lifreq lifr;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram int sock;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram addr->ipadm_lifnum = 0;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram status = i_ipadm_addr_exists_on_if(iph, addr->ipadm_ifname,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram addr->ipadm_af, &addif);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (status != IPADM_SUCCESS)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (status);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (addif) {
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram /*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * If there is an address on 0th logical interface,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * add a new logical interface.
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram bzero(&lifr, sizeof (lifr));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram (void) strlcpy(lifr.lifr_name, addr->ipadm_ifname,
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sizeof (lifr.lifr_name));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram sock = (addr->ipadm_af == AF_INET ? iph->iph_sock :
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram iph->iph_sock6);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (ioctl(sock, SIOCLIFADDIF, (caddr_t)&lifr) < 0)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (ipadm_errno2status(errno));
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram addr->ipadm_lifnum = i_ipadm_get_lnum(lifr.lifr_name);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram }
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (IPADM_SUCCESS);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram}
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Reads all the address lines from the persistent DB into the nvlist `onvl',
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * when both `ifname' and `aobjname' are NULL. If an `ifname' is provided,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * it returns all the addresses for the given interface `ifname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If an `aobjname' is specified, then the address line corresponding to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * that name will be returned.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_get_db_addr(ipadm_handle_t iph, const char *ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *aobjname, nvlist_t **onvl)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_getaddr_arg_t garg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_get_rval_t *rvalp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *nvlbuf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Populate the door_call argument structure */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&garg, sizeof (garg));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail garg.ia_cmd = IPMGMT_CMD_GETADDR;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(garg.ia_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (garg.ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifname != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(garg.ia_ifname, ifname, sizeof (garg.ia_ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail rvalp = malloc(sizeof (ipmgmt_get_rval_t));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, &garg, sizeof (garg), (void **)&rvalp,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (*rvalp), B_TRUE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlsize = rvalp->ir_nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlbuf = (char *)rvalp + sizeof (ipmgmt_get_rval_t);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_unpack(nvlbuf, nvlsize, onvl, NV_ENCODE_NATIVE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(rvalp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Adds the IP address contained in the 'ipaddr' argument to the physical
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * interface represented by 'ifname' after doing the required validation.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the interface does not exist, it is created before the address is
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * added.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If IPH_LEGACY is set in iph_flags, flags has to be IPADM_OPT_ACTIVE
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and a default addrobj name will be generated. Input `addr->ipadm_aobjname',
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * if provided, will be ignored and replaced with the newly generated name.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The interface name provided has to be a logical interface name that
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * already exists. No new logical interface will be added in this function.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey *
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * If IPADM_OPT_V46 is passed in the flags, then both IPv4 and IPv6 interfaces
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * are plumbed (if they haven't been already). Otherwise, just the interface
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * specified in `addr' is plumbed.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_create_addr(ipadm_handle_t iph, ipadm_addrobj_t addr, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t daf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t other_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t created_af = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t created_other_af = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_type_t type;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *ifname = addr->ipadm_ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t legacy = (iph->iph_flags & IPH_LEGACY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t aobjfound;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t is_6to4;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t ifflags;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan boolean_t is_boot = (iph->iph_flags & IPH_IPMGMTD);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ipadm_check_auth())
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_EAUTH);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Validate the addrobj. This also fills in addr->ipadm_ifname. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_validate_create_addr(iph, addr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For Legacy case, check if an addrobj already exists for the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * given logical interface name. If one does not exist,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * a default name will be generated and added to the daemon's
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * aobjmap.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (legacy) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr = *addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_lif2addrobj(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjfound = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * With IPH_LEGACY, modifying an address that is not
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * a static address will return with an error.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr.ipadm_atype != IPADM_ADDR_STATIC)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * we found the addrobj in daemon, copy over the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * aobjname to `addr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(addr->ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_aobjname, IPADM_AOBJSIZ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (status == IPADM_NOTFOUND) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjfound = B_FALSE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = addr->ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Create a placeholder for this address object in the daemon.
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * Skip this step if we are booting a zone (and therefore being called
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * from ipmgmtd itself), and, for IPH_LEGACY case if the
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * addrobj already exists.
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan *
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * Note that the placeholder is not needed in the NGZ boot case,
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * when zoneadmd has itself applied the "allowed-ips" property to clamp
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * down any interface configuration, so the namespace for the interface
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * is fully controlled by the GZ.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if (!is_boot && (!legacy || !aobjfound)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_lookupadd_addrobj(iph, addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail is_6to4 = i_ipadm_is_6to4(iph, ifname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Plumb the IP interfaces if necessary */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_create_if(iph, ifname, af, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS && status != IPADM_IF_EXISTS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_addrobj(iph, addr, IPADM_OPT_ACTIVE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail created_af = B_TRUE;
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey if (!is_6to4 && !legacy && (flags & IPADM_OPT_V46)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail other_af = (af == AF_INET ? AF_INET6 : AF_INET);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_create_if(iph, ifname, other_af, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS && status != IPADM_IF_EXISTS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_if(iph, ifname, af, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail created_other_af = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan /*
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * Some input validation based on the interface flags:
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * 1. in non-global zones, make sure that we are not persistently
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * creating addresses on interfaces that are acquiring
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * address from the global zone.
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan * 2. Validate static addresses for IFF_POINTOPOINT interfaces.
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addr->ipadm_atype == IPADM_ADDR_STATIC) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_flags(iph, ifname, af, &ifflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if (iph->iph_zoneid != GLOBAL_ZONEID &&
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan (ifflags & IFF_L3PROTECT) && (flags & IPADM_OPT_PERSIST)) {
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan status = IPADM_GZ_PERM;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan goto fail;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail daf = addr->ipadm_static_dst_addr.ss_family;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifflags & IFF_POINTOPOINT) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (is_6to4) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (af != AF_INET6 || daf != AF_UNSPEC) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_INVALID_ARG;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (daf != af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_INVALID_ARG;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Check for a valid dst address. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!legacy && sockaddrunspec(
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (struct sockaddr *)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &addr->ipadm_static_dst_addr)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_BAD_ADDR;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Disallow setting of dstaddr when the link is not
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * a point-to-point link.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (daf != AF_UNSPEC)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For 6to4 interfaces, kernel configures a default link-local
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address. We need to replace it, if the caller has provided
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * an address that is different from the default link-local.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS && is_6to4) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(lifr.lifr_name, addr->ipadm_ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(iph->iph_sock6, SIOCGLIFADDR, &lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_errno2status(errno);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (sockaddrcmp(&lifr.lifr_addr, &addr->ipadm_static_addr))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Create the address. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail type = addr->ipadm_atype;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (type) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_STATIC:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_create_addr(iph, addr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_create_dhcp(iph, addr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_create_ipv6addrs(iph, addr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_INVALID_ARG;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If address was not created successfully, unplumb the interface
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * if it was plumbed implicitly in this function and remove the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * addrobj created by the ipmgmtd daemon as a placeholder.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If IPH_LEGACY is set, then remove the addrobj only if it was
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * created in this function.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_DHCP_IPC_TIMEOUT &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status != IPADM_SUCCESS) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!legacy) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (created_af || created_other_af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (created_af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_if(iph, ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (created_other_af) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_if(iph, ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail other_af, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_addrobj(iph, addr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (!aobjfound) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_addrobj(iph, addr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Creates the static address in `ipaddr' in kernel. After successfully
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * creating it, it updates the ipmgmtd daemon's aobjmap with the logical
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * interface information.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_create_addr(ipadm_handle_t iph, ipadm_addrobj_t ipaddr, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int sock;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct sockaddr_storage m, *mask = &m;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const struct sockaddr_storage *addr = &ipaddr->ipadm_static_addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const struct sockaddr_storage *daddr = &ipaddr->ipadm_static_dst_addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t legacy = (iph->iph_flags & IPH_LEGACY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s legacy_addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t default_prefixlen = B_FALSE;
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan boolean_t is_boot;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan is_boot = ((iph->iph_flags & IPH_IPMGMTD) != 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = ipaddr->ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sock = (af == AF_INET ? iph->iph_sock : iph->iph_sock6);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* If prefixlen was not provided, get default prefixlen */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_static_prefixlen == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* prefixlen was not provided, get default prefixlen */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_default_prefixlen(
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &ipaddr->ipadm_static_addr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &ipaddr->ipadm_static_prefixlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default_prefixlen = B_TRUE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (void) plen2mask(ipaddr->ipadm_static_prefixlen, af,
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (struct sockaddr *)mask);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * Create a new logical interface if needed; otherwise, just
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * use the 0th logical interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaramretry:
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (!(iph->iph_flags & IPH_LEGACY)) {
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram status = i_ipadm_do_addif(iph, ipaddr);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (status != IPADM_SUCCESS)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * We don't have to set the lifnum for IPH_INIT case, because
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * there is no placeholder created for the address object in
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * this case. For IPH_LEGACY, we don't do this because the
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * lifnum is given by the caller and it will be set in the
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * end while we call the i_ipadm_addr_persist().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (!(iph->iph_flags & IPH_INIT)) {
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram status = i_ipadm_setlifnum_addrobj(iph, ipaddr);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (status == IPADM_ADDROBJ_EXISTS)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram goto retry;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (status != IPADM_SUCCESS)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (status);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lifr.lifr_addr = *mask;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_errno2status(errno);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lifr.lifr_addr = *addr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCSLIFADDR, (caddr_t)&lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_errno2status(errno);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Set the destination address, if one is given. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (daddr->ss_family != AF_UNSPEC) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail lifr.lifr_addr = *daddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(sock, SIOCSLIFDSTADDR, (caddr_t)&lifr) < 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_errno2status(errno);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_UP) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_set_flags(iph, lifr.lifr_name, af, IFF_UP, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_DAD_FOUND is a soft-error for create-addr.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * No need to tear down the address.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_DAD_FOUND)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
550b6e4083768ca350e9e7c3a1ebbf720b23dcadSowmini Varadhan if (status == IPADM_SUCCESS && !is_boot) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For IPH_LEGACY, we might be modifying the address on
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * an address object that already exists e.g. by doing
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * "ifconfig bge0:1 <addr>; ifconfig bge0:1 <newaddr>"
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * So, we need to store the object only if it does not
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * already exist in ipmgmtd.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (legacy) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&legacy_addr, sizeof (legacy_addr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(legacy_addr.ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (legacy_addr.ipadm_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_addrobj(iph, &legacy_addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail legacy_addr.ipadm_lifnum >= 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_addr_persist(iph, ipaddr, default_prefixlen,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailret:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS && !legacy)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_addr(iph, ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Removes the address object identified by `aobjname' from both active and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persistent configuration. The address object will be removed from only
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * active configuration if IPH_LEGACY is set in `iph->iph_flags'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address type is IPADM_ADDR_STATIC or IPADM_ADDR_DHCP, the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in the address object will be removed from the physical interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address type is IPADM_ADDR_DHCP, the flag IPADM_OPT_RELEASE specifies
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * whether the lease should be released. If IPADM_OPT_RELEASE is not
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * specified, the lease will be dropped. This option is not supported
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * for other address types.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address type is IPADM_ADDR_IPV6_ADDRCONF, the link-local address and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * all the autoconfigured addresses will be removed.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Finally, the address object is also removed from ipmgmtd's aobjmap and from
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * the persistent DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_delete_addr(ipadm_handle_t iph, const char *aobjname, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t release = ((flags & IPADM_OPT_RELEASE) != 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ipadm_check_auth())
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_EAUTH);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* validate input */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags == 0 || ((flags & IPADM_OPT_PERSIST) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail !(flags & IPADM_OPT_ACTIVE)) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (flags & ~(IPADM_COMMON_OPT_MASK|IPADM_OPT_RELEASE))) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&ipaddr, sizeof (ipaddr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname == NULL || strlcpy(ipaddr.ipadm_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_AOBJSIZ) >= IPADM_AOBJSIZ) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Retrieve the address object information from ipmgmtd. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_addrobj(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (release && ipaddr.ipadm_atype != IPADM_ADDR_DHCP)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If requested to delete just from active config but the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is not in active config, return error.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr.ipadm_flags & IPMGMT_ACTIVE) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (flags & IPADM_OPT_ACTIVE) && !(flags & IPADM_OPT_PERSIST)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTFOUND);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If address is present in active config, remove it from
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * kernel.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr.ipadm_flags & IPMGMT_ACTIVE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (ipaddr.ipadm_atype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_STATIC:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_delete_addr(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_delete_dhcp(iph, &ipaddr, release);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_delete_ipv6addrs(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This is the case of address object name residing in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * daemon's aobjmap (added by ADDROBJ_LOOKUPADD). Fall
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * through and delete that address object.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address was previously deleted from the active
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * config, we will get a IPADM_ENXIO from kernel.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We will still proceed and purge the address information
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in the DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_ENXIO)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr.ipadm_flags & IPMGMT_PERSIST) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (flags & IPADM_OPT_PERSIST)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags &= ~IPADM_OPT_PERSIST;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_delete_addrobj(iph, &ipaddr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_NOTFOUND)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Starts the dhcpagent and sends it the message DHCP_START to start
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * configuring a dhcp address on the given interface in `addr'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * After making the dhcpagent request, it also updates the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address object information in ipmgmtd's aobjmap and creates an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * entry in persistent DB if IPADM_OPT_PERSIST is set in `flags'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_create_dhcp(ipadm_handle_t iph, ipadm_addrobj_t addr, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t dh_status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (dhcp_start_agent(DHCP_IPC_MAX_WAIT) == -1)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_DHCP_START_ERROR);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * Create a new logical interface if needed; otherwise, just
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * use the 0th logical interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaramretry:
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram status = i_ipadm_do_addif(iph, addr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram /*
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * We don't have to set the lifnum for IPH_INIT case, because
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * there is no placeholder created for the address object in this
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram * case.
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram */
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (!(iph->iph_flags & IPH_INIT)) {
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram status = i_ipadm_setlifnum_addrobj(iph, addr);
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (status == IPADM_ADDROBJ_EXISTS)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram goto retry;
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram if (status != IPADM_SUCCESS)
ec3706caae60369bd59b4a7a2de365fc74637504Vasumathi Sundaram return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Send DHCP_START to the dhcpagent. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_op_dhcp(addr, DHCP_START, NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * We do not undo the create-addr operation for IPADM_DHCP_IPC_TIMEOUT
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * since it is only a soft error to indicate the caller that the lease
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * might be required after the function returns.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS && status != IPADM_DHCP_IPC_TIMEOUT)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail dh_status = status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Persist the address object information in ipmgmtd. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_addr_persist(iph, addr, B_FALSE, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto fail;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (dh_status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailfail:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* In case of error, delete the dhcp address */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) i_ipadm_delete_dhcp(iph, addr, B_TRUE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Releases/drops the dhcp lease on the logical interface in the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * object `addr'. If `release' is set to B_FALSE, the lease will be dropped.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_delete_dhcp(ipadm_handle_t iph, ipadm_addrobj_t addr, boolean_t release)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int dherr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Send DHCP_RELEASE or DHCP_DROP to the dhcpagent */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (release) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_op_dhcp(addr, DHCP_RELEASE, &dherr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If no lease was obtained on the object, we should
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * drop the dhcp control on the interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS && dherr == DHCP_IPC_E_OUTSTATE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_op_dhcp(addr, DHCP_DROP, NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_op_dhcp(addr, DHCP_DROP, NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Delete the logical interface */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addr->ipadm_lifnum != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&lifr, sizeof (lifr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(addr, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(iph->iph_sock, SIOCLIFREMOVEIF, (caddr_t)&lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Communicates with the dhcpagent to send a dhcp message of type `type'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * It returns the dhcp error in `dhcperror' if a non-null pointer is provided
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * in `dhcperror'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_op_dhcp(ipadm_addrobj_t addr, dhcp_ipc_type_t type, int *dhcperror)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail dhcp_ipc_request_t *request;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail dhcp_ipc_reply_t *reply = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char ifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int error;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int dhcp_timeout;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Construct a message to the dhcpagent. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bzero(&ifname, sizeof (ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(addr, ifname, sizeof (ifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addr->ipadm_primary)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail type |= DHCP_PRIMARY;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail request = dhcp_ipc_alloc_request(type, ifname, NULL, 0, DHCP_TYPE_NONE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (request == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addr->ipadm_wait == IPADM_DHCP_WAIT_FOREVER)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail dhcp_timeout = DHCP_IPC_WAIT_FOREVER;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (addr->ipadm_wait == IPADM_DHCP_WAIT_DEFAULT)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail dhcp_timeout = DHCP_IPC_WAIT_DEFAULT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail dhcp_timeout = addr->ipadm_wait;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Send the message to dhcpagent. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail error = dhcp_ipc_make_request(request, &reply, dhcp_timeout);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(request);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (error == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail error = reply->return_code;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(reply);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (error != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (dhcperror != NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *dhcperror = error;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (error != DHCP_IPC_E_TIMEOUT)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_DHCP_IPC_ERROR);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else if (dhcp_timeout != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_DHCP_IPC_TIMEOUT);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Returns the IP addresses of the specified interface in both the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * active and the persistent configuration. If no
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * interface is specified, it returns all non-zero IP addresses
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * configured on all interfaces in active and persistent
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * configurations.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `addrinfo' will contain addresses that are
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * (1) in both active and persistent configuration (created persistently)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * (2) only in active configuration (created temporarily)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * (3) only in persistent configuration (disabled addresses)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail *
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Address list that is returned by this function must be freed
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * using the ipadm_freeaddr_info() function.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_addr_info(ipadm_handle_t iph, const char *ifname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addr_info_t **addrinfo, uint32_t flags, int64_t lifc_flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifspec_t ifsp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (addrinfo == NULL || iph == NULL)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ifname != NULL &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (!ifparse_ifspec(ifname, &ifsp) || ifsp.ifsp_lunvalid)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_get_all_addr_info(iph, ifname, addrinfo,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail flags, lifc_flags));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Frees the structure allocated by ipadm_addr_info().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailvoid
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_free_addr_info(ipadm_addr_info_t *ainfo)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail freeifaddrs((struct ifaddrs *)ainfo);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Makes a door call to ipmgmtd to update its `aobjmap' with the address
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * object in `ipaddr'. This door call also updates the persistent DB to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * remember address object to be recreated on next reboot or on an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * ipadm_enable_addr()/ipadm_enable_if() call.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_addr_persist(ipadm_handle_t iph, const ipadm_addrobj_t ipaddr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t default_prefixlen, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aname = ipaddr->ipadm_aobjname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *nvl;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char pval[MAXPROPVALLEN];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint_t pflags = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_prop_desc_t *pdp = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Construct the nvl to send to the door.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NO_MEMORY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((err = nvlist_add_string(nvl, IPADM_NVP_IFNAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_ifname)) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_add_string(nvl, IPADM_NVP_AOBJNAME, aname)) != 0 ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (err = nvlist_add_int32(nvl, IPADM_NVP_LIFNUM,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_lifnum)) != 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_errno2status(err);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (ipaddr->ipadm_atype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_STATIC:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_add_ipaddr2nvl(nvl, ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) snprintf(pval, sizeof (pval), "%d",
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_static_prefixlen);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_UP)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_add_string(nvl, "up", "yes");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail else
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_add_string(nvl, "up", "no");
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = ipadm_errno2status(err);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_add_dhcp2nvl(nvl, ipaddr->ipadm_primary,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_wait);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_add_intfid2nvl(nvl, ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto ret;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (iph->iph_flags & IPH_INIT) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPMGMT_INIT tells the ipmgmtd to set both IPMGMT_ACTIVE and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPMGMT_PERSIST on the address object in its `aobjmap'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For the callers ipadm_enable_if() and ipadm_enable_addr(),
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_OPT_PERSIST is not set in their flags. They send
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPH_INIT in iph_flags, so that the address object will be
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * set as both IPMGMT_ACTIVE and IPMGMT_PERSIST.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pflags |= IPMGMT_INIT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_ACTIVE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pflags |= IPMGMT_ACTIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_PERSIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail pflags |= IPMGMT_PERSIST;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_addr_persist_nvl(iph, nvl, pflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * prefixlen is stored in a separate line in the DB and not along
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * with the address itself, since it is also an address property and
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * all address properties are stored in separate lines. We need to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * persist the prefixlen by calling the function that persists
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address properties.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status == IPADM_SUCCESS && !default_prefixlen &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr->ipadm_atype == IPADM_ADDR_STATIC &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (flags & IPADM_OPT_PERSIST)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (pdp = ipadm_addrprop_table; pdp->ipd_name != NULL; pdp++) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (strcmp("prefixlen", pdp->ipd_name) == 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(pdp != NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_persist_propval(iph, pdp, pval, ipaddr, flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailret:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_free(nvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Makes the door call to ipmgmtd to store the address object in the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * nvlist `nvl'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_addr_persist_nvl(ipadm_handle_t iph, nvlist_t *nvl, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *buf = NULL, *nvlbuf = NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail size_t nvlsize, bufsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_setaddr_arg_t *sargp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_pack(nvl, &nvlbuf, &nvlsize, NV_ENCODE_NATIVE, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail bufsize = sizeof (*sargp) + nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail buf = calloc(1, bufsize);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sargp = (void *)buf;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sargp->ia_cmd = IPMGMT_CMD_SETADDR;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sargp->ia_flags = flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sargp->ia_nvlsize = nvlsize;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) bcopy(nvlbuf, buf + sizeof (*sargp), nvlsize);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, buf, bufsize, NULL, 0, B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(buf);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail free(nvlbuf);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Makes a door call to ipmgmtd to remove the address object in `ipaddr'
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * from its `aobjmap'. This door call also removes the address object and all
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * its properties from the persistent DB if IPADM_OPT_PERSIST is set in
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `flags', so that the object will not be recreated on next reboot or on an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * ipadm_enable_addr()/ipadm_enable_if() call.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_delete_addrobj(ipadm_handle_t iph, const ipadm_addrobj_t ipaddr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipmgmt_addr_arg_t arg;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail arg.ia_cmd = IPMGMT_CMD_RESETADDR;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail arg.ia_flags = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_ACTIVE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail arg.ia_flags |= IPMGMT_ACTIVE;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_PERSIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail arg.ia_flags |= IPMGMT_PERSIST;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) strlcpy(arg.ia_aobjname, ipaddr->ipadm_aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (arg.ia_aobjname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail arg.ia_lnum = ipaddr->ipadm_lifnum;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = ipadm_door_call(iph, &arg, sizeof (arg), NULL, 0, B_FALSE);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Checks if the caller is authorized for the up/down operation.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Retrieves the address object corresponding to `aobjname' from ipmgmtd
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and retrieves the address flags for that object from kernel.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * The arguments `ipaddr' and `ifflags' must be allocated by the caller.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_updown_common(ipadm_handle_t iph, const char *aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_addrobj_t ipaddr, uint32_t ipadm_flags, uint64_t *ifflags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ipadm_check_auth())
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_EAUTH);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* validate input */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname == NULL || strlcpy(ipaddr->ipadm_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_AOBJSIZ) >= IPADM_AOBJSIZ) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Retrieve the address object information. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_addrobj(iph, ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr->ipadm_flags & IPMGMT_ACTIVE))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_OP_DISABLE_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((ipadm_flags & IPADM_OPT_PERSIST) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail !(ipaddr->ipadm_flags & IPMGMT_PERSIST))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_TEMPORARY_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_atype == IPADM_ADDR_IPV6_ADDRCONF ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (ipaddr->ipadm_atype == IPADM_ADDR_DHCP &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (ipadm_flags & IPADM_OPT_PERSIST)))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_get_flags(iph, lifname, ipaddr->ipadm_af, ifflags));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Marks the address in the address object `aobjname' up. This operation is
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * not supported for an address object of type IPADM_ADDR_IPV6_ADDRCONF.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For an address object of type IPADM_ADDR_DHCP, this operation can
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * only be temporary and no updates will be made to the persistent DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_up_addr(ipadm_handle_t iph, const char *aobjname, uint32_t ipadm_flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_updown_common(iph, aobjname, &ipaddr, ipadm_flags,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_UP)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail goto persist;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If the address is already a duplicate, then refresh-addr
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * should be used to mark it up.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_DUPLICATE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_DAD_FOUND);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(&ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_set_flags(iph, lifname, ipaddr.ipadm_af, IFF_UP, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailpersist:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Update persistent DB. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipadm_flags & IPADM_OPT_PERSIST) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_persist_propval(iph, &up_addrprop,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail "yes", &ipaddr, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Marks the address in the address object `aobjname' down. This operation is
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * not supported for an address object of type IPADM_ADDR_IPV6_ADDRCONF.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For an address object of type IPADM_ADDR_DHCP, this operation can
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * only be temporary and no updates will be made to the persistent DB.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_down_addr(ipadm_handle_t iph, const char *aobjname, uint32_t ipadm_flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct lifreq lifr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_updown_common(iph, aobjname, &ipaddr, ipadm_flags,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(&ipaddr, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sizeof (lifr.lifr_name));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IFF_UP) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_set_flags(iph, lifr.lifr_name,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_af, 0, IFF_UP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (flags & IFF_DUPLICATE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Clear the IFF_DUPLICATE flag.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(iph->iph_sock, SIOCGLIFADDR, &lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ioctl(iph->iph_sock, SIOCSLIFADDR, &lifr) < 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(errno));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Update persistent DB */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipadm_flags & IPADM_OPT_PERSIST) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_persist_propval(iph, &up_addrprop,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail "no", &ipaddr, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Refreshes the address in the address object `aobjname'. If the address object
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is of type IPADM_ADDR_STATIC, DAD is re-initiated on the address. If
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * `ipadm_flags' has IPADM_OPT_INFORM set, a DHCP_INFORM message is sent to the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * dhcpagent for this static address. If the address object is of type
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * IPADM_ADDR_DHCP, a DHCP_EXTEND message is sent to the dhcpagent.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If a dhcp address has not yet been acquired, a DHCP_START is sent to the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * dhcpagent. This operation is not supported for an address object of
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * type IPADM_ADDR_IPV6_ADDRCONF.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_refresh_addr(ipadm_handle_t iph, const char *aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t ipadm_flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t flags;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char lifname[LIFNAMSIZ];
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t inform =
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ((ipadm_flags & IPADM_OPT_INFORM) != 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int dherr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ipadm_check_auth())
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_EAUTH);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
4630c8be285403fab91e8b2de66643ef73b8e4adGirish Moodalbail bzero(&ipaddr, sizeof (ipaddr));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* validate input */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname == NULL || strlcpy(ipaddr.ipadm_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_AOBJSIZ) >= IPADM_AOBJSIZ) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Retrieve the address object information. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_addrobj(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(ipaddr.ipadm_flags & IPMGMT_ACTIVE))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_OP_DISABLE_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (i_ipadm_is_vni(ipaddr.ipadm_ifname))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (inform && ipaddr.ipadm_atype != IPADM_ADDR_STATIC)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = ipaddr.ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr.ipadm_atype == IPADM_ADDR_STATIC) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_addrobj2lifname(&ipaddr, lifname, sizeof (lifname));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_flags(iph, lifname, af, &flags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (inform) {
4630c8be285403fab91e8b2de66643ef73b8e4adGirish Moodalbail if (dhcp_start_agent(DHCP_IPC_MAX_WAIT) == -1)
4630c8be285403fab91e8b2de66643ef73b8e4adGirish Moodalbail return (IPADM_DHCP_START_ERROR);
4630c8be285403fab91e8b2de66643ef73b8e4adGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_wait = IPADM_DHCP_WAIT_DEFAULT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (i_ipadm_op_dhcp(&ipaddr, DHCP_INFORM, NULL));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!(flags & IFF_DUPLICATE))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_set_flags(iph, lifname, af, IFF_UP, 0);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else if (ipaddr.ipadm_atype == IPADM_ADDR_DHCP) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_op_dhcp(&ipaddr, DHCP_EXTEND, &dherr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Restart the dhcp address negotiation with server if no
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * address has been acquired yet.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS && dherr == DHCP_IPC_E_OUTSTATE) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipaddr.ipadm_wait = IPADM_DHCP_WAIT_DEFAULT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_op_dhcp(&ipaddr, DHCP_START, NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail } else {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = IPADM_NOTSUP;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * This is called from ipadm_create_addr() to validate the address parameters.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * It does the following steps:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * 1. Validates the interface name.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * 2. Verifies that the interface is not an IPMP meta-interface or an
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * underlying interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * 3. In case of a persistent operation, verifies that the interface
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is persistent. Returns error if interface is not enabled but
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * is in persistent config.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * 4. Verifies that the destination address is not set or the address type is
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * not DHCP or ADDRCONF when the interface is a loopback interface.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * 5. Verifies that the address type is not DHCP or ADDRCONF when the interface
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * has IFF_VRRP interface flag set.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailstatic ipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_validate_create_addr(ipadm_handle_t iph, ipadm_addrobj_t ipaddr,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail sa_family_t other_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t legacy = (iph->iph_flags & IPH_LEGACY);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t islo, isvni;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail uint64_t ifflags = 0;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t p_exists;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail boolean_t af_exists, other_af_exists, a_exists;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr == NULL || flags == 0 || flags == IPADM_OPT_PERSIST ||
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey (flags & ~(IPADM_COMMON_OPT_MASK|IPADM_OPT_UP|IPADM_OPT_V46))) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr->ipadm_af == AF_UNSPEC)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_BAD_ADDR);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!legacy && ipaddr->ipadm_lifnum != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (legacy && ipaddr->ipadm_atype != IPADM_ADDR_STATIC)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ifname = ipaddr->ipadm_ifname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (i_ipadm_is_ipmp(iph, ifname) || i_ipadm_is_under_ipmp(iph, ifname))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af = ipaddr->ipadm_af;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail af_exists = ipadm_if_enabled(iph, ifname, af);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * For legacy case, interfaces are not implicitly plumbed. We need to
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * check if the interface exists in the active configuration.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (legacy && !af_exists)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_ENXIO);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail other_af = (af == AF_INET ? AF_INET6 : AF_INET);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail other_af_exists = ipadm_if_enabled(iph, ifname, other_af);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Check if one of the v4 or the v6 interfaces exists in the
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * active configuration. An interface is considered disabled only
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * if both v4 and v6 are not active.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail a_exists = (af_exists || other_af_exists);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Check if interface exists in the persistent configuration. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_if_pexists(iph, ifname, af, &p_exists);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!a_exists && p_exists)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_OP_DISABLE_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((flags & IPADM_OPT_PERSIST) && a_exists && !p_exists) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * If address has to be created persistently,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * and the interface does not exist in the persistent
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * store but in active config, fail.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_TEMPORARY_OBJ);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (af_exists) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_flags(iph, ifname, af, &ifflags);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Perform validation steps (4) and (5) */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail islo = i_ipadm_is_loopback(ifname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail isvni = i_ipadm_is_vni(ifname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail switch (ipaddr->ipadm_atype) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_STATIC:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if ((islo || isvni) && ipaddr->ipadm_static_dname[0] != '\0')
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Check for a valid src address */
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed if (!legacy && sockaddrunspec(
64639aaf7beb84086b88f186ea1fa9ccf0be8c57Darren Reed (struct sockaddr *)&ipaddr->ipadm_static_addr))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_BAD_ADDR);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_DHCP:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (islo || (ifflags & IFF_VRRP))
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail case IPADM_ADDR_IPV6_ADDRCONF:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (islo || (ifflags & IFF_VRRP) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail i_ipadm_is_6to4(iph, ifname)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail default:
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbaili_ipadm_merge_prefixlen_from_nvl(nvlist_t *invl, nvlist_t *onvl,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail const char *aobjname)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp, *prefixnvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *tnvl;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail char *aname;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail int err;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(invl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(invl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvpair_value_nvlist(nvp, &tnvl) == 0 &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_exists(tnvl, IPADM_NVP_PREFIXLEN) &&
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_lookup_string(tnvl, IPADM_NVP_AOBJNAME,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &aname) == 0 && strcmp(aname, aobjname) == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* prefixlen exists for given address object */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail (void) nvlist_lookup_nvpair(tnvl, IPADM_NVP_PREFIXLEN,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail &prefixnvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_add_nvpair(onvl, prefixnvp);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (err == 0) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail err = nvlist_remove(invl, nvpair_name(nvp),
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_type(nvp));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_errno2status(err));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_SUCCESS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Re-enables the address object `aobjname' based on the saved
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * configuration for `aobjname'.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_enable_addr(ipadm_handle_t iph, const char *aobjname, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_t *addrnvl, *nvl;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvpair_t *nvp;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail ipadm_status_t status;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail struct ipadm_addrobj_s ipaddr;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* check for solaris.network.interface.config authorization */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (!ipadm_check_auth())
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_EAUTH);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* validate input */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_PERSIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (aobjname == NULL || strlcpy(ipaddr.ipadm_aobjname, aobjname,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail IPADM_AOBJSIZ) >= IPADM_AOBJSIZ) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_INVALID_ARG);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* Retrieve the address object information. */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_addrobj(iph, &ipaddr);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (ipaddr.ipadm_flags & IPMGMT_ACTIVE)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_ADDROBJ_EXISTS);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_get_db_addr(iph, NULL, aobjname, &addrnvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail assert(addrnvl != NULL);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail for (nvp = nvlist_next_nvpair(addrnvl, NULL); nvp != NULL;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvp = nvlist_next_nvpair(addrnvl, nvp)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvpair_value_nvlist(nvp, &nvl) != 0)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) ||
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_merge_prefixlen_from_nvl(addrnvl, nvl,
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail aobjname);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail continue;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail iph->iph_flags |= IPH_INIT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail status = i_ipadm_init_addrobj(iph, nvl);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail iph->iph_flags &= ~IPH_INIT;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (status != IPADM_SUCCESS)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail break;
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail }
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (status);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail/*
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Disables the address object in `aobjname' from the active configuration.
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail * Error code return values follow the model in ipadm_delete_addr().
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_status_t
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbailipadm_disable_addr(ipadm_handle_t iph, const char *aobjname, uint32_t flags)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail{
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail /* validate input */
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail if (flags & IPADM_OPT_PERSIST)
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (IPADM_NOTSUP);
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail return (ipadm_delete_addr(iph, aobjname, IPADM_OPT_ACTIVE));
6e91bba0d6c6bdabbba62cefae583715a4a58e2aGirish Moodalbail}