16e91bba0SGirish Moodalbail /* 26e91bba0SGirish Moodalbail * CDDL HEADER START 36e91bba0SGirish Moodalbail * 46e91bba0SGirish Moodalbail * The contents of this file are subject to the terms of the 56e91bba0SGirish Moodalbail * Common Development and Distribution License (the "License"). 66e91bba0SGirish Moodalbail * You may not use this file except in compliance with the License. 76e91bba0SGirish Moodalbail * 86e91bba0SGirish Moodalbail * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96e91bba0SGirish Moodalbail * or http://www.opensolaris.org/os/licensing. 106e91bba0SGirish Moodalbail * See the License for the specific language governing permissions 116e91bba0SGirish Moodalbail * and limitations under the License. 126e91bba0SGirish Moodalbail * 136e91bba0SGirish Moodalbail * When distributing Covered Code, include this CDDL HEADER in each 146e91bba0SGirish Moodalbail * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156e91bba0SGirish Moodalbail * If applicable, add the following below this CDDL HEADER, with the 166e91bba0SGirish Moodalbail * fields enclosed by brackets "[]" replaced with your own identifying 176e91bba0SGirish Moodalbail * information: Portions Copyright [yyyy] [name of copyright owner] 186e91bba0SGirish Moodalbail * 196e91bba0SGirish Moodalbail * CDDL HEADER END 206e91bba0SGirish Moodalbail */ 216e91bba0SGirish Moodalbail /* 228b88711aSGirish Moodalbail * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23*299625c6SSebastien Roy * Copyright (c) 2013 by Delphix. All rights reserved. 246e91bba0SGirish Moodalbail */ 256e91bba0SGirish Moodalbail 266e91bba0SGirish Moodalbail /* 276e91bba0SGirish Moodalbail * This file contains routines that are used to modify/retrieve protocol or 286e91bba0SGirish Moodalbail * interface property values. It also holds all the supported properties for 296e91bba0SGirish Moodalbail * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols 306e91bba0SGirish Moodalbail * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP. 316e91bba0SGirish Moodalbail * 326e91bba0SGirish Moodalbail * This file also contains walkers, which walks through the property table and 336e91bba0SGirish Moodalbail * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every 346e91bba0SGirish Moodalbail * property in the table. 356e91bba0SGirish Moodalbail */ 366e91bba0SGirish Moodalbail 376e91bba0SGirish Moodalbail #include <unistd.h> 386e91bba0SGirish Moodalbail #include <errno.h> 396e91bba0SGirish Moodalbail #include <ctype.h> 406e91bba0SGirish Moodalbail #include <fcntl.h> 416e91bba0SGirish Moodalbail #include <strings.h> 426e91bba0SGirish Moodalbail #include <stdlib.h> 436e91bba0SGirish Moodalbail #include <netinet/in.h> 446e91bba0SGirish Moodalbail #include <arpa/inet.h> 456e91bba0SGirish Moodalbail #include <sys/sockio.h> 466e91bba0SGirish Moodalbail #include <assert.h> 476e91bba0SGirish Moodalbail #include <libdllink.h> 486e91bba0SGirish Moodalbail #include <zone.h> 496e91bba0SGirish Moodalbail #include "libipadm_impl.h" 50f1e9465bSSowmini Varadhan #include <inet/tunables.h> 516e91bba0SGirish Moodalbail 526e91bba0SGirish Moodalbail #define IPADM_NONESTR "none" 536e91bba0SGirish Moodalbail #define DEF_METRIC_VAL 0 /* default metric value */ 546e91bba0SGirish Moodalbail 556e91bba0SGirish Moodalbail #define A_CNT(arr) (sizeof (arr) / sizeof (arr[0])) 566e91bba0SGirish Moodalbail 576e91bba0SGirish Moodalbail static ipadm_status_t i_ipadm_validate_if(ipadm_handle_t, const char *, 586e91bba0SGirish Moodalbail uint_t, uint_t); 596e91bba0SGirish Moodalbail 606e91bba0SGirish Moodalbail /* 616e91bba0SGirish Moodalbail * Callback functions to retrieve property values from the kernel. These 626e91bba0SGirish Moodalbail * functions, when required, translate the values from the kernel to a format 636e91bba0SGirish Moodalbail * suitable for printing. For example: boolean values will be translated 646e91bba0SGirish Moodalbail * to on/off. They also retrieve DEFAULT, PERM and POSSIBLE values for 656e91bba0SGirish Moodalbail * a given property. 666e91bba0SGirish Moodalbail */ 676e91bba0SGirish Moodalbail static ipadm_pd_getf_t i_ipadm_get_prop, i_ipadm_get_ifprop_flags, 686e91bba0SGirish Moodalbail i_ipadm_get_mtu, i_ipadm_get_metric, 696e91bba0SGirish Moodalbail i_ipadm_get_usesrc, i_ipadm_get_forwarding, 70f1e9465bSSowmini Varadhan i_ipadm_get_ecnsack, i_ipadm_get_hostmodel; 716e91bba0SGirish Moodalbail 726e91bba0SGirish Moodalbail /* 736e91bba0SGirish Moodalbail * Callback function to set property values. These functions translate the 746e91bba0SGirish Moodalbail * values to a format suitable for kernel consumption, allocates the necessary 756e91bba0SGirish Moodalbail * ioctl buffers and then invokes ioctl(). 766e91bba0SGirish Moodalbail */ 776e91bba0SGirish Moodalbail static ipadm_pd_setf_t i_ipadm_set_prop, i_ipadm_set_mtu, 786e91bba0SGirish Moodalbail i_ipadm_set_ifprop_flags, 796e91bba0SGirish Moodalbail i_ipadm_set_metric, i_ipadm_set_usesrc, 806e91bba0SGirish Moodalbail i_ipadm_set_forwarding, i_ipadm_set_eprivport, 81f1e9465bSSowmini Varadhan i_ipadm_set_ecnsack, i_ipadm_set_hostmodel; 826e91bba0SGirish Moodalbail 836e91bba0SGirish Moodalbail /* array of protocols we support */ 846e91bba0SGirish Moodalbail static int protocols[] = { MOD_PROTO_IP, MOD_PROTO_RAWIP, 856e91bba0SGirish Moodalbail MOD_PROTO_TCP, MOD_PROTO_UDP, 866e91bba0SGirish Moodalbail MOD_PROTO_SCTP }; 876e91bba0SGirish Moodalbail 886e91bba0SGirish Moodalbail /* 896e91bba0SGirish Moodalbail * Supported IP protocol properties. 906e91bba0SGirish Moodalbail */ 916e91bba0SGirish Moodalbail static ipadm_prop_desc_t ipadm_ip_prop_table[] = { 92*299625c6SSebastien Roy { "arp", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0, 936e91bba0SGirish Moodalbail i_ipadm_set_ifprop_flags, i_ipadm_get_onoff, 946e91bba0SGirish Moodalbail i_ipadm_get_ifprop_flags }, 956e91bba0SGirish Moodalbail 96*299625c6SSebastien Roy { "forwarding", NULL, IPADMPROP_CLASS_MODIF, MOD_PROTO_IPV4, 0, 976e91bba0SGirish Moodalbail i_ipadm_set_forwarding, i_ipadm_get_onoff, 986e91bba0SGirish Moodalbail i_ipadm_get_forwarding }, 996e91bba0SGirish Moodalbail 100*299625c6SSebastien Roy { "metric", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0, 1016e91bba0SGirish Moodalbail i_ipadm_set_metric, NULL, i_ipadm_get_metric }, 1026e91bba0SGirish Moodalbail 103*299625c6SSebastien Roy { "mtu", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0, 1046e91bba0SGirish Moodalbail i_ipadm_set_mtu, i_ipadm_get_mtu, i_ipadm_get_mtu }, 1056e91bba0SGirish Moodalbail 106*299625c6SSebastien Roy { "exchange_routes", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0, 1076e91bba0SGirish Moodalbail i_ipadm_set_ifprop_flags, i_ipadm_get_onoff, 1086e91bba0SGirish Moodalbail i_ipadm_get_ifprop_flags }, 1096e91bba0SGirish Moodalbail 110*299625c6SSebastien Roy { "usesrc", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0, 1116e91bba0SGirish Moodalbail i_ipadm_set_usesrc, NULL, i_ipadm_get_usesrc }, 1126e91bba0SGirish Moodalbail 113*299625c6SSebastien Roy { "ttl", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV4, 0, 1146e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1156e91bba0SGirish Moodalbail 116*299625c6SSebastien Roy { "forwarding", NULL, IPADMPROP_CLASS_MODIF, MOD_PROTO_IPV6, 0, 1176e91bba0SGirish Moodalbail i_ipadm_set_forwarding, i_ipadm_get_onoff, 1186e91bba0SGirish Moodalbail i_ipadm_get_forwarding }, 1196e91bba0SGirish Moodalbail 120*299625c6SSebastien Roy { "hoplimit", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV6, 0, 1216e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1226e91bba0SGirish Moodalbail 123*299625c6SSebastien Roy { "metric", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0, 1246e91bba0SGirish Moodalbail i_ipadm_set_metric, NULL, i_ipadm_get_metric }, 1256e91bba0SGirish Moodalbail 126*299625c6SSebastien Roy { "mtu", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0, 1276e91bba0SGirish Moodalbail i_ipadm_set_mtu, i_ipadm_get_mtu, i_ipadm_get_mtu }, 1286e91bba0SGirish Moodalbail 129*299625c6SSebastien Roy { "nud", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0, 1306e91bba0SGirish Moodalbail i_ipadm_set_ifprop_flags, i_ipadm_get_onoff, 1316e91bba0SGirish Moodalbail i_ipadm_get_ifprop_flags }, 1326e91bba0SGirish Moodalbail 133*299625c6SSebastien Roy { "exchange_routes", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0, 1346e91bba0SGirish Moodalbail i_ipadm_set_ifprop_flags, i_ipadm_get_onoff, 1356e91bba0SGirish Moodalbail i_ipadm_get_ifprop_flags }, 1366e91bba0SGirish Moodalbail 137*299625c6SSebastien Roy { "usesrc", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0, 1386e91bba0SGirish Moodalbail i_ipadm_set_usesrc, NULL, i_ipadm_get_usesrc }, 1396e91bba0SGirish Moodalbail 140*299625c6SSebastien Roy { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV6, 0, 141f1e9465bSSowmini Varadhan i_ipadm_set_hostmodel, i_ipadm_get_hostmodel, 142f1e9465bSSowmini Varadhan i_ipadm_get_hostmodel }, 143f1e9465bSSowmini Varadhan 144*299625c6SSebastien Roy { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV4, 0, 145f1e9465bSSowmini Varadhan i_ipadm_set_hostmodel, i_ipadm_get_hostmodel, 146f1e9465bSSowmini Varadhan i_ipadm_get_hostmodel }, 147f1e9465bSSowmini Varadhan 148*299625c6SSebastien Roy { NULL, NULL, 0, 0, 0, NULL, NULL, NULL } 1496e91bba0SGirish Moodalbail }; 1506e91bba0SGirish Moodalbail 1516e91bba0SGirish Moodalbail /* possible values for TCP properties `ecn' and `sack' */ 1526e91bba0SGirish Moodalbail static const char *ecn_sack_vals[] = {"never", "passive", "active", NULL}; 1536e91bba0SGirish Moodalbail 1546e91bba0SGirish Moodalbail /* Supported TCP protocol properties */ 1556e91bba0SGirish Moodalbail static ipadm_prop_desc_t ipadm_tcp_prop_table[] = { 156*299625c6SSebastien Roy { "ecn", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 1576e91bba0SGirish Moodalbail i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack }, 1586e91bba0SGirish Moodalbail 159*299625c6SSebastien Roy { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 1608b88711aSGirish Moodalbail IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop, 1618b88711aSGirish Moodalbail i_ipadm_get_prop }, 1626e91bba0SGirish Moodalbail 163*299625c6SSebastien Roy { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 1646e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1656e91bba0SGirish Moodalbail 166*299625c6SSebastien Roy { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 1676e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1686e91bba0SGirish Moodalbail 169*299625c6SSebastien Roy { "recv_buf", "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 170*299625c6SSebastien Roy i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 171*299625c6SSebastien Roy 172*299625c6SSebastien Roy { "sack", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 1736e91bba0SGirish Moodalbail i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack }, 1746e91bba0SGirish Moodalbail 175*299625c6SSebastien Roy { "send_buf", "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 1766e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1776e91bba0SGirish Moodalbail 178*299625c6SSebastien Roy { "smallest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0, 1796e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1806e91bba0SGirish Moodalbail 181*299625c6SSebastien Roy { "smallest_nonpriv_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 182*299625c6SSebastien Roy 0, i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1836e91bba0SGirish Moodalbail 184*299625c6SSebastien Roy { NULL, NULL, 0, 0, 0, NULL, NULL, NULL } 1856e91bba0SGirish Moodalbail }; 1866e91bba0SGirish Moodalbail 1876e91bba0SGirish Moodalbail /* Supported UDP protocol properties */ 1886e91bba0SGirish Moodalbail static ipadm_prop_desc_t ipadm_udp_prop_table[] = { 189*299625c6SSebastien Roy { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 1908b88711aSGirish Moodalbail IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop, 1918b88711aSGirish Moodalbail i_ipadm_get_prop }, 1926e91bba0SGirish Moodalbail 193*299625c6SSebastien Roy { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0, 1946e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1956e91bba0SGirish Moodalbail 196*299625c6SSebastien Roy { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0, 1976e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 1986e91bba0SGirish Moodalbail 199*299625c6SSebastien Roy { "recv_buf", "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0, 2006e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2016e91bba0SGirish Moodalbail 202*299625c6SSebastien Roy { "send_buf", "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0, 2036e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2046e91bba0SGirish Moodalbail 205*299625c6SSebastien Roy { "smallest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 0, 2066e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2076e91bba0SGirish Moodalbail 208*299625c6SSebastien Roy { "smallest_nonpriv_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_UDP, 209*299625c6SSebastien Roy 0, i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 210*299625c6SSebastien Roy 211*299625c6SSebastien Roy { NULL, NULL, 0, 0, 0, NULL, NULL, NULL } 2126e91bba0SGirish Moodalbail }; 2136e91bba0SGirish Moodalbail 2146e91bba0SGirish Moodalbail /* Supported SCTP protocol properties */ 2156e91bba0SGirish Moodalbail static ipadm_prop_desc_t ipadm_sctp_prop_table[] = { 216*299625c6SSebastien Roy { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 2178b88711aSGirish Moodalbail IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop, 2188b88711aSGirish Moodalbail i_ipadm_get_prop }, 2196e91bba0SGirish Moodalbail 220*299625c6SSebastien Roy { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0, 2216e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2226e91bba0SGirish Moodalbail 223*299625c6SSebastien Roy { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0, 2246e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2256e91bba0SGirish Moodalbail 226*299625c6SSebastien Roy { "recv_buf", "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0, 2276e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2286e91bba0SGirish Moodalbail 229*299625c6SSebastien Roy { "send_buf", "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0, 2306e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2316e91bba0SGirish Moodalbail 232*299625c6SSebastien Roy { "smallest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0, 2336e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2346e91bba0SGirish Moodalbail 235*299625c6SSebastien Roy { "smallest_nonpriv_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 236*299625c6SSebastien Roy 0, i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 237*299625c6SSebastien Roy 238*299625c6SSebastien Roy { NULL, NULL, 0, 0, 0, NULL, NULL, NULL } 2396e91bba0SGirish Moodalbail }; 2406e91bba0SGirish Moodalbail 2416e91bba0SGirish Moodalbail /* Supported ICMP protocol properties */ 2426e91bba0SGirish Moodalbail static ipadm_prop_desc_t ipadm_icmp_prop_table[] = { 243*299625c6SSebastien Roy { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0, 2446e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2456e91bba0SGirish Moodalbail 246*299625c6SSebastien Roy { "recv_buf", "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0, 2476e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 2486e91bba0SGirish Moodalbail 249*299625c6SSebastien Roy { "send_buf", "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0, 250*299625c6SSebastien Roy i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }, 251*299625c6SSebastien Roy 252*299625c6SSebastien Roy { NULL, NULL, 0, 0, 0, NULL, NULL, NULL } 2536e91bba0SGirish Moodalbail }; 2546e91bba0SGirish Moodalbail 2556e91bba0SGirish Moodalbail /* 2566e91bba0SGirish Moodalbail * A dummy private property structure, used while handling private 2576e91bba0SGirish Moodalbail * protocol properties (properties not yet supported by libipadm). 2586e91bba0SGirish Moodalbail */ 259*299625c6SSebastien Roy static ipadm_prop_desc_t ipadm_privprop = 260*299625c6SSebastien Roy { NULL, NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_NONE, 0, 2616e91bba0SGirish Moodalbail i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop }; 2626e91bba0SGirish Moodalbail 2636e91bba0SGirish Moodalbail /* 2646e91bba0SGirish Moodalbail * Returns the property description table, for the given protocol 2656e91bba0SGirish Moodalbail */ 2666e91bba0SGirish Moodalbail static ipadm_prop_desc_t * 2676e91bba0SGirish Moodalbail i_ipadm_get_propdesc_table(uint_t proto) 2686e91bba0SGirish Moodalbail { 2696e91bba0SGirish Moodalbail switch (proto) { 2706e91bba0SGirish Moodalbail case MOD_PROTO_IP: 2716e91bba0SGirish Moodalbail case MOD_PROTO_IPV4: 2726e91bba0SGirish Moodalbail case MOD_PROTO_IPV6: 2736e91bba0SGirish Moodalbail return (ipadm_ip_prop_table); 2746e91bba0SGirish Moodalbail case MOD_PROTO_RAWIP: 2756e91bba0SGirish Moodalbail return (ipadm_icmp_prop_table); 2766e91bba0SGirish Moodalbail case MOD_PROTO_TCP: 2776e91bba0SGirish Moodalbail return (ipadm_tcp_prop_table); 2786e91bba0SGirish Moodalbail case MOD_PROTO_UDP: 2796e91bba0SGirish Moodalbail return (ipadm_udp_prop_table); 2806e91bba0SGirish Moodalbail case MOD_PROTO_SCTP: 2816e91bba0SGirish Moodalbail return (ipadm_sctp_prop_table); 2826e91bba0SGirish Moodalbail } 2836e91bba0SGirish Moodalbail 2846e91bba0SGirish Moodalbail return (NULL); 2856e91bba0SGirish Moodalbail } 2866e91bba0SGirish Moodalbail 2878887b57dSGirish Moodalbail static ipadm_prop_desc_t * 2888887b57dSGirish Moodalbail i_ipadm_get_prop_desc(const char *pname, uint_t proto, int *errp) 2898887b57dSGirish Moodalbail { 2908887b57dSGirish Moodalbail int err = 0; 2918887b57dSGirish Moodalbail boolean_t matched_name = B_FALSE; 2928887b57dSGirish Moodalbail ipadm_prop_desc_t *ipdp = NULL, *ipdtbl; 2938887b57dSGirish Moodalbail 2948887b57dSGirish Moodalbail if ((ipdtbl = i_ipadm_get_propdesc_table(proto)) == NULL) { 2958887b57dSGirish Moodalbail err = EINVAL; 2968887b57dSGirish Moodalbail goto ret; 2978887b57dSGirish Moodalbail } 298*299625c6SSebastien Roy 2998887b57dSGirish Moodalbail for (ipdp = ipdtbl; ipdp->ipd_name != NULL; ipdp++) { 300*299625c6SSebastien Roy if (strcmp(pname, ipdp->ipd_name) == 0 || 301*299625c6SSebastien Roy (ipdp->ipd_old_name != NULL && 302*299625c6SSebastien Roy strcmp(pname, ipdp->ipd_old_name) == 0)) { 3038887b57dSGirish Moodalbail matched_name = B_TRUE; 3048887b57dSGirish Moodalbail if (ipdp->ipd_proto == proto) 3058887b57dSGirish Moodalbail break; 3068887b57dSGirish Moodalbail } 3078887b57dSGirish Moodalbail } 308*299625c6SSebastien Roy 3098887b57dSGirish Moodalbail if (ipdp->ipd_name == NULL) { 3108887b57dSGirish Moodalbail err = ENOENT; 3118887b57dSGirish Moodalbail /* if we matched name, but failed protocol check */ 3128887b57dSGirish Moodalbail if (matched_name) 3138887b57dSGirish Moodalbail err = EPROTO; 3148887b57dSGirish Moodalbail ipdp = NULL; 3158887b57dSGirish Moodalbail } 3168887b57dSGirish Moodalbail ret: 3178887b57dSGirish Moodalbail if (errp != NULL) 3188887b57dSGirish Moodalbail *errp = err; 3198887b57dSGirish Moodalbail return (ipdp); 3208887b57dSGirish Moodalbail } 3218887b57dSGirish Moodalbail 3226e91bba0SGirish Moodalbail char * 3236e91bba0SGirish Moodalbail ipadm_proto2str(uint_t proto) 3246e91bba0SGirish Moodalbail { 3256e91bba0SGirish Moodalbail switch (proto) { 3266e91bba0SGirish Moodalbail case MOD_PROTO_IP: 3276e91bba0SGirish Moodalbail return ("ip"); 3286e91bba0SGirish Moodalbail case MOD_PROTO_IPV4: 3296e91bba0SGirish Moodalbail return ("ipv4"); 3306e91bba0SGirish Moodalbail case MOD_PROTO_IPV6: 3316e91bba0SGirish Moodalbail return ("ipv6"); 3326e91bba0SGirish Moodalbail case MOD_PROTO_RAWIP: 3336e91bba0SGirish Moodalbail return ("icmp"); 3346e91bba0SGirish Moodalbail case MOD_PROTO_TCP: 3356e91bba0SGirish Moodalbail return ("tcp"); 3366e91bba0SGirish Moodalbail case MOD_PROTO_UDP: 3376e91bba0SGirish Moodalbail return ("udp"); 3386e91bba0SGirish Moodalbail case MOD_PROTO_SCTP: 3396e91bba0SGirish Moodalbail return ("sctp"); 3406e91bba0SGirish Moodalbail } 3416e91bba0SGirish Moodalbail 3426e91bba0SGirish Moodalbail return (NULL); 3436e91bba0SGirish Moodalbail } 3446e91bba0SGirish Moodalbail 3456e91bba0SGirish Moodalbail uint_t 3466e91bba0SGirish Moodalbail ipadm_str2proto(const char *protostr) 3476e91bba0SGirish Moodalbail { 3486e91bba0SGirish Moodalbail if (protostr == NULL) 3496e91bba0SGirish Moodalbail return (MOD_PROTO_NONE); 3506e91bba0SGirish Moodalbail if (strcmp(protostr, "tcp") == 0) 3516e91bba0SGirish Moodalbail return (MOD_PROTO_TCP); 3526e91bba0SGirish Moodalbail else if (strcmp(protostr, "udp") == 0) 3536e91bba0SGirish Moodalbail return (MOD_PROTO_UDP); 3546e91bba0SGirish Moodalbail else if (strcmp(protostr, "ip") == 0) 3556e91bba0SGirish Moodalbail return (MOD_PROTO_IP); 3566e91bba0SGirish Moodalbail else if (strcmp(protostr, "ipv4") == 0) 3576e91bba0SGirish Moodalbail return (MOD_PROTO_IPV4); 3586e91bba0SGirish Moodalbail else if (strcmp(protostr, "ipv6") == 0) 3596e91bba0SGirish Moodalbail return (MOD_PROTO_IPV6); 3606e91bba0SGirish Moodalbail else if (strcmp(protostr, "icmp") == 0) 3616e91bba0SGirish Moodalbail return (MOD_PROTO_RAWIP); 3626e91bba0SGirish Moodalbail else if (strcmp(protostr, "sctp") == 0) 3636e91bba0SGirish Moodalbail return (MOD_PROTO_SCTP); 3646e91bba0SGirish Moodalbail else if (strcmp(protostr, "arp") == 0) 3656e91bba0SGirish Moodalbail return (MOD_PROTO_IP); 3666e91bba0SGirish Moodalbail 3676e91bba0SGirish Moodalbail return (MOD_PROTO_NONE); 3686e91bba0SGirish Moodalbail } 3696e91bba0SGirish Moodalbail 3706e91bba0SGirish Moodalbail /* ARGSUSED */ 3716e91bba0SGirish Moodalbail static ipadm_status_t 3726e91bba0SGirish Moodalbail i_ipadm_set_mtu(ipadm_handle_t iph, const void *arg, 3736e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 3746e91bba0SGirish Moodalbail { 3756e91bba0SGirish Moodalbail struct lifreq lifr; 3766e91bba0SGirish Moodalbail char *endp; 3776e91bba0SGirish Moodalbail uint_t mtu; 3786e91bba0SGirish Moodalbail int s; 3796e91bba0SGirish Moodalbail const char *ifname = arg; 3806e91bba0SGirish Moodalbail char val[MAXPROPVALLEN]; 3816e91bba0SGirish Moodalbail 3826e91bba0SGirish Moodalbail /* to reset MTU first retrieve the default MTU and then set it */ 3836e91bba0SGirish Moodalbail if (flags & IPADM_OPT_DEFAULT) { 3846e91bba0SGirish Moodalbail ipadm_status_t status; 3856e91bba0SGirish Moodalbail uint_t size = MAXPROPVALLEN; 3866e91bba0SGirish Moodalbail 3876e91bba0SGirish Moodalbail status = i_ipadm_get_prop(iph, arg, pdp, val, &size, 3886e91bba0SGirish Moodalbail proto, MOD_PROP_DEFAULT); 3896e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 3906e91bba0SGirish Moodalbail return (status); 3916e91bba0SGirish Moodalbail pval = val; 3926e91bba0SGirish Moodalbail } 3936e91bba0SGirish Moodalbail 3946e91bba0SGirish Moodalbail errno = 0; 3956e91bba0SGirish Moodalbail mtu = (uint_t)strtol(pval, &endp, 10); 3966e91bba0SGirish Moodalbail if (errno != 0 || *endp != '\0') 3976e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 3986e91bba0SGirish Moodalbail 3996e91bba0SGirish Moodalbail bzero(&lifr, sizeof (lifr)); 4006e91bba0SGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 4016e91bba0SGirish Moodalbail lifr.lifr_mtu = mtu; 4026e91bba0SGirish Moodalbail 4036e91bba0SGirish Moodalbail s = (proto == MOD_PROTO_IPV6 ? iph->iph_sock6 : iph->iph_sock); 4046e91bba0SGirish Moodalbail if (ioctl(s, SIOCSLIFMTU, (caddr_t)&lifr) < 0) 4056e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 4066e91bba0SGirish Moodalbail 4076e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 4086e91bba0SGirish Moodalbail } 4096e91bba0SGirish Moodalbail 4106e91bba0SGirish Moodalbail /* ARGSUSED */ 4116e91bba0SGirish Moodalbail static ipadm_status_t 4126e91bba0SGirish Moodalbail i_ipadm_set_metric(ipadm_handle_t iph, const void *arg, 4136e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 4146e91bba0SGirish Moodalbail { 4156e91bba0SGirish Moodalbail struct lifreq lifr; 4166e91bba0SGirish Moodalbail char *endp; 4176e91bba0SGirish Moodalbail int metric; 4186e91bba0SGirish Moodalbail const char *ifname = arg; 4196e91bba0SGirish Moodalbail int s; 4206e91bba0SGirish Moodalbail 4216e91bba0SGirish Moodalbail /* if we are resetting, set the value to its default value */ 4226e91bba0SGirish Moodalbail if (flags & IPADM_OPT_DEFAULT) { 4236e91bba0SGirish Moodalbail metric = DEF_METRIC_VAL; 4246e91bba0SGirish Moodalbail } else { 4256e91bba0SGirish Moodalbail errno = 0; 4266e91bba0SGirish Moodalbail metric = (uint_t)strtol(pval, &endp, 10); 4276e91bba0SGirish Moodalbail if (errno != 0 || *endp != '\0') 4286e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 4296e91bba0SGirish Moodalbail } 4306e91bba0SGirish Moodalbail 4316e91bba0SGirish Moodalbail bzero(&lifr, sizeof (lifr)); 4326e91bba0SGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 4336e91bba0SGirish Moodalbail lifr.lifr_metric = metric; 4346e91bba0SGirish Moodalbail 4356e91bba0SGirish Moodalbail s = (proto == MOD_PROTO_IPV6 ? iph->iph_sock6 : iph->iph_sock); 4366e91bba0SGirish Moodalbail 4376e91bba0SGirish Moodalbail if (ioctl(s, SIOCSLIFMETRIC, (caddr_t)&lifr) < 0) 4386e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 4396e91bba0SGirish Moodalbail 4406e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 4416e91bba0SGirish Moodalbail } 4426e91bba0SGirish Moodalbail 4436e91bba0SGirish Moodalbail /* ARGSUSED */ 4446e91bba0SGirish Moodalbail static ipadm_status_t 4456e91bba0SGirish Moodalbail i_ipadm_set_usesrc(ipadm_handle_t iph, const void *arg, 4466e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 4476e91bba0SGirish Moodalbail { 4486e91bba0SGirish Moodalbail struct lifreq lifr; 4496e91bba0SGirish Moodalbail const char *ifname = arg; 4506e91bba0SGirish Moodalbail int s; 4516e91bba0SGirish Moodalbail uint_t ifindex = 0; 4526e91bba0SGirish Moodalbail 4536e91bba0SGirish Moodalbail /* if we are resetting, set the value to its default value */ 4546e91bba0SGirish Moodalbail if (flags & IPADM_OPT_DEFAULT) 4556e91bba0SGirish Moodalbail pval = IPADM_NONESTR; 4566e91bba0SGirish Moodalbail 4576e91bba0SGirish Moodalbail /* 4586e91bba0SGirish Moodalbail * cannot specify logical interface name. We can also filter out other 4596e91bba0SGirish Moodalbail * bogus interface names here itself through i_ipadm_validate_ifname(). 4606e91bba0SGirish Moodalbail */ 4616e91bba0SGirish Moodalbail if (strcmp(pval, IPADM_NONESTR) != 0 && 4626e91bba0SGirish Moodalbail !i_ipadm_validate_ifname(iph, pval)) 4636e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 4646e91bba0SGirish Moodalbail 4656e91bba0SGirish Moodalbail bzero(&lifr, sizeof (lifr)); 4666e91bba0SGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 4676e91bba0SGirish Moodalbail 4686e91bba0SGirish Moodalbail s = (proto == MOD_PROTO_IPV6 ? iph->iph_sock6 : iph->iph_sock); 4696e91bba0SGirish Moodalbail 4706e91bba0SGirish Moodalbail if (strcmp(pval, IPADM_NONESTR) != 0) { 4716e91bba0SGirish Moodalbail if ((ifindex = if_nametoindex(pval)) == 0) 4726e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 4736e91bba0SGirish Moodalbail lifr.lifr_index = ifindex; 4746e91bba0SGirish Moodalbail } else { 4756e91bba0SGirish Moodalbail if (ioctl(s, SIOCGLIFUSESRC, (caddr_t)&lifr) < 0) 4766e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 4776e91bba0SGirish Moodalbail lifr.lifr_index = 0; 4786e91bba0SGirish Moodalbail } 4796e91bba0SGirish Moodalbail if (ioctl(s, SIOCSLIFUSESRC, (caddr_t)&lifr) < 0) 4806e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 4816e91bba0SGirish Moodalbail 4826e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 4836e91bba0SGirish Moodalbail } 4846e91bba0SGirish Moodalbail 485f1e9465bSSowmini Varadhan static struct hostmodel_strval { 486f1e9465bSSowmini Varadhan char *esm_str; 487f1e9465bSSowmini Varadhan ip_hostmodel_t esm_val; 488f1e9465bSSowmini Varadhan } esm_arr[] = { 489f1e9465bSSowmini Varadhan {"weak", IP_WEAK_ES}, 490f1e9465bSSowmini Varadhan {"src-priority", IP_SRC_PRI_ES}, 491f1e9465bSSowmini Varadhan {"strong", IP_STRONG_ES}, 492f1e9465bSSowmini Varadhan {"custom", IP_MAXVAL_ES} 493f1e9465bSSowmini Varadhan }; 494f1e9465bSSowmini Varadhan 495f1e9465bSSowmini Varadhan static ip_hostmodel_t 496f1e9465bSSowmini Varadhan i_ipadm_hostmodel_str2val(const char *pval) 497f1e9465bSSowmini Varadhan { 498f1e9465bSSowmini Varadhan int i; 499f1e9465bSSowmini Varadhan 500f1e9465bSSowmini Varadhan for (i = 0; i < A_CNT(esm_arr); i++) { 501f1e9465bSSowmini Varadhan if (esm_arr[i].esm_str != NULL && 502f1e9465bSSowmini Varadhan strcmp(pval, esm_arr[i].esm_str) == 0) { 503f1e9465bSSowmini Varadhan return (esm_arr[i].esm_val); 504f1e9465bSSowmini Varadhan } 505f1e9465bSSowmini Varadhan } 506f1e9465bSSowmini Varadhan return (IP_MAXVAL_ES); 507f1e9465bSSowmini Varadhan } 508f1e9465bSSowmini Varadhan 509f1e9465bSSowmini Varadhan static char * 510f1e9465bSSowmini Varadhan i_ipadm_hostmodel_val2str(ip_hostmodel_t pval) 511f1e9465bSSowmini Varadhan { 512f1e9465bSSowmini Varadhan int i; 513f1e9465bSSowmini Varadhan 514f1e9465bSSowmini Varadhan for (i = 0; i < A_CNT(esm_arr); i++) { 515f1e9465bSSowmini Varadhan if (esm_arr[i].esm_val == pval) 516f1e9465bSSowmini Varadhan return (esm_arr[i].esm_str); 517f1e9465bSSowmini Varadhan } 518f1e9465bSSowmini Varadhan return (NULL); 519f1e9465bSSowmini Varadhan } 520f1e9465bSSowmini Varadhan 521f1e9465bSSowmini Varadhan /* ARGSUSED */ 522f1e9465bSSowmini Varadhan static ipadm_status_t 523f1e9465bSSowmini Varadhan i_ipadm_set_hostmodel(ipadm_handle_t iph, const void *arg, 524f1e9465bSSowmini Varadhan ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 525f1e9465bSSowmini Varadhan { 526f1e9465bSSowmini Varadhan ip_hostmodel_t hostmodel; 527f1e9465bSSowmini Varadhan char val[11]; /* covers uint32_max as a string */ 528f1e9465bSSowmini Varadhan 529f1e9465bSSowmini Varadhan if ((flags & IPADM_OPT_DEFAULT) == 0) { 530f1e9465bSSowmini Varadhan hostmodel = i_ipadm_hostmodel_str2val(pval); 531f1e9465bSSowmini Varadhan if (hostmodel == IP_MAXVAL_ES) 532f1e9465bSSowmini Varadhan return (IPADM_INVALID_ARG); 533f1e9465bSSowmini Varadhan (void) snprintf(val, sizeof (val), "%d", hostmodel); 534f1e9465bSSowmini Varadhan pval = val; 535f1e9465bSSowmini Varadhan } 536f1e9465bSSowmini Varadhan return (i_ipadm_set_prop(iph, NULL, pdp, pval, proto, flags)); 537f1e9465bSSowmini Varadhan } 538f1e9465bSSowmini Varadhan 539f1e9465bSSowmini Varadhan /* ARGSUSED */ 540f1e9465bSSowmini Varadhan static ipadm_status_t 541f1e9465bSSowmini Varadhan i_ipadm_get_hostmodel(ipadm_handle_t iph, const void *arg, 542f1e9465bSSowmini Varadhan ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 543f1e9465bSSowmini Varadhan uint_t valtype) 544f1e9465bSSowmini Varadhan { 545f1e9465bSSowmini Varadhan ip_hostmodel_t hostmodel; 546f1e9465bSSowmini Varadhan char *cp; 547f1e9465bSSowmini Varadhan size_t nbytes; 548f1e9465bSSowmini Varadhan ipadm_status_t status; 549f1e9465bSSowmini Varadhan 550f1e9465bSSowmini Varadhan switch (valtype) { 551f1e9465bSSowmini Varadhan case MOD_PROP_PERM: 552f1e9465bSSowmini Varadhan nbytes = snprintf(buf, *bufsize, "%d", MOD_PROP_PERM_RW); 553f1e9465bSSowmini Varadhan break; 554f1e9465bSSowmini Varadhan case MOD_PROP_DEFAULT: 555f1e9465bSSowmini Varadhan nbytes = snprintf(buf, *bufsize, "weak"); 556f1e9465bSSowmini Varadhan break; 557f1e9465bSSowmini Varadhan case MOD_PROP_ACTIVE: 558f1e9465bSSowmini Varadhan status = i_ipadm_get_prop(iph, arg, pdp, buf, bufsize, proto, 559f1e9465bSSowmini Varadhan valtype); 560f1e9465bSSowmini Varadhan if (status != IPADM_SUCCESS) 561f1e9465bSSowmini Varadhan return (status); 562f1e9465bSSowmini Varadhan bcopy(buf, &hostmodel, sizeof (hostmodel)); 563f1e9465bSSowmini Varadhan cp = i_ipadm_hostmodel_val2str(hostmodel); 564f1e9465bSSowmini Varadhan nbytes = snprintf(buf, *bufsize, "%s", 565f1e9465bSSowmini Varadhan (cp != NULL ? cp : "?")); 566f1e9465bSSowmini Varadhan break; 567f1e9465bSSowmini Varadhan case MOD_PROP_POSSIBLE: 568f1e9465bSSowmini Varadhan nbytes = snprintf(buf, *bufsize, "strong,src-priority,weak"); 569f1e9465bSSowmini Varadhan break; 570f1e9465bSSowmini Varadhan default: 571f1e9465bSSowmini Varadhan return (IPADM_INVALID_ARG); 572f1e9465bSSowmini Varadhan } 573f1e9465bSSowmini Varadhan if (nbytes >= *bufsize) { 574f1e9465bSSowmini Varadhan /* insufficient buffer space */ 575f1e9465bSSowmini Varadhan *bufsize = nbytes + 1; 576f1e9465bSSowmini Varadhan return (IPADM_NO_BUFS); 577f1e9465bSSowmini Varadhan } 578f1e9465bSSowmini Varadhan return (IPADM_SUCCESS); 579f1e9465bSSowmini Varadhan } 580f1e9465bSSowmini Varadhan 5816e91bba0SGirish Moodalbail /* ARGSUSED */ 5826e91bba0SGirish Moodalbail static ipadm_status_t 5836e91bba0SGirish Moodalbail i_ipadm_set_ifprop_flags(ipadm_handle_t iph, const void *arg, 5846e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 5856e91bba0SGirish Moodalbail { 5866e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 5876e91bba0SGirish Moodalbail const char *ifname = arg; 5886e91bba0SGirish Moodalbail uint64_t on_flags = 0, off_flags = 0; 5896e91bba0SGirish Moodalbail boolean_t on = B_FALSE; 5906e91bba0SGirish Moodalbail sa_family_t af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET); 5916e91bba0SGirish Moodalbail 5926e91bba0SGirish Moodalbail /* if we are resetting, set the value to its default value */ 5936e91bba0SGirish Moodalbail if (flags & IPADM_OPT_DEFAULT) { 5946e91bba0SGirish Moodalbail if (strcmp(pdp->ipd_name, "exchange_routes") == 0 || 5956e91bba0SGirish Moodalbail strcmp(pdp->ipd_name, "arp") == 0 || 5966e91bba0SGirish Moodalbail strcmp(pdp->ipd_name, "nud") == 0) { 5976e91bba0SGirish Moodalbail pval = IPADM_ONSTR; 5986e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "forwarding") == 0) { 5996e91bba0SGirish Moodalbail pval = IPADM_OFFSTR; 6006e91bba0SGirish Moodalbail } else { 6016e91bba0SGirish Moodalbail return (IPADM_PROP_UNKNOWN); 6026e91bba0SGirish Moodalbail } 6036e91bba0SGirish Moodalbail } 6046e91bba0SGirish Moodalbail 6056e91bba0SGirish Moodalbail if (strcmp(pval, IPADM_ONSTR) == 0) 6066e91bba0SGirish Moodalbail on = B_TRUE; 6076e91bba0SGirish Moodalbail else if (strcmp(pval, IPADM_OFFSTR) == 0) 6086e91bba0SGirish Moodalbail on = B_FALSE; 6096e91bba0SGirish Moodalbail else 6106e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 6116e91bba0SGirish Moodalbail 6126e91bba0SGirish Moodalbail if (strcmp(pdp->ipd_name, "exchange_routes") == 0) { 6136e91bba0SGirish Moodalbail if (on) 6146e91bba0SGirish Moodalbail off_flags = IFF_NORTEXCH; 6156e91bba0SGirish Moodalbail else 6166e91bba0SGirish Moodalbail on_flags = IFF_NORTEXCH; 6176e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "arp") == 0) { 6186e91bba0SGirish Moodalbail if (on) 6196e91bba0SGirish Moodalbail off_flags = IFF_NOARP; 6206e91bba0SGirish Moodalbail else 6216e91bba0SGirish Moodalbail on_flags = IFF_NOARP; 6226e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "nud") == 0) { 6236e91bba0SGirish Moodalbail if (on) 6246e91bba0SGirish Moodalbail off_flags = IFF_NONUD; 6256e91bba0SGirish Moodalbail else 6266e91bba0SGirish Moodalbail on_flags = IFF_NONUD; 6276e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "forwarding") == 0) { 6286e91bba0SGirish Moodalbail if (on) 6296e91bba0SGirish Moodalbail on_flags = IFF_ROUTER; 6306e91bba0SGirish Moodalbail else 6316e91bba0SGirish Moodalbail off_flags = IFF_ROUTER; 6326e91bba0SGirish Moodalbail } 6336e91bba0SGirish Moodalbail 6346e91bba0SGirish Moodalbail if (on_flags || off_flags) { 6356e91bba0SGirish Moodalbail status = i_ipadm_set_flags(iph, ifname, af, on_flags, 6366e91bba0SGirish Moodalbail off_flags); 6376e91bba0SGirish Moodalbail } 6386e91bba0SGirish Moodalbail return (status); 6396e91bba0SGirish Moodalbail } 6406e91bba0SGirish Moodalbail 6416e91bba0SGirish Moodalbail /* ARGSUSED */ 6426e91bba0SGirish Moodalbail static ipadm_status_t 6436e91bba0SGirish Moodalbail i_ipadm_set_eprivport(ipadm_handle_t iph, const void *arg, 6446e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 6456e91bba0SGirish Moodalbail { 6466e91bba0SGirish Moodalbail nvlist_t *portsnvl = NULL; 6476e91bba0SGirish Moodalbail nvpair_t *nvp; 6486e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 6496e91bba0SGirish Moodalbail int err; 6506e91bba0SGirish Moodalbail uint_t count = 0; 6516e91bba0SGirish Moodalbail 6526e91bba0SGirish Moodalbail if (flags & IPADM_OPT_DEFAULT) { 6536e91bba0SGirish Moodalbail assert(pval == NULL); 6546e91bba0SGirish Moodalbail return (i_ipadm_set_prop(iph, arg, pdp, pval, proto, flags)); 6556e91bba0SGirish Moodalbail } 6566e91bba0SGirish Moodalbail 6576e91bba0SGirish Moodalbail if ((err = ipadm_str2nvlist(pval, &portsnvl, IPADM_NORVAL)) != 0) 6586e91bba0SGirish Moodalbail return (ipadm_errno2status(err)); 6596e91bba0SGirish Moodalbail 6606e91bba0SGirish Moodalbail /* count the number of ports */ 6616e91bba0SGirish Moodalbail for (nvp = nvlist_next_nvpair(portsnvl, NULL); nvp != NULL; 6626e91bba0SGirish Moodalbail nvp = nvlist_next_nvpair(portsnvl, nvp)) { 6636e91bba0SGirish Moodalbail ++count; 6646e91bba0SGirish Moodalbail } 6656e91bba0SGirish Moodalbail 66617074b3aSGirish Moodalbail if (iph->iph_flags & IPH_INIT) { 66717074b3aSGirish Moodalbail flags |= IPADM_OPT_APPEND; 66817074b3aSGirish Moodalbail } else if (count > 1) { 6696e91bba0SGirish Moodalbail /* 67017074b3aSGirish Moodalbail * We allow only one port to be added, removed or 67117074b3aSGirish Moodalbail * assigned at a time. 67217074b3aSGirish Moodalbail * 67317074b3aSGirish Moodalbail * However on reboot, while initializing protocol 67417074b3aSGirish Moodalbail * properties, extra_priv_ports might have multiple 67517074b3aSGirish Moodalbail * values. Only in that case we allow setting multiple 67617074b3aSGirish Moodalbail * values. 6776e91bba0SGirish Moodalbail */ 67817074b3aSGirish Moodalbail nvlist_free(portsnvl); 6796e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 68017074b3aSGirish Moodalbail } 6816e91bba0SGirish Moodalbail 6826e91bba0SGirish Moodalbail for (nvp = nvlist_next_nvpair(portsnvl, NULL); nvp != NULL; 6836e91bba0SGirish Moodalbail nvp = nvlist_next_nvpair(portsnvl, nvp)) { 68417074b3aSGirish Moodalbail status = i_ipadm_set_prop(iph, arg, pdp, nvpair_name(nvp), 68517074b3aSGirish Moodalbail proto, flags); 6866e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 6876e91bba0SGirish Moodalbail break; 6886e91bba0SGirish Moodalbail } 6896e91bba0SGirish Moodalbail nvlist_free(portsnvl); 6906e91bba0SGirish Moodalbail return (status); 6916e91bba0SGirish Moodalbail } 6926e91bba0SGirish Moodalbail 6936e91bba0SGirish Moodalbail /* ARGSUSED */ 6946e91bba0SGirish Moodalbail static ipadm_status_t 6956e91bba0SGirish Moodalbail i_ipadm_set_forwarding(ipadm_handle_t iph, const void *arg, 6966e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 6976e91bba0SGirish Moodalbail { 6986e91bba0SGirish Moodalbail const char *ifname = arg; 6996e91bba0SGirish Moodalbail ipadm_status_t status; 7006e91bba0SGirish Moodalbail 7016e91bba0SGirish Moodalbail /* 7026e91bba0SGirish Moodalbail * if interface name is provided, then set forwarding using the 7036e91bba0SGirish Moodalbail * IFF_ROUTER flag 7046e91bba0SGirish Moodalbail */ 7056e91bba0SGirish Moodalbail if (ifname != NULL) { 7066e91bba0SGirish Moodalbail status = i_ipadm_set_ifprop_flags(iph, ifname, pdp, pval, 7076e91bba0SGirish Moodalbail proto, flags); 7086e91bba0SGirish Moodalbail } else { 7096e91bba0SGirish Moodalbail char *val = NULL; 7106e91bba0SGirish Moodalbail 7116e91bba0SGirish Moodalbail /* 7126e91bba0SGirish Moodalbail * if the caller is IPH_LEGACY, `pval' already contains 7136e91bba0SGirish Moodalbail * numeric values. 7146e91bba0SGirish Moodalbail */ 7156e91bba0SGirish Moodalbail if (!(flags & IPADM_OPT_DEFAULT) && 7166e91bba0SGirish Moodalbail !(iph->iph_flags & IPH_LEGACY)) { 7176e91bba0SGirish Moodalbail 7186e91bba0SGirish Moodalbail if (strcmp(pval, IPADM_ONSTR) == 0) 7196e91bba0SGirish Moodalbail val = "1"; 7206e91bba0SGirish Moodalbail else if (strcmp(pval, IPADM_OFFSTR) == 0) 7216e91bba0SGirish Moodalbail val = "0"; 7226e91bba0SGirish Moodalbail else 7236e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 7246e91bba0SGirish Moodalbail pval = val; 7256e91bba0SGirish Moodalbail } 7266e91bba0SGirish Moodalbail 7276e91bba0SGirish Moodalbail status = i_ipadm_set_prop(iph, ifname, pdp, pval, proto, flags); 7286e91bba0SGirish Moodalbail } 7296e91bba0SGirish Moodalbail 7306e91bba0SGirish Moodalbail return (status); 7316e91bba0SGirish Moodalbail } 7326e91bba0SGirish Moodalbail 7336e91bba0SGirish Moodalbail /* ARGSUSED */ 7346e91bba0SGirish Moodalbail static ipadm_status_t 7356e91bba0SGirish Moodalbail i_ipadm_set_ecnsack(ipadm_handle_t iph, const void *arg, 7366e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 7376e91bba0SGirish Moodalbail { 7386e91bba0SGirish Moodalbail uint_t i; 7396e91bba0SGirish Moodalbail char val[MAXPROPVALLEN]; 7406e91bba0SGirish Moodalbail 7416e91bba0SGirish Moodalbail /* if IPH_LEGACY is set, `pval' already contains numeric values */ 7426e91bba0SGirish Moodalbail if (!(flags & IPADM_OPT_DEFAULT) && !(iph->iph_flags & IPH_LEGACY)) { 7436e91bba0SGirish Moodalbail for (i = 0; ecn_sack_vals[i] != NULL; i++) { 7446e91bba0SGirish Moodalbail if (strcmp(pval, ecn_sack_vals[i]) == 0) 7456e91bba0SGirish Moodalbail break; 7466e91bba0SGirish Moodalbail } 7476e91bba0SGirish Moodalbail if (ecn_sack_vals[i] == NULL) 7486e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 7496e91bba0SGirish Moodalbail (void) snprintf(val, MAXPROPVALLEN, "%d", i); 7506e91bba0SGirish Moodalbail pval = val; 7516e91bba0SGirish Moodalbail } 7526e91bba0SGirish Moodalbail 7536e91bba0SGirish Moodalbail return (i_ipadm_set_prop(iph, arg, pdp, pval, proto, flags)); 7546e91bba0SGirish Moodalbail } 7556e91bba0SGirish Moodalbail 7566e91bba0SGirish Moodalbail /* ARGSUSED */ 7576e91bba0SGirish Moodalbail ipadm_status_t 7586e91bba0SGirish Moodalbail i_ipadm_get_ecnsack(ipadm_handle_t iph, const void *arg, 7596e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 7606e91bba0SGirish Moodalbail uint_t valtype) 7616e91bba0SGirish Moodalbail { 7626e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 7636e91bba0SGirish Moodalbail uint_t i, nbytes = 0; 7646e91bba0SGirish Moodalbail 7656e91bba0SGirish Moodalbail switch (valtype) { 7666e91bba0SGirish Moodalbail case MOD_PROP_POSSIBLE: 7676e91bba0SGirish Moodalbail for (i = 0; ecn_sack_vals[i] != NULL; i++) { 7686e91bba0SGirish Moodalbail if (i == 0) 7696e91bba0SGirish Moodalbail nbytes += snprintf(buf + nbytes, 7706e91bba0SGirish Moodalbail *bufsize - nbytes, "%s", ecn_sack_vals[i]); 7716e91bba0SGirish Moodalbail else 7726e91bba0SGirish Moodalbail nbytes += snprintf(buf + nbytes, 7736e91bba0SGirish Moodalbail *bufsize - nbytes, ",%s", ecn_sack_vals[i]); 7746e91bba0SGirish Moodalbail if (nbytes >= *bufsize) 7756e91bba0SGirish Moodalbail break; 7766e91bba0SGirish Moodalbail } 7776e91bba0SGirish Moodalbail break; 7786e91bba0SGirish Moodalbail case MOD_PROP_PERM: 7796e91bba0SGirish Moodalbail case MOD_PROP_DEFAULT: 7806e91bba0SGirish Moodalbail case MOD_PROP_ACTIVE: 7816e91bba0SGirish Moodalbail status = i_ipadm_get_prop(iph, arg, pdp, buf, bufsize, proto, 7826e91bba0SGirish Moodalbail valtype); 7836e91bba0SGirish Moodalbail 7846e91bba0SGirish Moodalbail /* 7856e91bba0SGirish Moodalbail * If IPH_LEGACY is set, do not convert the value returned 7866e91bba0SGirish Moodalbail * from kernel, 7876e91bba0SGirish Moodalbail */ 7886e91bba0SGirish Moodalbail if (iph->iph_flags & IPH_LEGACY) 7896e91bba0SGirish Moodalbail break; 7906e91bba0SGirish Moodalbail 7916e91bba0SGirish Moodalbail /* 7926e91bba0SGirish Moodalbail * For current and default value, convert the value returned 7936e91bba0SGirish Moodalbail * from kernel to more discrete representation. 7946e91bba0SGirish Moodalbail */ 7956e91bba0SGirish Moodalbail if (status == IPADM_SUCCESS && (valtype == MOD_PROP_ACTIVE || 7966e91bba0SGirish Moodalbail valtype == MOD_PROP_DEFAULT)) { 7976e91bba0SGirish Moodalbail i = atoi(buf); 7986e91bba0SGirish Moodalbail assert(i < 3); 7996e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", 8006e91bba0SGirish Moodalbail ecn_sack_vals[i]); 8016e91bba0SGirish Moodalbail } 8026e91bba0SGirish Moodalbail break; 8036e91bba0SGirish Moodalbail default: 8046e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 8056e91bba0SGirish Moodalbail } 8066e91bba0SGirish Moodalbail if (nbytes >= *bufsize) { 8076e91bba0SGirish Moodalbail /* insufficient buffer space */ 8086e91bba0SGirish Moodalbail *bufsize = nbytes + 1; 8096e91bba0SGirish Moodalbail return (IPADM_NO_BUFS); 8106e91bba0SGirish Moodalbail } 8116e91bba0SGirish Moodalbail 8126e91bba0SGirish Moodalbail return (status); 8136e91bba0SGirish Moodalbail } 8146e91bba0SGirish Moodalbail 8156e91bba0SGirish Moodalbail /* ARGSUSED */ 8166e91bba0SGirish Moodalbail static ipadm_status_t 8176e91bba0SGirish Moodalbail i_ipadm_get_forwarding(ipadm_handle_t iph, const void *arg, 8186e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 8196e91bba0SGirish Moodalbail uint_t valtype) 8206e91bba0SGirish Moodalbail { 8216e91bba0SGirish Moodalbail const char *ifname = arg; 8226e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 8236e91bba0SGirish Moodalbail 8246e91bba0SGirish Moodalbail /* 8256e91bba0SGirish Moodalbail * if interface name is provided, then get forwarding status using 8266e91bba0SGirish Moodalbail * SIOCGLIFFLAGS 8276e91bba0SGirish Moodalbail */ 8286e91bba0SGirish Moodalbail if (ifname != NULL) { 8296e91bba0SGirish Moodalbail status = i_ipadm_get_ifprop_flags(iph, ifname, pdp, 8306e91bba0SGirish Moodalbail buf, bufsize, pdp->ipd_proto, valtype); 8316e91bba0SGirish Moodalbail } else { 8326e91bba0SGirish Moodalbail status = i_ipadm_get_prop(iph, ifname, pdp, buf, 8336e91bba0SGirish Moodalbail bufsize, proto, valtype); 8346e91bba0SGirish Moodalbail /* 8356e91bba0SGirish Moodalbail * If IPH_LEGACY is set, do not convert the value returned 8366e91bba0SGirish Moodalbail * from kernel, 8376e91bba0SGirish Moodalbail */ 8386e91bba0SGirish Moodalbail if (iph->iph_flags & IPH_LEGACY) 8396e91bba0SGirish Moodalbail goto ret; 8406e91bba0SGirish Moodalbail if (status == IPADM_SUCCESS && (valtype == MOD_PROP_ACTIVE || 8416e91bba0SGirish Moodalbail valtype == MOD_PROP_DEFAULT)) { 8426e91bba0SGirish Moodalbail uint_t val = atoi(buf); 8436e91bba0SGirish Moodalbail 8446e91bba0SGirish Moodalbail (void) snprintf(buf, *bufsize, 8456e91bba0SGirish Moodalbail (val == 1 ? IPADM_ONSTR : IPADM_OFFSTR)); 8466e91bba0SGirish Moodalbail } 8476e91bba0SGirish Moodalbail } 8486e91bba0SGirish Moodalbail 8496e91bba0SGirish Moodalbail ret: 8506e91bba0SGirish Moodalbail return (status); 8516e91bba0SGirish Moodalbail } 8526e91bba0SGirish Moodalbail 8536e91bba0SGirish Moodalbail /* ARGSUSED */ 8546e91bba0SGirish Moodalbail static ipadm_status_t 8556e91bba0SGirish Moodalbail i_ipadm_get_mtu(ipadm_handle_t iph, const void *arg, 8566e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 8576e91bba0SGirish Moodalbail uint_t valtype) 8586e91bba0SGirish Moodalbail { 8596e91bba0SGirish Moodalbail struct lifreq lifr; 8606e91bba0SGirish Moodalbail const char *ifname = arg; 8616e91bba0SGirish Moodalbail size_t nbytes; 8626e91bba0SGirish Moodalbail int s; 8636e91bba0SGirish Moodalbail 8646e91bba0SGirish Moodalbail switch (valtype) { 8656e91bba0SGirish Moodalbail case MOD_PROP_PERM: 8666e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%d", MOD_PROP_PERM_RW); 8676e91bba0SGirish Moodalbail break; 8686e91bba0SGirish Moodalbail case MOD_PROP_DEFAULT: 8696e91bba0SGirish Moodalbail case MOD_PROP_POSSIBLE: 8706e91bba0SGirish Moodalbail return (i_ipadm_get_prop(iph, arg, pdp, buf, bufsize, 8716e91bba0SGirish Moodalbail proto, valtype)); 8726e91bba0SGirish Moodalbail case MOD_PROP_ACTIVE: 8736e91bba0SGirish Moodalbail bzero(&lifr, sizeof (lifr)); 8746e91bba0SGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 8756e91bba0SGirish Moodalbail s = (proto == MOD_PROTO_IPV6 ? iph->iph_sock6 : iph->iph_sock); 8766e91bba0SGirish Moodalbail 8776e91bba0SGirish Moodalbail if (ioctl(s, SIOCGLIFMTU, (caddr_t)&lifr) < 0) 8786e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 8796e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%u", lifr.lifr_mtu); 8806e91bba0SGirish Moodalbail break; 8816e91bba0SGirish Moodalbail default: 8826e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 8836e91bba0SGirish Moodalbail } 8846e91bba0SGirish Moodalbail if (nbytes >= *bufsize) { 8856e91bba0SGirish Moodalbail /* insufficient buffer space */ 8866e91bba0SGirish Moodalbail *bufsize = nbytes + 1; 8876e91bba0SGirish Moodalbail return (IPADM_NO_BUFS); 8886e91bba0SGirish Moodalbail } 8896e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 8906e91bba0SGirish Moodalbail } 8916e91bba0SGirish Moodalbail 8926e91bba0SGirish Moodalbail /* ARGSUSED */ 8936e91bba0SGirish Moodalbail static ipadm_status_t 8946e91bba0SGirish Moodalbail i_ipadm_get_metric(ipadm_handle_t iph, const void *arg, 8956e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 8966e91bba0SGirish Moodalbail uint_t valtype) 8976e91bba0SGirish Moodalbail { 8986e91bba0SGirish Moodalbail struct lifreq lifr; 8996e91bba0SGirish Moodalbail const char *ifname = arg; 9006e91bba0SGirish Moodalbail size_t nbytes; 9016e91bba0SGirish Moodalbail int s, val; 9026e91bba0SGirish Moodalbail 9036e91bba0SGirish Moodalbail switch (valtype) { 9046e91bba0SGirish Moodalbail case MOD_PROP_PERM: 9056e91bba0SGirish Moodalbail val = MOD_PROP_PERM_RW; 9066e91bba0SGirish Moodalbail break; 9076e91bba0SGirish Moodalbail case MOD_PROP_DEFAULT: 9086e91bba0SGirish Moodalbail val = DEF_METRIC_VAL; 9096e91bba0SGirish Moodalbail break; 9106e91bba0SGirish Moodalbail case MOD_PROP_ACTIVE: 9116e91bba0SGirish Moodalbail bzero(&lifr, sizeof (lifr)); 9126e91bba0SGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 9136e91bba0SGirish Moodalbail 9146e91bba0SGirish Moodalbail s = (proto == MOD_PROTO_IPV6 ? iph->iph_sock6 : iph->iph_sock); 9156e91bba0SGirish Moodalbail if (ioctl(s, SIOCGLIFMETRIC, (caddr_t)&lifr) < 0) 9166e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 9176e91bba0SGirish Moodalbail val = lifr.lifr_metric; 9186e91bba0SGirish Moodalbail break; 9196e91bba0SGirish Moodalbail default: 9206e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 9216e91bba0SGirish Moodalbail } 9226e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%d", val); 9236e91bba0SGirish Moodalbail if (nbytes >= *bufsize) { 9246e91bba0SGirish Moodalbail /* insufficient buffer space */ 9256e91bba0SGirish Moodalbail *bufsize = nbytes + 1; 9266e91bba0SGirish Moodalbail return (IPADM_NO_BUFS); 9276e91bba0SGirish Moodalbail } 9286e91bba0SGirish Moodalbail 9296e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 9306e91bba0SGirish Moodalbail } 9316e91bba0SGirish Moodalbail 9326e91bba0SGirish Moodalbail /* ARGSUSED */ 9336e91bba0SGirish Moodalbail static ipadm_status_t 9346e91bba0SGirish Moodalbail i_ipadm_get_usesrc(ipadm_handle_t iph, const void *arg, 9356e91bba0SGirish Moodalbail ipadm_prop_desc_t *ipd, char *buf, uint_t *bufsize, uint_t proto, 9366e91bba0SGirish Moodalbail uint_t valtype) 9376e91bba0SGirish Moodalbail { 9386e91bba0SGirish Moodalbail struct lifreq lifr; 9396e91bba0SGirish Moodalbail const char *ifname = arg; 9406e91bba0SGirish Moodalbail int s; 9416e91bba0SGirish Moodalbail char if_name[IF_NAMESIZE]; 9426e91bba0SGirish Moodalbail size_t nbytes; 9436e91bba0SGirish Moodalbail 9446e91bba0SGirish Moodalbail switch (valtype) { 9456e91bba0SGirish Moodalbail case MOD_PROP_PERM: 9466e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%d", MOD_PROP_PERM_RW); 9476e91bba0SGirish Moodalbail break; 9486e91bba0SGirish Moodalbail case MOD_PROP_DEFAULT: 9496e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", IPADM_NONESTR); 9506e91bba0SGirish Moodalbail break; 9516e91bba0SGirish Moodalbail case MOD_PROP_ACTIVE: 9526e91bba0SGirish Moodalbail bzero(&lifr, sizeof (lifr)); 9536e91bba0SGirish Moodalbail (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 9546e91bba0SGirish Moodalbail 9556e91bba0SGirish Moodalbail s = (proto == MOD_PROTO_IPV6 ? iph->iph_sock6 : iph->iph_sock); 9566e91bba0SGirish Moodalbail if (ioctl(s, SIOCGLIFUSESRC, (caddr_t)&lifr) < 0) 9576e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 9586e91bba0SGirish Moodalbail if (lifr.lifr_index == 0) { 9596e91bba0SGirish Moodalbail /* no src address was set, so print 'none' */ 9606e91bba0SGirish Moodalbail (void) strlcpy(if_name, IPADM_NONESTR, 9616e91bba0SGirish Moodalbail sizeof (if_name)); 9626e91bba0SGirish Moodalbail } else if (if_indextoname(lifr.lifr_index, if_name) == NULL) { 9636e91bba0SGirish Moodalbail return (ipadm_errno2status(errno)); 9646e91bba0SGirish Moodalbail } 9656e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", if_name); 9666e91bba0SGirish Moodalbail break; 9676e91bba0SGirish Moodalbail default: 9686e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 9696e91bba0SGirish Moodalbail } 9706e91bba0SGirish Moodalbail if (nbytes >= *bufsize) { 9716e91bba0SGirish Moodalbail /* insufficient buffer space */ 9726e91bba0SGirish Moodalbail *bufsize = nbytes + 1; 9736e91bba0SGirish Moodalbail return (IPADM_NO_BUFS); 9746e91bba0SGirish Moodalbail } 9756e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 9766e91bba0SGirish Moodalbail } 9776e91bba0SGirish Moodalbail 9786e91bba0SGirish Moodalbail /* ARGSUSED */ 9796e91bba0SGirish Moodalbail static ipadm_status_t 9806e91bba0SGirish Moodalbail i_ipadm_get_ifprop_flags(ipadm_handle_t iph, const void *arg, 9816e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 9826e91bba0SGirish Moodalbail uint_t valtype) 9836e91bba0SGirish Moodalbail { 9846e91bba0SGirish Moodalbail uint64_t intf_flags; 9856e91bba0SGirish Moodalbail char *val; 9866e91bba0SGirish Moodalbail size_t nbytes; 9876e91bba0SGirish Moodalbail const char *ifname = arg; 9886e91bba0SGirish Moodalbail sa_family_t af; 9896e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 9906e91bba0SGirish Moodalbail 9916e91bba0SGirish Moodalbail switch (valtype) { 9926e91bba0SGirish Moodalbail case MOD_PROP_PERM: 9936e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%d", MOD_PROP_PERM_RW); 9946e91bba0SGirish Moodalbail break; 9956e91bba0SGirish Moodalbail case MOD_PROP_DEFAULT: 9966e91bba0SGirish Moodalbail if (strcmp(pdp->ipd_name, "exchange_routes") == 0 || 9976e91bba0SGirish Moodalbail strcmp(pdp->ipd_name, "arp") == 0 || 9986e91bba0SGirish Moodalbail strcmp(pdp->ipd_name, "nud") == 0) { 9996e91bba0SGirish Moodalbail val = IPADM_ONSTR; 10006e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "forwarding") == 0) { 10016e91bba0SGirish Moodalbail val = IPADM_OFFSTR; 10026e91bba0SGirish Moodalbail } else { 10036e91bba0SGirish Moodalbail return (IPADM_PROP_UNKNOWN); 10046e91bba0SGirish Moodalbail } 10056e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", val); 10066e91bba0SGirish Moodalbail break; 10076e91bba0SGirish Moodalbail case MOD_PROP_ACTIVE: 10086e91bba0SGirish Moodalbail af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET); 10096e91bba0SGirish Moodalbail status = i_ipadm_get_flags(iph, ifname, af, &intf_flags); 10106e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 10116e91bba0SGirish Moodalbail return (status); 10126e91bba0SGirish Moodalbail 10136e91bba0SGirish Moodalbail val = IPADM_OFFSTR; 10146e91bba0SGirish Moodalbail if (strcmp(pdp->ipd_name, "exchange_routes") == 0) { 10156e91bba0SGirish Moodalbail if (!(intf_flags & IFF_NORTEXCH)) 10166e91bba0SGirish Moodalbail val = IPADM_ONSTR; 10176e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "forwarding") == 0) { 10186e91bba0SGirish Moodalbail if (intf_flags & IFF_ROUTER) 10196e91bba0SGirish Moodalbail val = IPADM_ONSTR; 10206e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "arp") == 0) { 10216e91bba0SGirish Moodalbail if (!(intf_flags & IFF_NOARP)) 10226e91bba0SGirish Moodalbail val = IPADM_ONSTR; 10236e91bba0SGirish Moodalbail } else if (strcmp(pdp->ipd_name, "nud") == 0) { 10246e91bba0SGirish Moodalbail if (!(intf_flags & IFF_NONUD)) 10256e91bba0SGirish Moodalbail val = IPADM_ONSTR; 10266e91bba0SGirish Moodalbail } 10276e91bba0SGirish Moodalbail nbytes = snprintf(buf, *bufsize, "%s", val); 10286e91bba0SGirish Moodalbail break; 10296e91bba0SGirish Moodalbail default: 10306e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 10316e91bba0SGirish Moodalbail } 10326e91bba0SGirish Moodalbail if (nbytes >= *bufsize) { 10336e91bba0SGirish Moodalbail /* insufficient buffer space */ 10346e91bba0SGirish Moodalbail *bufsize = nbytes + 1; 10356e91bba0SGirish Moodalbail status = IPADM_NO_BUFS; 10366e91bba0SGirish Moodalbail } 10376e91bba0SGirish Moodalbail 10386e91bba0SGirish Moodalbail return (status); 10396e91bba0SGirish Moodalbail } 10406e91bba0SGirish Moodalbail 10416e91bba0SGirish Moodalbail static void 10426e91bba0SGirish Moodalbail i_ipadm_perm2str(char *buf, uint_t *bufsize) 10436e91bba0SGirish Moodalbail { 10446e91bba0SGirish Moodalbail uint_t perm = atoi(buf); 10456e91bba0SGirish Moodalbail 10466e91bba0SGirish Moodalbail (void) snprintf(buf, *bufsize, "%c%c", 10476e91bba0SGirish Moodalbail ((perm & MOD_PROP_PERM_READ) != 0) ? 'r' : '-', 10486e91bba0SGirish Moodalbail ((perm & MOD_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 10496e91bba0SGirish Moodalbail } 10506e91bba0SGirish Moodalbail 10516e91bba0SGirish Moodalbail /* ARGSUSED */ 10526e91bba0SGirish Moodalbail static ipadm_status_t 10536e91bba0SGirish Moodalbail i_ipadm_get_prop(ipadm_handle_t iph, const void *arg, 10546e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto, 10556e91bba0SGirish Moodalbail uint_t valtype) 10566e91bba0SGirish Moodalbail { 10576e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 10586e91bba0SGirish Moodalbail const char *ifname = arg; 10596e91bba0SGirish Moodalbail mod_ioc_prop_t *mip; 10606e91bba0SGirish Moodalbail char *pname = pdp->ipd_name; 10616e91bba0SGirish Moodalbail uint_t iocsize; 10626e91bba0SGirish Moodalbail 10636e91bba0SGirish Moodalbail /* allocate sufficient ioctl buffer to retrieve value */ 10646e91bba0SGirish Moodalbail iocsize = sizeof (mod_ioc_prop_t) + *bufsize - 1; 10656e91bba0SGirish Moodalbail if ((mip = calloc(1, iocsize)) == NULL) 10666e91bba0SGirish Moodalbail return (IPADM_NO_BUFS); 10676e91bba0SGirish Moodalbail 10686e91bba0SGirish Moodalbail mip->mpr_version = MOD_PROP_VERSION; 10696e91bba0SGirish Moodalbail mip->mpr_flags = valtype; 10706e91bba0SGirish Moodalbail mip->mpr_proto = proto; 10716e91bba0SGirish Moodalbail if (ifname != NULL) { 10726e91bba0SGirish Moodalbail (void) strlcpy(mip->mpr_ifname, ifname, 10736e91bba0SGirish Moodalbail sizeof (mip->mpr_ifname)); 10746e91bba0SGirish Moodalbail } 10756e91bba0SGirish Moodalbail (void) strlcpy(mip->mpr_name, pname, sizeof (mip->mpr_name)); 10766e91bba0SGirish Moodalbail mip->mpr_valsize = *bufsize; 10776e91bba0SGirish Moodalbail 10786e91bba0SGirish Moodalbail if (i_ipadm_strioctl(iph->iph_sock, SIOCGETPROP, (char *)mip, 10796e91bba0SGirish Moodalbail iocsize) < 0) { 10806e91bba0SGirish Moodalbail if (errno == ENOENT) 10816e91bba0SGirish Moodalbail status = IPADM_PROP_UNKNOWN; 10826e91bba0SGirish Moodalbail else 10836e91bba0SGirish Moodalbail status = ipadm_errno2status(errno); 10846e91bba0SGirish Moodalbail } else { 10856e91bba0SGirish Moodalbail bcopy(mip->mpr_val, buf, *bufsize); 10866e91bba0SGirish Moodalbail } 10876e91bba0SGirish Moodalbail 10886e91bba0SGirish Moodalbail free(mip); 10896e91bba0SGirish Moodalbail return (status); 10906e91bba0SGirish Moodalbail } 10916e91bba0SGirish Moodalbail 10926e91bba0SGirish Moodalbail /* 10938887b57dSGirish Moodalbail * Populates the ipmgmt_prop_arg_t based on the class of property. 10948887b57dSGirish Moodalbail * 10958887b57dSGirish Moodalbail * For private protocol properties, while persisting information in ipadm 10968887b57dSGirish Moodalbail * data store, to ensure there is no collision of namespace between ipadm 10978887b57dSGirish Moodalbail * private nvpair names (which also starts with '_', see ipadm_ipmgmt.h) 10988887b57dSGirish Moodalbail * and private protocol property names, we will prepend IPADM_PRIV_PROP_PREFIX 10998887b57dSGirish Moodalbail * to property names. 11006e91bba0SGirish Moodalbail */ 11016e91bba0SGirish Moodalbail static void 11026e91bba0SGirish Moodalbail i_ipadm_populate_proparg(ipmgmt_prop_arg_t *pargp, ipadm_prop_desc_t *pdp, 11036e91bba0SGirish Moodalbail const char *pval, const void *object) 11046e91bba0SGirish Moodalbail { 11056e91bba0SGirish Moodalbail const struct ipadm_addrobj_s *ipaddr; 11066e91bba0SGirish Moodalbail uint_t class = pdp->ipd_class; 11076e91bba0SGirish Moodalbail uint_t proto = pdp->ipd_proto; 11086e91bba0SGirish Moodalbail 11096e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_pname, pdp->ipd_name, 11106e91bba0SGirish Moodalbail sizeof (pargp->ia_pname)); 11116e91bba0SGirish Moodalbail if (pval != NULL) 11126e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_pval, pval, sizeof (pargp->ia_pval)); 11136e91bba0SGirish Moodalbail 11146e91bba0SGirish Moodalbail switch (class) { 11156e91bba0SGirish Moodalbail case IPADMPROP_CLASS_MODULE: 11168887b57dSGirish Moodalbail /* if it's a private property then add the prefix. */ 11178887b57dSGirish Moodalbail if (pdp->ipd_name[0] == '_') { 11188887b57dSGirish Moodalbail (void) snprintf(pargp->ia_pname, 11198887b57dSGirish Moodalbail sizeof (pargp->ia_pname), "_%s", pdp->ipd_name); 11208887b57dSGirish Moodalbail } 11216e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_module, object, 11226e91bba0SGirish Moodalbail sizeof (pargp->ia_module)); 11236e91bba0SGirish Moodalbail break; 11246e91bba0SGirish Moodalbail case IPADMPROP_CLASS_MODIF: 11256e91bba0SGirish Moodalbail /* check if object is protostr or an ifname */ 11266e91bba0SGirish Moodalbail if (ipadm_str2proto(object) != MOD_PROTO_NONE) { 11276e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_module, object, 11286e91bba0SGirish Moodalbail sizeof (pargp->ia_module)); 11296e91bba0SGirish Moodalbail break; 11306e91bba0SGirish Moodalbail } 11316e91bba0SGirish Moodalbail /* it's an interface property, fall through */ 11326e91bba0SGirish Moodalbail /* FALLTHRU */ 11336e91bba0SGirish Moodalbail case IPADMPROP_CLASS_IF: 11346e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_ifname, object, 11356e91bba0SGirish Moodalbail sizeof (pargp->ia_ifname)); 11366e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_module, ipadm_proto2str(proto), 11376e91bba0SGirish Moodalbail sizeof (pargp->ia_module)); 11386e91bba0SGirish Moodalbail break; 11396e91bba0SGirish Moodalbail case IPADMPROP_CLASS_ADDR: 11406e91bba0SGirish Moodalbail ipaddr = object; 11416e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_ifname, ipaddr->ipadm_ifname, 11426e91bba0SGirish Moodalbail sizeof (pargp->ia_ifname)); 11436e91bba0SGirish Moodalbail (void) strlcpy(pargp->ia_aobjname, ipaddr->ipadm_aobjname, 11446e91bba0SGirish Moodalbail sizeof (pargp->ia_aobjname)); 11456e91bba0SGirish Moodalbail break; 11466e91bba0SGirish Moodalbail } 11476e91bba0SGirish Moodalbail } 11486e91bba0SGirish Moodalbail 11496e91bba0SGirish Moodalbail /* 11506e91bba0SGirish Moodalbail * Common function to retrieve property value for a given interface `ifname' or 11516e91bba0SGirish Moodalbail * for a given protocol `proto'. The property name is in `pname'. 11526e91bba0SGirish Moodalbail * 11536e91bba0SGirish Moodalbail * `valtype' determines the type of value that will be retrieved. 11546e91bba0SGirish Moodalbail * IPADM_OPT_ACTIVE - current value of the property (active config) 11556e91bba0SGirish Moodalbail * IPADM_OPT_PERSIST - value of the property from persistent store 11566e91bba0SGirish Moodalbail * IPADM_OPT_DEFAULT - default hard coded value (boot-time value) 11576e91bba0SGirish Moodalbail * IPADM_OPT_PERM - read/write permissions for the value 11586e91bba0SGirish Moodalbail * IPADM_OPT_POSSIBLE - range of values 11596e91bba0SGirish Moodalbail */ 11606e91bba0SGirish Moodalbail static ipadm_status_t 11616e91bba0SGirish Moodalbail i_ipadm_getprop_common(ipadm_handle_t iph, const char *ifname, 11626e91bba0SGirish Moodalbail const char *pname, char *buf, uint_t *bufsize, uint_t proto, 11636e91bba0SGirish Moodalbail uint_t valtype) 11646e91bba0SGirish Moodalbail { 11656e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 11668887b57dSGirish Moodalbail ipadm_prop_desc_t *pdp; 11676e91bba0SGirish Moodalbail char priv_propname[MAXPROPNAMELEN]; 11686e91bba0SGirish Moodalbail boolean_t is_if = (ifname != NULL); 11698887b57dSGirish Moodalbail int err = 0; 11706e91bba0SGirish Moodalbail 11718887b57dSGirish Moodalbail pdp = i_ipadm_get_prop_desc(pname, proto, &err); 11728887b57dSGirish Moodalbail if (err == EPROTO) 11738887b57dSGirish Moodalbail return (IPADM_BAD_PROTOCOL); 11748887b57dSGirish Moodalbail /* there are no private interface properties */ 11758887b57dSGirish Moodalbail if (is_if && err == ENOENT) 11768887b57dSGirish Moodalbail return (IPADM_PROP_UNKNOWN); 11776e91bba0SGirish Moodalbail 11788887b57dSGirish Moodalbail if (pdp != NULL) { 11796e91bba0SGirish Moodalbail /* 11806e91bba0SGirish Moodalbail * check whether the property can be 11816e91bba0SGirish Moodalbail * applied on an interface 11826e91bba0SGirish Moodalbail */ 11836e91bba0SGirish Moodalbail if (is_if && !(pdp->ipd_class & IPADMPROP_CLASS_IF)) 11846e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 11856e91bba0SGirish Moodalbail /* 11866e91bba0SGirish Moodalbail * check whether the property can be 11876e91bba0SGirish Moodalbail * applied on a module 11886e91bba0SGirish Moodalbail */ 11896e91bba0SGirish Moodalbail if (!is_if && !(pdp->ipd_class & IPADMPROP_CLASS_MODULE)) 11906e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 11916e91bba0SGirish Moodalbail 11926e91bba0SGirish Moodalbail } else { 11936e91bba0SGirish Moodalbail /* private protocol properties, pass it to kernel directly */ 11946e91bba0SGirish Moodalbail pdp = &ipadm_privprop; 11956e91bba0SGirish Moodalbail (void) strlcpy(priv_propname, pname, sizeof (priv_propname)); 11966e91bba0SGirish Moodalbail pdp->ipd_name = priv_propname; 11976e91bba0SGirish Moodalbail } 11986e91bba0SGirish Moodalbail 11996e91bba0SGirish Moodalbail switch (valtype) { 12006e91bba0SGirish Moodalbail case IPADM_OPT_PERM: 12016e91bba0SGirish Moodalbail status = pdp->ipd_get(iph, ifname, pdp, buf, bufsize, proto, 12026e91bba0SGirish Moodalbail MOD_PROP_PERM); 12036e91bba0SGirish Moodalbail if (status == IPADM_SUCCESS) 12046e91bba0SGirish Moodalbail i_ipadm_perm2str(buf, bufsize); 12056e91bba0SGirish Moodalbail break; 12066e91bba0SGirish Moodalbail case IPADM_OPT_ACTIVE: 12076e91bba0SGirish Moodalbail status = pdp->ipd_get(iph, ifname, pdp, buf, bufsize, proto, 12086e91bba0SGirish Moodalbail MOD_PROP_ACTIVE); 12096e91bba0SGirish Moodalbail break; 12106e91bba0SGirish Moodalbail case IPADM_OPT_DEFAULT: 12116e91bba0SGirish Moodalbail status = pdp->ipd_get(iph, ifname, pdp, buf, bufsize, proto, 12126e91bba0SGirish Moodalbail MOD_PROP_DEFAULT); 12136e91bba0SGirish Moodalbail break; 12146e91bba0SGirish Moodalbail case IPADM_OPT_POSSIBLE: 12156e91bba0SGirish Moodalbail if (pdp->ipd_get_range != NULL) { 12166e91bba0SGirish Moodalbail status = pdp->ipd_get_range(iph, ifname, pdp, buf, 12176e91bba0SGirish Moodalbail bufsize, proto, MOD_PROP_POSSIBLE); 12186e91bba0SGirish Moodalbail break; 12196e91bba0SGirish Moodalbail } 12206e91bba0SGirish Moodalbail buf[0] = '\0'; 12216e91bba0SGirish Moodalbail break; 12226e91bba0SGirish Moodalbail case IPADM_OPT_PERSIST: 12236e91bba0SGirish Moodalbail /* retrieve from database */ 12246e91bba0SGirish Moodalbail if (is_if) 12256e91bba0SGirish Moodalbail status = i_ipadm_get_persist_propval(iph, pdp, buf, 12266e91bba0SGirish Moodalbail bufsize, ifname); 12276e91bba0SGirish Moodalbail else 12286e91bba0SGirish Moodalbail status = i_ipadm_get_persist_propval(iph, pdp, buf, 12296e91bba0SGirish Moodalbail bufsize, ipadm_proto2str(proto)); 12306e91bba0SGirish Moodalbail break; 12316e91bba0SGirish Moodalbail default: 12326e91bba0SGirish Moodalbail status = IPADM_INVALID_ARG; 12336e91bba0SGirish Moodalbail break; 12346e91bba0SGirish Moodalbail } 12356e91bba0SGirish Moodalbail return (status); 12366e91bba0SGirish Moodalbail } 12376e91bba0SGirish Moodalbail 12386e91bba0SGirish Moodalbail /* 12396e91bba0SGirish Moodalbail * Get protocol property of the specified protocol. 12406e91bba0SGirish Moodalbail */ 12416e91bba0SGirish Moodalbail ipadm_status_t 12426e91bba0SGirish Moodalbail ipadm_get_prop(ipadm_handle_t iph, const char *pname, char *buf, 12436e91bba0SGirish Moodalbail uint_t *bufsize, uint_t proto, uint_t valtype) 12446e91bba0SGirish Moodalbail { 12456e91bba0SGirish Moodalbail /* 12466e91bba0SGirish Moodalbail * validate the arguments of the function. 12476e91bba0SGirish Moodalbail */ 12486e91bba0SGirish Moodalbail if (iph == NULL || pname == NULL || buf == NULL || 12496e91bba0SGirish Moodalbail bufsize == NULL || *bufsize == 0) { 12506e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 12516e91bba0SGirish Moodalbail } 12526e91bba0SGirish Moodalbail /* 12536e91bba0SGirish Moodalbail * Do we support this proto, if not return error. 12546e91bba0SGirish Moodalbail */ 12556e91bba0SGirish Moodalbail if (ipadm_proto2str(proto) == NULL) 12566e91bba0SGirish Moodalbail return (IPADM_NOTSUP); 12576e91bba0SGirish Moodalbail 12586e91bba0SGirish Moodalbail return (i_ipadm_getprop_common(iph, NULL, pname, buf, bufsize, 12596e91bba0SGirish Moodalbail proto, valtype)); 12606e91bba0SGirish Moodalbail } 12616e91bba0SGirish Moodalbail 12626e91bba0SGirish Moodalbail /* 12636e91bba0SGirish Moodalbail * Get interface property of the specified interface. 12646e91bba0SGirish Moodalbail */ 12656e91bba0SGirish Moodalbail ipadm_status_t 12666e91bba0SGirish Moodalbail ipadm_get_ifprop(ipadm_handle_t iph, const char *ifname, const char *pname, 12676e91bba0SGirish Moodalbail char *buf, uint_t *bufsize, uint_t proto, uint_t valtype) 12686e91bba0SGirish Moodalbail { 12696e91bba0SGirish Moodalbail /* validate the arguments of the function. */ 12706e91bba0SGirish Moodalbail if (iph == NULL || pname == NULL || buf == NULL || 12716e91bba0SGirish Moodalbail bufsize == NULL || *bufsize == 0) { 12726e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 12736e91bba0SGirish Moodalbail } 12746e91bba0SGirish Moodalbail 12756e91bba0SGirish Moodalbail /* Do we support this proto, if not return error. */ 12766e91bba0SGirish Moodalbail if (ipadm_proto2str(proto) == NULL) 12776e91bba0SGirish Moodalbail return (IPADM_NOTSUP); 12786e91bba0SGirish Moodalbail 12796e91bba0SGirish Moodalbail /* 12806e91bba0SGirish Moodalbail * check if interface name is provided for interface property and 12816e91bba0SGirish Moodalbail * is valid. 12826e91bba0SGirish Moodalbail */ 12836e91bba0SGirish Moodalbail if (!i_ipadm_validate_ifname(iph, ifname)) 12846e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 12856e91bba0SGirish Moodalbail 12866e91bba0SGirish Moodalbail return (i_ipadm_getprop_common(iph, ifname, pname, buf, bufsize, 12876e91bba0SGirish Moodalbail proto, valtype)); 12886e91bba0SGirish Moodalbail } 12896e91bba0SGirish Moodalbail 12906e91bba0SGirish Moodalbail /* 12916e91bba0SGirish Moodalbail * Allocates sufficient ioctl buffers and copies property name and the 12926e91bba0SGirish Moodalbail * value, among other things. If the flag IPADM_OPT_DEFAULT is set, then 12936e91bba0SGirish Moodalbail * `pval' will be NULL and it instructs the kernel to reset the current 12946e91bba0SGirish Moodalbail * value to property's default value. 12956e91bba0SGirish Moodalbail */ 12966e91bba0SGirish Moodalbail static ipadm_status_t 12976e91bba0SGirish Moodalbail i_ipadm_set_prop(ipadm_handle_t iph, const void *arg, 12986e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags) 12996e91bba0SGirish Moodalbail { 13006e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 13016e91bba0SGirish Moodalbail const char *ifname = arg; 13026e91bba0SGirish Moodalbail mod_ioc_prop_t *mip; 13036e91bba0SGirish Moodalbail char *pname = pdp->ipd_name; 13046e91bba0SGirish Moodalbail uint_t valsize, iocsize; 13056e91bba0SGirish Moodalbail uint_t iocflags = 0; 13066e91bba0SGirish Moodalbail 13076e91bba0SGirish Moodalbail if (flags & IPADM_OPT_DEFAULT) { 13086e91bba0SGirish Moodalbail iocflags |= MOD_PROP_DEFAULT; 13096e91bba0SGirish Moodalbail } else if (flags & IPADM_OPT_ACTIVE) { 13106e91bba0SGirish Moodalbail iocflags |= MOD_PROP_ACTIVE; 13116e91bba0SGirish Moodalbail if (flags & IPADM_OPT_APPEND) 13126e91bba0SGirish Moodalbail iocflags |= MOD_PROP_APPEND; 13136e91bba0SGirish Moodalbail else if (flags & IPADM_OPT_REMOVE) 13146e91bba0SGirish Moodalbail iocflags |= MOD_PROP_REMOVE; 13156e91bba0SGirish Moodalbail } 13166e91bba0SGirish Moodalbail 13176e91bba0SGirish Moodalbail if (pval != NULL) { 13186e91bba0SGirish Moodalbail valsize = strlen(pval); 13196e91bba0SGirish Moodalbail iocsize = sizeof (mod_ioc_prop_t) + valsize - 1; 13206e91bba0SGirish Moodalbail } else { 13216e91bba0SGirish Moodalbail valsize = 0; 13226e91bba0SGirish Moodalbail iocsize = sizeof (mod_ioc_prop_t); 13236e91bba0SGirish Moodalbail } 13246e91bba0SGirish Moodalbail 13256e91bba0SGirish Moodalbail if ((mip = calloc(1, iocsize)) == NULL) 13266e91bba0SGirish Moodalbail return (IPADM_NO_BUFS); 13276e91bba0SGirish Moodalbail 13286e91bba0SGirish Moodalbail mip->mpr_version = MOD_PROP_VERSION; 13296e91bba0SGirish Moodalbail mip->mpr_flags = iocflags; 13306e91bba0SGirish Moodalbail mip->mpr_proto = proto; 13316e91bba0SGirish Moodalbail if (ifname != NULL) { 13326e91bba0SGirish Moodalbail (void) strlcpy(mip->mpr_ifname, ifname, 13336e91bba0SGirish Moodalbail sizeof (mip->mpr_ifname)); 13346e91bba0SGirish Moodalbail } 13356e91bba0SGirish Moodalbail 13366e91bba0SGirish Moodalbail (void) strlcpy(mip->mpr_name, pname, sizeof (mip->mpr_name)); 13376e91bba0SGirish Moodalbail mip->mpr_valsize = valsize; 13386e91bba0SGirish Moodalbail if (pval != NULL) 13396e91bba0SGirish Moodalbail bcopy(pval, mip->mpr_val, valsize); 13406e91bba0SGirish Moodalbail 13416e91bba0SGirish Moodalbail if (i_ipadm_strioctl(iph->iph_sock, SIOCSETPROP, (char *)mip, 13426e91bba0SGirish Moodalbail iocsize) < 0) { 13436e91bba0SGirish Moodalbail if (errno == ENOENT) 13446e91bba0SGirish Moodalbail status = IPADM_PROP_UNKNOWN; 13456e91bba0SGirish Moodalbail else 13466e91bba0SGirish Moodalbail status = ipadm_errno2status(errno); 13476e91bba0SGirish Moodalbail } 13486e91bba0SGirish Moodalbail free(mip); 13496e91bba0SGirish Moodalbail return (status); 13506e91bba0SGirish Moodalbail } 13516e91bba0SGirish Moodalbail 13526e91bba0SGirish Moodalbail /* 13536e91bba0SGirish Moodalbail * Common function for modifying both protocol/interface property. 13546e91bba0SGirish Moodalbail * 13556e91bba0SGirish Moodalbail * If: 13566e91bba0SGirish Moodalbail * IPADM_OPT_PERSIST is set then the value is persisted. 13576e91bba0SGirish Moodalbail * IPADM_OPT_DEFAULT is set then the default value for the property will 13586e91bba0SGirish Moodalbail * be applied. 13596e91bba0SGirish Moodalbail */ 13606e91bba0SGirish Moodalbail static ipadm_status_t 13616e91bba0SGirish Moodalbail i_ipadm_setprop_common(ipadm_handle_t iph, const char *ifname, 13626e91bba0SGirish Moodalbail const char *pname, const char *buf, uint_t proto, uint_t pflags) 13636e91bba0SGirish Moodalbail { 13646e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 13656e91bba0SGirish Moodalbail boolean_t persist = (pflags & IPADM_OPT_PERSIST); 13666e91bba0SGirish Moodalbail boolean_t reset = (pflags & IPADM_OPT_DEFAULT); 13678887b57dSGirish Moodalbail ipadm_prop_desc_t *pdp; 13686e91bba0SGirish Moodalbail boolean_t is_if = (ifname != NULL); 13696e91bba0SGirish Moodalbail char priv_propname[MAXPROPNAMELEN]; 13708887b57dSGirish Moodalbail int err = 0; 13716e91bba0SGirish Moodalbail 13726e91bba0SGirish Moodalbail /* Check that property value is within the allowed size */ 13736e91bba0SGirish Moodalbail if (!reset && strnlen(buf, MAXPROPVALLEN) >= MAXPROPVALLEN) 13746e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 13756e91bba0SGirish Moodalbail 13768887b57dSGirish Moodalbail pdp = i_ipadm_get_prop_desc(pname, proto, &err); 13778887b57dSGirish Moodalbail if (err == EPROTO) 13788887b57dSGirish Moodalbail return (IPADM_BAD_PROTOCOL); 13798887b57dSGirish Moodalbail /* there are no private interface properties */ 13808887b57dSGirish Moodalbail if (is_if && err == ENOENT) 13818887b57dSGirish Moodalbail return (IPADM_PROP_UNKNOWN); 13826e91bba0SGirish Moodalbail 13838887b57dSGirish Moodalbail if (pdp != NULL) { 13846e91bba0SGirish Moodalbail /* do some sanity checks */ 13856e91bba0SGirish Moodalbail if (is_if) { 13866e91bba0SGirish Moodalbail if (!(pdp->ipd_class & IPADMPROP_CLASS_IF)) 13876e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 13886e91bba0SGirish Moodalbail } else { 13896e91bba0SGirish Moodalbail if (!(pdp->ipd_class & IPADMPROP_CLASS_MODULE)) 13906e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 13916e91bba0SGirish Moodalbail } 13928b88711aSGirish Moodalbail /* 13938b88711aSGirish Moodalbail * if the property is not multi-valued and IPADM_OPT_APPEND or 13948b88711aSGirish Moodalbail * IPADM_OPT_REMOVE is specified, return IPADM_INVALID_ARG. 13958b88711aSGirish Moodalbail */ 13968b88711aSGirish Moodalbail if (!(pdp->ipd_flags & IPADMPROP_MULVAL) && (pflags & 13978b88711aSGirish Moodalbail (IPADM_OPT_APPEND|IPADM_OPT_REMOVE))) { 13988b88711aSGirish Moodalbail return (IPADM_INVALID_ARG); 13998b88711aSGirish Moodalbail } 14006e91bba0SGirish Moodalbail } else { 14018887b57dSGirish Moodalbail /* private protocol property, pass it to kernel directly */ 14026e91bba0SGirish Moodalbail pdp = &ipadm_privprop; 14036e91bba0SGirish Moodalbail (void) strlcpy(priv_propname, pname, sizeof (priv_propname)); 14046e91bba0SGirish Moodalbail pdp->ipd_name = priv_propname; 14056e91bba0SGirish Moodalbail } 14066e91bba0SGirish Moodalbail 14076e91bba0SGirish Moodalbail status = pdp->ipd_set(iph, ifname, pdp, buf, proto, pflags); 14086e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 14096e91bba0SGirish Moodalbail return (status); 14106e91bba0SGirish Moodalbail 14116e91bba0SGirish Moodalbail if (persist) { 14126e91bba0SGirish Moodalbail if (is_if) 14136e91bba0SGirish Moodalbail status = i_ipadm_persist_propval(iph, pdp, buf, ifname, 14146e91bba0SGirish Moodalbail pflags); 14156e91bba0SGirish Moodalbail else 14166e91bba0SGirish Moodalbail status = i_ipadm_persist_propval(iph, pdp, buf, 14176e91bba0SGirish Moodalbail ipadm_proto2str(proto), pflags); 14186e91bba0SGirish Moodalbail } 14196e91bba0SGirish Moodalbail return (status); 14206e91bba0SGirish Moodalbail } 14216e91bba0SGirish Moodalbail 14226e91bba0SGirish Moodalbail /* 14236e91bba0SGirish Moodalbail * Sets the property value of the specified interface 14246e91bba0SGirish Moodalbail */ 14256e91bba0SGirish Moodalbail ipadm_status_t 14266e91bba0SGirish Moodalbail ipadm_set_ifprop(ipadm_handle_t iph, const char *ifname, const char *pname, 14276e91bba0SGirish Moodalbail const char *buf, uint_t proto, uint_t pflags) 14286e91bba0SGirish Moodalbail { 14296e91bba0SGirish Moodalbail boolean_t reset = (pflags & IPADM_OPT_DEFAULT); 14306e91bba0SGirish Moodalbail ipadm_status_t status; 14316e91bba0SGirish Moodalbail 14326e91bba0SGirish Moodalbail /* check for solaris.network.interface.config authorization */ 14336e91bba0SGirish Moodalbail if (!ipadm_check_auth()) 14346e91bba0SGirish Moodalbail return (IPADM_EAUTH); 14356e91bba0SGirish Moodalbail /* 14366e91bba0SGirish Moodalbail * validate the arguments of the function. 14376e91bba0SGirish Moodalbail */ 14386e91bba0SGirish Moodalbail if (iph == NULL || pname == NULL || (!reset && buf == NULL) || 14396e91bba0SGirish Moodalbail pflags == 0 || pflags == IPADM_OPT_PERSIST || 14406e91bba0SGirish Moodalbail (pflags & ~(IPADM_COMMON_OPT_MASK|IPADM_OPT_DEFAULT))) { 14416e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 14426e91bba0SGirish Moodalbail } 14436e91bba0SGirish Moodalbail 14446e91bba0SGirish Moodalbail /* 14456e91bba0SGirish Moodalbail * Do we support this protocol, if not return error. 14466e91bba0SGirish Moodalbail */ 14476e91bba0SGirish Moodalbail if (ipadm_proto2str(proto) == NULL) 14486e91bba0SGirish Moodalbail return (IPADM_NOTSUP); 14496e91bba0SGirish Moodalbail 14506e91bba0SGirish Moodalbail /* 14516e91bba0SGirish Moodalbail * Validate the interface and check if a persistent 14526e91bba0SGirish Moodalbail * operation is performed on a temporary object. 14536e91bba0SGirish Moodalbail */ 14546e91bba0SGirish Moodalbail status = i_ipadm_validate_if(iph, ifname, proto, pflags); 14556e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 14566e91bba0SGirish Moodalbail return (status); 14576e91bba0SGirish Moodalbail 14586e91bba0SGirish Moodalbail return (i_ipadm_setprop_common(iph, ifname, pname, buf, proto, 14596e91bba0SGirish Moodalbail pflags)); 14606e91bba0SGirish Moodalbail } 14616e91bba0SGirish Moodalbail 14626e91bba0SGirish Moodalbail /* 14636e91bba0SGirish Moodalbail * Sets the property value of the specified protocol. 14646e91bba0SGirish Moodalbail */ 14656e91bba0SGirish Moodalbail ipadm_status_t 14666e91bba0SGirish Moodalbail ipadm_set_prop(ipadm_handle_t iph, const char *pname, const char *buf, 14676e91bba0SGirish Moodalbail uint_t proto, uint_t pflags) 14686e91bba0SGirish Moodalbail { 14696e91bba0SGirish Moodalbail boolean_t reset = (pflags & IPADM_OPT_DEFAULT); 14706e91bba0SGirish Moodalbail 14716e91bba0SGirish Moodalbail /* check for solaris.network.interface.config authorization */ 14726e91bba0SGirish Moodalbail if (!ipadm_check_auth()) 14736e91bba0SGirish Moodalbail return (IPADM_EAUTH); 14746e91bba0SGirish Moodalbail /* 14756e91bba0SGirish Moodalbail * validate the arguments of the function. 14766e91bba0SGirish Moodalbail */ 14776e91bba0SGirish Moodalbail if (iph == NULL || pname == NULL ||(!reset && buf == NULL) || 14786e91bba0SGirish Moodalbail pflags == 0 || pflags == IPADM_OPT_PERSIST || 14796e91bba0SGirish Moodalbail (pflags & ~(IPADM_COMMON_OPT_MASK|IPADM_OPT_DEFAULT| 14806e91bba0SGirish Moodalbail IPADM_OPT_APPEND|IPADM_OPT_REMOVE))) { 14816e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 14826e91bba0SGirish Moodalbail } 14836e91bba0SGirish Moodalbail 14846e91bba0SGirish Moodalbail /* 14856e91bba0SGirish Moodalbail * Do we support this proto, if not return error. 14866e91bba0SGirish Moodalbail */ 14876e91bba0SGirish Moodalbail if (ipadm_proto2str(proto) == NULL) 14886e91bba0SGirish Moodalbail return (IPADM_NOTSUP); 14896e91bba0SGirish Moodalbail 14906e91bba0SGirish Moodalbail return (i_ipadm_setprop_common(iph, NULL, pname, buf, proto, 14916e91bba0SGirish Moodalbail pflags)); 14926e91bba0SGirish Moodalbail } 14936e91bba0SGirish Moodalbail 14946e91bba0SGirish Moodalbail /* helper function for ipadm_walk_proptbl */ 14956e91bba0SGirish Moodalbail static void 14966e91bba0SGirish Moodalbail i_ipadm_walk_proptbl(ipadm_prop_desc_t *pdtbl, uint_t proto, uint_t class, 14976e91bba0SGirish Moodalbail ipadm_prop_wfunc_t *func, void *arg) 14986e91bba0SGirish Moodalbail { 14996e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdp; 15006e91bba0SGirish Moodalbail 15016e91bba0SGirish Moodalbail for (pdp = pdtbl; pdp->ipd_name != NULL; pdp++) { 15026e91bba0SGirish Moodalbail if (!(pdp->ipd_class & class)) 15036e91bba0SGirish Moodalbail continue; 15046e91bba0SGirish Moodalbail 15056e91bba0SGirish Moodalbail if (proto != MOD_PROTO_NONE && !(pdp->ipd_proto & proto)) 15066e91bba0SGirish Moodalbail continue; 15076e91bba0SGirish Moodalbail 15086e91bba0SGirish Moodalbail /* 15096e91bba0SGirish Moodalbail * we found a class specific match, call the 15106e91bba0SGirish Moodalbail * user callback function. 15116e91bba0SGirish Moodalbail */ 15126e91bba0SGirish Moodalbail if (func(arg, pdp->ipd_name, pdp->ipd_proto) == B_FALSE) 15136e91bba0SGirish Moodalbail break; 15146e91bba0SGirish Moodalbail } 15156e91bba0SGirish Moodalbail } 15166e91bba0SGirish Moodalbail 15176e91bba0SGirish Moodalbail /* 15186e91bba0SGirish Moodalbail * Walks through all the properties, for a given protocol and property class 15196e91bba0SGirish Moodalbail * (protocol or interface). 15206e91bba0SGirish Moodalbail * 15216e91bba0SGirish Moodalbail * Further if proto == MOD_PROTO_NONE, then it walks through all the supported 15226e91bba0SGirish Moodalbail * protocol property tables. 15236e91bba0SGirish Moodalbail */ 15246e91bba0SGirish Moodalbail ipadm_status_t 15256e91bba0SGirish Moodalbail ipadm_walk_proptbl(uint_t proto, uint_t class, ipadm_prop_wfunc_t *func, 15266e91bba0SGirish Moodalbail void *arg) 15276e91bba0SGirish Moodalbail { 15286e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdtbl; 15296e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 15306e91bba0SGirish Moodalbail int i; 15316e91bba0SGirish Moodalbail int count = A_CNT(protocols); 15326e91bba0SGirish Moodalbail 15336e91bba0SGirish Moodalbail if (func == NULL) 15346e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 15356e91bba0SGirish Moodalbail 15366e91bba0SGirish Moodalbail switch (class) { 15376e91bba0SGirish Moodalbail case IPADMPROP_CLASS_ADDR: 15386e91bba0SGirish Moodalbail pdtbl = ipadm_addrprop_table; 15396e91bba0SGirish Moodalbail break; 15406e91bba0SGirish Moodalbail case IPADMPROP_CLASS_IF: 15416e91bba0SGirish Moodalbail case IPADMPROP_CLASS_MODULE: 15426e91bba0SGirish Moodalbail pdtbl = i_ipadm_get_propdesc_table(proto); 15436e91bba0SGirish Moodalbail if (pdtbl == NULL && proto != MOD_PROTO_NONE) 15446e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 15456e91bba0SGirish Moodalbail break; 15466e91bba0SGirish Moodalbail default: 15476e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 15486e91bba0SGirish Moodalbail } 15496e91bba0SGirish Moodalbail 15506e91bba0SGirish Moodalbail if (pdtbl != NULL) { 15516e91bba0SGirish Moodalbail /* 15526e91bba0SGirish Moodalbail * proto will be MOD_PROTO_NONE in the case of 15536e91bba0SGirish Moodalbail * IPADMPROP_CLASS_ADDR. 15546e91bba0SGirish Moodalbail */ 15556e91bba0SGirish Moodalbail i_ipadm_walk_proptbl(pdtbl, proto, class, func, arg); 15566e91bba0SGirish Moodalbail } else { 15576e91bba0SGirish Moodalbail /* Walk thru all the protocol tables, we support */ 15586e91bba0SGirish Moodalbail for (i = 0; i < count; i++) { 15596e91bba0SGirish Moodalbail pdtbl = i_ipadm_get_propdesc_table(protocols[i]); 15606e91bba0SGirish Moodalbail i_ipadm_walk_proptbl(pdtbl, protocols[i], class, func, 15616e91bba0SGirish Moodalbail arg); 15626e91bba0SGirish Moodalbail } 15636e91bba0SGirish Moodalbail } 15646e91bba0SGirish Moodalbail return (status); 15656e91bba0SGirish Moodalbail } 15666e91bba0SGirish Moodalbail 15676e91bba0SGirish Moodalbail /* 15686e91bba0SGirish Moodalbail * Given a property name, walks through all the instances of a property name. 15696e91bba0SGirish Moodalbail * Some properties have two instances one for v4 interfaces and another for v6 15706e91bba0SGirish Moodalbail * interfaces. For example: MTU. MTU can have different values for v4 and v6. 15716e91bba0SGirish Moodalbail * Therefore there are two properties for 'MTU'. 15726e91bba0SGirish Moodalbail * 15736e91bba0SGirish Moodalbail * This function invokes `func' for every instance of property `pname' 15746e91bba0SGirish Moodalbail */ 15756e91bba0SGirish Moodalbail ipadm_status_t 15766e91bba0SGirish Moodalbail ipadm_walk_prop(const char *pname, uint_t proto, uint_t class, 15776e91bba0SGirish Moodalbail ipadm_prop_wfunc_t *func, void *arg) 15786e91bba0SGirish Moodalbail { 15796e91bba0SGirish Moodalbail ipadm_prop_desc_t *pdtbl, *pdp; 15806e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 15816e91bba0SGirish Moodalbail boolean_t matched = B_FALSE; 15826e91bba0SGirish Moodalbail 15836e91bba0SGirish Moodalbail if (pname == NULL || func == NULL) 15846e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 15856e91bba0SGirish Moodalbail 15866e91bba0SGirish Moodalbail switch (class) { 15876e91bba0SGirish Moodalbail case IPADMPROP_CLASS_ADDR: 15886e91bba0SGirish Moodalbail pdtbl = ipadm_addrprop_table; 15896e91bba0SGirish Moodalbail break; 15906e91bba0SGirish Moodalbail case IPADMPROP_CLASS_IF: 15916e91bba0SGirish Moodalbail case IPADMPROP_CLASS_MODULE: 15926e91bba0SGirish Moodalbail pdtbl = i_ipadm_get_propdesc_table(proto); 15936e91bba0SGirish Moodalbail break; 15946e91bba0SGirish Moodalbail default: 15956e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 15966e91bba0SGirish Moodalbail } 15976e91bba0SGirish Moodalbail 15986e91bba0SGirish Moodalbail if (pdtbl == NULL) 15996e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 16006e91bba0SGirish Moodalbail 16016e91bba0SGirish Moodalbail for (pdp = pdtbl; pdp->ipd_name != NULL; pdp++) { 16026e91bba0SGirish Moodalbail if (strcmp(pname, pdp->ipd_name) != 0) 16036e91bba0SGirish Moodalbail continue; 16046e91bba0SGirish Moodalbail if (!(pdp->ipd_proto & proto)) 16056e91bba0SGirish Moodalbail continue; 16066e91bba0SGirish Moodalbail matched = B_TRUE; 16076e91bba0SGirish Moodalbail /* we found a match, call the callback function */ 16086e91bba0SGirish Moodalbail if (func(arg, pdp->ipd_name, pdp->ipd_proto) == B_FALSE) 16096e91bba0SGirish Moodalbail break; 16106e91bba0SGirish Moodalbail } 16116e91bba0SGirish Moodalbail if (!matched) 16126e91bba0SGirish Moodalbail status = IPADM_PROP_UNKNOWN; 16136e91bba0SGirish Moodalbail return (status); 16146e91bba0SGirish Moodalbail } 16156e91bba0SGirish Moodalbail 16166e91bba0SGirish Moodalbail /* ARGSUSED */ 16176e91bba0SGirish Moodalbail ipadm_status_t 16186e91bba0SGirish Moodalbail i_ipadm_get_onoff(ipadm_handle_t iph, const void *arg, ipadm_prop_desc_t *dp, 16196e91bba0SGirish Moodalbail char *buf, uint_t *bufsize, uint_t proto, uint_t valtype) 16206e91bba0SGirish Moodalbail { 16216e91bba0SGirish Moodalbail (void) snprintf(buf, *bufsize, "%s,%s", IPADM_ONSTR, IPADM_OFFSTR); 16226e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 16236e91bba0SGirish Moodalbail } 16246e91bba0SGirish Moodalbail 16256e91bba0SGirish Moodalbail /* 16266e91bba0SGirish Moodalbail * Makes a door call to ipmgmtd to retrieve the persisted property value 16276e91bba0SGirish Moodalbail */ 16286e91bba0SGirish Moodalbail ipadm_status_t 16296e91bba0SGirish Moodalbail i_ipadm_get_persist_propval(ipadm_handle_t iph, ipadm_prop_desc_t *pdp, 16306e91bba0SGirish Moodalbail char *gbuf, uint_t *gbufsize, const void *object) 16316e91bba0SGirish Moodalbail { 16326e91bba0SGirish Moodalbail ipmgmt_prop_arg_t parg; 16336e91bba0SGirish Moodalbail ipmgmt_getprop_rval_t rval, *rvalp; 16346e91bba0SGirish Moodalbail size_t nbytes; 16356e91bba0SGirish Moodalbail int err = 0; 16366e91bba0SGirish Moodalbail 16376e91bba0SGirish Moodalbail bzero(&parg, sizeof (parg)); 16386e91bba0SGirish Moodalbail parg.ia_cmd = IPMGMT_CMD_GETPROP; 16396e91bba0SGirish Moodalbail i_ipadm_populate_proparg(&parg, pdp, NULL, object); 16406e91bba0SGirish Moodalbail 16416e91bba0SGirish Moodalbail rvalp = &rval; 16426e91bba0SGirish Moodalbail err = ipadm_door_call(iph, &parg, sizeof (parg), (void **)&rvalp, 16436e91bba0SGirish Moodalbail sizeof (rval), B_FALSE); 16446e91bba0SGirish Moodalbail if (err == 0) { 16456e91bba0SGirish Moodalbail /* assert that rvalp was not reallocated */ 16466e91bba0SGirish Moodalbail assert(rvalp == &rval); 16476e91bba0SGirish Moodalbail 16486e91bba0SGirish Moodalbail /* `ir_pval' contains the property value */ 16496e91bba0SGirish Moodalbail nbytes = snprintf(gbuf, *gbufsize, "%s", rvalp->ir_pval); 16506e91bba0SGirish Moodalbail if (nbytes >= *gbufsize) { 16516e91bba0SGirish Moodalbail /* insufficient buffer space */ 16526e91bba0SGirish Moodalbail *gbufsize = nbytes + 1; 16536e91bba0SGirish Moodalbail err = ENOBUFS; 16546e91bba0SGirish Moodalbail } 16556e91bba0SGirish Moodalbail } 16566e91bba0SGirish Moodalbail return (ipadm_errno2status(err)); 16576e91bba0SGirish Moodalbail } 16586e91bba0SGirish Moodalbail 16596e91bba0SGirish Moodalbail /* 16606e91bba0SGirish Moodalbail * Persists the property value for a given property in the data store 16616e91bba0SGirish Moodalbail */ 16626e91bba0SGirish Moodalbail ipadm_status_t 16636e91bba0SGirish Moodalbail i_ipadm_persist_propval(ipadm_handle_t iph, ipadm_prop_desc_t *pdp, 16646e91bba0SGirish Moodalbail const char *pval, const void *object, uint_t flags) 16656e91bba0SGirish Moodalbail { 16666e91bba0SGirish Moodalbail ipmgmt_prop_arg_t parg; 16676e91bba0SGirish Moodalbail int err = 0; 16686e91bba0SGirish Moodalbail 16696e91bba0SGirish Moodalbail bzero(&parg, sizeof (parg)); 16706e91bba0SGirish Moodalbail i_ipadm_populate_proparg(&parg, pdp, pval, object); 16716e91bba0SGirish Moodalbail /* 16726e91bba0SGirish Moodalbail * Check if value to be persisted need to be appended or removed. This 16736e91bba0SGirish Moodalbail * is required for multi-valued property. 16746e91bba0SGirish Moodalbail */ 16756e91bba0SGirish Moodalbail if (flags & IPADM_OPT_APPEND) 16766e91bba0SGirish Moodalbail parg.ia_flags |= IPMGMT_APPEND; 16776e91bba0SGirish Moodalbail if (flags & IPADM_OPT_REMOVE) 16786e91bba0SGirish Moodalbail parg.ia_flags |= IPMGMT_REMOVE; 16796e91bba0SGirish Moodalbail 16806e91bba0SGirish Moodalbail if (flags & (IPADM_OPT_DEFAULT|IPADM_OPT_REMOVE)) 16816e91bba0SGirish Moodalbail parg.ia_cmd = IPMGMT_CMD_RESETPROP; 16826e91bba0SGirish Moodalbail else 16836e91bba0SGirish Moodalbail parg.ia_cmd = IPMGMT_CMD_SETPROP; 16846e91bba0SGirish Moodalbail 16856e91bba0SGirish Moodalbail err = ipadm_door_call(iph, &parg, sizeof (parg), NULL, 0, B_FALSE); 16866e91bba0SGirish Moodalbail 16876e91bba0SGirish Moodalbail /* 16886e91bba0SGirish Moodalbail * its fine if there were no entry in the DB to delete. The user 16896e91bba0SGirish Moodalbail * might be changing property value, which was not changed 16906e91bba0SGirish Moodalbail * persistently. 16916e91bba0SGirish Moodalbail */ 16926e91bba0SGirish Moodalbail if (err == ENOENT) 16936e91bba0SGirish Moodalbail err = 0; 16946e91bba0SGirish Moodalbail return (ipadm_errno2status(err)); 16956e91bba0SGirish Moodalbail } 16966e91bba0SGirish Moodalbail 16976e91bba0SGirish Moodalbail /* 16986e91bba0SGirish Moodalbail * This is called from ipadm_set_ifprop() to validate the set operation. 16996e91bba0SGirish Moodalbail * It does the following steps: 17006e91bba0SGirish Moodalbail * 1. Validates the interface name. 17016e91bba0SGirish Moodalbail * 2. Fails if it is an IPMP meta-interface or an underlying interface. 17026e91bba0SGirish Moodalbail * 3. In case of a persistent operation, verifies that the 17036e91bba0SGirish Moodalbail * interface is persistent. 17046e91bba0SGirish Moodalbail */ 17056e91bba0SGirish Moodalbail static ipadm_status_t 17066e91bba0SGirish Moodalbail i_ipadm_validate_if(ipadm_handle_t iph, const char *ifname, 17076e91bba0SGirish Moodalbail uint_t proto, uint_t flags) 17086e91bba0SGirish Moodalbail { 17096e91bba0SGirish Moodalbail sa_family_t af, other_af; 17106e91bba0SGirish Moodalbail ipadm_status_t status; 17116e91bba0SGirish Moodalbail boolean_t p_exists; 17126e91bba0SGirish Moodalbail boolean_t af_exists, other_af_exists, a_exists; 17136e91bba0SGirish Moodalbail 17146e91bba0SGirish Moodalbail /* Check if the interface name is valid. */ 17156e91bba0SGirish Moodalbail if (!i_ipadm_validate_ifname(iph, ifname)) 17166e91bba0SGirish Moodalbail return (IPADM_INVALID_ARG); 17176e91bba0SGirish Moodalbail 17186e91bba0SGirish Moodalbail af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET); 17196e91bba0SGirish Moodalbail /* 17206e91bba0SGirish Moodalbail * Setting properties on an IPMP meta-interface or underlying 17216e91bba0SGirish Moodalbail * interface is not supported. 17226e91bba0SGirish Moodalbail */ 17236e91bba0SGirish Moodalbail if (i_ipadm_is_ipmp(iph, ifname) || i_ipadm_is_under_ipmp(iph, ifname)) 17246e91bba0SGirish Moodalbail return (IPADM_NOTSUP); 17256e91bba0SGirish Moodalbail 17266e91bba0SGirish Moodalbail /* Check if interface exists in the persistent configuration. */ 17276e91bba0SGirish Moodalbail status = i_ipadm_if_pexists(iph, ifname, af, &p_exists); 17286e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 17296e91bba0SGirish Moodalbail return (status); 17306e91bba0SGirish Moodalbail 17316e91bba0SGirish Moodalbail /* Check if interface exists in the active configuration. */ 17326e91bba0SGirish Moodalbail af_exists = ipadm_if_enabled(iph, ifname, af); 17336e91bba0SGirish Moodalbail other_af = (af == AF_INET ? AF_INET6 : AF_INET); 17346e91bba0SGirish Moodalbail other_af_exists = ipadm_if_enabled(iph, ifname, other_af); 17356e91bba0SGirish Moodalbail a_exists = (af_exists || other_af_exists); 17366e91bba0SGirish Moodalbail if (!a_exists && p_exists) 17376e91bba0SGirish Moodalbail return (IPADM_OP_DISABLE_OBJ); 17386e91bba0SGirish Moodalbail if (!af_exists) 17396e91bba0SGirish Moodalbail return (IPADM_ENXIO); 17406e91bba0SGirish Moodalbail 17416e91bba0SGirish Moodalbail /* 17426e91bba0SGirish Moodalbail * If a persistent operation is requested, check if the underlying 17436e91bba0SGirish Moodalbail * IP interface is persistent. 17446e91bba0SGirish Moodalbail */ 17456e91bba0SGirish Moodalbail if ((flags & IPADM_OPT_PERSIST) && !p_exists) 17466e91bba0SGirish Moodalbail return (IPADM_TEMPORARY_OBJ); 17476e91bba0SGirish Moodalbail return (IPADM_SUCCESS); 17486e91bba0SGirish Moodalbail } 17498887b57dSGirish Moodalbail 17508887b57dSGirish Moodalbail /* 17518887b57dSGirish Moodalbail * Private protocol properties namespace scheme: 17528887b57dSGirish Moodalbail * 17538887b57dSGirish Moodalbail * PSARC 2010/080 identified the private protocol property names to be the 17548887b57dSGirish Moodalbail * leading protocol names. For e.g. tcp_strong_iss, ip_strict_src_multihoming, 17558887b57dSGirish Moodalbail * et al,. However to be consistent with private data-link property names, 17568887b57dSGirish Moodalbail * which starts with '_', private protocol property names will start with '_'. 17578887b57dSGirish Moodalbail * For e.g. _strong_iss, _strict_src_multihoming, et al,. 17588887b57dSGirish Moodalbail */ 17598887b57dSGirish Moodalbail 17608887b57dSGirish Moodalbail /* maps new private protocol property name to the old private property name */ 17618887b57dSGirish Moodalbail typedef struct ipadm_oname2nname_map { 17628887b57dSGirish Moodalbail char *iom_oname; 17638887b57dSGirish Moodalbail char *iom_nname; 17648887b57dSGirish Moodalbail uint_t iom_proto; 17658887b57dSGirish Moodalbail } ipadm_oname2nname_map_t; 17668887b57dSGirish Moodalbail 17678887b57dSGirish Moodalbail /* 17688887b57dSGirish Moodalbail * IP is a special case. It isn't straight forward to derive the legacy name 17698887b57dSGirish Moodalbail * from the new name and vice versa. No set standard was followed in naming 17708887b57dSGirish Moodalbail * the properties and hence we need a table to capture the mapping. 17718887b57dSGirish Moodalbail */ 17728887b57dSGirish Moodalbail static ipadm_oname2nname_map_t name_map[] = { 17738887b57dSGirish Moodalbail { "arp_probe_delay", "_arp_probe_delay", 17748887b57dSGirish Moodalbail MOD_PROTO_IP }, 17758887b57dSGirish Moodalbail { "arp_fastprobe_delay", "_arp_fastprobe_delay", 17768887b57dSGirish Moodalbail MOD_PROTO_IP }, 17778887b57dSGirish Moodalbail { "arp_probe_interval", "_arp_probe_interval", 17788887b57dSGirish Moodalbail MOD_PROTO_IP }, 17798887b57dSGirish Moodalbail { "arp_fastprobe_interval", "_arp_fastprobe_interval", 17808887b57dSGirish Moodalbail MOD_PROTO_IP }, 17818887b57dSGirish Moodalbail { "arp_probe_count", "_arp_probe_count", 17828887b57dSGirish Moodalbail MOD_PROTO_IP }, 17838887b57dSGirish Moodalbail { "arp_fastprobe_count", "_arp_fastprobe_count", 17848887b57dSGirish Moodalbail MOD_PROTO_IP }, 17858887b57dSGirish Moodalbail { "arp_defend_interval", "_arp_defend_interval", 17868887b57dSGirish Moodalbail MOD_PROTO_IP }, 17878887b57dSGirish Moodalbail { "arp_defend_rate", "_arp_defend_rate", 17888887b57dSGirish Moodalbail MOD_PROTO_IP }, 17898887b57dSGirish Moodalbail { "arp_defend_period", "_arp_defend_period", 17908887b57dSGirish Moodalbail MOD_PROTO_IP }, 17918887b57dSGirish Moodalbail { "ndp_defend_interval", "_ndp_defend_interval", 17928887b57dSGirish Moodalbail MOD_PROTO_IP }, 17938887b57dSGirish Moodalbail { "ndp_defend_rate", "_ndp_defend_rate", 17948887b57dSGirish Moodalbail MOD_PROTO_IP }, 17958887b57dSGirish Moodalbail { "ndp_defend_period", "_ndp_defend_period", 17968887b57dSGirish Moodalbail MOD_PROTO_IP }, 17978887b57dSGirish Moodalbail { "igmp_max_version", "_igmp_max_version", 17988887b57dSGirish Moodalbail MOD_PROTO_IP }, 17998887b57dSGirish Moodalbail { "mld_max_version", "_mld_max_version", 18008887b57dSGirish Moodalbail MOD_PROTO_IP }, 18018887b57dSGirish Moodalbail { "ipsec_override_persocket_policy", "_ipsec_override_persocket_policy", 18028887b57dSGirish Moodalbail MOD_PROTO_IP }, 18038887b57dSGirish Moodalbail { "ipsec_policy_log_interval", "_ipsec_policy_log_interval", 18048887b57dSGirish Moodalbail MOD_PROTO_IP }, 18058887b57dSGirish Moodalbail { "icmp_accept_clear_messages", "_icmp_accept_clear_messages", 18068887b57dSGirish Moodalbail MOD_PROTO_IP }, 18078887b57dSGirish Moodalbail { "igmp_accept_clear_messages", "_igmp_accept_clear_messages", 18088887b57dSGirish Moodalbail MOD_PROTO_IP }, 18098887b57dSGirish Moodalbail { "pim_accept_clear_messages", "_pim_accept_clear_messages", 18108887b57dSGirish Moodalbail MOD_PROTO_IP }, 18118887b57dSGirish Moodalbail { "ip_respond_to_echo_multicast", "_respond_to_echo_multicast", 18128887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18138887b57dSGirish Moodalbail { "ip_send_redirects", "_send_redirects", 18148887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18158887b57dSGirish Moodalbail { "ip_forward_src_routed", "_forward_src_routed", 18168887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18178887b57dSGirish Moodalbail { "ip_icmp_return_data_bytes", "_icmp_return_data_bytes", 18188887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18198887b57dSGirish Moodalbail { "ip_ignore_redirect", "_ignore_redirect", 18208887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18218887b57dSGirish Moodalbail { "ip_strict_dst_multihoming", "_strict_dst_multihoming", 18228887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18238887b57dSGirish Moodalbail { "ip_reasm_timeout", "_reasm_timeout", 18248887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18258887b57dSGirish Moodalbail { "ip_strict_src_multihoming", "_strict_src_multihoming", 18268887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18278887b57dSGirish Moodalbail { "ipv4_dad_announce_interval", "_dad_announce_interval", 18288887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18298887b57dSGirish Moodalbail { "ipv4_icmp_return_pmtu", "_icmp_return_pmtu", 18308887b57dSGirish Moodalbail MOD_PROTO_IPV4 }, 18318887b57dSGirish Moodalbail { "ipv6_dad_announce_interval", "_dad_announce_interval", 18328887b57dSGirish Moodalbail MOD_PROTO_IPV6 }, 18338887b57dSGirish Moodalbail { "ipv6_icmp_return_pmtu", "_icmp_return_pmtu", 18348887b57dSGirish Moodalbail MOD_PROTO_IPV6 }, 18358887b57dSGirish Moodalbail { NULL, NULL, MOD_PROTO_NONE } 18368887b57dSGirish Moodalbail }; 18378887b57dSGirish Moodalbail 18388887b57dSGirish Moodalbail /* 18398887b57dSGirish Moodalbail * Following API returns a new property name in `nname' for the given legacy 18408887b57dSGirish Moodalbail * property name in `oname'. 18418887b57dSGirish Moodalbail */ 18428887b57dSGirish Moodalbail int 18438887b57dSGirish Moodalbail ipadm_legacy2new_propname(const char *oname, char *nname, uint_t nnamelen, 18448887b57dSGirish Moodalbail uint_t *proto) 18458887b57dSGirish Moodalbail { 18468887b57dSGirish Moodalbail const char *str; 18478887b57dSGirish Moodalbail ipadm_oname2nname_map_t *ionmp; 18488887b57dSGirish Moodalbail 18498887b57dSGirish Moodalbail /* if it's a public property, there is nothing to return */ 18508887b57dSGirish Moodalbail if (i_ipadm_get_prop_desc(oname, *proto, NULL) != NULL) 18518887b57dSGirish Moodalbail return (-1); 18528887b57dSGirish Moodalbail 18538887b57dSGirish Moodalbail /* 18548887b57dSGirish Moodalbail * we didn't find the `oname' in the table, check if the property 18558887b57dSGirish Moodalbail * name begins with a leading protocol. 18568887b57dSGirish Moodalbail */ 18578887b57dSGirish Moodalbail str = oname; 18588887b57dSGirish Moodalbail switch (*proto) { 18598887b57dSGirish Moodalbail case MOD_PROTO_TCP: 18608887b57dSGirish Moodalbail if (strstr(oname, "tcp_") == oname) 18618887b57dSGirish Moodalbail str += strlen("tcp"); 18628887b57dSGirish Moodalbail break; 18638887b57dSGirish Moodalbail case MOD_PROTO_SCTP: 18648887b57dSGirish Moodalbail if (strstr(oname, "sctp_") == oname) 18658887b57dSGirish Moodalbail str += strlen("sctp"); 18668887b57dSGirish Moodalbail break; 18678887b57dSGirish Moodalbail case MOD_PROTO_UDP: 18688887b57dSGirish Moodalbail if (strstr(oname, "udp_") == oname) 18698887b57dSGirish Moodalbail str += strlen("udp"); 18708887b57dSGirish Moodalbail break; 18718887b57dSGirish Moodalbail case MOD_PROTO_RAWIP: 18728887b57dSGirish Moodalbail if (strstr(oname, "icmp_") == oname) 18738887b57dSGirish Moodalbail str += strlen("icmp"); 18748887b57dSGirish Moodalbail break; 18758887b57dSGirish Moodalbail case MOD_PROTO_IP: 18768887b57dSGirish Moodalbail case MOD_PROTO_IPV4: 18778887b57dSGirish Moodalbail case MOD_PROTO_IPV6: 18788887b57dSGirish Moodalbail if (strstr(oname, "ip6_") == oname) { 18798887b57dSGirish Moodalbail *proto = MOD_PROTO_IPV6; 18808887b57dSGirish Moodalbail str += strlen("ip6"); 18818887b57dSGirish Moodalbail } else { 18828887b57dSGirish Moodalbail for (ionmp = name_map; ionmp->iom_oname != NULL; 18838887b57dSGirish Moodalbail ionmp++) { 18848887b57dSGirish Moodalbail if (strcmp(oname, ionmp->iom_oname) == 0) { 18858887b57dSGirish Moodalbail str = ionmp->iom_nname; 18868887b57dSGirish Moodalbail *proto = ionmp->iom_proto; 18878887b57dSGirish Moodalbail break; 18888887b57dSGirish Moodalbail } 18898887b57dSGirish Moodalbail } 18908887b57dSGirish Moodalbail if (ionmp->iom_oname != NULL) 18918887b57dSGirish Moodalbail break; 18928887b57dSGirish Moodalbail 18938887b57dSGirish Moodalbail if (strstr(oname, "ip_") == oname) { 18948887b57dSGirish Moodalbail *proto = MOD_PROTO_IP; 18958887b57dSGirish Moodalbail str += strlen("ip"); 18968887b57dSGirish Moodalbail } 18978887b57dSGirish Moodalbail } 18988887b57dSGirish Moodalbail break; 18998887b57dSGirish Moodalbail default: 19008887b57dSGirish Moodalbail return (-1); 19018887b57dSGirish Moodalbail } 19028887b57dSGirish Moodalbail (void) snprintf(nname, nnamelen, "%s", str); 19038887b57dSGirish Moodalbail return (0); 19048887b57dSGirish Moodalbail } 19058887b57dSGirish Moodalbail 19068887b57dSGirish Moodalbail /* 19078887b57dSGirish Moodalbail * Following API is required for ndd.c alone. To maintain backward 19088887b57dSGirish Moodalbail * compatibility with ndd output, we need to print the legacy name 19098887b57dSGirish Moodalbail * for the new name. 19108887b57dSGirish Moodalbail */ 19118887b57dSGirish Moodalbail int 19128887b57dSGirish Moodalbail ipadm_new2legacy_propname(const char *oname, char *nname, 19138887b57dSGirish Moodalbail uint_t nnamelen, uint_t proto) 19148887b57dSGirish Moodalbail { 19158887b57dSGirish Moodalbail char *prefix; 19168887b57dSGirish Moodalbail ipadm_oname2nname_map_t *ionmp; 19178887b57dSGirish Moodalbail 19188887b57dSGirish Moodalbail /* if it's a public property, there is nothing to prepend */ 19198887b57dSGirish Moodalbail if (i_ipadm_get_prop_desc(oname, proto, NULL) != NULL) 19208887b57dSGirish Moodalbail return (-1); 19218887b57dSGirish Moodalbail 19228887b57dSGirish Moodalbail switch (proto) { 19238887b57dSGirish Moodalbail case MOD_PROTO_TCP: 19248887b57dSGirish Moodalbail prefix = "tcp"; 19258887b57dSGirish Moodalbail break; 19268887b57dSGirish Moodalbail case MOD_PROTO_SCTP: 19278887b57dSGirish Moodalbail prefix = "sctp"; 19288887b57dSGirish Moodalbail break; 19298887b57dSGirish Moodalbail case MOD_PROTO_UDP: 19308887b57dSGirish Moodalbail prefix = "udp"; 19318887b57dSGirish Moodalbail break; 19328887b57dSGirish Moodalbail case MOD_PROTO_RAWIP: 19338887b57dSGirish Moodalbail prefix = "icmp"; 19348887b57dSGirish Moodalbail break; 19358887b57dSGirish Moodalbail case MOD_PROTO_IP: 19368887b57dSGirish Moodalbail case MOD_PROTO_IPV4: 19378887b57dSGirish Moodalbail case MOD_PROTO_IPV6: 19388887b57dSGirish Moodalbail /* handle special case for IP */ 19398887b57dSGirish Moodalbail for (ionmp = name_map; ionmp->iom_oname != NULL; ionmp++) { 19408887b57dSGirish Moodalbail if (strcmp(oname, ionmp->iom_nname) == 0 && 19418887b57dSGirish Moodalbail ionmp->iom_proto == proto) { 19428887b57dSGirish Moodalbail (void) strlcpy(nname, ionmp->iom_oname, 19438887b57dSGirish Moodalbail nnamelen); 19448887b57dSGirish Moodalbail return (0); 19458887b57dSGirish Moodalbail } 19468887b57dSGirish Moodalbail } 19478887b57dSGirish Moodalbail if (proto == MOD_PROTO_IPV6) 19488887b57dSGirish Moodalbail prefix = "ip6"; 19498887b57dSGirish Moodalbail else 19508887b57dSGirish Moodalbail prefix = "ip"; 19518887b57dSGirish Moodalbail break; 19528887b57dSGirish Moodalbail default: 19538887b57dSGirish Moodalbail return (-1); 19548887b57dSGirish Moodalbail } 19558887b57dSGirish Moodalbail (void) snprintf(nname, nnamelen, "%s%s", prefix, oname); 19568887b57dSGirish Moodalbail return (0); 19578887b57dSGirish Moodalbail } 1958