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 *
i_ipadm_get_propdesc_table(uint_t proto)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 *
i_ipadm_get_prop_desc(const char * pname,uint_t proto,int * errp)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 *
ipadm_proto2str(uint_t proto)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
ipadm_str2proto(const char * protostr)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
i_ipadm_set_mtu(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_set_metric(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_set_usesrc(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_hostmodel_str2val(const char * pval)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 *
i_ipadm_hostmodel_val2str(ip_hostmodel_t pval)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
i_ipadm_set_hostmodel(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_get_hostmodel(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_set_ifprop_flags(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_set_eprivport(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_set_forwarding(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_set_ecnsack(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_get_ecnsack(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_get_forwarding(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_get_mtu(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_get_metric(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_get_usesrc(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * ipd,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_get_ifprop_flags(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_perm2str(char * buf,uint_t * bufsize)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
i_ipadm_get_prop(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_populate_proparg(ipmgmt_prop_arg_t * pargp,ipadm_prop_desc_t * pdp,const char * pval,const void * object)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
i_ipadm_getprop_common(ipadm_handle_t iph,const char * ifname,const char * pname,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
ipadm_get_prop(ipadm_handle_t iph,const char * pname,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
ipadm_get_ifprop(ipadm_handle_t iph,const char * ifname,const char * pname,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_set_prop(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * pdp,const void * pval,uint_t proto,uint_t flags)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
i_ipadm_setprop_common(ipadm_handle_t iph,const char * ifname,const char * pname,const char * buf,uint_t proto,uint_t pflags)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
ipadm_set_ifprop(ipadm_handle_t iph,const char * ifname,const char * pname,const char * buf,uint_t proto,uint_t pflags)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
ipadm_set_prop(ipadm_handle_t iph,const char * pname,const char * buf,uint_t proto,uint_t pflags)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
i_ipadm_walk_proptbl(ipadm_prop_desc_t * pdtbl,uint_t proto,uint_t class,ipadm_prop_wfunc_t * func,void * arg)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
ipadm_walk_proptbl(uint_t proto,uint_t class,ipadm_prop_wfunc_t * func,void * arg)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
ipadm_walk_prop(const char * pname,uint_t proto,uint_t class,ipadm_prop_wfunc_t * func,void * arg)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
i_ipadm_get_onoff(ipadm_handle_t iph,const void * arg,ipadm_prop_desc_t * dp,char * buf,uint_t * bufsize,uint_t proto,uint_t valtype)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
i_ipadm_get_persist_propval(ipadm_handle_t iph,ipadm_prop_desc_t * pdp,char * gbuf,uint_t * gbufsize,const void * object)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
i_ipadm_persist_propval(ipadm_handle_t iph,ipadm_prop_desc_t * pdp,const char * pval,const void * object,uint_t flags)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
i_ipadm_validate_if(ipadm_handle_t iph,const char * ifname,uint_t proto,uint_t flags)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
ipadm_legacy2new_propname(const char * oname,char * nname,uint_t nnamelen,uint_t * proto)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
ipadm_new2legacy_propname(const char * oname,char * nname,uint_t nnamelen,uint_t proto)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