5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * CDDL HEADER START
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * The contents of this file are subject to the terms of the
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Common Development and Distribution License (the "License").
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * You may not use this file except in compliance with the License.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * See the License for the specific language governing permissions
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * and limitations under the License.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * When distributing Covered Code, include this CDDL HEADER in each
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * If applicable, add the following below this CDDL HEADER, with the
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * fields enclosed by brackets "[]" replaced with your own identifying
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * information: Portions Copyright [yyyy] [name of copyright owner]
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * CDDL HEADER END
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Copyright (c) 2013 by Delphix. All rights reserved.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * This file contains routines that are used to modify/retrieve protocol or
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * interface property values. It also holds all the supported properties for
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * This file also contains walkers, which walks through the property table and
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * property in the table.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DEF_METRIC_VAL 0 /* default metric value */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define A_CNT(arr) (sizeof (arr) / sizeof (arr[0]))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic ipadm_status_t i_ipadm_validate_if(ipadm_handle_t, const char *,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk * Callback functions to retrieve property values from the kernel. These
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * functions, when required, translate the values from the kernel to a format
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * suitable for printing. For example: boolean values will be translated
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * to on/off. They also retrieve DEFAULT, PERM and POSSIBLE values for
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * a given property.
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenkstatic ipadm_pd_getf_t i_ipadm_get_prop, i_ipadm_get_ifprop_flags,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk * Callback function to set property values. These functions translate the
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk * values to a format suitable for kernel consumption, allocates the necessary
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * ioctl buffers and then invokes ioctl().
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic ipadm_pd_setf_t i_ipadm_set_prop, i_ipadm_set_mtu,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/* array of protocols we support */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int protocols[] = { MOD_PROTO_IP, MOD_PROTO_RAWIP,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Supported IP protocol properties.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic ipadm_prop_desc_t ipadm_ip_prop_table[] = {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "arp", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "forwarding", NULL, IPADMPROP_CLASS_MODIF, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "metric", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "mtu", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_mtu, i_ipadm_get_mtu, i_ipadm_get_mtu },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "exchange_routes", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "usesrc", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "ttl", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "forwarding", NULL, IPADMPROP_CLASS_MODIF, MOD_PROTO_IPV6, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "hoplimit", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV6, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "metric", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "mtu", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_mtu, i_ipadm_get_mtu, i_ipadm_get_mtu },
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "nud", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "exchange_routes", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "usesrc", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV6, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV4, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/* possible values for TCP properties `ecn' and `sack' */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic const char *ecn_sack_vals[] = {"never", "passive", "active", NULL};
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/* Supported TCP protocol properties */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic ipadm_prop_desc_t ipadm_tcp_prop_table[] = {
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk { "ecn", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "recv_buf", "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "sack", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "send_buf", "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "smallest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "smallest_nonpriv_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 0, i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/* Supported UDP protocol properties */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic ipadm_prop_desc_t ipadm_udp_prop_table[] = {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
static ipadm_prop_desc_t *
switch (proto) {
case MOD_PROTO_IP:
case MOD_PROTO_IPV4:
case MOD_PROTO_IPV6:
return (ipadm_ip_prop_table);
case MOD_PROTO_RAWIP:
return (ipadm_icmp_prop_table);
case MOD_PROTO_TCP:
return (ipadm_tcp_prop_table);
case MOD_PROTO_UDP:
return (ipadm_udp_prop_table);
case MOD_PROTO_SCTP:
return (ipadm_sctp_prop_table);
return (NULL);
static ipadm_prop_desc_t *
goto ret;
if (matched_name)
ret:
return (ipdp);
switch (proto) {
case MOD_PROTO_IP:
case MOD_PROTO_IPV4:
case MOD_PROTO_IPV6:
case MOD_PROTO_RAWIP:
case MOD_PROTO_TCP:
case MOD_PROTO_UDP:
case MOD_PROTO_SCTP:
return (NULL);
return (MOD_PROTO_NONE);
return (MOD_PROTO_TCP);
return (MOD_PROTO_UDP);
return (MOD_PROTO_IP);
return (MOD_PROTO_IPV4);
return (MOD_PROTO_IPV6);
return (MOD_PROTO_RAWIP);
return (MOD_PROTO_SCTP);
return (MOD_PROTO_IP);
return (MOD_PROTO_NONE);
static ipadm_status_t
return (status);
errno = 0;
return (IPADM_INVALID_ARG);
return (IPADM_SUCCESS);
static ipadm_status_t
errno = 0;
return (IPADM_INVALID_ARG);
return (IPADM_SUCCESS);
static ipadm_status_t
return (IPADM_INVALID_ARG);
return (IPADM_SUCCESS);
static ip_hostmodel_t
return (IP_MAXVAL_ES);
return (NULL);
static ipadm_status_t
return (IPADM_INVALID_ARG);
static ipadm_status_t
switch (valtype) {
case MOD_PROP_PERM:
case MOD_PROP_DEFAULT:
case MOD_PROP_ACTIVE:
valtype);
return (status);
case MOD_PROP_POSSIBLE:
return (IPADM_INVALID_ARG);
return (IPADM_NO_BUFS);
return (IPADM_SUCCESS);
static ipadm_status_t
return (IPADM_PROP_UNKNOWN);
return (IPADM_INVALID_ARG);
if (on)
if (on)
if (on)
if (on)
return (status);
static ipadm_status_t
++count;
return (IPADM_INVALID_ARG);
return (status);
static ipadm_status_t
return (IPADM_INVALID_ARG);
return (status);
static ipadm_status_t
uint_t i;
return (IPADM_INVALID_ARG);
switch (valtype) {
case MOD_PROP_POSSIBLE:
case MOD_PROP_PERM:
case MOD_PROP_DEFAULT:
case MOD_PROP_ACTIVE:
valtype);
ecn_sack_vals[i]);
return (IPADM_INVALID_ARG);
return (IPADM_NO_BUFS);
return (status);
static ipadm_status_t
goto ret;
ret:
return (status);
static ipadm_status_t
switch (valtype) {
case MOD_PROP_PERM:
case MOD_PROP_DEFAULT:
case MOD_PROP_POSSIBLE:
case MOD_PROP_ACTIVE:
return (IPADM_INVALID_ARG);
return (IPADM_NO_BUFS);
return (IPADM_SUCCESS);
static ipadm_status_t
switch (valtype) {
case MOD_PROP_PERM:
case MOD_PROP_DEFAULT:
case MOD_PROP_ACTIVE:
return (IPADM_INVALID_ARG);
return (IPADM_NO_BUFS);
return (IPADM_SUCCESS);
static ipadm_status_t
switch (valtype) {
case MOD_PROP_PERM:
case MOD_PROP_DEFAULT:
case MOD_PROP_ACTIVE:
sizeof (if_name));
return (IPADM_INVALID_ARG);
return (IPADM_NO_BUFS);
return (IPADM_SUCCESS);
static ipadm_status_t
switch (valtype) {
case MOD_PROP_PERM:
case MOD_PROP_DEFAULT:
return (IPADM_PROP_UNKNOWN);
case MOD_PROP_ACTIVE:
return (status);
return (IPADM_INVALID_ARG);
return (status);
static ipadm_status_t
return (IPADM_NO_BUFS);
iocsize) < 0) {
return (status);
* private nvpair names (which also starts with '_', see ipadm_ipmgmt.h)
switch (class) {
case IPADMPROP_CLASS_MODULE:
case IPADMPROP_CLASS_MODIF:
case IPADMPROP_CLASS_IF:
case IPADMPROP_CLASS_ADDR:
static ipadm_status_t
return (IPADM_BAD_PROTOCOL);
return (IPADM_PROP_UNKNOWN);
return (IPADM_INVALID_ARG);
return (IPADM_INVALID_ARG);
switch (valtype) {
case IPADM_OPT_PERM:
case IPADM_OPT_ACTIVE:
case IPADM_OPT_DEFAULT:
case IPADM_OPT_POSSIBLE:
case IPADM_OPT_PERSIST:
if (is_if)
return (status);
return (IPADM_INVALID_ARG);
return (IPADM_NOTSUP);
return (IPADM_INVALID_ARG);
return (IPADM_NOTSUP);
return (IPADM_INVALID_ARG);
static ipadm_status_t
valsize = 0;
return (IPADM_NO_BUFS);
iocsize) < 0) {
return (status);
static ipadm_status_t
return (IPADM_INVALID_ARG);
return (IPADM_BAD_PROTOCOL);
return (IPADM_PROP_UNKNOWN);
if (is_if) {
return (IPADM_INVALID_ARG);
return (IPADM_INVALID_ARG);
return (IPADM_INVALID_ARG);
return (status);
if (persist) {
if (is_if)
pflags);
return (status);
/* check for solaris.network.interface.config authorization */
if (!ipadm_check_auth())
return (IPADM_EAUTH);
return (IPADM_INVALID_ARG);
return (IPADM_NOTSUP);
return (status);
pflags));
/* check for solaris.network.interface.config authorization */
if (!ipadm_check_auth())
return (IPADM_EAUTH);
return (IPADM_INVALID_ARG);
return (IPADM_NOTSUP);
pflags));
void *arg)
return (IPADM_INVALID_ARG);
switch (class) {
case IPADMPROP_CLASS_ADDR:
case IPADMPROP_CLASS_IF:
case IPADMPROP_CLASS_MODULE:
return (IPADM_INVALID_ARG);
return (IPADM_INVALID_ARG);
for (i = 0; i < count; i++) {
arg);
return (status);
return (IPADM_INVALID_ARG);
switch (class) {
case IPADMPROP_CLASS_ADDR:
case IPADMPROP_CLASS_IF:
case IPADMPROP_CLASS_MODULE:
return (IPADM_INVALID_ARG);
return (IPADM_INVALID_ARG);
if (!matched)
return (status);
return (IPADM_SUCCESS);
if (err == 0) {
err = 0;
static ipadm_status_t
return (IPADM_INVALID_ARG);
return (IPADM_NOTSUP);
return (status);
return (IPADM_OP_DISABLE_OBJ);
if (!af_exists)
return (IPADM_ENXIO);
return (IPADM_TEMPORARY_OBJ);
return (IPADM_SUCCESS);
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
MOD_PROTO_IP },
switch (*proto) {
case MOD_PROTO_TCP:
case MOD_PROTO_SCTP:
case MOD_PROTO_UDP:
case MOD_PROTO_RAWIP:
case MOD_PROTO_IP:
case MOD_PROTO_IPV4:
case MOD_PROTO_IPV6:
ionmp++) {
* Following API is required for ndd.c alone. To maintain backward
switch (proto) {
case MOD_PROTO_TCP:
case MOD_PROTO_SCTP:
case MOD_PROTO_UDP:
case MOD_PROTO_RAWIP:
case MOD_PROTO_IP:
case MOD_PROTO_IPV4:
case MOD_PROTO_IPV6:
nnamelen);