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 /* 22*f4b3ec61Sdh155122 * 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> 32*f4b3ec61Sdh155122 #include <sys/types.h> 330ba2cbe9Sxc151355 #include <sys/stat.h> 34*f4b3ec61Sdh155122 #include <sys/dld.h> 35*f4b3ec61Sdh155122 #include <sys/zone.h> 36*f4b3ec61Sdh155122 #include <fcntl.h> 37*f4b3ec61Sdh155122 #include <unistd.h> 38*f4b3ec61Sdh155122 #include <libdevinfo.h> 39*f4b3ec61Sdh155122 #include <zone.h> 400ba2cbe9Sxc151355 #include <libwladm.h> 410ba2cbe9Sxc151355 #include <libdladm_impl.h> 420ba2cbe9Sxc151355 43*f4b3ec61Sdh155122 #include <dlfcn.h> 44*f4b3ec61Sdh155122 #include <link.h> 45*f4b3ec61Sdh155122 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 *); 50*f4b3ec61Sdh155122 static dladm_status_t i_dladm_get_prop_temp(const char *, dladm_prop_type_t, 51*f4b3ec61Sdh155122 const char *, char **, uint_t *); 52*f4b3ec61Sdh155122 static dladm_status_t i_dladm_set_prop_temp(const char *, const char *, 53*f4b3ec61Sdh155122 char **, uint_t, uint_t, char **); 54*f4b3ec61Sdh155122 static boolean_t i_dladm_is_prop_temponly(const char *prop_name, 55*f4b3ec61Sdh155122 char **); 56*f4b3ec61Sdh155122 57*f4b3ec61Sdh155122 typedef struct val_desc { 58*f4b3ec61Sdh155122 char *vd_name; 59*f4b3ec61Sdh155122 void *vd_val; 60*f4b3ec61Sdh155122 } val_desc_t; 61*f4b3ec61Sdh155122 62*f4b3ec61Sdh155122 struct prop_desc; 63*f4b3ec61Sdh155122 64*f4b3ec61Sdh155122 typedef dladm_status_t pd_getf_t(const char *, char **, uint_t *); 65*f4b3ec61Sdh155122 typedef dladm_status_t pd_setf_t(const char *, val_desc_t *, uint_t); 66*f4b3ec61Sdh155122 typedef dladm_status_t pd_checkf_t(struct prop_desc *, char **, 67*f4b3ec61Sdh155122 uint_t, val_desc_t **); 68*f4b3ec61Sdh155122 69*f4b3ec61Sdh155122 static pd_getf_t do_get_zone; 70*f4b3ec61Sdh155122 static pd_setf_t do_set_zone; 71*f4b3ec61Sdh155122 static pd_checkf_t do_check_zone; 72*f4b3ec61Sdh155122 73*f4b3ec61Sdh155122 typedef struct prop_desc { 74*f4b3ec61Sdh155122 char *pd_name; 75*f4b3ec61Sdh155122 val_desc_t pd_defval; 76*f4b3ec61Sdh155122 val_desc_t *pd_modval; 77*f4b3ec61Sdh155122 uint_t pd_nmodval; 78*f4b3ec61Sdh155122 boolean_t pd_temponly; 79*f4b3ec61Sdh155122 pd_setf_t *pd_set; 80*f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 81*f4b3ec61Sdh155122 pd_getf_t *pd_get; 82*f4b3ec61Sdh155122 pd_checkf_t *pd_check; 83*f4b3ec61Sdh155122 } prop_desc_t; 84*f4b3ec61Sdh155122 85*f4b3ec61Sdh155122 static prop_desc_t prop_table[] = { 86*f4b3ec61Sdh155122 { "zone", { "", NULL }, NULL, 0, B_TRUE, 87*f4b3ec61Sdh155122 do_set_zone, NULL, 88*f4b3ec61Sdh155122 do_get_zone, do_check_zone} 89*f4b3ec61Sdh155122 }; 90*f4b3ec61Sdh155122 91*f4b3ec61Sdh155122 #define MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 920ba2cbe9Sxc151355 930ba2cbe9Sxc151355 /* 940ba2cbe9Sxc151355 * Convert a wladm_status_t to a dladm_status_t. This is used by wrappers 950ba2cbe9Sxc151355 * to libwladm routines (e.g. dladm_set_prop()). Note that the mapping is 960ba2cbe9Sxc151355 * not 1-1; whenever possible we try to look for an error code with a 970ba2cbe9Sxc151355 * similar meaning. Error codes with no suitable counterpart in libdladm 980ba2cbe9Sxc151355 * will be mapped to DLADM_STATUS_FAILED. Clients who require clearer error 990ba2cbe9Sxc151355 * reporting should use libwladm directly. 1000ba2cbe9Sxc151355 */ 1010ba2cbe9Sxc151355 static dladm_status_t 1020ba2cbe9Sxc151355 dladm_wladmstatus2status(wladm_status_t wstatus) 1030ba2cbe9Sxc151355 { 1040ba2cbe9Sxc151355 switch (wstatus) { 1050ba2cbe9Sxc151355 case WLADM_STATUS_OK: 1060ba2cbe9Sxc151355 return (DLADM_STATUS_OK); 1070ba2cbe9Sxc151355 case WLADM_STATUS_FAILED: 1080ba2cbe9Sxc151355 return (DLADM_STATUS_FAILED); 1090ba2cbe9Sxc151355 case WLADM_STATUS_NOTSUP: 1100ba2cbe9Sxc151355 return (DLADM_STATUS_NOTSUP); 1110ba2cbe9Sxc151355 case WLADM_STATUS_BADARG: 1120ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1130ba2cbe9Sxc151355 case WLADM_STATUS_NOTFOUND: 1140ba2cbe9Sxc151355 return (DLADM_STATUS_NOTFOUND); 1150ba2cbe9Sxc151355 case WLADM_STATUS_BADVAL: 1160ba2cbe9Sxc151355 return (DLADM_STATUS_BADVAL); 1170ba2cbe9Sxc151355 case WLADM_STATUS_LINKINVAL: 1180ba2cbe9Sxc151355 return (DLADM_STATUS_LINKINVAL); 1190ba2cbe9Sxc151355 case WLADM_STATUS_NOMEM: 1200ba2cbe9Sxc151355 return (DLADM_STATUS_NOMEM); 1210ba2cbe9Sxc151355 case WLADM_STATUS_PROPRDONLY: 1220ba2cbe9Sxc151355 return (DLADM_STATUS_PROPRDONLY); 1230ba2cbe9Sxc151355 case WLADM_STATUS_TOOSMALL: 1240ba2cbe9Sxc151355 return (DLADM_STATUS_TOOSMALL); 1250ba2cbe9Sxc151355 case WLADM_STATUS_BADVALCNT: 1260ba2cbe9Sxc151355 return (DLADM_STATUS_BADVALCNT); 1270ba2cbe9Sxc151355 default: 1280ba2cbe9Sxc151355 return (DLADM_STATUS_FAILED); 1290ba2cbe9Sxc151355 } 1300ba2cbe9Sxc151355 } 1310ba2cbe9Sxc151355 1320ba2cbe9Sxc151355 dladm_status_t 1330ba2cbe9Sxc151355 dladm_set_prop(const char *link, const char *prop_name, char **prop_val, 134*f4b3ec61Sdh155122 uint_t val_cnt, uint_t flags, char **errprop) 1350ba2cbe9Sxc151355 { 1360ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_BADARG; 1370ba2cbe9Sxc151355 1380ba2cbe9Sxc151355 if (link == NULL || (prop_val == NULL && val_cnt > 0) || 1390ba2cbe9Sxc151355 (prop_val != NULL && val_cnt == 0) || flags == 0) 1400ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1410ba2cbe9Sxc151355 1420ba2cbe9Sxc151355 if ((flags & DLADM_OPT_TEMP) != 0) { 143*f4b3ec61Sdh155122 status = i_dladm_set_prop_temp(link, prop_name, prop_val, 144*f4b3ec61Sdh155122 val_cnt, flags, errprop); 145*f4b3ec61Sdh155122 if (status == DLADM_STATUS_TEMPONLY && 146*f4b3ec61Sdh155122 (flags & DLADM_OPT_PERSIST) != 0) 147*f4b3ec61Sdh155122 return (DLADM_STATUS_TEMPONLY); 148*f4b3ec61Sdh155122 149*f4b3ec61Sdh155122 if (status == DLADM_STATUS_NOTFOUND) { 150*f4b3ec61Sdh155122 status = DLADM_STATUS_BADARG; 1510ba2cbe9Sxc151355 if (wladm_is_valid(link)) { 1520ba2cbe9Sxc151355 status = dladm_wladmstatus2status( 1530ba2cbe9Sxc151355 wladm_set_prop(link, prop_name, 154*f4b3ec61Sdh155122 prop_val, val_cnt, errprop)); 155*f4b3ec61Sdh155122 } 1560ba2cbe9Sxc151355 } 1570ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 1580ba2cbe9Sxc151355 return (status); 1590ba2cbe9Sxc151355 } 1600ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) { 161*f4b3ec61Sdh155122 if (i_dladm_is_prop_temponly(prop_name, errprop)) 162*f4b3ec61Sdh155122 return (DLADM_STATUS_TEMPONLY); 163*f4b3ec61Sdh155122 1640ba2cbe9Sxc151355 status = i_dladm_set_prop_db(link, prop_name, 1650ba2cbe9Sxc151355 prop_val, val_cnt); 1660ba2cbe9Sxc151355 } 1670ba2cbe9Sxc151355 return (status); 1680ba2cbe9Sxc151355 } 1690ba2cbe9Sxc151355 1700ba2cbe9Sxc151355 dladm_status_t 1710ba2cbe9Sxc151355 dladm_walk_prop(const char *link, void *arg, 1720ba2cbe9Sxc151355 boolean_t (*func)(void *, const char *)) 1730ba2cbe9Sxc151355 { 174*f4b3ec61Sdh155122 int i; 175*f4b3ec61Sdh155122 1760ba2cbe9Sxc151355 if (link == NULL || func == NULL) 1770ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 1780ba2cbe9Sxc151355 179*f4b3ec61Sdh155122 /* For wifi links, show wifi properties first */ 1800ba2cbe9Sxc151355 if (wladm_is_valid(link)) { 181*f4b3ec61Sdh155122 dladm_status_t status; 182*f4b3ec61Sdh155122 183*f4b3ec61Sdh155122 status = dladm_wladmstatus2status( 184*f4b3ec61Sdh155122 wladm_walk_prop(link, arg, func)); 185*f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 186*f4b3ec61Sdh155122 return (status); 1870ba2cbe9Sxc151355 } 188*f4b3ec61Sdh155122 189*f4b3ec61Sdh155122 /* Then show data-link properties if there are any */ 190*f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) { 191*f4b3ec61Sdh155122 if (!func(arg, prop_table[i].pd_name)) 192*f4b3ec61Sdh155122 break; 193*f4b3ec61Sdh155122 } 194*f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1950ba2cbe9Sxc151355 } 1960ba2cbe9Sxc151355 1970ba2cbe9Sxc151355 dladm_status_t 1980ba2cbe9Sxc151355 dladm_get_prop(const char *link, dladm_prop_type_t type, 1990ba2cbe9Sxc151355 const char *prop_name, char **prop_val, uint_t *val_cntp) 2000ba2cbe9Sxc151355 { 201*f4b3ec61Sdh155122 dladm_status_t status; 202*f4b3ec61Sdh155122 2030ba2cbe9Sxc151355 if (link == NULL || prop_name == NULL || prop_val == NULL || 2040ba2cbe9Sxc151355 val_cntp == NULL || *val_cntp == 0) 2050ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 2060ba2cbe9Sxc151355 2070ba2cbe9Sxc151355 if (type == DLADM_PROP_VAL_PERSISTENT) { 2080ba2cbe9Sxc151355 return (i_dladm_get_prop_db(link, prop_name, 2090ba2cbe9Sxc151355 prop_val, val_cntp)); 2100ba2cbe9Sxc151355 } 2110ba2cbe9Sxc151355 212*f4b3ec61Sdh155122 status = i_dladm_get_prop_temp(link, type, prop_name, 213*f4b3ec61Sdh155122 prop_val, val_cntp); 214*f4b3ec61Sdh155122 if (status != DLADM_STATUS_NOTFOUND) 215*f4b3ec61Sdh155122 return (status); 216*f4b3ec61Sdh155122 2170ba2cbe9Sxc151355 if (wladm_is_valid(link)) { 2180ba2cbe9Sxc151355 wladm_prop_type_t wtype; 2190ba2cbe9Sxc151355 2200ba2cbe9Sxc151355 switch (type) { 2210ba2cbe9Sxc151355 case DLADM_PROP_VAL_CURRENT: 2220ba2cbe9Sxc151355 wtype = WLADM_PROP_VAL_CURRENT; 2230ba2cbe9Sxc151355 break; 2240ba2cbe9Sxc151355 case DLADM_PROP_VAL_DEFAULT: 2250ba2cbe9Sxc151355 wtype = WLADM_PROP_VAL_DEFAULT; 2260ba2cbe9Sxc151355 break; 2270ba2cbe9Sxc151355 case DLADM_PROP_VAL_MODIFIABLE: 2280ba2cbe9Sxc151355 wtype = WLADM_PROP_VAL_MODIFIABLE; 2290ba2cbe9Sxc151355 break; 2300ba2cbe9Sxc151355 default: 2310ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 2320ba2cbe9Sxc151355 } 2330ba2cbe9Sxc151355 2340ba2cbe9Sxc151355 return (dladm_wladmstatus2status( 2350ba2cbe9Sxc151355 wladm_get_prop(link, wtype, prop_name, 2360ba2cbe9Sxc151355 prop_val, val_cntp))); 2370ba2cbe9Sxc151355 } 2380ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 2390ba2cbe9Sxc151355 } 2400ba2cbe9Sxc151355 2410ba2cbe9Sxc151355 /* 2420ba2cbe9Sxc151355 * Data structures used for implementing persistent link properties 2430ba2cbe9Sxc151355 */ 2440ba2cbe9Sxc151355 typedef struct linkprop_val { 2450ba2cbe9Sxc151355 const char *lv_name; 2460ba2cbe9Sxc151355 struct linkprop_val *lv_nextval; 2470ba2cbe9Sxc151355 } linkprop_val_t; 2480ba2cbe9Sxc151355 2490ba2cbe9Sxc151355 typedef struct linkprop_info { 2500ba2cbe9Sxc151355 const char *li_name; 2510ba2cbe9Sxc151355 struct linkprop_info *li_nextprop; 2520ba2cbe9Sxc151355 struct linkprop_val *li_val; 2530ba2cbe9Sxc151355 } linkprop_info_t; 2540ba2cbe9Sxc151355 2550ba2cbe9Sxc151355 typedef struct linkprop_db_state linkprop_db_state_t; 2560ba2cbe9Sxc151355 2570ba2cbe9Sxc151355 typedef boolean_t (*linkprop_db_op_t)(linkprop_db_state_t *, 2580ba2cbe9Sxc151355 char *, linkprop_info_t *, dladm_status_t *); 2590ba2cbe9Sxc151355 2600ba2cbe9Sxc151355 struct linkprop_db_state { 2610ba2cbe9Sxc151355 linkprop_db_op_t ls_op; 2620ba2cbe9Sxc151355 const char *ls_link; 2630ba2cbe9Sxc151355 const char *ls_propname; 2640ba2cbe9Sxc151355 char **ls_propval; 2650ba2cbe9Sxc151355 uint_t *ls_valcntp; 2660ba2cbe9Sxc151355 }; 2670ba2cbe9Sxc151355 2680ba2cbe9Sxc151355 static void 2690ba2cbe9Sxc151355 free_linkprops(linkprop_info_t *lip) 2700ba2cbe9Sxc151355 { 2710ba2cbe9Sxc151355 linkprop_info_t *lip_next; 2720ba2cbe9Sxc151355 linkprop_val_t *lvp, *lvp_next; 2730ba2cbe9Sxc151355 2740ba2cbe9Sxc151355 for (; lip != NULL; lip = lip_next) { 2750ba2cbe9Sxc151355 lip_next = lip->li_nextprop; 2760ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp_next) { 2770ba2cbe9Sxc151355 lvp_next = lvp->lv_nextval; 2780ba2cbe9Sxc151355 free(lvp); 2790ba2cbe9Sxc151355 } 2800ba2cbe9Sxc151355 free(lip); 2810ba2cbe9Sxc151355 } 2820ba2cbe9Sxc151355 } 2830ba2cbe9Sxc151355 2840ba2cbe9Sxc151355 /* 2850ba2cbe9Sxc151355 * Generate an entry in the link property database. 2860ba2cbe9Sxc151355 * Each entry has this format: 2870ba2cbe9Sxc151355 * <linkname> <prop0>=<val0>,...,<valn>;...;<propn>=<val0>,...,<valn>; 2880ba2cbe9Sxc151355 */ 2890ba2cbe9Sxc151355 static void 2900ba2cbe9Sxc151355 generate_linkprop_line(linkprop_db_state_t *lsp, char *buf, 2910ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 2920ba2cbe9Sxc151355 { 2930ba2cbe9Sxc151355 char tmpbuf[MAXLINELEN]; 2940ba2cbe9Sxc151355 char *ptr, *lim = tmpbuf + MAXLINELEN; 2950ba2cbe9Sxc151355 linkprop_info_t *lip = listp; 2960ba2cbe9Sxc151355 linkprop_val_t *lvp = NULL; 2970ba2cbe9Sxc151355 2980ba2cbe9Sxc151355 /* 2990ba2cbe9Sxc151355 * Delete line if there are no properties left. 3000ba2cbe9Sxc151355 */ 3010ba2cbe9Sxc151355 if (lip == NULL || 3020ba2cbe9Sxc151355 (lip->li_val == NULL && lip->li_nextprop == NULL)) { 3030ba2cbe9Sxc151355 buf[0] = '\0'; 3040ba2cbe9Sxc151355 return; 3050ba2cbe9Sxc151355 } 3060ba2cbe9Sxc151355 ptr = tmpbuf; 3070ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", lsp->ls_link); 3080ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 3090ba2cbe9Sxc151355 /* 3100ba2cbe9Sxc151355 * Skip properties without values. 3110ba2cbe9Sxc151355 */ 3120ba2cbe9Sxc151355 if (lip->li_val == NULL) 3130ba2cbe9Sxc151355 continue; 3140ba2cbe9Sxc151355 3150ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s=", lip->li_name); 3160ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp->lv_nextval) { 3170ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s%c", 3180ba2cbe9Sxc151355 lvp->lv_name, 3190ba2cbe9Sxc151355 ((lvp->lv_nextval == NULL) ? ';' : ',')); 3200ba2cbe9Sxc151355 } 3210ba2cbe9Sxc151355 } 3220ba2cbe9Sxc151355 if (ptr > lim) { 3230ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL; 3240ba2cbe9Sxc151355 return; 3250ba2cbe9Sxc151355 } 3260ba2cbe9Sxc151355 (void) snprintf(buf, MAXLINELEN, "%s\n", tmpbuf); 3270ba2cbe9Sxc151355 } 3280ba2cbe9Sxc151355 3290ba2cbe9Sxc151355 /* 3300ba2cbe9Sxc151355 * This function is used to update or create an entry in the persistent db. 3310ba2cbe9Sxc151355 * process_linkprop_db() will first scan the db for an entry matching the 3320ba2cbe9Sxc151355 * specified link. If a match is found, this function is invoked with the 3330ba2cbe9Sxc151355 * entry's contents (buf) and its linked-list representation (listp). lsp 3340ba2cbe9Sxc151355 * holds the name and values of the property to be added or updated; this 3350ba2cbe9Sxc151355 * information will be merged with listp. Subsequently, an updated entry 3360ba2cbe9Sxc151355 * will be written to buf, which will in turn be written to disk by 3370ba2cbe9Sxc151355 * process_linkprop_db(). If no entry matches the specified link, listp 3380ba2cbe9Sxc151355 * will be NULL; a new entry will be generated in this case and it will 3390ba2cbe9Sxc151355 * contain only the property information in lsp. 3400ba2cbe9Sxc151355 */ 3410ba2cbe9Sxc151355 static boolean_t 3420ba2cbe9Sxc151355 process_linkprop_set(linkprop_db_state_t *lsp, char *buf, 3430ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 3440ba2cbe9Sxc151355 { 3450ba2cbe9Sxc151355 dladm_status_t status; 3460ba2cbe9Sxc151355 linkprop_info_t *lastp = NULL, *lip = listp, *nlip = NULL; 3470ba2cbe9Sxc151355 linkprop_val_t **lvpp; 3480ba2cbe9Sxc151355 int i; 3490ba2cbe9Sxc151355 3500ba2cbe9Sxc151355 if (lsp->ls_propname == NULL) { 3510ba2cbe9Sxc151355 buf[0] = '\0'; 3520ba2cbe9Sxc151355 return (B_FALSE); 3530ba2cbe9Sxc151355 } 3540ba2cbe9Sxc151355 3550ba2cbe9Sxc151355 /* 3560ba2cbe9Sxc151355 * Find the linkprop we want to change. 3570ba2cbe9Sxc151355 */ 3580ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 3590ba2cbe9Sxc151355 if (strcmp(lip->li_name, lsp->ls_propname) == 0) 3600ba2cbe9Sxc151355 break; 3610ba2cbe9Sxc151355 3620ba2cbe9Sxc151355 lastp = lip; 3630ba2cbe9Sxc151355 } 3640ba2cbe9Sxc151355 3650ba2cbe9Sxc151355 if (lip == NULL) { 3660ba2cbe9Sxc151355 /* 3670ba2cbe9Sxc151355 * If the linkprop is not found, append it to the list. 3680ba2cbe9Sxc151355 */ 3690ba2cbe9Sxc151355 if ((nlip = malloc(sizeof (linkprop_info_t))) == NULL) { 3700ba2cbe9Sxc151355 status = DLADM_STATUS_NOMEM; 3710ba2cbe9Sxc151355 goto fail; 3720ba2cbe9Sxc151355 } 3730ba2cbe9Sxc151355 /* 3740ba2cbe9Sxc151355 * nlip will need to be freed later if there is no list to 3750ba2cbe9Sxc151355 * append to. 3760ba2cbe9Sxc151355 */ 3770ba2cbe9Sxc151355 if (lastp != NULL) 3780ba2cbe9Sxc151355 lastp->li_nextprop = nlip; 3790ba2cbe9Sxc151355 nlip->li_name = lsp->ls_propname; 3800ba2cbe9Sxc151355 nlip->li_nextprop = NULL; 3810ba2cbe9Sxc151355 nlip->li_val = NULL; 3820ba2cbe9Sxc151355 lvpp = &nlip->li_val; 3830ba2cbe9Sxc151355 } else { 3840ba2cbe9Sxc151355 linkprop_val_t *lvp, *lvp_next; 3850ba2cbe9Sxc151355 3860ba2cbe9Sxc151355 /* 3870ba2cbe9Sxc151355 * If the linkprop is found, delete the existing values from it. 3880ba2cbe9Sxc151355 */ 3890ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp_next) { 3900ba2cbe9Sxc151355 lvp_next = lvp->lv_nextval; 3910ba2cbe9Sxc151355 free(lvp); 3920ba2cbe9Sxc151355 } 3930ba2cbe9Sxc151355 lip->li_val = NULL; 3940ba2cbe9Sxc151355 lvpp = &lip->li_val; 3950ba2cbe9Sxc151355 } 3960ba2cbe9Sxc151355 3970ba2cbe9Sxc151355 /* 3980ba2cbe9Sxc151355 * Fill our linkprop with the specified values. 3990ba2cbe9Sxc151355 */ 4000ba2cbe9Sxc151355 for (i = 0; i < *lsp->ls_valcntp; i++) { 4010ba2cbe9Sxc151355 if ((*lvpp = malloc(sizeof (linkprop_val_t))) == NULL) { 4020ba2cbe9Sxc151355 status = DLADM_STATUS_NOMEM; 4030ba2cbe9Sxc151355 goto fail; 4040ba2cbe9Sxc151355 } 4050ba2cbe9Sxc151355 (*lvpp)->lv_name = lsp->ls_propval[i]; 4060ba2cbe9Sxc151355 (*lvpp)->lv_nextval = NULL; 4070ba2cbe9Sxc151355 lvpp = &(*lvpp)->lv_nextval; 4080ba2cbe9Sxc151355 } 4090ba2cbe9Sxc151355 4100ba2cbe9Sxc151355 if (listp != NULL) { 4110ba2cbe9Sxc151355 generate_linkprop_line(lsp, buf, listp, statusp); 4120ba2cbe9Sxc151355 } else { 4130ba2cbe9Sxc151355 generate_linkprop_line(lsp, buf, nlip, statusp); 4140ba2cbe9Sxc151355 free_linkprops(nlip); 4150ba2cbe9Sxc151355 } 4160ba2cbe9Sxc151355 return (B_FALSE); 4170ba2cbe9Sxc151355 4180ba2cbe9Sxc151355 fail: 4190ba2cbe9Sxc151355 *statusp = status; 4200ba2cbe9Sxc151355 if (listp == NULL) 4210ba2cbe9Sxc151355 free_linkprops(nlip); 4220ba2cbe9Sxc151355 4230ba2cbe9Sxc151355 return (B_FALSE); 4240ba2cbe9Sxc151355 } 4250ba2cbe9Sxc151355 4260ba2cbe9Sxc151355 /* 4270ba2cbe9Sxc151355 * This function is used for retrieving the values for a specific property. 4280ba2cbe9Sxc151355 * It gets called if an entry matching the specified link exists in the db. 4290ba2cbe9Sxc151355 * The entry is converted into a linked-list listp. This list is then scanned 4300ba2cbe9Sxc151355 * for the specified property name; if a matching property exists, its 4310ba2cbe9Sxc151355 * associated values are copied to the array lsp->ls_propval. 4320ba2cbe9Sxc151355 */ 4330ba2cbe9Sxc151355 /* ARGSUSED */ 4340ba2cbe9Sxc151355 static boolean_t 4350ba2cbe9Sxc151355 process_linkprop_get(linkprop_db_state_t *lsp, char *buf, 4360ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 4370ba2cbe9Sxc151355 { 4380ba2cbe9Sxc151355 linkprop_info_t *lip = listp; 4390ba2cbe9Sxc151355 linkprop_val_t *lvp; 4400ba2cbe9Sxc151355 uint_t valcnt = 0; 4410ba2cbe9Sxc151355 4420ba2cbe9Sxc151355 /* 4430ba2cbe9Sxc151355 * Find the linkprop we want to get. 4440ba2cbe9Sxc151355 */ 4450ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 4460ba2cbe9Sxc151355 if (strcmp(lip->li_name, lsp->ls_propname) == 0) 4470ba2cbe9Sxc151355 break; 4480ba2cbe9Sxc151355 } 4490ba2cbe9Sxc151355 if (lip == NULL) { 4500ba2cbe9Sxc151355 *statusp = DLADM_STATUS_NOTFOUND; 4510ba2cbe9Sxc151355 return (B_FALSE); 4520ba2cbe9Sxc151355 } 4530ba2cbe9Sxc151355 4540ba2cbe9Sxc151355 for (lvp = lip->li_val; lvp != NULL; lvp = lvp->lv_nextval) { 4550ba2cbe9Sxc151355 (void) strncpy(lsp->ls_propval[valcnt], lvp->lv_name, 4560ba2cbe9Sxc151355 DLADM_PROP_VAL_MAX); 4570ba2cbe9Sxc151355 4580ba2cbe9Sxc151355 if (++valcnt >= *lsp->ls_valcntp && lvp->lv_nextval != NULL) { 4590ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL; 4600ba2cbe9Sxc151355 return (B_FALSE); 4610ba2cbe9Sxc151355 } 4620ba2cbe9Sxc151355 } 4630ba2cbe9Sxc151355 /* 4640ba2cbe9Sxc151355 * This function is meant to be called at most once for each call 4650ba2cbe9Sxc151355 * to process_linkprop_db(). For this reason, it's ok to overwrite 4660ba2cbe9Sxc151355 * the caller's valcnt array size with the actual number of values 4670ba2cbe9Sxc151355 * returned. 4680ba2cbe9Sxc151355 */ 4690ba2cbe9Sxc151355 *lsp->ls_valcntp = valcnt; 4700ba2cbe9Sxc151355 return (B_FALSE); 4710ba2cbe9Sxc151355 } 4720ba2cbe9Sxc151355 4730ba2cbe9Sxc151355 /* 4740ba2cbe9Sxc151355 * This is used for initializing link properties. 4750ba2cbe9Sxc151355 * Unlike the other routines, this gets called for every entry in the 4760ba2cbe9Sxc151355 * database. lsp->ls_link is not user-specified but instead is set to 4770ba2cbe9Sxc151355 * the current link being processed. 4780ba2cbe9Sxc151355 */ 4790ba2cbe9Sxc151355 /* ARGSUSED */ 4800ba2cbe9Sxc151355 static boolean_t 4810ba2cbe9Sxc151355 process_linkprop_init(linkprop_db_state_t *lsp, char *buf, 4820ba2cbe9Sxc151355 linkprop_info_t *listp, dladm_status_t *statusp) 4830ba2cbe9Sxc151355 { 4840ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 4850ba2cbe9Sxc151355 linkprop_info_t *lip = listp; 4860ba2cbe9Sxc151355 linkprop_val_t *lvp; 4870ba2cbe9Sxc151355 uint_t valcnt, i; 4880ba2cbe9Sxc151355 char **propval; 4890ba2cbe9Sxc151355 4900ba2cbe9Sxc151355 for (; lip != NULL; lip = lip->li_nextprop) { 4910ba2cbe9Sxc151355 /* 4920ba2cbe9Sxc151355 * Construct the propval array and fill it with 4930ba2cbe9Sxc151355 * values from listp. 4940ba2cbe9Sxc151355 */ 4950ba2cbe9Sxc151355 for (lvp = lip->li_val, valcnt = 0; 4960ba2cbe9Sxc151355 lvp != NULL; lvp = lvp->lv_nextval, valcnt++); 4970ba2cbe9Sxc151355 4980ba2cbe9Sxc151355 propval = malloc(sizeof (char *) * valcnt); 4990ba2cbe9Sxc151355 if (propval == NULL) { 5000ba2cbe9Sxc151355 *statusp = DLADM_STATUS_NOMEM; 5010ba2cbe9Sxc151355 break; 5020ba2cbe9Sxc151355 } 5030ba2cbe9Sxc151355 lvp = lip->li_val; 5040ba2cbe9Sxc151355 for (i = 0; i < valcnt; i++, lvp = lvp->lv_nextval) 5050ba2cbe9Sxc151355 propval[i] = (char *)lvp->lv_name; 5060ba2cbe9Sxc151355 5070ba2cbe9Sxc151355 status = dladm_set_prop(lsp->ls_link, lip->li_name, 508*f4b3ec61Sdh155122 propval, valcnt, DLADM_OPT_TEMP, NULL); 5090ba2cbe9Sxc151355 5100ba2cbe9Sxc151355 /* 5110ba2cbe9Sxc151355 * We continue with initializing other properties even 5120ba2cbe9Sxc151355 * after encountering an error. This error will be 5130ba2cbe9Sxc151355 * propagated to the caller via 'statusp'. 5140ba2cbe9Sxc151355 */ 5150ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 5160ba2cbe9Sxc151355 *statusp = status; 5170ba2cbe9Sxc151355 5180ba2cbe9Sxc151355 free(propval); 5190ba2cbe9Sxc151355 } 5200ba2cbe9Sxc151355 return (B_TRUE); 5210ba2cbe9Sxc151355 } 5220ba2cbe9Sxc151355 5230ba2cbe9Sxc151355 static int 5240ba2cbe9Sxc151355 parse_linkprops(char *buf, linkprop_info_t **lipp) 5250ba2cbe9Sxc151355 { 5260ba2cbe9Sxc151355 int i, len; 5270ba2cbe9Sxc151355 char *curr; 5280ba2cbe9Sxc151355 linkprop_info_t *lip = NULL; 5290ba2cbe9Sxc151355 linkprop_info_t **tailp = lipp; 5300ba2cbe9Sxc151355 linkprop_val_t *lvp = NULL; 5310ba2cbe9Sxc151355 linkprop_val_t **vtailp = NULL; 5320ba2cbe9Sxc151355 5330ba2cbe9Sxc151355 curr = buf; 5340ba2cbe9Sxc151355 len = strlen(buf); 5350ba2cbe9Sxc151355 for (i = 0; i < len; i++) { 5360ba2cbe9Sxc151355 char c = buf[i]; 5370ba2cbe9Sxc151355 boolean_t match = (c == '=' || c == ',' || c == ';'); 5380ba2cbe9Sxc151355 5390ba2cbe9Sxc151355 /* 5400ba2cbe9Sxc151355 * Move to the next character if there is no match and 5410ba2cbe9Sxc151355 * if we have not reached the last character. 5420ba2cbe9Sxc151355 */ 5430ba2cbe9Sxc151355 if (!match && i != len - 1) 5440ba2cbe9Sxc151355 continue; 5450ba2cbe9Sxc151355 5460ba2cbe9Sxc151355 if (match) { 5470ba2cbe9Sxc151355 /* 5480ba2cbe9Sxc151355 * Nul-terminate the string pointed to by 'curr'. 5490ba2cbe9Sxc151355 */ 5500ba2cbe9Sxc151355 buf[i] = '\0'; 5510ba2cbe9Sxc151355 if (*curr == '\0') 5520ba2cbe9Sxc151355 goto fail; 5530ba2cbe9Sxc151355 } 5540ba2cbe9Sxc151355 5550ba2cbe9Sxc151355 if (lip != NULL) { 5560ba2cbe9Sxc151355 /* 5570ba2cbe9Sxc151355 * We get here after we have processed the "<prop>=" 5580ba2cbe9Sxc151355 * pattern. The pattern we are now interested in is 5590ba2cbe9Sxc151355 * "<val0>,<val1>,...,<valn>;". For each value we 5600ba2cbe9Sxc151355 * find, a linkprop_val_t will be allocated and 5610ba2cbe9Sxc151355 * added to the current 'lip'. 5620ba2cbe9Sxc151355 */ 5630ba2cbe9Sxc151355 if (c == '=') 5640ba2cbe9Sxc151355 goto fail; 5650ba2cbe9Sxc151355 5660ba2cbe9Sxc151355 lvp = malloc(sizeof (*lvp)); 5670ba2cbe9Sxc151355 if (lvp == NULL) 5680ba2cbe9Sxc151355 goto fail; 5690ba2cbe9Sxc151355 5700ba2cbe9Sxc151355 lvp->lv_name = curr; 5710ba2cbe9Sxc151355 lvp->lv_nextval = NULL; 5720ba2cbe9Sxc151355 *vtailp = lvp; 5730ba2cbe9Sxc151355 vtailp = &lvp->lv_nextval; 5740ba2cbe9Sxc151355 5750ba2cbe9Sxc151355 if (c == ';') { 5760ba2cbe9Sxc151355 tailp = &lip->li_nextprop; 5770ba2cbe9Sxc151355 vtailp = NULL; 5780ba2cbe9Sxc151355 lip = NULL; 5790ba2cbe9Sxc151355 } 5800ba2cbe9Sxc151355 } else { 5810ba2cbe9Sxc151355 /* 5820ba2cbe9Sxc151355 * lip == NULL indicates that 'curr' must be refering 5830ba2cbe9Sxc151355 * to a property name. We allocate a new linkprop_info_t 5840ba2cbe9Sxc151355 * append it to the list given by the caller. 5850ba2cbe9Sxc151355 */ 5860ba2cbe9Sxc151355 if (c != '=') 5870ba2cbe9Sxc151355 goto fail; 5880ba2cbe9Sxc151355 5890ba2cbe9Sxc151355 lip = malloc(sizeof (*lip)); 5900ba2cbe9Sxc151355 if (lip == NULL) 5910ba2cbe9Sxc151355 goto fail; 5920ba2cbe9Sxc151355 5930ba2cbe9Sxc151355 lip->li_name = curr; 5940ba2cbe9Sxc151355 lip->li_val = NULL; 5950ba2cbe9Sxc151355 lip->li_nextprop = NULL; 5960ba2cbe9Sxc151355 *tailp = lip; 5970ba2cbe9Sxc151355 vtailp = &lip->li_val; 5980ba2cbe9Sxc151355 } 5990ba2cbe9Sxc151355 curr = buf + i + 1; 6000ba2cbe9Sxc151355 } 6010ba2cbe9Sxc151355 /* 6020ba2cbe9Sxc151355 * The list must be non-empty and the last character must be ';'. 6030ba2cbe9Sxc151355 */ 6040ba2cbe9Sxc151355 if (*lipp == NULL || lip != NULL) 6050ba2cbe9Sxc151355 goto fail; 6060ba2cbe9Sxc151355 6070ba2cbe9Sxc151355 return (0); 6080ba2cbe9Sxc151355 6090ba2cbe9Sxc151355 fail: 6100ba2cbe9Sxc151355 free_linkprops(*lipp); 6110ba2cbe9Sxc151355 *lipp = NULL; 6120ba2cbe9Sxc151355 return (-1); 6130ba2cbe9Sxc151355 } 6140ba2cbe9Sxc151355 6150ba2cbe9Sxc151355 static boolean_t 6160ba2cbe9Sxc151355 process_linkprop_line(linkprop_db_state_t *lsp, char *buf, 6170ba2cbe9Sxc151355 dladm_status_t *statusp) 6180ba2cbe9Sxc151355 { 6190ba2cbe9Sxc151355 linkprop_info_t *lip = NULL; 6200ba2cbe9Sxc151355 int i, len, llen; 6210ba2cbe9Sxc151355 char *str, *lasts; 6220ba2cbe9Sxc151355 boolean_t cont, nolink = B_FALSE; 6230ba2cbe9Sxc151355 6240ba2cbe9Sxc151355 /* 6250ba2cbe9Sxc151355 * Skip leading spaces, blank lines, and comments. 6260ba2cbe9Sxc151355 */ 6270ba2cbe9Sxc151355 len = strlen(buf); 6280ba2cbe9Sxc151355 for (i = 0; i < len; i++) { 6290ba2cbe9Sxc151355 if (!isspace(buf[i])) 6300ba2cbe9Sxc151355 break; 6310ba2cbe9Sxc151355 } 6320ba2cbe9Sxc151355 if (i == len || buf[i] == '#') 6330ba2cbe9Sxc151355 return (B_TRUE); 6340ba2cbe9Sxc151355 6350ba2cbe9Sxc151355 str = buf + i; 6360ba2cbe9Sxc151355 if (lsp->ls_link != NULL) { 6370ba2cbe9Sxc151355 /* 6380ba2cbe9Sxc151355 * Skip links we're not interested in. 6390ba2cbe9Sxc151355 * Note that strncmp() and isspace() are used here 6400ba2cbe9Sxc151355 * instead of strtok() and strcmp() because we don't 6410ba2cbe9Sxc151355 * want to modify buf in case it does not contain the 6420ba2cbe9Sxc151355 * specified link. 6430ba2cbe9Sxc151355 */ 6440ba2cbe9Sxc151355 llen = strlen(lsp->ls_link); 6450ba2cbe9Sxc151355 if (strncmp(str, lsp->ls_link, llen) != 0 || 6460ba2cbe9Sxc151355 !isspace(str[llen])) 6470ba2cbe9Sxc151355 return (B_TRUE); 6480ba2cbe9Sxc151355 } else { 6490ba2cbe9Sxc151355 /* 6500ba2cbe9Sxc151355 * If a link is not specified, find the link name 6510ba2cbe9Sxc151355 * and assign it to lsp->ls_link. 6520ba2cbe9Sxc151355 */ 6530ba2cbe9Sxc151355 if (strtok_r(str, " \n\t", &lasts) == NULL) 6540ba2cbe9Sxc151355 goto fail; 6550ba2cbe9Sxc151355 6560ba2cbe9Sxc151355 llen = strlen(str); 6570ba2cbe9Sxc151355 lsp->ls_link = str; 6580ba2cbe9Sxc151355 nolink = B_TRUE; 6590ba2cbe9Sxc151355 } 6600ba2cbe9Sxc151355 str += llen + 1; 6610ba2cbe9Sxc151355 if (str >= buf + len) 6620ba2cbe9Sxc151355 goto fail; 6630ba2cbe9Sxc151355 6640ba2cbe9Sxc151355 /* 6650ba2cbe9Sxc151355 * Now find the list of link properties. 6660ba2cbe9Sxc151355 */ 6670ba2cbe9Sxc151355 if ((str = strtok_r(str, " \n\t", &lasts)) == NULL) 6680ba2cbe9Sxc151355 goto fail; 6690ba2cbe9Sxc151355 6700ba2cbe9Sxc151355 if (parse_linkprops(str, &lip) < 0) 6710ba2cbe9Sxc151355 goto fail; 6720ba2cbe9Sxc151355 6730ba2cbe9Sxc151355 cont = (*lsp->ls_op)(lsp, buf, lip, statusp); 6740ba2cbe9Sxc151355 free_linkprops(lip); 6750ba2cbe9Sxc151355 if (nolink) 6760ba2cbe9Sxc151355 lsp->ls_link = NULL; 6770ba2cbe9Sxc151355 return (cont); 6780ba2cbe9Sxc151355 6790ba2cbe9Sxc151355 fail: 6800ba2cbe9Sxc151355 free_linkprops(lip); 6810ba2cbe9Sxc151355 if (nolink) 6820ba2cbe9Sxc151355 lsp->ls_link = NULL; 6830ba2cbe9Sxc151355 6840ba2cbe9Sxc151355 /* 6850ba2cbe9Sxc151355 * Delete corrupted line. 6860ba2cbe9Sxc151355 */ 6870ba2cbe9Sxc151355 buf[0] = '\0'; 6880ba2cbe9Sxc151355 return (B_TRUE); 6890ba2cbe9Sxc151355 } 6900ba2cbe9Sxc151355 6910ba2cbe9Sxc151355 static dladm_status_t 6920ba2cbe9Sxc151355 process_linkprop_db(void *arg, FILE *fp, FILE *nfp) 6930ba2cbe9Sxc151355 { 6940ba2cbe9Sxc151355 linkprop_db_state_t *lsp = arg; 6950ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 6960ba2cbe9Sxc151355 char buf[MAXLINELEN]; 6970ba2cbe9Sxc151355 boolean_t cont = B_TRUE; 6980ba2cbe9Sxc151355 6990ba2cbe9Sxc151355 /* 7000ba2cbe9Sxc151355 * This loop processes each line of the configuration file. 7010ba2cbe9Sxc151355 * buf can potentially be modified by process_linkprop_line(). 7020ba2cbe9Sxc151355 * If this is a write operation and buf is not truncated, buf will 7030ba2cbe9Sxc151355 * be written to disk. process_linkprop_line() will no longer be 7040ba2cbe9Sxc151355 * called after it returns B_FALSE; at which point the remainder 7050ba2cbe9Sxc151355 * of the file will continue to be read and, if necessary, written 7060ba2cbe9Sxc151355 * to disk as well. 7070ba2cbe9Sxc151355 */ 7080ba2cbe9Sxc151355 while (fgets(buf, MAXLINELEN, fp) != NULL) { 7090ba2cbe9Sxc151355 if (cont) 7100ba2cbe9Sxc151355 cont = process_linkprop_line(lsp, buf, &status); 7110ba2cbe9Sxc151355 7120ba2cbe9Sxc151355 if (nfp != NULL && buf[0] != '\0' && fputs(buf, nfp) == EOF) { 7130ba2cbe9Sxc151355 status = dladm_errno2status(errno); 7140ba2cbe9Sxc151355 break; 7150ba2cbe9Sxc151355 } 7160ba2cbe9Sxc151355 } 7170ba2cbe9Sxc151355 7180ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK || !cont) 7190ba2cbe9Sxc151355 return (status); 7200ba2cbe9Sxc151355 7210ba2cbe9Sxc151355 if (lsp->ls_op == process_linkprop_set) { 7220ba2cbe9Sxc151355 /* 7230ba2cbe9Sxc151355 * If the specified link is not found above, we add the 7240ba2cbe9Sxc151355 * link and its properties to the configuration file. 7250ba2cbe9Sxc151355 */ 7260ba2cbe9Sxc151355 (void) (*lsp->ls_op)(lsp, buf, NULL, &status); 7270ba2cbe9Sxc151355 if (status == DLADM_STATUS_OK && fputs(buf, nfp) == EOF) 7280ba2cbe9Sxc151355 status = dladm_errno2status(errno); 7290ba2cbe9Sxc151355 } 7300ba2cbe9Sxc151355 7310ba2cbe9Sxc151355 if (lsp->ls_op == process_linkprop_get) 7320ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 7330ba2cbe9Sxc151355 7340ba2cbe9Sxc151355 return (status); 7350ba2cbe9Sxc151355 } 7360ba2cbe9Sxc151355 7370ba2cbe9Sxc151355 #define LINKPROP_RW_DB(statep, writeop) \ 7380ba2cbe9Sxc151355 (i_dladm_rw_db("/etc/dladm/linkprop.conf", \ 7390ba2cbe9Sxc151355 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, process_linkprop_db, \ 7400ba2cbe9Sxc151355 (statep), (writeop))) 7410ba2cbe9Sxc151355 7420ba2cbe9Sxc151355 static dladm_status_t 7430ba2cbe9Sxc151355 i_dladm_set_prop_db(const char *link, const char *prop_name, 7440ba2cbe9Sxc151355 char **prop_val, uint_t val_cnt) 7450ba2cbe9Sxc151355 { 7460ba2cbe9Sxc151355 linkprop_db_state_t state; 7470ba2cbe9Sxc151355 7480ba2cbe9Sxc151355 state.ls_op = process_linkprop_set; 7490ba2cbe9Sxc151355 state.ls_link = link; 7500ba2cbe9Sxc151355 state.ls_propname = prop_name; 7510ba2cbe9Sxc151355 state.ls_propval = prop_val; 7520ba2cbe9Sxc151355 state.ls_valcntp = &val_cnt; 7530ba2cbe9Sxc151355 7540ba2cbe9Sxc151355 return (LINKPROP_RW_DB(&state, B_TRUE)); 7550ba2cbe9Sxc151355 } 7560ba2cbe9Sxc151355 7570ba2cbe9Sxc151355 static dladm_status_t 7580ba2cbe9Sxc151355 i_dladm_get_prop_db(const char *link, const char *prop_name, 7590ba2cbe9Sxc151355 char **prop_val, uint_t *val_cntp) 7600ba2cbe9Sxc151355 { 7610ba2cbe9Sxc151355 linkprop_db_state_t state; 7620ba2cbe9Sxc151355 7630ba2cbe9Sxc151355 state.ls_op = process_linkprop_get; 7640ba2cbe9Sxc151355 state.ls_link = link; 7650ba2cbe9Sxc151355 state.ls_propname = prop_name; 7660ba2cbe9Sxc151355 state.ls_propval = prop_val; 7670ba2cbe9Sxc151355 state.ls_valcntp = val_cntp; 7680ba2cbe9Sxc151355 7690ba2cbe9Sxc151355 return (LINKPROP_RW_DB(&state, B_FALSE)); 7700ba2cbe9Sxc151355 } 7710ba2cbe9Sxc151355 7720ba2cbe9Sxc151355 dladm_status_t 7730ba2cbe9Sxc151355 dladm_init_linkprop(void) 7740ba2cbe9Sxc151355 { 7750ba2cbe9Sxc151355 linkprop_db_state_t state; 7760ba2cbe9Sxc151355 7770ba2cbe9Sxc151355 state.ls_op = process_linkprop_init; 7780ba2cbe9Sxc151355 state.ls_link = NULL; 7790ba2cbe9Sxc151355 state.ls_propname = NULL; 7800ba2cbe9Sxc151355 state.ls_propval = NULL; 7810ba2cbe9Sxc151355 state.ls_valcntp = NULL; 7820ba2cbe9Sxc151355 7830ba2cbe9Sxc151355 return (LINKPROP_RW_DB(&state, B_FALSE)); 7840ba2cbe9Sxc151355 } 785*f4b3ec61Sdh155122 786*f4b3ec61Sdh155122 static dladm_status_t 787*f4b3ec61Sdh155122 i_dladm_get_zoneid(const char *link, zoneid_t *zidp) 788*f4b3ec61Sdh155122 { 789*f4b3ec61Sdh155122 int fd; 790*f4b3ec61Sdh155122 dld_hold_vlan_t dhv; 791*f4b3ec61Sdh155122 792*f4b3ec61Sdh155122 if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) 793*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 794*f4b3ec61Sdh155122 795*f4b3ec61Sdh155122 bzero(&dhv, sizeof (dld_hold_vlan_t)); 796*f4b3ec61Sdh155122 (void) strlcpy(dhv.dhv_name, link, IFNAMSIZ); 797*f4b3ec61Sdh155122 dhv.dhv_zid = -1; 798*f4b3ec61Sdh155122 799*f4b3ec61Sdh155122 if (i_dladm_ioctl(fd, DLDIOCZIDGET, &dhv, sizeof (dhv)) < 0 && 800*f4b3ec61Sdh155122 errno != ENOENT) { 801*f4b3ec61Sdh155122 dladm_status_t status = dladm_errno2status(errno); 802*f4b3ec61Sdh155122 803*f4b3ec61Sdh155122 (void) close(fd); 804*f4b3ec61Sdh155122 return (status); 805*f4b3ec61Sdh155122 } 806*f4b3ec61Sdh155122 807*f4b3ec61Sdh155122 if (errno == ENOENT) 808*f4b3ec61Sdh155122 *zidp = GLOBAL_ZONEID; 809*f4b3ec61Sdh155122 else 810*f4b3ec61Sdh155122 *zidp = dhv.dhv_zid; 811*f4b3ec61Sdh155122 812*f4b3ec61Sdh155122 (void) close(fd); 813*f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 814*f4b3ec61Sdh155122 } 815*f4b3ec61Sdh155122 816*f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 817*f4b3ec61Sdh155122 818*f4b3ec61Sdh155122 static int 819*f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 820*f4b3ec61Sdh155122 { 821*f4b3ec61Sdh155122 char root[MAXPATHLEN]; 822*f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 823*f4b3ec61Sdh155122 void *dlhandle; 824*f4b3ec61Sdh155122 void *sym; 825*f4b3ec61Sdh155122 int ret; 826*f4b3ec61Sdh155122 827*f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 828*f4b3ec61Sdh155122 return (-1); 829*f4b3ec61Sdh155122 830*f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 831*f4b3ec61Sdh155122 (void) dlclose(dlhandle); 832*f4b3ec61Sdh155122 return (-1); 833*f4b3ec61Sdh155122 } 834*f4b3ec61Sdh155122 835*f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 836*f4b3ec61Sdh155122 837*f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 838*f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 839*f4b3ec61Sdh155122 (void) dlclose(dlhandle); 840*f4b3ec61Sdh155122 return (ret); 841*f4b3ec61Sdh155122 } 842*f4b3ec61Sdh155122 843*f4b3ec61Sdh155122 static dladm_status_t 844*f4b3ec61Sdh155122 i_dladm_add_deventry(zoneid_t zid, const char *link) 845*f4b3ec61Sdh155122 { 846*f4b3ec61Sdh155122 char path[MAXPATHLEN]; 847*f4b3ec61Sdh155122 di_prof_t prof = NULL; 848*f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 849*f4b3ec61Sdh155122 dladm_status_t status; 850*f4b3ec61Sdh155122 851*f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 852*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 853*f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 854*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 855*f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 856*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 857*f4b3ec61Sdh155122 858*f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 859*f4b3ec61Sdh155122 if (di_prof_add_dev(prof, link) != 0) { 860*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 861*f4b3ec61Sdh155122 goto cleanup; 862*f4b3ec61Sdh155122 } 863*f4b3ec61Sdh155122 if (di_prof_commit(prof) != 0) 864*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 865*f4b3ec61Sdh155122 cleanup: 866*f4b3ec61Sdh155122 if (prof) 867*f4b3ec61Sdh155122 di_prof_fini(prof); 868*f4b3ec61Sdh155122 869*f4b3ec61Sdh155122 return (status); 870*f4b3ec61Sdh155122 } 871*f4b3ec61Sdh155122 872*f4b3ec61Sdh155122 static dladm_status_t 873*f4b3ec61Sdh155122 i_dladm_remove_deventry(zoneid_t zid, const char *link) 874*f4b3ec61Sdh155122 { 875*f4b3ec61Sdh155122 char path[MAXPATHLEN]; 876*f4b3ec61Sdh155122 di_prof_t prof = NULL; 877*f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 878*f4b3ec61Sdh155122 dladm_status_t status; 879*f4b3ec61Sdh155122 880*f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 881*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 882*f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 883*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 884*f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 885*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 886*f4b3ec61Sdh155122 887*f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 888*f4b3ec61Sdh155122 if (di_prof_add_exclude(prof, link) != 0) { 889*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 890*f4b3ec61Sdh155122 goto cleanup; 891*f4b3ec61Sdh155122 } 892*f4b3ec61Sdh155122 if (di_prof_commit(prof) != 0) 893*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 894*f4b3ec61Sdh155122 cleanup: 895*f4b3ec61Sdh155122 if (prof) 896*f4b3ec61Sdh155122 di_prof_fini(prof); 897*f4b3ec61Sdh155122 898*f4b3ec61Sdh155122 return (status); 899*f4b3ec61Sdh155122 } 900*f4b3ec61Sdh155122 901*f4b3ec61Sdh155122 static dladm_status_t 902*f4b3ec61Sdh155122 do_get_zone(const char *link, char **prop_val, uint_t *val_cnt) 903*f4b3ec61Sdh155122 { 904*f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 905*f4b3ec61Sdh155122 zoneid_t zid; 906*f4b3ec61Sdh155122 dladm_status_t status; 907*f4b3ec61Sdh155122 908*f4b3ec61Sdh155122 status = i_dladm_get_zoneid(link, &zid); 909*f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 910*f4b3ec61Sdh155122 return (status); 911*f4b3ec61Sdh155122 912*f4b3ec61Sdh155122 *val_cnt = 1; 913*f4b3ec61Sdh155122 if (zid != GLOBAL_ZONEID) { 914*f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 915*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 916*f4b3ec61Sdh155122 917*f4b3ec61Sdh155122 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 918*f4b3ec61Sdh155122 } else { 919*f4b3ec61Sdh155122 *prop_val[0] = '\0'; 920*f4b3ec61Sdh155122 } 921*f4b3ec61Sdh155122 922*f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 923*f4b3ec61Sdh155122 } 924*f4b3ec61Sdh155122 925*f4b3ec61Sdh155122 static dladm_status_t 926*f4b3ec61Sdh155122 do_set_zone(const char *link, val_desc_t *vdp, uint_t val_cnt) 927*f4b3ec61Sdh155122 { 928*f4b3ec61Sdh155122 dladm_status_t status; 929*f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 930*f4b3ec61Sdh155122 char buff[IF_NAMESIZE + 1]; 931*f4b3ec61Sdh155122 struct stat st; 932*f4b3ec61Sdh155122 933*f4b3ec61Sdh155122 if (val_cnt != 1) 934*f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 935*f4b3ec61Sdh155122 936*f4b3ec61Sdh155122 status = i_dladm_get_zoneid(link, &zid_old); 937*f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 938*f4b3ec61Sdh155122 return (status); 939*f4b3ec61Sdh155122 940*f4b3ec61Sdh155122 /* Do nothing if setting to current value */ 941*f4b3ec61Sdh155122 zid_new = (zoneid_t)vdp->vd_val; 942*f4b3ec61Sdh155122 if (zid_new == zid_old) 943*f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 944*f4b3ec61Sdh155122 945*f4b3ec61Sdh155122 /* Do a stat to get the vlan created by MAC, if it's not there */ 946*f4b3ec61Sdh155122 (void) strcpy(buff, "/dev/"); 947*f4b3ec61Sdh155122 (void) strlcat(buff, link, IF_NAMESIZE); 948*f4b3ec61Sdh155122 (void) stat(buff, &st); 949*f4b3ec61Sdh155122 950*f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) { 951*f4b3ec61Sdh155122 if (dladm_rele_link(link, GLOBAL_ZONEID, B_TRUE) < 0) 952*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 953*f4b3ec61Sdh155122 954*f4b3ec61Sdh155122 if (zone_remove_datalink(zid_old, (char *)link) != 0 && 955*f4b3ec61Sdh155122 errno != ENXIO) { 956*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 957*f4b3ec61Sdh155122 goto rollback1; 958*f4b3ec61Sdh155122 } 959*f4b3ec61Sdh155122 960*f4b3ec61Sdh155122 status = i_dladm_remove_deventry(zid_old, link); 961*f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 962*f4b3ec61Sdh155122 goto rollback2; 963*f4b3ec61Sdh155122 } 964*f4b3ec61Sdh155122 965*f4b3ec61Sdh155122 if (zid_new != GLOBAL_ZONEID) { 966*f4b3ec61Sdh155122 if (zone_add_datalink(zid_new, (char *)link) != 0) { 967*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 968*f4b3ec61Sdh155122 goto rollback3; 969*f4b3ec61Sdh155122 } 970*f4b3ec61Sdh155122 971*f4b3ec61Sdh155122 if (dladm_hold_link(link, zid_new, B_TRUE) < 0) { 972*f4b3ec61Sdh155122 (void) zone_remove_datalink(zid_new, (char *)link); 973*f4b3ec61Sdh155122 status = dladm_errno2status(errno); 974*f4b3ec61Sdh155122 goto rollback3; 975*f4b3ec61Sdh155122 } 976*f4b3ec61Sdh155122 977*f4b3ec61Sdh155122 status = i_dladm_add_deventry(zid_new, link); 978*f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) { 979*f4b3ec61Sdh155122 (void) dladm_rele_link(link, GLOBAL_ZONEID, B_FALSE); 980*f4b3ec61Sdh155122 (void) zone_remove_datalink(zid_new, (char *)link); 981*f4b3ec61Sdh155122 goto rollback3; 982*f4b3ec61Sdh155122 } 983*f4b3ec61Sdh155122 } 984*f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 985*f4b3ec61Sdh155122 986*f4b3ec61Sdh155122 rollback3: 987*f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 988*f4b3ec61Sdh155122 (void) i_dladm_add_deventry(zid_old, link); 989*f4b3ec61Sdh155122 rollback2: 990*f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 991*f4b3ec61Sdh155122 (void) zone_add_datalink(zid_old, (char *)link); 992*f4b3ec61Sdh155122 rollback1: 993*f4b3ec61Sdh155122 (void) dladm_hold_link(link, zid_old, B_FALSE); 994*f4b3ec61Sdh155122 cleanexit: 995*f4b3ec61Sdh155122 return (status); 996*f4b3ec61Sdh155122 } 997*f4b3ec61Sdh155122 998*f4b3ec61Sdh155122 /* ARGSUSED */ 999*f4b3ec61Sdh155122 static dladm_status_t 1000*f4b3ec61Sdh155122 do_check_zone(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 1001*f4b3ec61Sdh155122 val_desc_t **vdpp) 1002*f4b3ec61Sdh155122 { 1003*f4b3ec61Sdh155122 zoneid_t zid; 1004*f4b3ec61Sdh155122 val_desc_t *vdp = NULL; 1005*f4b3ec61Sdh155122 1006*f4b3ec61Sdh155122 if (val_cnt != 1) 1007*f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1008*f4b3ec61Sdh155122 1009*f4b3ec61Sdh155122 if ((zid = getzoneidbyname(*prop_val)) == -1) 1010*f4b3ec61Sdh155122 return (DLADM_STATUS_BADVAL); 1011*f4b3ec61Sdh155122 1012*f4b3ec61Sdh155122 if (zid != GLOBAL_ZONEID) { 1013*f4b3ec61Sdh155122 ushort_t flags; 1014*f4b3ec61Sdh155122 1015*f4b3ec61Sdh155122 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags, 1016*f4b3ec61Sdh155122 sizeof (flags)) < 0) { 1017*f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1018*f4b3ec61Sdh155122 } 1019*f4b3ec61Sdh155122 1020*f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 1021*f4b3ec61Sdh155122 return (DLADM_STATUS_BADVAL); 1022*f4b3ec61Sdh155122 } 1023*f4b3ec61Sdh155122 } 1024*f4b3ec61Sdh155122 1025*f4b3ec61Sdh155122 vdp = malloc(sizeof (val_desc_t)); 1026*f4b3ec61Sdh155122 if (vdp == NULL) 1027*f4b3ec61Sdh155122 return (DLADM_STATUS_NOMEM); 1028*f4b3ec61Sdh155122 1029*f4b3ec61Sdh155122 vdp->vd_val = (void *)zid; 1030*f4b3ec61Sdh155122 *vdpp = vdp; 1031*f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1032*f4b3ec61Sdh155122 } 1033*f4b3ec61Sdh155122 1034*f4b3ec61Sdh155122 static dladm_status_t 1035*f4b3ec61Sdh155122 i_dladm_get_prop_temp(const char *link, dladm_prop_type_t type, 1036*f4b3ec61Sdh155122 const char *prop_name, char **prop_val, uint_t *val_cntp) 1037*f4b3ec61Sdh155122 { 1038*f4b3ec61Sdh155122 int i; 1039*f4b3ec61Sdh155122 dladm_status_t status; 1040*f4b3ec61Sdh155122 uint_t cnt; 1041*f4b3ec61Sdh155122 prop_desc_t *pdp; 1042*f4b3ec61Sdh155122 1043*f4b3ec61Sdh155122 if (link == NULL || prop_name == NULL || prop_val == NULL || 1044*f4b3ec61Sdh155122 val_cntp == NULL || *val_cntp == 0) 1045*f4b3ec61Sdh155122 return (DLADM_STATUS_BADARG); 1046*f4b3ec61Sdh155122 1047*f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) 1048*f4b3ec61Sdh155122 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 1049*f4b3ec61Sdh155122 break; 1050*f4b3ec61Sdh155122 1051*f4b3ec61Sdh155122 if (i == MAX_PROPS) 1052*f4b3ec61Sdh155122 return (DLADM_STATUS_NOTFOUND); 1053*f4b3ec61Sdh155122 1054*f4b3ec61Sdh155122 pdp = &prop_table[i]; 1055*f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 1056*f4b3ec61Sdh155122 1057*f4b3ec61Sdh155122 switch (type) { 1058*f4b3ec61Sdh155122 case DLADM_PROP_VAL_CURRENT: 1059*f4b3ec61Sdh155122 status = pdp->pd_get(link, prop_val, val_cntp); 1060*f4b3ec61Sdh155122 break; 1061*f4b3ec61Sdh155122 case DLADM_PROP_VAL_DEFAULT: 1062*f4b3ec61Sdh155122 if (pdp->pd_defval.vd_name == NULL) { 1063*f4b3ec61Sdh155122 status = DLADM_STATUS_NOTSUP; 1064*f4b3ec61Sdh155122 break; 1065*f4b3ec61Sdh155122 } 1066*f4b3ec61Sdh155122 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 1067*f4b3ec61Sdh155122 *val_cntp = 1; 1068*f4b3ec61Sdh155122 break; 1069*f4b3ec61Sdh155122 1070*f4b3ec61Sdh155122 case DLADM_PROP_VAL_MODIFIABLE: 1071*f4b3ec61Sdh155122 if (pdp->pd_getmod != NULL) { 1072*f4b3ec61Sdh155122 status = pdp->pd_getmod(link, prop_val, val_cntp); 1073*f4b3ec61Sdh155122 break; 1074*f4b3ec61Sdh155122 } 1075*f4b3ec61Sdh155122 cnt = pdp->pd_nmodval; 1076*f4b3ec61Sdh155122 if (cnt == 0) { 1077*f4b3ec61Sdh155122 status = DLADM_STATUS_NOTSUP; 1078*f4b3ec61Sdh155122 } else if (cnt > *val_cntp) { 1079*f4b3ec61Sdh155122 status = DLADM_STATUS_TOOSMALL; 1080*f4b3ec61Sdh155122 } else { 1081*f4b3ec61Sdh155122 for (i = 0; i < cnt; i++) { 1082*f4b3ec61Sdh155122 (void) strcpy(prop_val[i], 1083*f4b3ec61Sdh155122 pdp->pd_modval[i].vd_name); 1084*f4b3ec61Sdh155122 } 1085*f4b3ec61Sdh155122 *val_cntp = cnt; 1086*f4b3ec61Sdh155122 } 1087*f4b3ec61Sdh155122 break; 1088*f4b3ec61Sdh155122 default: 1089*f4b3ec61Sdh155122 status = DLADM_STATUS_BADARG; 1090*f4b3ec61Sdh155122 break; 1091*f4b3ec61Sdh155122 } 1092*f4b3ec61Sdh155122 1093*f4b3ec61Sdh155122 return (status); 1094*f4b3ec61Sdh155122 } 1095*f4b3ec61Sdh155122 1096*f4b3ec61Sdh155122 static dladm_status_t 1097*f4b3ec61Sdh155122 i_dladm_set_one_prop_temp(const char *link, prop_desc_t *pdp, char **prop_val, 1098*f4b3ec61Sdh155122 uint_t val_cnt, uint_t flags) 1099*f4b3ec61Sdh155122 { 1100*f4b3ec61Sdh155122 dladm_status_t status; 1101*f4b3ec61Sdh155122 val_desc_t *vdp = NULL; 1102*f4b3ec61Sdh155122 uint_t cnt; 1103*f4b3ec61Sdh155122 1104*f4b3ec61Sdh155122 if (pdp->pd_temponly && (flags & DLADM_OPT_PERSIST) != 0) 1105*f4b3ec61Sdh155122 return (DLADM_STATUS_TEMPONLY); 1106*f4b3ec61Sdh155122 1107*f4b3ec61Sdh155122 if (pdp->pd_set == NULL) 1108*f4b3ec61Sdh155122 return (DLADM_STATUS_PROPRDONLY); 1109*f4b3ec61Sdh155122 1110*f4b3ec61Sdh155122 if (prop_val != NULL) { 1111*f4b3ec61Sdh155122 if (pdp->pd_check != NULL) 1112*f4b3ec61Sdh155122 status = pdp->pd_check(pdp, prop_val, val_cnt, &vdp); 1113*f4b3ec61Sdh155122 else 1114*f4b3ec61Sdh155122 status = DLADM_STATUS_BADARG; 1115*f4b3ec61Sdh155122 1116*f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1117*f4b3ec61Sdh155122 return (status); 1118*f4b3ec61Sdh155122 1119*f4b3ec61Sdh155122 cnt = val_cnt; 1120*f4b3ec61Sdh155122 } else { 1121*f4b3ec61Sdh155122 if (pdp->pd_defval.vd_name == NULL) 1122*f4b3ec61Sdh155122 return (DLADM_STATUS_NOTSUP); 1123*f4b3ec61Sdh155122 1124*f4b3ec61Sdh155122 if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 1125*f4b3ec61Sdh155122 return (DLADM_STATUS_NOMEM); 1126*f4b3ec61Sdh155122 1127*f4b3ec61Sdh155122 (void) memcpy(vdp, &pdp->pd_defval, sizeof (val_desc_t)); 1128*f4b3ec61Sdh155122 cnt = 1; 1129*f4b3ec61Sdh155122 } 1130*f4b3ec61Sdh155122 1131*f4b3ec61Sdh155122 status = pdp->pd_set(link, vdp, cnt); 1132*f4b3ec61Sdh155122 1133*f4b3ec61Sdh155122 free(vdp); 1134*f4b3ec61Sdh155122 return (status); 1135*f4b3ec61Sdh155122 } 1136*f4b3ec61Sdh155122 1137*f4b3ec61Sdh155122 static dladm_status_t 1138*f4b3ec61Sdh155122 i_dladm_set_prop_temp(const char *link, const char *prop_name, char **prop_val, 1139*f4b3ec61Sdh155122 uint_t val_cnt, uint_t flags, char **errprop) 1140*f4b3ec61Sdh155122 { 1141*f4b3ec61Sdh155122 int i; 1142*f4b3ec61Sdh155122 dladm_status_t status = DLADM_STATUS_OK; 1143*f4b3ec61Sdh155122 boolean_t found = B_FALSE; 1144*f4b3ec61Sdh155122 1145*f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) { 1146*f4b3ec61Sdh155122 prop_desc_t *pdp = &prop_table[i]; 1147*f4b3ec61Sdh155122 dladm_status_t s; 1148*f4b3ec61Sdh155122 1149*f4b3ec61Sdh155122 if (prop_name != NULL && 1150*f4b3ec61Sdh155122 (strcasecmp(prop_name, pdp->pd_name) != 0)) 1151*f4b3ec61Sdh155122 continue; 1152*f4b3ec61Sdh155122 1153*f4b3ec61Sdh155122 found = B_TRUE; 1154*f4b3ec61Sdh155122 s = i_dladm_set_one_prop_temp(link, pdp, prop_val, val_cnt, 1155*f4b3ec61Sdh155122 flags); 1156*f4b3ec61Sdh155122 1157*f4b3ec61Sdh155122 if (prop_name != NULL) { 1158*f4b3ec61Sdh155122 status = s; 1159*f4b3ec61Sdh155122 break; 1160*f4b3ec61Sdh155122 } else { 1161*f4b3ec61Sdh155122 if (s != DLADM_STATUS_OK && 1162*f4b3ec61Sdh155122 s != DLADM_STATUS_NOTSUP) { 1163*f4b3ec61Sdh155122 if (errprop != NULL) 1164*f4b3ec61Sdh155122 *errprop = pdp->pd_name; 1165*f4b3ec61Sdh155122 status = s; 1166*f4b3ec61Sdh155122 break; 1167*f4b3ec61Sdh155122 } 1168*f4b3ec61Sdh155122 } 1169*f4b3ec61Sdh155122 } 1170*f4b3ec61Sdh155122 1171*f4b3ec61Sdh155122 if (!found) 1172*f4b3ec61Sdh155122 status = DLADM_STATUS_NOTFOUND; 1173*f4b3ec61Sdh155122 1174*f4b3ec61Sdh155122 return (status); 1175*f4b3ec61Sdh155122 } 1176*f4b3ec61Sdh155122 1177*f4b3ec61Sdh155122 static boolean_t 1178*f4b3ec61Sdh155122 i_dladm_is_prop_temponly(const char *prop_name, char **errprop) 1179*f4b3ec61Sdh155122 { 1180*f4b3ec61Sdh155122 int i; 1181*f4b3ec61Sdh155122 1182*f4b3ec61Sdh155122 for (i = 0; i < MAX_PROPS; i++) { 1183*f4b3ec61Sdh155122 prop_desc_t *pdp = &prop_table[i]; 1184*f4b3ec61Sdh155122 1185*f4b3ec61Sdh155122 if (prop_name != NULL && 1186*f4b3ec61Sdh155122 (strcasecmp(prop_name, pdp->pd_name) != 0)) 1187*f4b3ec61Sdh155122 continue; 1188*f4b3ec61Sdh155122 1189*f4b3ec61Sdh155122 if (errprop != NULL) 1190*f4b3ec61Sdh155122 *errprop = pdp->pd_name; 1191*f4b3ec61Sdh155122 1192*f4b3ec61Sdh155122 if (pdp->pd_temponly) 1193*f4b3ec61Sdh155122 return (B_TRUE); 1194*f4b3ec61Sdh155122 } 1195*f4b3ec61Sdh155122 1196*f4b3ec61Sdh155122 return (B_FALSE); 1197*f4b3ec61Sdh155122 } 1198*f4b3ec61Sdh155122 1199*f4b3ec61Sdh155122 boolean_t 1200*f4b3ec61Sdh155122 dladm_is_prop_temponly(const char *prop_name, char **errprop) 1201*f4b3ec61Sdh155122 { 1202*f4b3ec61Sdh155122 return (i_dladm_is_prop_temponly(prop_name, errprop)); 1203*f4b3ec61Sdh155122 } 1204