10ba2cbe9Sxc151355 /* 20ba2cbe9Sxc151355 * CDDL HEADER START 30ba2cbe9Sxc151355 * 40ba2cbe9Sxc151355 * The contents of this file are subject to the terms of the 50ba2cbe9Sxc151355 * Common Development and Distribution License (the "License"). 60ba2cbe9Sxc151355 * You may not use this file except in compliance with the License. 70ba2cbe9Sxc151355 * 80ba2cbe9Sxc151355 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90ba2cbe9Sxc151355 * or http://www.opensolaris.org/os/licensing. 100ba2cbe9Sxc151355 * See the License for the specific language governing permissions 110ba2cbe9Sxc151355 * and limitations under the License. 120ba2cbe9Sxc151355 * 130ba2cbe9Sxc151355 * When distributing Covered Code, include this CDDL HEADER in each 140ba2cbe9Sxc151355 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150ba2cbe9Sxc151355 * If applicable, add the following below this CDDL HEADER, with the 160ba2cbe9Sxc151355 * fields enclosed by brackets "[]" replaced with your own identifying 170ba2cbe9Sxc151355 * information: Portions Copyright [yyyy] [name of copyright owner] 180ba2cbe9Sxc151355 * 190ba2cbe9Sxc151355 * CDDL HEADER END 200ba2cbe9Sxc151355 */ 210ba2cbe9Sxc151355 /* 22f4b3ec61Sdh155122 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230ba2cbe9Sxc151355 * Use is subject to license terms. 240ba2cbe9Sxc151355 */ 250ba2cbe9Sxc151355 260ba2cbe9Sxc151355 #pragma ident "%Z%%M% %I% %E% SMI" 270ba2cbe9Sxc151355 280ba2cbe9Sxc151355 #include <stdlib.h> 290ba2cbe9Sxc151355 #include <strings.h> 300ba2cbe9Sxc151355 #include <errno.h> 310ba2cbe9Sxc151355 #include <ctype.h> 32f4b3ec61Sdh155122 #include <sys/types.h> 330ba2cbe9Sxc151355 #include <sys/stat.h> 34f4b3ec61Sdh155122 #include <sys/dld.h> 35f4b3ec61Sdh155122 #include <sys/zone.h> 36f4b3ec61Sdh155122 #include <fcntl.h> 37f4b3ec61Sdh155122 #include <unistd.h> 38f4b3ec61Sdh155122 #include <libdevinfo.h> 39f4b3ec61Sdh155122 #include <zone.h> 40f595a68aSyz147064 #include <libdllink.h> 410ba2cbe9Sxc151355 #include <libdladm_impl.h> 42f595a68aSyz147064 #include <libdlwlan.h> 43f4b3ec61Sdh155122 #include <dlfcn.h> 44f4b3ec61Sdh155122 #include <link.h> 45f4b3ec61Sdh155122 460ba2cbe9Sxc151355 static dladm_status_t i_dladm_set_prop_db(const char *, const char *, 470ba2cbe9Sxc151355 char **, uint_t); 480ba2cbe9Sxc151355 static dladm_status_t i_dladm_get_prop_db(const char *, const char *, 490ba2cbe9Sxc151355 char **, uint_t *); 50f4b3ec61Sdh155122 static dladm_status_t i_dladm_get_prop_temp(const char *, dladm_prop_type_t, 51f4b3ec61Sdh155122 const char *, char **, uint_t *); 52f4b3ec61Sdh155122 static dladm_status_t i_dladm_set_prop_temp(const char *, const char *, 53f4b3ec61Sdh155122 char **, uint_t, uint_t, char **); 54f4b3ec61Sdh155122 static boolean_t i_dladm_is_prop_temponly(const char *prop_name, 55f4b3ec61Sdh155122 char **); 56f4b3ec61Sdh155122 57f4b3ec61Sdh155122 typedef struct val_desc { 58f4b3ec61Sdh155122 char *vd_name; 59f4b3ec61Sdh155122 void *vd_val; 60f4b3ec61Sdh155122 } val_desc_t; 61f4b3ec61Sdh155122 62f4b3ec61Sdh155122 struct prop_desc; 63f4b3ec61Sdh155122 64f4b3ec61Sdh155122 typedef dladm_status_t pd_getf_t(const char *, char **, uint_t *); 65f4b3ec61Sdh155122 typedef dladm_status_t pd_setf_t(const char *, val_desc_t *, uint_t); 66f4b3ec61Sdh155122 typedef dladm_status_t pd_checkf_t(struct prop_desc *, char **, 67f4b3ec61Sdh155122 uint_t, val_desc_t **); 68f4b3ec61Sdh155122 69f4b3ec61Sdh155122 static pd_getf_t do_get_zone; 70f4b3ec61Sdh155122 static pd_setf_t do_set_zone; 71f4b3ec61Sdh155122 static pd_checkf_t do_check_zone; 72f4b3ec61Sdh155122 73f4b3ec61Sdh155122 typedef struct prop_desc { 74f4b3ec61Sdh155122 char *pd_name; 75f4b3ec61Sdh155122 val_desc_t pd_defval; 76f4b3ec61Sdh155122 val_desc_t *pd_modval; 77f4b3ec61Sdh155122 uint_t pd_nmodval; 78f4b3ec61Sdh155122 boolean_t pd_temponly; 79f4b3ec61Sdh155122 pd_setf_t *pd_set; 80f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 81f4b3ec61Sdh155122 pd_getf_t *pd_get; 82f4b3ec61Sdh155122 pd_checkf_t *pd_check; 83f4b3ec61Sdh155122 } prop_desc_t; 84f4b3ec61Sdh155122 85f4b3ec61Sdh155122 static prop_desc_t prop_table[] = { 86f4b3ec61Sdh155122 { "zone", { "", NULL }, NULL, 0, B_TRUE, 87f4b3ec61Sdh155122 do_set_zone, NULL, 88f4b3ec61Sdh155122 do_get_zone, do_check_zone} 89f4b3ec61Sdh155122 }; 90f4b3ec61Sdh155122 91f4b3ec61Sdh155122 #define MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 920ba2cbe9Sxc151355 930ba2cbe9Sxc151355 dladm_status_t 940ba2cbe9Sxc151355 dladm_set_prop(const char *link, const char *prop_name, char **prop_val, 95f4b3ec61Sdh155122 uint_t val_cnt, uint_t flags, char **errprop) 960ba2cbe9Sxc151355 { 970ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_BADARG; 980ba2cbe9Sxc151355 990ba2cbe9Sxc151355 if (link == NULL || (prop_val == NULL && val_cnt > 0) || 1000ba2cbe9Sxc151355 (prop_val != NULL && val_cnt == 0) || flags == 0) 1010ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1020ba2cbe9Sxc151355 1030ba2cbe9Sxc151355 if ((flags & DLADM_OPT_TEMP) != 0) { 104f4b3ec61Sdh155122 status = i_dladm_set_prop_temp(link, prop_name, prop_val, 105f4b3ec61Sdh155122 val_cnt, flags, errprop); 106f4b3ec61Sdh155122 if (status == DLADM_STATUS_TEMPONLY && 107f4b3ec61Sdh155122 (flags & DLADM_OPT_PERSIST) != 0) 108f4b3ec61Sdh155122 return (DLADM_STATUS_TEMPONLY); 109f4b3ec61Sdh155122 110f4b3ec61Sdh155122 if (status == DLADM_STATUS_NOTFOUND) { 111f4b3ec61Sdh155122 status = DLADM_STATUS_BADARG; 112f595a68aSyz147064 if (dladm_wlan_is_valid(link)) { 113f595a68aSyz147064 status = dladm_wlan_set_prop(link, prop_name, 114f595a68aSyz147064 prop_val, val_cnt, errprop); 115f4b3ec61Sdh155122 } 1160ba2cbe9Sxc151355 } 1170ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 1180ba2cbe9Sxc151355 return (status); 1190ba2cbe9Sxc151355 } 1200ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) { 121f4b3ec61Sdh155122 if (i_dladm_is_prop_temponly(prop_name, errprop)) 122f4b3ec61Sdh155122 return (DLADM_STATUS_TEMPONLY); 123f4b3ec61Sdh155122 1240ba2cbe9Sxc151355 status = i_dladm_set_prop_db(link, prop_name, 1250ba2cbe9Sxc151355 prop_val, val_cnt); 1260ba2cbe9Sxc151355 } 1270ba2cbe9Sxc151355 return (status); 1280ba2cbe9Sxc151355 } 1290ba2cbe9Sxc151355 1300ba2cbe9Sxc151355 dladm_status_t 1310ba2cbe9Sxc151355 dladm_walk_prop(const char *link, void *arg, 1320ba2cbe9Sxc151355 boolean_t (*func)(void *, const char *)) 1330ba2cbe9Sxc151355 { 134f4b3ec61Sdh155122 int i; 135f4b3ec61Sdh155122 1360ba2cbe9Sxc151355 if (link == NULL || func == NULL) 1370ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1380ba2cbe9Sxc151355 139f4b3ec61Sdh155122 /* For wifi links, show wifi properties first */ 140f595a68aSyz147064 if (dladm_wlan_is_valid(link)) { 141f4b3ec61Sdh155122 dladm_status_t status; 142f4b3ec61Sdh155122 143f595a68aSyz147064 status = dladm_wlan_walk_prop(link, arg, func); 144f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 145f4b3ec61Sdh155122 return (status); 1460ba2cbe9Sxc151355 } 147f4b3ec61Sdh155122 148f4b3ec61Sdh155122 /* Then show data-link properties if there are any */ 149f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) { 150f4b3ec61Sdh155122 if (!func(arg, prop_table[i].pd_name)) 151f4b3ec61Sdh155122 break; 152f4b3ec61Sdh155122 } 153f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1540ba2cbe9Sxc151355 } 1550ba2cbe9Sxc151355 1560ba2cbe9Sxc151355 dladm_status_t 1570ba2cbe9Sxc151355 dladm_get_prop(const char *link, dladm_prop_type_t type, 1580ba2cbe9Sxc151355 const char *prop_name, char **prop_val, uint_t *val_cntp) 1590ba2cbe9Sxc151355 { 160f4b3ec61Sdh155122 dladm_status_t status; 161f4b3ec61Sdh155122 1620ba2cbe9Sxc151355 if (link == NULL || prop_name == NULL || prop_val == NULL || 1630ba2cbe9Sxc151355 val_cntp == NULL || *val_cntp == 0) 1640ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1650ba2cbe9Sxc151355 1660ba2cbe9Sxc151355 if (type == DLADM_PROP_VAL_PERSISTENT) { 167f595a68aSyz147064 if (i_dladm_is_prop_temponly(prop_name, NULL)) 168f595a68aSyz147064 return (DLADM_STATUS_TEMPONLY); 1690ba2cbe9Sxc151355 return (i_dladm_get_prop_db(link, prop_name, 1700ba2cbe9Sxc151355 prop_val, val_cntp)); 1710ba2cbe9Sxc151355 } 1720ba2cbe9Sxc151355 173f4b3ec61Sdh155122 status = i_dladm_get_prop_temp(link, type, prop_name, 174f4b3ec61Sdh155122 prop_val, val_cntp); 175f4b3ec61Sdh155122 if (status != DLADM_STATUS_NOTFOUND) 176f4b3ec61Sdh155122 return (status); 177f4b3ec61Sdh155122 178f595a68aSyz147064 if (dladm_wlan_is_valid(link)) { 179f595a68aSyz147064 return (dladm_wlan_get_prop(link, type, prop_name, 180f595a68aSyz147064 prop_val, val_cntp)); 1810ba2cbe9Sxc151355 } 1820ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1830ba2cbe9Sxc151355 } 1840ba2cbe9Sxc151355 1850ba2cbe9Sxc151355 /* 1860ba2cbe9Sxc151355 * Data structures used for implementing persistent link properties 1870ba2cbe9Sxc151355 */ 1880ba2cbe9Sxc151355 typedef struct linkprop_val { 1890ba2cbe9Sxc151355 const char *lv_name; 1900ba2cbe9Sxc151355 struct linkprop_val *lv_nextval; 1910ba2cbe9Sxc151355 } linkprop_val_t; 1920ba2cbe9Sxc151355 1930ba2cbe9Sxc151355 typedef struct linkprop_info { 1940ba2cbe9Sxc151355 const char *li_name; 1950ba2cbe9Sxc151355 struct linkprop_info *li_nextprop; 1960ba2cbe9Sxc151355 struct linkprop_val *li_val; 1970ba2cbe9Sxc151355 } linkprop_info_t; 1980ba2cbe9Sxc151355 1990ba2cbe9Sxc151355 typedef struct linkprop_db_state linkprop_db_state_t; 2000ba2cbe9Sxc151355 2010ba2cbe9Sxc151355 typedef boolean_t (*linkprop_db_op_t)(linkprop_db_state_t *, 2020ba2cbe9Sxc151355 char *, linkprop_info_t *, dladm_status_t *); 2030ba2cbe9Sxc151355 2040ba2cbe9Sxc151355 struct linkprop_db_state { 2050ba2cbe9Sxc151355 linkprop_db_op_t ls_op; 2060ba2cbe9Sxc151355 const char *ls_link; 2070ba2cbe9Sxc151355 const char *ls_propname; 2080ba2cbe9Sxc151355 char **ls_propval; 2090ba2cbe9Sxc151355 uint_t *ls_valcntp; 2100ba2cbe9Sxc151355 }; 2110ba2cbe9Sxc151355 2120ba2cbe9Sxc151355 static void 2130ba2cbe9Sxc151355 free_linkprops(linkprop_info_t *lip) 2140ba2cbe9Sxc151355 { 2150ba2cbe9Sxc151355 linkprop_info_t *lip_next; 2160ba2cbe9Sxc151355 linkprop_val_t *lvp, *lvp_next; 2170ba2cbe9Sxc151355 2180ba2cbe9Sxc151355 for (; lip != NULL; lip = lip_next) { 2190ba2cbe9Sxc151355 lip_next = lip->li_nextprop; 2200ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp_next) { 2210ba2cbe9Sxc151355 lvp_next = lvp->lv_nextval; 2220ba2cbe9Sxc151355 free(lvp); 2230ba2cbe9Sxc151355 } 2240ba2cbe9Sxc151355 free(lip); 2250ba2cbe9Sxc151355 } 2260ba2cbe9Sxc151355 } 2270ba2cbe9Sxc151355 2280ba2cbe9Sxc151355 /* 2290ba2cbe9Sxc151355 * Generate an entry in the link property database. 2300ba2cbe9Sxc151355 * Each entry has this format: 2310ba2cbe9Sxc151355 * <linkname> <prop0>=<val0>,...,<valn>;...;<propn>=<val0>,...,<valn>; 2320ba2cbe9Sxc151355 */ 2330ba2cbe9Sxc151355 static void 2340ba2cbe9Sxc151355 generate_linkprop_line(linkprop_db_state_t *lsp, char *buf, 2350ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 2360ba2cbe9Sxc151355 { 2370ba2cbe9Sxc151355 char tmpbuf[MAXLINELEN]; 2380ba2cbe9Sxc151355 char *ptr, *lim = tmpbuf + MAXLINELEN; 2390ba2cbe9Sxc151355 linkprop_info_t *lip = listp; 2400ba2cbe9Sxc151355 linkprop_val_t *lvp = NULL; 2410ba2cbe9Sxc151355 2420ba2cbe9Sxc151355 /* 2430ba2cbe9Sxc151355 * Delete line if there are no properties left. 2440ba2cbe9Sxc151355 */ 2450ba2cbe9Sxc151355 if (lip == NULL || 2460ba2cbe9Sxc151355 (lip->li_val == NULL && lip->li_nextprop == NULL)) { 2470ba2cbe9Sxc151355 buf[0] = '\0'; 2480ba2cbe9Sxc151355 return; 2490ba2cbe9Sxc151355 } 2500ba2cbe9Sxc151355 ptr = tmpbuf; 2510ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", lsp->ls_link); 2520ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 2530ba2cbe9Sxc151355 /* 2540ba2cbe9Sxc151355 * Skip properties without values. 2550ba2cbe9Sxc151355 */ 2560ba2cbe9Sxc151355 if (lip->li_val == NULL) 2570ba2cbe9Sxc151355 continue; 2580ba2cbe9Sxc151355 2590ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s=", lip->li_name); 2600ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp->lv_nextval) { 2610ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s%c", 2620ba2cbe9Sxc151355 lvp->lv_name, 2630ba2cbe9Sxc151355 ((lvp->lv_nextval == NULL) ? ';' : ',')); 2640ba2cbe9Sxc151355 } 2650ba2cbe9Sxc151355 } 2660ba2cbe9Sxc151355 if (ptr > lim) { 2670ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL; 2680ba2cbe9Sxc151355 return; 2690ba2cbe9Sxc151355 } 2700ba2cbe9Sxc151355 (void) snprintf(buf, MAXLINELEN, "%s\n", tmpbuf); 2710ba2cbe9Sxc151355 } 2720ba2cbe9Sxc151355 2730ba2cbe9Sxc151355 /* 2740ba2cbe9Sxc151355 * This function is used to update or create an entry in the persistent db. 2750ba2cbe9Sxc151355 * process_linkprop_db() will first scan the db for an entry matching the 2760ba2cbe9Sxc151355 * specified link. If a match is found, this function is invoked with the 2770ba2cbe9Sxc151355 * entry's contents (buf) and its linked-list representation (listp). lsp 2780ba2cbe9Sxc151355 * holds the name and values of the property to be added or updated; this 2790ba2cbe9Sxc151355 * information will be merged with listp. Subsequently, an updated entry 2800ba2cbe9Sxc151355 * will be written to buf, which will in turn be written to disk by 2810ba2cbe9Sxc151355 * process_linkprop_db(). If no entry matches the specified link, listp 2820ba2cbe9Sxc151355 * will be NULL; a new entry will be generated in this case and it will 2830ba2cbe9Sxc151355 * contain only the property information in lsp. 2840ba2cbe9Sxc151355 */ 2850ba2cbe9Sxc151355 static boolean_t 2860ba2cbe9Sxc151355 process_linkprop_set(linkprop_db_state_t *lsp, char *buf, 2870ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 2880ba2cbe9Sxc151355 { 2890ba2cbe9Sxc151355 dladm_status_t status; 2900ba2cbe9Sxc151355 linkprop_info_t *lastp = NULL, *lip = listp, *nlip = NULL; 2910ba2cbe9Sxc151355 linkprop_val_t **lvpp; 2920ba2cbe9Sxc151355 int i; 2930ba2cbe9Sxc151355 2940ba2cbe9Sxc151355 if (lsp->ls_propname == NULL) { 2950ba2cbe9Sxc151355 buf[0] = '\0'; 2960ba2cbe9Sxc151355 return (B_FALSE); 2970ba2cbe9Sxc151355 } 2980ba2cbe9Sxc151355 2990ba2cbe9Sxc151355 /* 3000ba2cbe9Sxc151355 * Find the linkprop we want to change. 3010ba2cbe9Sxc151355 */ 3020ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 3030ba2cbe9Sxc151355 if (strcmp(lip->li_name, lsp->ls_propname) == 0) 3040ba2cbe9Sxc151355 break; 3050ba2cbe9Sxc151355 3060ba2cbe9Sxc151355 lastp = lip; 3070ba2cbe9Sxc151355 } 3080ba2cbe9Sxc151355 3090ba2cbe9Sxc151355 if (lip == NULL) { 3100ba2cbe9Sxc151355 /* 3110ba2cbe9Sxc151355 * If the linkprop is not found, append it to the list. 3120ba2cbe9Sxc151355 */ 3130ba2cbe9Sxc151355 if ((nlip = malloc(sizeof (linkprop_info_t))) == NULL) { 3140ba2cbe9Sxc151355 status = DLADM_STATUS_NOMEM; 3150ba2cbe9Sxc151355 goto fail; 3160ba2cbe9Sxc151355 } 3170ba2cbe9Sxc151355 /* 3180ba2cbe9Sxc151355 * nlip will need to be freed later if there is no list to 3190ba2cbe9Sxc151355 * append to. 3200ba2cbe9Sxc151355 */ 3210ba2cbe9Sxc151355 if (lastp != NULL) 3220ba2cbe9Sxc151355 lastp->li_nextprop = nlip; 3230ba2cbe9Sxc151355 nlip->li_name = lsp->ls_propname; 3240ba2cbe9Sxc151355 nlip->li_nextprop = NULL; 3250ba2cbe9Sxc151355 nlip->li_val = NULL; 3260ba2cbe9Sxc151355 lvpp = &nlip->li_val; 3270ba2cbe9Sxc151355 } else { 3280ba2cbe9Sxc151355 linkprop_val_t *lvp, *lvp_next; 3290ba2cbe9Sxc151355 3300ba2cbe9Sxc151355 /* 3310ba2cbe9Sxc151355 * If the linkprop is found, delete the existing values from it. 3320ba2cbe9Sxc151355 */ 3330ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp_next) { 3340ba2cbe9Sxc151355 lvp_next = lvp->lv_nextval; 3350ba2cbe9Sxc151355 free(lvp); 3360ba2cbe9Sxc151355 } 3370ba2cbe9Sxc151355 lip->li_val = NULL; 3380ba2cbe9Sxc151355 lvpp = &lip->li_val; 3390ba2cbe9Sxc151355 } 3400ba2cbe9Sxc151355 3410ba2cbe9Sxc151355 /* 3420ba2cbe9Sxc151355 * Fill our linkprop with the specified values. 3430ba2cbe9Sxc151355 */ 3440ba2cbe9Sxc151355 for (i = 0; i < *lsp->ls_valcntp; i++) { 3450ba2cbe9Sxc151355 if ((*lvpp = malloc(sizeof (linkprop_val_t))) == NULL) { 3460ba2cbe9Sxc151355 status = DLADM_STATUS_NOMEM; 3470ba2cbe9Sxc151355 goto fail; 3480ba2cbe9Sxc151355 } 3490ba2cbe9Sxc151355 (*lvpp)->lv_name = lsp->ls_propval[i]; 3500ba2cbe9Sxc151355 (*lvpp)->lv_nextval = NULL; 3510ba2cbe9Sxc151355 lvpp = &(*lvpp)->lv_nextval; 3520ba2cbe9Sxc151355 } 3530ba2cbe9Sxc151355 3540ba2cbe9Sxc151355 if (listp != NULL) { 3550ba2cbe9Sxc151355 generate_linkprop_line(lsp, buf, listp, statusp); 3560ba2cbe9Sxc151355 } else { 3570ba2cbe9Sxc151355 generate_linkprop_line(lsp, buf, nlip, statusp); 3580ba2cbe9Sxc151355 free_linkprops(nlip); 3590ba2cbe9Sxc151355 } 3600ba2cbe9Sxc151355 return (B_FALSE); 3610ba2cbe9Sxc151355 3620ba2cbe9Sxc151355 fail: 3630ba2cbe9Sxc151355 *statusp = status; 3640ba2cbe9Sxc151355 if (listp == NULL) 3650ba2cbe9Sxc151355 free_linkprops(nlip); 3660ba2cbe9Sxc151355 3670ba2cbe9Sxc151355 return (B_FALSE); 3680ba2cbe9Sxc151355 } 3690ba2cbe9Sxc151355 3700ba2cbe9Sxc151355 /* 3710ba2cbe9Sxc151355 * This function is used for retrieving the values for a specific property. 3720ba2cbe9Sxc151355 * It gets called if an entry matching the specified link exists in the db. 3730ba2cbe9Sxc151355 * The entry is converted into a linked-list listp. This list is then scanned 3740ba2cbe9Sxc151355 * for the specified property name; if a matching property exists, its 3750ba2cbe9Sxc151355 * associated values are copied to the array lsp->ls_propval. 3760ba2cbe9Sxc151355 */ 3770ba2cbe9Sxc151355 /* ARGSUSED */ 3780ba2cbe9Sxc151355 static boolean_t 3790ba2cbe9Sxc151355 process_linkprop_get(linkprop_db_state_t *lsp, char *buf, 3800ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 3810ba2cbe9Sxc151355 { 3820ba2cbe9Sxc151355 linkprop_info_t *lip = listp; 3830ba2cbe9Sxc151355 linkprop_val_t *lvp; 3840ba2cbe9Sxc151355 uint_t valcnt = 0; 3850ba2cbe9Sxc151355 3860ba2cbe9Sxc151355 /* 3870ba2cbe9Sxc151355 * Find the linkprop we want to get. 3880ba2cbe9Sxc151355 */ 3890ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 3900ba2cbe9Sxc151355 if (strcmp(lip->li_name, lsp->ls_propname) == 0) 3910ba2cbe9Sxc151355 break; 3920ba2cbe9Sxc151355 } 3930ba2cbe9Sxc151355 if (lip == NULL) { 3940ba2cbe9Sxc151355 *statusp = DLADM_STATUS_NOTFOUND; 3950ba2cbe9Sxc151355 return (B_FALSE); 3960ba2cbe9Sxc151355 } 3970ba2cbe9Sxc151355 3980ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp->lv_nextval) { 3990ba2cbe9Sxc151355 (void) strncpy(lsp->ls_propval[valcnt], lvp->lv_name, 4000ba2cbe9Sxc151355 DLADM_PROP_VAL_MAX); 4010ba2cbe9Sxc151355 4020ba2cbe9Sxc151355 if (++valcnt >= *lsp->ls_valcntp && lvp->lv_nextval != NULL) { 4030ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL; 4040ba2cbe9Sxc151355 return (B_FALSE); 4050ba2cbe9Sxc151355 } 4060ba2cbe9Sxc151355 } 4070ba2cbe9Sxc151355 /* 4080ba2cbe9Sxc151355 * This function is meant to be called at most once for each call 4090ba2cbe9Sxc151355 * to process_linkprop_db(). For this reason, it's ok to overwrite 4100ba2cbe9Sxc151355 * the caller's valcnt array size with the actual number of values 4110ba2cbe9Sxc151355 * returned. 4120ba2cbe9Sxc151355 */ 4130ba2cbe9Sxc151355 *lsp->ls_valcntp = valcnt; 4140ba2cbe9Sxc151355 return (B_FALSE); 4150ba2cbe9Sxc151355 } 4160ba2cbe9Sxc151355 4170ba2cbe9Sxc151355 /* 4180ba2cbe9Sxc151355 * This is used for initializing link properties. 4190ba2cbe9Sxc151355 * Unlike the other routines, this gets called for every entry in the 4200ba2cbe9Sxc151355 * database. lsp->ls_link is not user-specified but instead is set to 4210ba2cbe9Sxc151355 * the current link being processed. 4220ba2cbe9Sxc151355 */ 4230ba2cbe9Sxc151355 /* ARGSUSED */ 4240ba2cbe9Sxc151355 static boolean_t 4250ba2cbe9Sxc151355 process_linkprop_init(linkprop_db_state_t *lsp, char *buf, 4260ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 4270ba2cbe9Sxc151355 { 4280ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 4290ba2cbe9Sxc151355 linkprop_info_t *lip = listp; 4300ba2cbe9Sxc151355 linkprop_val_t *lvp; 4310ba2cbe9Sxc151355 uint_t valcnt, i; 4320ba2cbe9Sxc151355 char **propval; 4330ba2cbe9Sxc151355 4340ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 4350ba2cbe9Sxc151355 /* 4360ba2cbe9Sxc151355 * Construct the propval array and fill it with 4370ba2cbe9Sxc151355 * values from listp. 4380ba2cbe9Sxc151355 */ 4390ba2cbe9Sxc151355 for (lvp = lip->li_val, valcnt = 0; 440948f2876Sss150715 lvp != NULL; lvp = lvp->lv_nextval, valcnt++) 441948f2876Sss150715 ; 4420ba2cbe9Sxc151355 4430ba2cbe9Sxc151355 propval = malloc(sizeof (char *) * valcnt); 4440ba2cbe9Sxc151355 if (propval == NULL) { 4450ba2cbe9Sxc151355 *statusp = DLADM_STATUS_NOMEM; 4460ba2cbe9Sxc151355 break; 4470ba2cbe9Sxc151355 } 4480ba2cbe9Sxc151355 lvp = lip->li_val; 4490ba2cbe9Sxc151355 for (i = 0; i < valcnt; i++, lvp = lvp->lv_nextval) 4500ba2cbe9Sxc151355 propval[i] = (char *)lvp->lv_name; 4510ba2cbe9Sxc151355 4520ba2cbe9Sxc151355 status = dladm_set_prop(lsp->ls_link, lip->li_name, 453f4b3ec61Sdh155122 propval, valcnt, DLADM_OPT_TEMP, NULL); 4540ba2cbe9Sxc151355 4550ba2cbe9Sxc151355 /* 4560ba2cbe9Sxc151355 * We continue with initializing other properties even 4570ba2cbe9Sxc151355 * after encountering an error. This error will be 4580ba2cbe9Sxc151355 * propagated to the caller via 'statusp'. 4590ba2cbe9Sxc151355 */ 4600ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 4610ba2cbe9Sxc151355 *statusp = status; 4620ba2cbe9Sxc151355 4630ba2cbe9Sxc151355 free(propval); 4640ba2cbe9Sxc151355 } 4650ba2cbe9Sxc151355 return (B_TRUE); 4660ba2cbe9Sxc151355 } 4670ba2cbe9Sxc151355 4680ba2cbe9Sxc151355 static int 4690ba2cbe9Sxc151355 parse_linkprops(char *buf, linkprop_info_t **lipp) 4700ba2cbe9Sxc151355 { 4710ba2cbe9Sxc151355 int i, len; 4720ba2cbe9Sxc151355 char *curr; 4730ba2cbe9Sxc151355 linkprop_info_t *lip = NULL; 4740ba2cbe9Sxc151355 linkprop_info_t **tailp = lipp; 4750ba2cbe9Sxc151355 linkprop_val_t *lvp = NULL; 4760ba2cbe9Sxc151355 linkprop_val_t **vtailp = NULL; 4770ba2cbe9Sxc151355 4780ba2cbe9Sxc151355 curr = buf; 4790ba2cbe9Sxc151355 len = strlen(buf); 4800ba2cbe9Sxc151355 for (i = 0; i < len; i++) { 4810ba2cbe9Sxc151355 char c = buf[i]; 4820ba2cbe9Sxc151355 boolean_t match = (c == '=' || c == ',' || c == ';'); 4830ba2cbe9Sxc151355 4840ba2cbe9Sxc151355 /* 4850ba2cbe9Sxc151355 * Move to the next character if there is no match and 4860ba2cbe9Sxc151355 * if we have not reached the last character. 4870ba2cbe9Sxc151355 */ 4880ba2cbe9Sxc151355 if (!match && i != len - 1) 4890ba2cbe9Sxc151355 continue; 4900ba2cbe9Sxc151355 4910ba2cbe9Sxc151355 if (match) { 4920ba2cbe9Sxc151355 /* 4930ba2cbe9Sxc151355 * Nul-terminate the string pointed to by 'curr'. 4940ba2cbe9Sxc151355 */ 4950ba2cbe9Sxc151355 buf[i] = '\0'; 4960ba2cbe9Sxc151355 if (*curr == '\0') 4970ba2cbe9Sxc151355 goto fail; 4980ba2cbe9Sxc151355 } 4990ba2cbe9Sxc151355 5000ba2cbe9Sxc151355 if (lip != NULL) { 5010ba2cbe9Sxc151355 /* 5020ba2cbe9Sxc151355 * We get here after we have processed the "<prop>=" 5030ba2cbe9Sxc151355 * pattern. The pattern we are now interested in is 5040ba2cbe9Sxc151355 * "<val0>,<val1>,...,<valn>;". For each value we 5050ba2cbe9Sxc151355 * find, a linkprop_val_t will be allocated and 5060ba2cbe9Sxc151355 * added to the current 'lip'. 5070ba2cbe9Sxc151355 */ 5080ba2cbe9Sxc151355 if (c == '=') 5090ba2cbe9Sxc151355 goto fail; 5100ba2cbe9Sxc151355 5110ba2cbe9Sxc151355 lvp = malloc(sizeof (*lvp)); 5120ba2cbe9Sxc151355 if (lvp == NULL) 5130ba2cbe9Sxc151355 goto fail; 5140ba2cbe9Sxc151355 5150ba2cbe9Sxc151355 lvp->lv_name = curr; 5160ba2cbe9Sxc151355 lvp->lv_nextval = NULL; 5170ba2cbe9Sxc151355 *vtailp = lvp; 5180ba2cbe9Sxc151355 vtailp = &lvp->lv_nextval; 5190ba2cbe9Sxc151355 5200ba2cbe9Sxc151355 if (c == ';') { 5210ba2cbe9Sxc151355 tailp = &lip->li_nextprop; 5220ba2cbe9Sxc151355 vtailp = NULL; 5230ba2cbe9Sxc151355 lip = NULL; 5240ba2cbe9Sxc151355 } 5250ba2cbe9Sxc151355 } else { 5260ba2cbe9Sxc151355 /* 5270ba2cbe9Sxc151355 * lip == NULL indicates that 'curr' must be refering 5280ba2cbe9Sxc151355 * to a property name. We allocate a new linkprop_info_t 5290ba2cbe9Sxc151355 * append it to the list given by the caller. 5300ba2cbe9Sxc151355 */ 5310ba2cbe9Sxc151355 if (c != '=') 5320ba2cbe9Sxc151355 goto fail; 5330ba2cbe9Sxc151355 5340ba2cbe9Sxc151355 lip = malloc(sizeof (*lip)); 5350ba2cbe9Sxc151355 if (lip == NULL) 5360ba2cbe9Sxc151355 goto fail; 5370ba2cbe9Sxc151355 5380ba2cbe9Sxc151355 lip->li_name = curr; 5390ba2cbe9Sxc151355 lip->li_val = NULL; 5400ba2cbe9Sxc151355 lip->li_nextprop = NULL; 5410ba2cbe9Sxc151355 *tailp = lip; 5420ba2cbe9Sxc151355 vtailp = &lip->li_val; 5430ba2cbe9Sxc151355 } 5440ba2cbe9Sxc151355 curr = buf + i + 1; 5450ba2cbe9Sxc151355 } 5460ba2cbe9Sxc151355 /* 5470ba2cbe9Sxc151355 * The list must be non-empty and the last character must be ';'. 5480ba2cbe9Sxc151355 */ 5490ba2cbe9Sxc151355 if (*lipp == NULL || lip != NULL) 5500ba2cbe9Sxc151355 goto fail; 5510ba2cbe9Sxc151355 5520ba2cbe9Sxc151355 return (0); 5530ba2cbe9Sxc151355 5540ba2cbe9Sxc151355 fail: 5550ba2cbe9Sxc151355 free_linkprops(*lipp); 5560ba2cbe9Sxc151355 *lipp = NULL; 5570ba2cbe9Sxc151355 return (-1); 5580ba2cbe9Sxc151355 } 5590ba2cbe9Sxc151355 5600ba2cbe9Sxc151355 static boolean_t 5610ba2cbe9Sxc151355 process_linkprop_line(linkprop_db_state_t *lsp, char *buf, 5620ba2cbe9Sxc151355 dladm_status_t *statusp) 5630ba2cbe9Sxc151355 { 5640ba2cbe9Sxc151355 linkprop_info_t *lip = NULL; 5650ba2cbe9Sxc151355 int i, len, llen; 5660ba2cbe9Sxc151355 char *str, *lasts; 5670ba2cbe9Sxc151355 boolean_t cont, nolink = B_FALSE; 5680ba2cbe9Sxc151355 5690ba2cbe9Sxc151355 /* 5700ba2cbe9Sxc151355 * Skip leading spaces, blank lines, and comments. 5710ba2cbe9Sxc151355 */ 5720ba2cbe9Sxc151355 len = strlen(buf); 5730ba2cbe9Sxc151355 for (i = 0; i < len; i++) { 5740ba2cbe9Sxc151355 if (!isspace(buf[i])) 5750ba2cbe9Sxc151355 break; 5760ba2cbe9Sxc151355 } 5770ba2cbe9Sxc151355 if (i == len || buf[i] == '#') 5780ba2cbe9Sxc151355 return (B_TRUE); 5790ba2cbe9Sxc151355 5800ba2cbe9Sxc151355 str = buf + i; 5810ba2cbe9Sxc151355 if (lsp->ls_link != NULL) { 5820ba2cbe9Sxc151355 /* 5830ba2cbe9Sxc151355 * Skip links we're not interested in. 5840ba2cbe9Sxc151355 * Note that strncmp() and isspace() are used here 5850ba2cbe9Sxc151355 * instead of strtok() and strcmp() because we don't 5860ba2cbe9Sxc151355 * want to modify buf in case it does not contain the 5870ba2cbe9Sxc151355 * specified link. 5880ba2cbe9Sxc151355 */ 5890ba2cbe9Sxc151355 llen = strlen(lsp->ls_link); 5900ba2cbe9Sxc151355 if (strncmp(str, lsp->ls_link, llen) != 0 || 5910ba2cbe9Sxc151355 !isspace(str[llen])) 5920ba2cbe9Sxc151355 return (B_TRUE); 5930ba2cbe9Sxc151355 } else { 5940ba2cbe9Sxc151355 /* 5950ba2cbe9Sxc151355 * If a link is not specified, find the link name 5960ba2cbe9Sxc151355 * and assign it to lsp->ls_link. 5970ba2cbe9Sxc151355 */ 5980ba2cbe9Sxc151355 if (strtok_r(str, " \n\t", &lasts) == NULL) 5990ba2cbe9Sxc151355 goto fail; 6000ba2cbe9Sxc151355 6010ba2cbe9Sxc151355 llen = strlen(str); 6020ba2cbe9Sxc151355 lsp->ls_link = str; 6030ba2cbe9Sxc151355 nolink = B_TRUE; 6040ba2cbe9Sxc151355 } 6050ba2cbe9Sxc151355 str += llen + 1; 6060ba2cbe9Sxc151355 if (str >= buf + len) 6070ba2cbe9Sxc151355 goto fail; 6080ba2cbe9Sxc151355 6090ba2cbe9Sxc151355 /* 6100ba2cbe9Sxc151355 * Now find the list of link properties. 6110ba2cbe9Sxc151355 */ 6120ba2cbe9Sxc151355 if ((str = strtok_r(str, " \n\t", &lasts)) == NULL) 6130ba2cbe9Sxc151355 goto fail; 6140ba2cbe9Sxc151355 6150ba2cbe9Sxc151355 if (parse_linkprops(str, &lip) < 0) 6160ba2cbe9Sxc151355 goto fail; 6170ba2cbe9Sxc151355 6180ba2cbe9Sxc151355 cont = (*lsp->ls_op)(lsp, buf, lip, statusp); 6190ba2cbe9Sxc151355 free_linkprops(lip); 6200ba2cbe9Sxc151355 if (nolink) 6210ba2cbe9Sxc151355 lsp->ls_link = NULL; 6220ba2cbe9Sxc151355 return (cont); 6230ba2cbe9Sxc151355 6240ba2cbe9Sxc151355 fail: 6250ba2cbe9Sxc151355 free_linkprops(lip); 6260ba2cbe9Sxc151355 if (nolink) 6270ba2cbe9Sxc151355 lsp->ls_link = NULL; 6280ba2cbe9Sxc151355 6290ba2cbe9Sxc151355 /* 6300ba2cbe9Sxc151355 * Delete corrupted line. 6310ba2cbe9Sxc151355 */ 6320ba2cbe9Sxc151355 buf[0] = '\0'; 6330ba2cbe9Sxc151355 return (B_TRUE); 6340ba2cbe9Sxc151355 } 6350ba2cbe9Sxc151355 6360ba2cbe9Sxc151355 static dladm_status_t 6370ba2cbe9Sxc151355 process_linkprop_db(void *arg, FILE *fp, FILE *nfp) 6380ba2cbe9Sxc151355 { 6390ba2cbe9Sxc151355 linkprop_db_state_t *lsp = arg; 6400ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 6410ba2cbe9Sxc151355 char buf[MAXLINELEN]; 6420ba2cbe9Sxc151355 boolean_t cont = B_TRUE; 6430ba2cbe9Sxc151355 6440ba2cbe9Sxc151355 /* 6450ba2cbe9Sxc151355 * This loop processes each line of the configuration file. 6460ba2cbe9Sxc151355 * buf can potentially be modified by process_linkprop_line(). 6470ba2cbe9Sxc151355 * If this is a write operation and buf is not truncated, buf will 6480ba2cbe9Sxc151355 * be written to disk. process_linkprop_line() will no longer be 6490ba2cbe9Sxc151355 * called after it returns B_FALSE; at which point the remainder 6500ba2cbe9Sxc151355 * of the file will continue to be read and, if necessary, written 6510ba2cbe9Sxc151355 * to disk as well. 6520ba2cbe9Sxc151355 */ 6530ba2cbe9Sxc151355 while (fgets(buf, MAXLINELEN, fp) != NULL) { 6540ba2cbe9Sxc151355 if (cont) 6550ba2cbe9Sxc151355 cont = process_linkprop_line(lsp, buf, &status); 6560ba2cbe9Sxc151355 6570ba2cbe9Sxc151355 if (nfp != NULL && buf[0] != '\0' && fputs(buf, nfp) == EOF) { 6580ba2cbe9Sxc151355 status = dladm_errno2status(errno); 6590ba2cbe9Sxc151355 break; 6600ba2cbe9Sxc151355 } 6610ba2cbe9Sxc151355 } 6620ba2cbe9Sxc151355 6630ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK || !cont) 6640ba2cbe9Sxc151355 return (status); 6650ba2cbe9Sxc151355 6660ba2cbe9Sxc151355 if (lsp->ls_op == process_linkprop_set) { 6670ba2cbe9Sxc151355 /* 6680ba2cbe9Sxc151355 * If the specified link is not found above, we add the 6690ba2cbe9Sxc151355 * link and its properties to the configuration file. 6700ba2cbe9Sxc151355 */ 6710ba2cbe9Sxc151355 (void) (*lsp->ls_op)(lsp, buf, NULL, &status); 6720ba2cbe9Sxc151355 if (status == DLADM_STATUS_OK && fputs(buf, nfp) == EOF) 6730ba2cbe9Sxc151355 status = dladm_errno2status(errno); 6740ba2cbe9Sxc151355 } 6750ba2cbe9Sxc151355 6760ba2cbe9Sxc151355 if (lsp->ls_op == process_linkprop_get) 6770ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 6780ba2cbe9Sxc151355 6790ba2cbe9Sxc151355 return (status); 6800ba2cbe9Sxc151355 } 6810ba2cbe9Sxc151355 6820ba2cbe9Sxc151355 #define LINKPROP_RW_DB(statep, writeop) \ 6830ba2cbe9Sxc151355 (i_dladm_rw_db("/etc/dladm/linkprop.conf", \ 6840ba2cbe9Sxc151355 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, process_linkprop_db, \ 6850ba2cbe9Sxc151355 (statep), (writeop))) 6860ba2cbe9Sxc151355 6870ba2cbe9Sxc151355 static dladm_status_t 6880ba2cbe9Sxc151355 i_dladm_set_prop_db(const char *link, const char *prop_name, 6890ba2cbe9Sxc151355 char **prop_val, uint_t val_cnt) 6900ba2cbe9Sxc151355 { 6910ba2cbe9Sxc151355 linkprop_db_state_t state; 6920ba2cbe9Sxc151355 6930ba2cbe9Sxc151355 state.ls_op = process_linkprop_set; 6940ba2cbe9Sxc151355 state.ls_link = link; 6950ba2cbe9Sxc151355 state.ls_propname = prop_name; 6960ba2cbe9Sxc151355 state.ls_propval = prop_val; 6970ba2cbe9Sxc151355 state.ls_valcntp = &val_cnt; 6980ba2cbe9Sxc151355 6990ba2cbe9Sxc151355 return (LINKPROP_RW_DB(&state, B_TRUE)); 7000ba2cbe9Sxc151355 } 7010ba2cbe9Sxc151355 7020ba2cbe9Sxc151355 static dladm_status_t 7030ba2cbe9Sxc151355 i_dladm_get_prop_db(const char *link, const char *prop_name, 7040ba2cbe9Sxc151355 char **prop_val, uint_t *val_cntp) 7050ba2cbe9Sxc151355 { 7060ba2cbe9Sxc151355 linkprop_db_state_t state; 7070ba2cbe9Sxc151355 7080ba2cbe9Sxc151355 state.ls_op = process_linkprop_get; 7090ba2cbe9Sxc151355 state.ls_link = link; 7100ba2cbe9Sxc151355 state.ls_propname = prop_name; 7110ba2cbe9Sxc151355 state.ls_propval = prop_val; 7120ba2cbe9Sxc151355 state.ls_valcntp = val_cntp; 7130ba2cbe9Sxc151355 7140ba2cbe9Sxc151355 return (LINKPROP_RW_DB(&state, B_FALSE)); 7150ba2cbe9Sxc151355 } 7160ba2cbe9Sxc151355 7170ba2cbe9Sxc151355 dladm_status_t 7180ba2cbe9Sxc151355 dladm_init_linkprop(void) 7190ba2cbe9Sxc151355 { 7200ba2cbe9Sxc151355 linkprop_db_state_t state; 7210ba2cbe9Sxc151355 7220ba2cbe9Sxc151355 state.ls_op = process_linkprop_init; 7230ba2cbe9Sxc151355 state.ls_link = NULL; 7240ba2cbe9Sxc151355 state.ls_propname = NULL; 7250ba2cbe9Sxc151355 state.ls_propval = NULL; 7260ba2cbe9Sxc151355 state.ls_valcntp = NULL; 7270ba2cbe9Sxc151355 7280ba2cbe9Sxc151355 return (LINKPROP_RW_DB(&state, B_FALSE)); 7290ba2cbe9Sxc151355 } 730f4b3ec61Sdh155122 731f4b3ec61Sdh155122 static dladm_status_t 732f4b3ec61Sdh155122 i_dladm_get_zoneid(const char *link, zoneid_t *zidp) 733f4b3ec61Sdh155122 { 734f4b3ec61Sdh155122 int fd; 735f4b3ec61Sdh155122 dld_hold_vlan_t dhv; 736f4b3ec61Sdh155122 737f4b3ec61Sdh155122 if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) 738f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 739f4b3ec61Sdh155122 740f4b3ec61Sdh155122 bzero(&dhv, sizeof (dld_hold_vlan_t)); 741f4b3ec61Sdh155122 (void) strlcpy(dhv.dhv_name, link, IFNAMSIZ); 742f4b3ec61Sdh155122 dhv.dhv_zid = -1; 743f4b3ec61Sdh155122 744*47a01978Sbw if (i_dladm_ioctl(fd, DLDIOCZIDGET, &dhv, sizeof (dhv)) < 0) { 745*47a01978Sbw if (errno == ENOENT) { 746*47a01978Sbw *zidp = GLOBAL_ZONEID; 747*47a01978Sbw } else { 748f4b3ec61Sdh155122 dladm_status_t status = dladm_errno2status(errno); 749f4b3ec61Sdh155122 (void) close(fd); 750f4b3ec61Sdh155122 return (status); 751f4b3ec61Sdh155122 } 752*47a01978Sbw } else { 753f4b3ec61Sdh155122 *zidp = dhv.dhv_zid; 754*47a01978Sbw } 755f4b3ec61Sdh155122 756f4b3ec61Sdh155122 (void) close(fd); 757f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 758f4b3ec61Sdh155122 } 759f4b3ec61Sdh155122 760f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 761f4b3ec61Sdh155122 762f4b3ec61Sdh155122 static int 763f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 764f4b3ec61Sdh155122 { 765f4b3ec61Sdh155122 char root[MAXPATHLEN]; 766f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 767f4b3ec61Sdh155122 void *dlhandle; 768f4b3ec61Sdh155122 void *sym; 769f4b3ec61Sdh155122 int ret; 770f4b3ec61Sdh155122 771f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 772f4b3ec61Sdh155122 return (-1); 773f4b3ec61Sdh155122 774f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 775f4b3ec61Sdh155122 (void) dlclose(dlhandle); 776f4b3ec61Sdh155122 return (-1); 777f4b3ec61Sdh155122 } 778f4b3ec61Sdh155122 779f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 780f4b3ec61Sdh155122 781f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 782f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 783f4b3ec61Sdh155122 (void) dlclose(dlhandle); 784f4b3ec61Sdh155122 return (ret); 785f4b3ec61Sdh155122 } 786f4b3ec61Sdh155122 787f4b3ec61Sdh155122 static dladm_status_t 788f4b3ec61Sdh155122 i_dladm_add_deventry(zoneid_t zid, const char *link) 789f4b3ec61Sdh155122 { 790f4b3ec61Sdh155122 char path[MAXPATHLEN]; 791f4b3ec61Sdh155122 di_prof_t prof = NULL; 792f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 793f4b3ec61Sdh155122 dladm_status_t status; 794f4b3ec61Sdh155122 795f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 796f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 797f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 798f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 799f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 800f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 801f4b3ec61Sdh155122 802f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 803f4b3ec61Sdh155122 if (di_prof_add_dev(prof, link) != 0) { 804f4b3ec61Sdh155122 status = dladm_errno2status(errno); 805f4b3ec61Sdh155122 goto cleanup; 806f4b3ec61Sdh155122 } 807f4b3ec61Sdh155122 if (di_prof_commit(prof) != 0) 808f4b3ec61Sdh155122 status = dladm_errno2status(errno); 809f4b3ec61Sdh155122 cleanup: 810f4b3ec61Sdh155122 if (prof) 811f4b3ec61Sdh155122 di_prof_fini(prof); 812f4b3ec61Sdh155122 813f4b3ec61Sdh155122 return (status); 814f4b3ec61Sdh155122 } 815f4b3ec61Sdh155122 816f4b3ec61Sdh155122 static dladm_status_t 817f4b3ec61Sdh155122 i_dladm_remove_deventry(zoneid_t zid, const char *link) 818f4b3ec61Sdh155122 { 819f4b3ec61Sdh155122 char path[MAXPATHLEN]; 820f4b3ec61Sdh155122 di_prof_t prof = NULL; 821f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 822f4b3ec61Sdh155122 dladm_status_t status; 823f4b3ec61Sdh155122 824f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 825f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 826f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 827f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 828f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 829f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 830f4b3ec61Sdh155122 831f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 832f4b3ec61Sdh155122 if (di_prof_add_exclude(prof, link) != 0) { 833f4b3ec61Sdh155122 status = dladm_errno2status(errno); 834f4b3ec61Sdh155122 goto cleanup; 835f4b3ec61Sdh155122 } 836f4b3ec61Sdh155122 if (di_prof_commit(prof) != 0) 837f4b3ec61Sdh155122 status = dladm_errno2status(errno); 838f4b3ec61Sdh155122 cleanup: 839f4b3ec61Sdh155122 if (prof) 840f4b3ec61Sdh155122 di_prof_fini(prof); 841f4b3ec61Sdh155122 842f4b3ec61Sdh155122 return (status); 843f4b3ec61Sdh155122 } 844f4b3ec61Sdh155122 845f4b3ec61Sdh155122 static dladm_status_t 846f4b3ec61Sdh155122 do_get_zone(const char *link, char **prop_val, uint_t *val_cnt) 847f4b3ec61Sdh155122 { 848f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 849f4b3ec61Sdh155122 zoneid_t zid; 850f4b3ec61Sdh155122 dladm_status_t status; 851f4b3ec61Sdh155122 852f4b3ec61Sdh155122 status = i_dladm_get_zoneid(link, &zid); 853f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 854f4b3ec61Sdh155122 return (status); 855f4b3ec61Sdh155122 856f4b3ec61Sdh155122 *val_cnt = 1; 857f4b3ec61Sdh155122 if (zid != GLOBAL_ZONEID) { 858f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 859f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 860f4b3ec61Sdh155122 861f4b3ec61Sdh155122 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 862f4b3ec61Sdh155122 } else { 863f4b3ec61Sdh155122 *prop_val[0] = '\0'; 864f4b3ec61Sdh155122 } 865f4b3ec61Sdh155122 866f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 867f4b3ec61Sdh155122 } 868f4b3ec61Sdh155122 869f4b3ec61Sdh155122 static dladm_status_t 870f4b3ec61Sdh155122 do_set_zone(const char *link, val_desc_t *vdp, uint_t val_cnt) 871f4b3ec61Sdh155122 { 872f4b3ec61Sdh155122 dladm_status_t status; 873f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 874f4b3ec61Sdh155122 875f4b3ec61Sdh155122 if (val_cnt != 1) 876f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 877f4b3ec61Sdh155122 878f4b3ec61Sdh155122 status = i_dladm_get_zoneid(link, &zid_old); 879f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 880f4b3ec61Sdh155122 return (status); 881f4b3ec61Sdh155122 882f4b3ec61Sdh155122 /* Do nothing if setting to current value */ 883948f2876Sss150715 zid_new = (intptr_t)(void *)vdp->vd_val; 884f4b3ec61Sdh155122 if (zid_new == zid_old) 885f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 886f4b3ec61Sdh155122 887f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) { 888f4b3ec61Sdh155122 if (dladm_rele_link(link, GLOBAL_ZONEID, B_TRUE) < 0) 889f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 890f4b3ec61Sdh155122 891f4b3ec61Sdh155122 if (zone_remove_datalink(zid_old, (char *)link) != 0 && 892f4b3ec61Sdh155122 errno != ENXIO) { 893f4b3ec61Sdh155122 status = dladm_errno2status(errno); 894f4b3ec61Sdh155122 goto rollback1; 895f4b3ec61Sdh155122 } 896f4b3ec61Sdh155122 897f4b3ec61Sdh155122 status = i_dladm_remove_deventry(zid_old, link); 898f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 899f4b3ec61Sdh155122 goto rollback2; 900f4b3ec61Sdh155122 } 901f4b3ec61Sdh155122 902f4b3ec61Sdh155122 if (zid_new != GLOBAL_ZONEID) { 903f4b3ec61Sdh155122 if (zone_add_datalink(zid_new, (char *)link) != 0) { 904f4b3ec61Sdh155122 status = dladm_errno2status(errno); 905f4b3ec61Sdh155122 goto rollback3; 906f4b3ec61Sdh155122 } 907f4b3ec61Sdh155122 908f4b3ec61Sdh155122 if (dladm_hold_link(link, zid_new, B_TRUE) < 0) { 909f4b3ec61Sdh155122 (void) zone_remove_datalink(zid_new, (char *)link); 910f4b3ec61Sdh155122 status = dladm_errno2status(errno); 911f4b3ec61Sdh155122 goto rollback3; 912f4b3ec61Sdh155122 } 913f4b3ec61Sdh155122 914f4b3ec61Sdh155122 status = i_dladm_add_deventry(zid_new, link); 915f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) { 916f4b3ec61Sdh155122 (void) dladm_rele_link(link, GLOBAL_ZONEID, B_FALSE); 917f4b3ec61Sdh155122 (void) zone_remove_datalink(zid_new, (char *)link); 918f4b3ec61Sdh155122 goto rollback3; 919f4b3ec61Sdh155122 } 920f4b3ec61Sdh155122 } 921f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 922f4b3ec61Sdh155122 923f4b3ec61Sdh155122 rollback3: 924f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 925f4b3ec61Sdh155122 (void) i_dladm_add_deventry(zid_old, link); 926f4b3ec61Sdh155122 rollback2: 927f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 928f4b3ec61Sdh155122 (void) zone_add_datalink(zid_old, (char *)link); 929f4b3ec61Sdh155122 rollback1: 930f4b3ec61Sdh155122 (void) dladm_hold_link(link, zid_old, B_FALSE); 931f4b3ec61Sdh155122 cleanexit: 932f4b3ec61Sdh155122 return (status); 933f4b3ec61Sdh155122 } 934f4b3ec61Sdh155122 935f4b3ec61Sdh155122 /* ARGSUSED */ 936f4b3ec61Sdh155122 static dladm_status_t 937f4b3ec61Sdh155122 do_check_zone(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 938f4b3ec61Sdh155122 val_desc_t **vdpp) 939f4b3ec61Sdh155122 { 940f4b3ec61Sdh155122 zoneid_t zid; 941f4b3ec61Sdh155122 val_desc_t *vdp = NULL; 942f4b3ec61Sdh155122 943f4b3ec61Sdh155122 if (val_cnt != 1) 944f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 945f4b3ec61Sdh155122 946f4b3ec61Sdh155122 if ((zid = getzoneidbyname(*prop_val)) == -1) 947f4b3ec61Sdh155122 return (DLADM_STATUS_BADVAL); 948f4b3ec61Sdh155122 949f4b3ec61Sdh155122 if (zid != GLOBAL_ZONEID) { 950f4b3ec61Sdh155122 ushort_t flags; 951f4b3ec61Sdh155122 952f4b3ec61Sdh155122 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags, 953f4b3ec61Sdh155122 sizeof (flags)) < 0) { 954f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 955f4b3ec61Sdh155122 } 956f4b3ec61Sdh155122 957f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 958f4b3ec61Sdh155122 return (DLADM_STATUS_BADVAL); 959f4b3ec61Sdh155122 } 960f4b3ec61Sdh155122 } 961f4b3ec61Sdh155122 962f4b3ec61Sdh155122 vdp = malloc(sizeof (val_desc_t)); 963f4b3ec61Sdh155122 if (vdp == NULL) 964f4b3ec61Sdh155122 return (DLADM_STATUS_NOMEM); 965f4b3ec61Sdh155122 966948f2876Sss150715 vdp->vd_val = (void *)(uintptr_t)zid; 967f4b3ec61Sdh155122 *vdpp = vdp; 968f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 969f4b3ec61Sdh155122 } 970f4b3ec61Sdh155122 971f4b3ec61Sdh155122 static dladm_status_t 972f4b3ec61Sdh155122 i_dladm_get_prop_temp(const char *link, dladm_prop_type_t type, 973f4b3ec61Sdh155122 const char *prop_name, char **prop_val, uint_t *val_cntp) 974f4b3ec61Sdh155122 { 975f4b3ec61Sdh155122 int i; 976f4b3ec61Sdh155122 dladm_status_t status; 977f4b3ec61Sdh155122 uint_t cnt; 978f4b3ec61Sdh155122 prop_desc_t *pdp; 979f4b3ec61Sdh155122 980f4b3ec61Sdh155122 if (link == NULL || prop_name == NULL || prop_val == NULL || 981f4b3ec61Sdh155122 val_cntp == NULL || *val_cntp == 0) 982f4b3ec61Sdh155122 return (DLADM_STATUS_BADARG); 983f4b3ec61Sdh155122 984f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) 985f4b3ec61Sdh155122 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 986f4b3ec61Sdh155122 break; 987f4b3ec61Sdh155122 988f4b3ec61Sdh155122 if (i == MAX_PROPS) 989f4b3ec61Sdh155122 return (DLADM_STATUS_NOTFOUND); 990f4b3ec61Sdh155122 991f4b3ec61Sdh155122 pdp = &prop_table[i]; 992f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 993f4b3ec61Sdh155122 994f4b3ec61Sdh155122 switch (type) { 995f4b3ec61Sdh155122 case DLADM_PROP_VAL_CURRENT: 996f4b3ec61Sdh155122 status = pdp->pd_get(link, prop_val, val_cntp); 997f4b3ec61Sdh155122 break; 998f4b3ec61Sdh155122 case DLADM_PROP_VAL_DEFAULT: 999f4b3ec61Sdh155122 if (pdp->pd_defval.vd_name == NULL) { 1000f4b3ec61Sdh155122 status = DLADM_STATUS_NOTSUP; 1001f4b3ec61Sdh155122 break; 1002f4b3ec61Sdh155122 } 1003f4b3ec61Sdh155122 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 1004f4b3ec61Sdh155122 *val_cntp = 1; 1005f4b3ec61Sdh155122 break; 1006f4b3ec61Sdh155122 1007f4b3ec61Sdh155122 case DLADM_PROP_VAL_MODIFIABLE: 1008f4b3ec61Sdh155122 if (pdp->pd_getmod != NULL) { 1009f4b3ec61Sdh155122 status = pdp->pd_getmod(link, prop_val, val_cntp); 1010f4b3ec61Sdh155122 break; 1011f4b3ec61Sdh155122 } 1012f4b3ec61Sdh155122 cnt = pdp->pd_nmodval; 1013f4b3ec61Sdh155122 if (cnt == 0) { 1014f4b3ec61Sdh155122 status = DLADM_STATUS_NOTSUP; 1015f4b3ec61Sdh155122 } else if (cnt > *val_cntp) { 1016f4b3ec61Sdh155122 status = DLADM_STATUS_TOOSMALL; 1017f4b3ec61Sdh155122 } else { 1018f4b3ec61Sdh155122 for (i = 0; i < cnt; i++) { 1019f4b3ec61Sdh155122 (void) strcpy(prop_val[i], 1020f4b3ec61Sdh155122 pdp->pd_modval[i].vd_name); 1021f4b3ec61Sdh155122 } 1022f4b3ec61Sdh155122 *val_cntp = cnt; 1023f4b3ec61Sdh155122 } 1024f4b3ec61Sdh155122 break; 1025f4b3ec61Sdh155122 default: 1026f4b3ec61Sdh155122 status = DLADM_STATUS_BADARG; 1027f4b3ec61Sdh155122 break; 1028f4b3ec61Sdh155122 } 1029f4b3ec61Sdh155122 1030f4b3ec61Sdh155122 return (status); 1031f4b3ec61Sdh155122 } 1032f4b3ec61Sdh155122 1033f4b3ec61Sdh155122 static dladm_status_t 1034f4b3ec61Sdh155122 i_dladm_set_one_prop_temp(const char *link, prop_desc_t *pdp, char **prop_val, 1035f4b3ec61Sdh155122 uint_t val_cnt, uint_t flags) 1036f4b3ec61Sdh155122 { 1037f4b3ec61Sdh155122 dladm_status_t status; 1038f4b3ec61Sdh155122 val_desc_t *vdp = NULL; 1039f4b3ec61Sdh155122 uint_t cnt; 1040f4b3ec61Sdh155122 1041f4b3ec61Sdh155122 if (pdp->pd_temponly && (flags & DLADM_OPT_PERSIST) != 0) 1042f4b3ec61Sdh155122 return (DLADM_STATUS_TEMPONLY); 1043f4b3ec61Sdh155122 1044f4b3ec61Sdh155122 if (pdp->pd_set == NULL) 1045f4b3ec61Sdh155122 return (DLADM_STATUS_PROPRDONLY); 1046f4b3ec61Sdh155122 1047f4b3ec61Sdh155122 if (prop_val != NULL) { 1048f4b3ec61Sdh155122 if (pdp->pd_check != NULL) 1049f4b3ec61Sdh155122 status = pdp->pd_check(pdp, prop_val, val_cnt, &vdp); 1050f4b3ec61Sdh155122 else 1051f4b3ec61Sdh155122 status = DLADM_STATUS_BADARG; 1052f4b3ec61Sdh155122 1053f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1054f4b3ec61Sdh155122 return (status); 1055f4b3ec61Sdh155122 1056f4b3ec61Sdh155122 cnt = val_cnt; 1057f4b3ec61Sdh155122 } else { 1058f4b3ec61Sdh155122 if (pdp->pd_defval.vd_name == NULL) 1059f4b3ec61Sdh155122 return (DLADM_STATUS_NOTSUP); 1060f4b3ec61Sdh155122 1061f4b3ec61Sdh155122 if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 1062f4b3ec61Sdh155122 return (DLADM_STATUS_NOMEM); 1063f4b3ec61Sdh155122 1064f4b3ec61Sdh155122 (void) memcpy(vdp, &pdp->pd_defval, sizeof (val_desc_t)); 1065f4b3ec61Sdh155122 cnt = 1; 1066f4b3ec61Sdh155122 } 1067f4b3ec61Sdh155122 1068f4b3ec61Sdh155122 status = pdp->pd_set(link, vdp, cnt); 1069f4b3ec61Sdh155122 1070f4b3ec61Sdh155122 free(vdp); 1071f4b3ec61Sdh155122 return (status); 1072f4b3ec61Sdh155122 } 1073f4b3ec61Sdh155122 1074f4b3ec61Sdh155122 static dladm_status_t 1075f4b3ec61Sdh155122 i_dladm_set_prop_temp(const char *link, const char *prop_name, char **prop_val, 1076f4b3ec61Sdh155122 uint_t val_cnt, uint_t flags, char **errprop) 1077f4b3ec61Sdh155122 { 1078f4b3ec61Sdh155122 int i; 1079f4b3ec61Sdh155122 dladm_status_t status = DLADM_STATUS_OK; 1080f4b3ec61Sdh155122 boolean_t found = B_FALSE; 1081f4b3ec61Sdh155122 1082f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) { 1083f4b3ec61Sdh155122 prop_desc_t *pdp = &prop_table[i]; 1084f4b3ec61Sdh155122 dladm_status_t s; 1085f4b3ec61Sdh155122 1086f4b3ec61Sdh155122 if (prop_name != NULL && 1087f4b3ec61Sdh155122 (strcasecmp(prop_name, pdp->pd_name) != 0)) 1088f4b3ec61Sdh155122 continue; 1089f4b3ec61Sdh155122 1090f4b3ec61Sdh155122 found = B_TRUE; 1091f4b3ec61Sdh155122 s = i_dladm_set_one_prop_temp(link, pdp, prop_val, val_cnt, 1092f4b3ec61Sdh155122 flags); 1093f4b3ec61Sdh155122 1094f4b3ec61Sdh155122 if (prop_name != NULL) { 1095f4b3ec61Sdh155122 status = s; 1096f4b3ec61Sdh155122 break; 1097f4b3ec61Sdh155122 } else { 1098f4b3ec61Sdh155122 if (s != DLADM_STATUS_OK && 1099f4b3ec61Sdh155122 s != DLADM_STATUS_NOTSUP) { 1100f4b3ec61Sdh155122 if (errprop != NULL) 1101f4b3ec61Sdh155122 *errprop = pdp->pd_name; 1102f4b3ec61Sdh155122 status = s; 1103f4b3ec61Sdh155122 break; 1104f4b3ec61Sdh155122 } 1105f4b3ec61Sdh155122 } 1106f4b3ec61Sdh155122 } 1107f4b3ec61Sdh155122 1108f4b3ec61Sdh155122 if (!found) 1109f4b3ec61Sdh155122 status = DLADM_STATUS_NOTFOUND; 1110f4b3ec61Sdh155122 1111f4b3ec61Sdh155122 return (status); 1112f4b3ec61Sdh155122 } 1113f4b3ec61Sdh155122 1114f4b3ec61Sdh155122 static boolean_t 1115f4b3ec61Sdh155122 i_dladm_is_prop_temponly(const char *prop_name, char **errprop) 1116f4b3ec61Sdh155122 { 1117f4b3ec61Sdh155122 int i; 1118f4b3ec61Sdh155122 1119f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) { 1120f4b3ec61Sdh155122 prop_desc_t *pdp = &prop_table[i]; 1121f4b3ec61Sdh155122 1122f4b3ec61Sdh155122 if (prop_name != NULL && 1123f4b3ec61Sdh155122 (strcasecmp(prop_name, pdp->pd_name) != 0)) 1124f4b3ec61Sdh155122 continue; 1125f4b3ec61Sdh155122 1126f4b3ec61Sdh155122 if (errprop != NULL) 1127f4b3ec61Sdh155122 *errprop = pdp->pd_name; 1128f4b3ec61Sdh155122 1129f4b3ec61Sdh155122 if (pdp->pd_temponly) 1130f4b3ec61Sdh155122 return (B_TRUE); 1131f4b3ec61Sdh155122 } 1132f4b3ec61Sdh155122 1133f4b3ec61Sdh155122 return (B_FALSE); 1134f4b3ec61Sdh155122 } 1135