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 /* 22d62bc4baSyz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230ba2cbe9Sxc151355 * Use is subject to license terms. 240ba2cbe9Sxc151355 */ 250ba2cbe9Sxc151355 260ba2cbe9Sxc151355 #include <stdlib.h> 270ba2cbe9Sxc151355 #include <strings.h> 280ba2cbe9Sxc151355 #include <errno.h> 290ba2cbe9Sxc151355 #include <ctype.h> 30d62bc4baSyz147064 #include <stddef.h> 31f4b3ec61Sdh155122 #include <sys/types.h> 320ba2cbe9Sxc151355 #include <sys/stat.h> 33f4b3ec61Sdh155122 #include <sys/dld.h> 34f4b3ec61Sdh155122 #include <sys/zone.h> 35f4b3ec61Sdh155122 #include <fcntl.h> 36f4b3ec61Sdh155122 #include <unistd.h> 37f4b3ec61Sdh155122 #include <libdevinfo.h> 38f4b3ec61Sdh155122 #include <zone.h> 39f595a68aSyz147064 #include <libdllink.h> 400ba2cbe9Sxc151355 #include <libdladm_impl.h> 41d62bc4baSyz147064 #include <libdlwlan_impl.h> 42f595a68aSyz147064 #include <libdlwlan.h> 43d62bc4baSyz147064 #include <libdlvlan.h> 44*da14cebeSEric Cheng #include <libdlvnic.h> 45*da14cebeSEric Cheng #include <libintl.h> 46f4b3ec61Sdh155122 #include <dlfcn.h> 47f4b3ec61Sdh155122 #include <link.h> 48d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 49e7801d59Ssowmini #include <libdladm.h> 50*da14cebeSEric Cheng #include <libdlstat.h> 51e7801d59Ssowmini #include <sys/param.h> 52*da14cebeSEric Cheng #include <sys/debug.h> 53*da14cebeSEric Cheng #include <sys/dld.h> 54*da14cebeSEric Cheng #include <sys/mac_flow.h> 55e7801d59Ssowmini #include <inttypes.h> 56e7801d59Ssowmini #include <sys/ethernet.h> 57bcb5c89dSSowmini Varadhan #include <net/wpa.h> 58bcb5c89dSSowmini Varadhan #include <sys/sysmacros.h> 59f4b3ec61Sdh155122 60d62bc4baSyz147064 /* 61d62bc4baSyz147064 * The linkprop get() callback. 62*da14cebeSEric Cheng * - pd: pointer to the prop_desc_t 63d62bc4baSyz147064 * - propstrp: a property string array to keep the returned property. 64d62bc4baSyz147064 * Caller allocated. 65d62bc4baSyz147064 * - cntp: number of returned properties. 66d62bc4baSyz147064 * Caller also uses it to indicate how many it expects. 67d62bc4baSyz147064 */ 68e7801d59Ssowmini struct prop_desc; 69*da14cebeSEric Cheng typedef struct prop_desc prop_desc_t; 70e7801d59Ssowmini 71*da14cebeSEric Cheng typedef dladm_status_t pd_getf_t(prop_desc_t *pdp, 726b9e797cSsowmini datalink_id_t, char **propstp, uint_t *cntp, 73afdda45fSVasumathi Sundaram - Sun Microsystems datalink_media_t, uint_t, uint_t *); 74f4b3ec61Sdh155122 75d62bc4baSyz147064 /* 76d62bc4baSyz147064 * The linkprop set() callback. 77d62bc4baSyz147064 * - propval: a val_desc_t array which keeps the property values to be set. 78d62bc4baSyz147064 * - cnt: number of properties to be set. 79e7801d59Ssowmini * - flags: additional flags passed down the system call. 80e7801d59Ssowmini * 81e7801d59Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 82e7801d59Ssowmini * a format suitable for kernel consumption. This may require allocation 83e7801d59Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 84e7801d59Ssowmini * by all other pd_sets) which invokes the ioctl. 85d62bc4baSyz147064 */ 86*da14cebeSEric Cheng typedef dladm_status_t pd_setf_t(prop_desc_t *, datalink_id_t, 876b9e797cSsowmini val_desc_t *propval, uint_t cnt, uint_t flags, 886b9e797cSsowmini datalink_media_t); 89f4b3ec61Sdh155122 90d62bc4baSyz147064 /* 91d62bc4baSyz147064 * The linkprop check() callback. 92d62bc4baSyz147064 * - propstrp: property string array which keeps the property to be checked. 93d62bc4baSyz147064 * - cnt: number of properties. 94d62bc4baSyz147064 * - propval: return value; the property values of the given property strings. 95e7801d59Ssowmini * 96e7801d59Ssowmini * pd_check checks that the input values are valid. It does so by 97e7801d59Ssowmini * iteraring through the pd_modval list for the property. If 98e7801d59Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 99e7801d59Ssowmini * specific to this property can be used. If the input values are 100e7801d59Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 101e7801d59Ssowmini * with either a val_desc_t found on the pd_modval list or something 102e7801d59Ssowmini * generated on the fly. 103d62bc4baSyz147064 */ 104*da14cebeSEric Cheng typedef dladm_status_t pd_checkf_t(prop_desc_t *pdp, datalink_id_t, 105*da14cebeSEric Cheng char **propstrp, uint_t cnt, val_desc_t *propval, 1066b9e797cSsowmini datalink_media_t); 107f4b3ec61Sdh155122 108bcb5c89dSSowmini Varadhan typedef struct link_attr_s { 1093fd94f8cSam223141 mac_prop_id_t pp_id; 110e7801d59Ssowmini size_t pp_valsize; 111e7801d59Ssowmini char *pp_name; 112bcb5c89dSSowmini Varadhan } link_attr_t; 113e7801d59Ssowmini 114bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 115bcb5c89dSSowmini Varadhan const char *, uint_t, dladm_status_t *); 116bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 117*da14cebeSEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 118*da14cebeSEric Cheng static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t, 119*da14cebeSEric Cheng dladm_status_t *, uint_t *); 120*da14cebeSEric Cheng 1213bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **, 122e7801d59Ssowmini uint_t, uint_t); 1233bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **, 1244045d941Ssowmini uint_t *, dladm_prop_type_t, uint_t); 125bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *); 126bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t); 127*da14cebeSEric Cheng 128d62bc4baSyz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 129d62bc4baSyz147064 do_get_rate_prop, do_get_channel_prop, 130e7801d59Ssowmini do_get_powermode_prop, do_get_radio_prop, 1313bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_duplex_get, i_dladm_status_get, 1323bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_binary_get, i_dladm_uint32_get, 133*da14cebeSEric Cheng i_dladm_flowctl_get, dld_maxbw_get, dld_cpus_get, 134*da14cebeSEric Cheng dld_priority_get; 135*da14cebeSEric Cheng 1363bc21d0aSAruna Ramakrishna - Sun Microsystems static pd_setf_t do_set_zone, do_set_rate_prop, 137e7801d59Ssowmini do_set_powermode_prop, do_set_radio_prop, 138*da14cebeSEric Cheng i_dladm_set_public_prop, do_set_res, do_set_cpus; 139f4b3ec61Sdh155122 140*da14cebeSEric Cheng static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 141*da14cebeSEric Cheng i_dladm_defmtu_check, do_check_maxbw, do_check_cpus, 142*da14cebeSEric Cheng do_check_priority; 143*da14cebeSEric Cheng 144*da14cebeSEric Cheng static dladm_status_t i_dladm_speed_get(prop_desc_t *, datalink_id_t, 145*da14cebeSEric Cheng char **, uint_t *, uint_t, uint_t *); 146bcb5c89dSSowmini Varadhan static dladm_status_t i_dladm_wlan_get_legacy_ioctl(datalink_id_t, void *, 147bcb5c89dSSowmini Varadhan uint_t, uint_t); 148bcb5c89dSSowmini Varadhan static dladm_status_t i_dladm_wlan_set_legacy_ioctl(datalink_id_t, void *, 149bcb5c89dSSowmini Varadhan uint_t, uint_t); 150bcb5c89dSSowmini Varadhan static dladm_status_t i_dladm_macprop(void *, boolean_t); 151*da14cebeSEric Cheng static const char *dladm_perm2str(uint_t, char *); 1526b9e797cSsowmini 153*da14cebeSEric Cheng struct prop_desc { 154d62bc4baSyz147064 /* 155d62bc4baSyz147064 * link property name 156d62bc4baSyz147064 */ 157f4b3ec61Sdh155122 char *pd_name; 158d62bc4baSyz147064 159d62bc4baSyz147064 /* 160d62bc4baSyz147064 * default property value, can be set to { "", NULL } 161d62bc4baSyz147064 */ 162f4b3ec61Sdh155122 val_desc_t pd_defval; 163d62bc4baSyz147064 164d62bc4baSyz147064 /* 165d62bc4baSyz147064 * list of optional property values, can be NULL. 166d62bc4baSyz147064 * 167d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 168d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 169d62bc4baSyz147064 */ 170d62bc4baSyz147064 val_desc_t *pd_optval; 171d62bc4baSyz147064 172d62bc4baSyz147064 /* 173d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 174d62bc4baSyz147064 */ 175d62bc4baSyz147064 uint_t pd_noptval; 176d62bc4baSyz147064 177d62bc4baSyz147064 /* 178d62bc4baSyz147064 * callback to set link property; 179d62bc4baSyz147064 * set to NULL if this property is read-only 180d62bc4baSyz147064 */ 181f4b3ec61Sdh155122 pd_setf_t *pd_set; 182d62bc4baSyz147064 183d62bc4baSyz147064 /* 184d62bc4baSyz147064 * callback to get modifiable link property 185d62bc4baSyz147064 */ 186f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 187d62bc4baSyz147064 188d62bc4baSyz147064 /* 189d62bc4baSyz147064 * callback to get current link property 190d62bc4baSyz147064 */ 191f4b3ec61Sdh155122 pd_getf_t *pd_get; 192d62bc4baSyz147064 193d62bc4baSyz147064 /* 194d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 195d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 196d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 197d62bc4baSyz147064 * valid. 198d62bc4baSyz147064 */ 199f4b3ec61Sdh155122 pd_checkf_t *pd_check; 200d62bc4baSyz147064 201d62bc4baSyz147064 uint_t pd_flags; 202e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 203e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 204d62bc4baSyz147064 /* 205d62bc4baSyz147064 * indicate link classes this property applies to. 206d62bc4baSyz147064 */ 207d62bc4baSyz147064 datalink_class_t pd_class; 208d62bc4baSyz147064 209d62bc4baSyz147064 /* 210d62bc4baSyz147064 * indicate link media type this property applies to. 211d62bc4baSyz147064 */ 212d62bc4baSyz147064 datalink_media_t pd_dmedia; 213*da14cebeSEric Cheng }; 214f4b3ec61Sdh155122 2153fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 216e7801d59Ssowmini 217bcb5c89dSSowmini Varadhan /* 218bcb5c89dSSowmini Varadhan * Supported link properties enumerated in the prop_table[] array are 219bcb5c89dSSowmini Varadhan * computed using the callback functions in that array. To compute the 220bcb5c89dSSowmini Varadhan * property value, multiple distinct system calls may be needed (e.g., 221bcb5c89dSSowmini Varadhan * for wifi speed, we need to issue system calls to get desired/supported 222bcb5c89dSSowmini Varadhan * rates). The link_attr[] table enumerates the interfaces to the kernel, 223bcb5c89dSSowmini Varadhan * and the type/size of the data passed in the user-kernel interface. 224bcb5c89dSSowmini Varadhan */ 225bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = { 226bcb5c89dSSowmini Varadhan { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 227e7801d59Ssowmini 228bcb5c89dSSowmini Varadhan { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 229e7801d59Ssowmini 230bcb5c89dSSowmini Varadhan { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 231e7801d59Ssowmini 232bcb5c89dSSowmini Varadhan { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 233e7801d59Ssowmini 234bcb5c89dSSowmini Varadhan { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 235e7801d59Ssowmini 236bcb5c89dSSowmini Varadhan { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 237e7801d59Ssowmini 238bcb5c89dSSowmini Varadhan { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 239e7801d59Ssowmini 240bcb5c89dSSowmini Varadhan { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2413bc21d0aSAruna Ramakrishna - Sun Microsystems 242bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2433bc21d0aSAruna Ramakrishna - Sun Microsystems 244bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 245e7801d59Ssowmini 246bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 247e7801d59Ssowmini 248bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 249e7801d59Ssowmini 250bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 251e7801d59Ssowmini 252bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 253e7801d59Ssowmini 254bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 255e7801d59Ssowmini 256bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 257e7801d59Ssowmini 258bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 259e7801d59Ssowmini 260bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 261e7801d59Ssowmini 262bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 263e7801d59Ssowmini 264bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 265e7801d59Ssowmini 266bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 267e7801d59Ssowmini 268bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 269bcb5c89dSSowmini Varadhan 270bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 271bcb5c89dSSowmini Varadhan 272bcb5c89dSSowmini Varadhan { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 273bcb5c89dSSowmini Varadhan 274bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 275bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 276bcb5c89dSSowmini Varadhan 277bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 278bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 279bcb5c89dSSowmini Varadhan 280bcb5c89dSSowmini Varadhan { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 281bcb5c89dSSowmini Varadhan 282bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 283bcb5c89dSSowmini Varadhan 284bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 285bcb5c89dSSowmini Varadhan 286bcb5c89dSSowmini Varadhan { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 287bcb5c89dSSowmini Varadhan 288bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 289bcb5c89dSSowmini Varadhan 290bcb5c89dSSowmini Varadhan { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 291bcb5c89dSSowmini Varadhan 292bcb5c89dSSowmini Varadhan /* wl_wpa_ess_t has variable length */ 293bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 294bcb5c89dSSowmini Varadhan 295bcb5c89dSSowmini Varadhan { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 296bcb5c89dSSowmini Varadhan 297bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 298bcb5c89dSSowmini Varadhan 299bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 300bcb5c89dSSowmini Varadhan 301bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 302bcb5c89dSSowmini Varadhan 303bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 304bcb5c89dSSowmini Varadhan 305bcb5c89dSSowmini Varadhan /* wl_wpa_ie_t has variable length */ 306bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 307bcb5c89dSSowmini Varadhan 308bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 309bcb5c89dSSowmini Varadhan 310bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 311bcb5c89dSSowmini Varadhan 312bcb5c89dSSowmini Varadhan { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 313bcb5c89dSSowmini Varadhan 314*da14cebeSEric Cheng { MAC_PROP_MAXBW, sizeof (mac_resource_props_t), "maxbw"}, 315*da14cebeSEric Cheng 316*da14cebeSEric Cheng { MAC_PROP_PRIO, sizeof (mac_resource_props_t), "priority"}, 317*da14cebeSEric Cheng 318*da14cebeSEric Cheng { MAC_PROP_BIND_CPU, sizeof (mac_resource_props_t), "cpus"}, 319*da14cebeSEric Cheng 320bcb5c89dSSowmini Varadhan { MAC_PROP_PRIVATE, 0, "driver-private"} 321*da14cebeSEric Cheng 322e7801d59Ssowmini }; 323e7801d59Ssowmini 324e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 325e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 326e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 327e7801d59Ssowmini }; 328e7801d59Ssowmini static val_desc_t link_status_vals[] = { 329e7801d59Ssowmini { "up", LINK_STATE_UP }, 330e7801d59Ssowmini { "down", LINK_STATE_DOWN } 331e7801d59Ssowmini }; 332e7801d59Ssowmini static val_desc_t link_01_vals[] = { 333e7801d59Ssowmini { "1", 1 }, 334e7801d59Ssowmini { "0", 0 } 335e7801d59Ssowmini }; 336e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 337e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 338e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 339e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 340e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 341e7801d59Ssowmini }; 342*da14cebeSEric Cheng static val_desc_t link_priority_vals[] = { 343*da14cebeSEric Cheng { "low", MPL_LOW }, 344*da14cebeSEric Cheng { "medium", MPL_MEDIUM }, 345*da14cebeSEric Cheng { "high", MPL_HIGH } 346*da14cebeSEric Cheng }; 347e7801d59Ssowmini 348d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 349d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 350d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 351d62bc4baSyz147064 }; 352d62bc4baSyz147064 353d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 354d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 355d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 356d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 357d62bc4baSyz147064 }; 358d62bc4baSyz147064 359*da14cebeSEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 360*da14cebeSEric Cheng #define RESET_VAL ((uintptr_t)-1) 361d62bc4baSyz147064 362*da14cebeSEric Cheng static prop_desc_t prop_table[] = { 363e7801d59Ssowmini { "channel", { NULL, 0 }, 364e7801d59Ssowmini NULL, 0, NULL, NULL, 365d62bc4baSyz147064 do_get_channel_prop, NULL, 0, 366d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 367d62bc4baSyz147064 368d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 369d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 370d62bc4baSyz147064 do_set_powermode_prop, NULL, 371d62bc4baSyz147064 do_get_powermode_prop, NULL, 0, 372d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 373d62bc4baSyz147064 374d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 375d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 376d62bc4baSyz147064 do_set_radio_prop, NULL, 377d62bc4baSyz147064 do_get_radio_prop, NULL, 0, 378d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 379d62bc4baSyz147064 380d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 381d62bc4baSyz147064 do_set_rate_prop, do_get_rate_mod, 382d62bc4baSyz147064 do_get_rate_prop, do_check_rate, 0, 3836b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 384d62bc4baSyz147064 3854045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 3863bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, 3873bc21d0aSAruna Ramakrishna - Sun Microsystems do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 388d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 389d62bc4baSyz147064 3904045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 391f4b3ec61Sdh155122 do_set_zone, NULL, 3923bc21d0aSAruna Ramakrishna - Sun Microsystems do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 393e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 394e7801d59Ssowmini 3954045d941Ssowmini { "duplex", { "", 0 }, 396e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 3973bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_duplex_get, NULL, 398e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 399e7801d59Ssowmini 4006b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 401e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 4023bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_status_get, NULL, 4034045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 404e7801d59Ssowmini 405e7801d59Ssowmini { "adv_autoneg_cap", { "1", 1 }, 406e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4073bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 408e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 409e7801d59Ssowmini 4104045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 4113bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 4123bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_defmtu_check, 0, DATALINK_CLASS_ALL, 4133bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 414e7801d59Ssowmini 4154045d941Ssowmini { "flowctrl", { "", 0 }, 416e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 4173bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 418e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 419e7801d59Ssowmini 4204045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 4214045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 4223bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 423e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 424e7801d59Ssowmini 4254045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 426e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4273bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 428e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 429e7801d59Ssowmini 4304045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 431e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4323bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 433e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 434e7801d59Ssowmini 4354045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 436e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4373bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 438e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 439e7801d59Ssowmini 4404045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 441e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4423bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 443e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 444e7801d59Ssowmini 4454045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 446e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4473bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 448e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 449e7801d59Ssowmini 4504045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 451e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4523bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 453e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 454e7801d59Ssowmini 4554045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 456e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4573bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 458e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 459e7801d59Ssowmini 4604045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 461e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4623bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 463e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 464e7801d59Ssowmini 4654045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 466e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4673bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 468e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 469e7801d59Ssowmini 4704045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 471e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4723bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 473e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 474e7801d59Ssowmini 4754045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 476e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4773bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 478*da14cebeSEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 479e7801d59Ssowmini 480*da14cebeSEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 481*da14cebeSEric Cheng do_set_res, NULL, 482*da14cebeSEric Cheng dld_maxbw_get, do_check_maxbw, PD_CHECK_ALLOC, 483*da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 484*da14cebeSEric Cheng 485*da14cebeSEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 486*da14cebeSEric Cheng do_set_cpus, NULL, 487*da14cebeSEric Cheng dld_cpus_get, do_check_cpus, 0, 488*da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 489*da14cebeSEric Cheng 490*da14cebeSEric Cheng { "priority", { "high", RESET_VAL }, 491*da14cebeSEric Cheng link_priority_vals, VALCNT(link_priority_vals), do_set_res, NULL, 492*da14cebeSEric Cheng dld_priority_get, do_check_priority, PD_CHECK_ALLOC, 493*da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 494f4b3ec61Sdh155122 }; 495f4b3ec61Sdh155122 496d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 4970ba2cbe9Sxc151355 498*da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 499*da14cebeSEric Cheng {"maxbw", do_extract_maxbw}, 500*da14cebeSEric Cheng {"priority", do_extract_priority}, 501*da14cebeSEric Cheng {"cpus", do_extract_cpus} 502*da14cebeSEric Cheng }; 503*da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 504*da14cebeSEric Cheng sizeof (resource_prop_t)) 505*da14cebeSEric Cheng 506bcb5c89dSSowmini Varadhan /* 507bcb5c89dSSowmini Varadhan * when retrieving private properties, we pass down a buffer with 508bcb5c89dSSowmini Varadhan * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 509bcb5c89dSSowmini Varadhan */ 510bcb5c89dSSowmini Varadhan #define DLADM_PROP_BUF_CHUNK 1024 511bcb5c89dSSowmini Varadhan 512d62bc4baSyz147064 static dladm_status_t i_dladm_set_linkprop_db(datalink_id_t, const char *, 513d62bc4baSyz147064 char **, uint_t); 514d62bc4baSyz147064 static dladm_status_t i_dladm_get_linkprop_db(datalink_id_t, const char *, 515d62bc4baSyz147064 char **, uint_t *); 516d62bc4baSyz147064 static dladm_status_t i_dladm_set_single_prop(datalink_id_t, datalink_class_t, 517d62bc4baSyz147064 uint32_t, prop_desc_t *, char **, uint_t, uint_t); 518d62bc4baSyz147064 static dladm_status_t i_dladm_set_linkprop(datalink_id_t, const char *, 519d62bc4baSyz147064 char **, uint_t, uint_t); 5204045d941Ssowmini static dladm_status_t i_dladm_getset_defval(prop_desc_t *, datalink_id_t, 5214045d941Ssowmini datalink_media_t, uint_t); 522*da14cebeSEric Cheng 523*da14cebeSEric Cheng static dladm_status_t link_proplist_check(dladm_arg_list_t *); 524*da14cebeSEric Cheng 525d62bc4baSyz147064 /* 526d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 527d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 528d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 529d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 530d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 531d62bc4baSyz147064 */ 532d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 533d62bc4baSyz147064 534d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 535d62bc4baSyz147064 #define AP_DELIMITER '.' 536d62bc4baSyz147064 537d62bc4baSyz147064 static dladm_status_t 538d62bc4baSyz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 539d62bc4baSyz147064 val_desc_t *vdp) 5400ba2cbe9Sxc151355 { 541d62bc4baSyz147064 int i, j; 5420ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 5430ba2cbe9Sxc151355 544d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 545d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 546d62bc4baSyz147064 if (strcasecmp(*prop_val, 547d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 5480ba2cbe9Sxc151355 break; 5490ba2cbe9Sxc151355 } 5500ba2cbe9Sxc151355 } 551d62bc4baSyz147064 if (i == pdp->pd_noptval) { 552d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 553d62bc4baSyz147064 goto done; 554d62bc4baSyz147064 } 555d62bc4baSyz147064 (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); 5560ba2cbe9Sxc151355 } 5570ba2cbe9Sxc151355 558d62bc4baSyz147064 done: 559d62bc4baSyz147064 return (status); 5600ba2cbe9Sxc151355 } 5610ba2cbe9Sxc151355 5620ba2cbe9Sxc151355 static dladm_status_t 563d62bc4baSyz147064 i_dladm_set_single_prop(datalink_id_t linkid, datalink_class_t class, 564d62bc4baSyz147064 uint32_t media, prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 565d62bc4baSyz147064 uint_t flags) 5660ba2cbe9Sxc151355 { 5670ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 568d62bc4baSyz147064 val_desc_t *vdp = NULL; 569d62bc4baSyz147064 boolean_t needfree = B_FALSE; 570d62bc4baSyz147064 uint_t cnt, i; 5710ba2cbe9Sxc151355 572d62bc4baSyz147064 if (!(pdp->pd_class & class)) 573d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 5740ba2cbe9Sxc151355 575d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 576d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 577d62bc4baSyz147064 578d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 579d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 580d62bc4baSyz147064 581d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 582d62bc4baSyz147064 return (DLADM_STATUS_OK); 583d62bc4baSyz147064 584d62bc4baSyz147064 if (pdp->pd_set == NULL) 585d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 586d62bc4baSyz147064 587d62bc4baSyz147064 if (prop_val != NULL) { 588d62bc4baSyz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 589d62bc4baSyz147064 if (vdp == NULL) 590d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 591d62bc4baSyz147064 592d62bc4baSyz147064 if (pdp->pd_check != NULL) { 593*da14cebeSEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 594e7801d59Ssowmini status = pdp->pd_check(pdp, linkid, prop_val, val_cnt, 5956b9e797cSsowmini vdp, media); 596d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 597d62bc4baSyz147064 status = do_check_prop(pdp, prop_val, val_cnt, vdp); 598d62bc4baSyz147064 } else { 599d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 6000ba2cbe9Sxc151355 } 6010ba2cbe9Sxc151355 602d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 603d62bc4baSyz147064 goto done; 604d62bc4baSyz147064 605d62bc4baSyz147064 cnt = val_cnt; 606d62bc4baSyz147064 } else { 607*da14cebeSEric Cheng boolean_t defval = B_FALSE; 608*da14cebeSEric Cheng 609d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 610d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 611d62bc4baSyz147064 6123bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 613*da14cebeSEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 614*da14cebeSEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 615d62bc4baSyz147064 if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 616d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 6173bc21d0aSAruna Ramakrishna - Sun Microsystems 618*da14cebeSEric Cheng if (defval) { 619*da14cebeSEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 620*da14cebeSEric Cheng sizeof (val_desc_t)); 621*da14cebeSEric Cheng } else if (pdp->pd_check != NULL) { 6223bc21d0aSAruna Ramakrishna - Sun Microsystems status = pdp->pd_check(pdp, linkid, prop_val, 6233bc21d0aSAruna Ramakrishna - Sun Microsystems cnt, vdp, media); 6243bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 6253bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 6263bc21d0aSAruna Ramakrishna - Sun Microsystems } 6274045d941Ssowmini } else { 6284045d941Ssowmini status = i_dladm_getset_defval(pdp, linkid, 6294045d941Ssowmini media, flags); 6304045d941Ssowmini return (status); 6314045d941Ssowmini } 632d62bc4baSyz147064 } 6336b9e797cSsowmini status = pdp->pd_set(pdp, linkid, vdp, cnt, flags, media); 634d62bc4baSyz147064 if (needfree) { 635d62bc4baSyz147064 for (i = 0; i < cnt; i++) 636e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 637d62bc4baSyz147064 } 638d62bc4baSyz147064 done: 639d62bc4baSyz147064 free(vdp); 640d62bc4baSyz147064 return (status); 641d62bc4baSyz147064 } 642d62bc4baSyz147064 643d62bc4baSyz147064 static dladm_status_t 644d62bc4baSyz147064 i_dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, 645d62bc4baSyz147064 char **prop_val, uint_t val_cnt, uint_t flags) 646d62bc4baSyz147064 { 647d62bc4baSyz147064 int i; 648d62bc4baSyz147064 boolean_t found = B_FALSE; 649d62bc4baSyz147064 datalink_class_t class; 650d62bc4baSyz147064 uint32_t media; 651d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 652d62bc4baSyz147064 653d62bc4baSyz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 654d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 6550ba2cbe9Sxc151355 return (status); 6560ba2cbe9Sxc151355 657d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 658d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 659d62bc4baSyz147064 dladm_status_t s; 6600ba2cbe9Sxc151355 661d62bc4baSyz147064 if (prop_name != NULL && 662d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 663d62bc4baSyz147064 continue; 664d62bc4baSyz147064 found = B_TRUE; 665d62bc4baSyz147064 s = i_dladm_set_single_prop(linkid, class, media, pdp, prop_val, 666d62bc4baSyz147064 val_cnt, flags); 667d62bc4baSyz147064 668d62bc4baSyz147064 if (prop_name != NULL) { 669d62bc4baSyz147064 status = s; 670d62bc4baSyz147064 break; 671d62bc4baSyz147064 } else { 672d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 673d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 674d62bc4baSyz147064 status = s; 675d62bc4baSyz147064 } 676d62bc4baSyz147064 } 677e7801d59Ssowmini if (!found) { 678e7801d59Ssowmini if (prop_name[0] == '_') { 679e7801d59Ssowmini /* other private properties */ 6803bc21d0aSAruna Ramakrishna - Sun Microsystems status = i_dladm_set_prop(linkid, prop_name, prop_val, 681e7801d59Ssowmini val_cnt, flags); 682e7801d59Ssowmini } else { 6830ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 684e7801d59Ssowmini } 685e7801d59Ssowmini } 6860ba2cbe9Sxc151355 6870ba2cbe9Sxc151355 return (status); 6880ba2cbe9Sxc151355 } 6890ba2cbe9Sxc151355 690d62bc4baSyz147064 /* 691d62bc4baSyz147064 * Set/reset link property for specific link 692d62bc4baSyz147064 */ 693d62bc4baSyz147064 dladm_status_t 694d62bc4baSyz147064 dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, char **prop_val, 695d62bc4baSyz147064 uint_t val_cnt, uint_t flags) 6960ba2cbe9Sxc151355 { 697d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 6980ba2cbe9Sxc151355 699d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 700d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 701d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 702d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 703d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 7040ba2cbe9Sxc151355 } 7050ba2cbe9Sxc151355 706d62bc4baSyz147064 status = i_dladm_set_linkprop(linkid, prop_name, prop_val, 707d62bc4baSyz147064 val_cnt, flags); 708d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 709d62bc4baSyz147064 return (status); 710d62bc4baSyz147064 711d62bc4baSyz147064 if (flags & DLADM_OPT_PERSIST) { 712d62bc4baSyz147064 status = i_dladm_set_linkprop_db(linkid, prop_name, 713d62bc4baSyz147064 prop_val, val_cnt); 714d62bc4baSyz147064 } 715d62bc4baSyz147064 return (status); 716d62bc4baSyz147064 } 717d62bc4baSyz147064 718d62bc4baSyz147064 /* 719d62bc4baSyz147064 * Walk link properties of the given specific link. 720d62bc4baSyz147064 */ 721d62bc4baSyz147064 dladm_status_t 722d62bc4baSyz147064 dladm_walk_linkprop(datalink_id_t linkid, void *arg, 723d62bc4baSyz147064 int (*func)(datalink_id_t, const char *, void *)) 7240ba2cbe9Sxc151355 { 725d62bc4baSyz147064 dladm_status_t status; 726d62bc4baSyz147064 datalink_class_t class; 727d62bc4baSyz147064 uint_t media; 728d62bc4baSyz147064 int i; 7290ba2cbe9Sxc151355 730d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 731d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 7320ba2cbe9Sxc151355 733d62bc4baSyz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 734d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 735d62bc4baSyz147064 return (status); 736d62bc4baSyz147064 737d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 738d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 739d62bc4baSyz147064 continue; 740d62bc4baSyz147064 741d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 742d62bc4baSyz147064 continue; 743d62bc4baSyz147064 744d62bc4baSyz147064 if (func(linkid, prop_table[i].pd_name, arg) == 745d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 746d62bc4baSyz147064 break; 747d62bc4baSyz147064 } 748d62bc4baSyz147064 } 749d62bc4baSyz147064 750d62bc4baSyz147064 return (DLADM_STATUS_OK); 751d62bc4baSyz147064 } 752d62bc4baSyz147064 753d62bc4baSyz147064 /* 754d62bc4baSyz147064 * Get linkprop of the given specific link. 755d62bc4baSyz147064 */ 756d62bc4baSyz147064 dladm_status_t 757d62bc4baSyz147064 dladm_get_linkprop(datalink_id_t linkid, dladm_prop_type_t type, 758d62bc4baSyz147064 const char *prop_name, char **prop_val, uint_t *val_cntp) 759d62bc4baSyz147064 { 760d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 761d62bc4baSyz147064 datalink_class_t class; 762d62bc4baSyz147064 uint_t media; 763d62bc4baSyz147064 prop_desc_t *pdp; 7644045d941Ssowmini uint_t cnt, dld_flags = 0; 765d62bc4baSyz147064 int i; 766afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 767d62bc4baSyz147064 7684045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 7693fd94f8cSam223141 dld_flags = MAC_PROP_DEFAULT; 7704045d941Ssowmini 771d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 772d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 773d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 774d62bc4baSyz147064 775d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 776d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 777d62bc4baSyz147064 break; 778d62bc4baSyz147064 779e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 780e7801d59Ssowmini if (prop_name[0] == '_') { 781e7801d59Ssowmini /* 782e7801d59Ssowmini * private property. 783e7801d59Ssowmini */ 7843bc21d0aSAruna Ramakrishna - Sun Microsystems return (i_dladm_get_prop(linkid, prop_name, 7854045d941Ssowmini prop_val, val_cntp, type, dld_flags)); 786e7801d59Ssowmini } else { 787d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 788e7801d59Ssowmini } 789e7801d59Ssowmini } 790d62bc4baSyz147064 791d62bc4baSyz147064 pdp = &prop_table[i]; 792d62bc4baSyz147064 793d62bc4baSyz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 794d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 795d62bc4baSyz147064 return (status); 796d62bc4baSyz147064 797d62bc4baSyz147064 if (!(pdp->pd_class & class)) 798d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 799d62bc4baSyz147064 800d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 801d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 802d62bc4baSyz147064 803d62bc4baSyz147064 switch (type) { 804d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 8054045d941Ssowmini status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, media, 806afdda45fSVasumathi Sundaram - Sun Microsystems dld_flags, &perm_flags); 807afdda45fSVasumathi Sundaram - Sun Microsystems break; 808afdda45fSVasumathi Sundaram - Sun Microsystems 809afdda45fSVasumathi Sundaram - Sun Microsystems case DLADM_PROP_VAL_PERM: 810afdda45fSVasumathi Sundaram - Sun Microsystems if (pdp->pd_set == NULL) { 811afdda45fSVasumathi Sundaram - Sun Microsystems perm_flags = MAC_PROP_PERM_READ; 812afdda45fSVasumathi Sundaram - Sun Microsystems *val_cntp = 1; 813afdda45fSVasumathi Sundaram - Sun Microsystems } else { 814afdda45fSVasumathi Sundaram - Sun Microsystems status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, 815afdda45fSVasumathi Sundaram - Sun Microsystems media, dld_flags, &perm_flags); 816afdda45fSVasumathi Sundaram - Sun Microsystems } 817afdda45fSVasumathi Sundaram - Sun Microsystems 818afdda45fSVasumathi Sundaram - Sun Microsystems *prop_val[0] = '\0'; 819*da14cebeSEric Cheng if (status == DLADM_STATUS_OK) 820*da14cebeSEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 821d62bc4baSyz147064 break; 822d62bc4baSyz147064 823d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 82413a55820Sar224390 /* 82513a55820Sar224390 * If defaults are not defined for the property, 82613a55820Sar224390 * pd_defval.vd_name should be null. If the driver 82713a55820Sar224390 * has to be contacted for the value, vd_name should 82813a55820Sar224390 * be the empty string (""). Otherwise, dladm will 82913a55820Sar224390 * just print whatever is in the table. 83013a55820Sar224390 */ 831d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 832d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 833d62bc4baSyz147064 break; 834d62bc4baSyz147064 } 8354045d941Ssowmini 8364045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 8374045d941Ssowmini status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, 838afdda45fSVasumathi Sundaram - Sun Microsystems media, dld_flags, &perm_flags); 8394045d941Ssowmini } else { 840d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 8414045d941Ssowmini } 842d62bc4baSyz147064 *val_cntp = 1; 843d62bc4baSyz147064 break; 844d62bc4baSyz147064 845d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 846d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 847e7801d59Ssowmini status = pdp->pd_getmod(pdp, linkid, prop_val, 848afdda45fSVasumathi Sundaram - Sun Microsystems val_cntp, media, dld_flags, &perm_flags); 849d62bc4baSyz147064 break; 850d62bc4baSyz147064 } 851d62bc4baSyz147064 cnt = pdp->pd_noptval; 852d62bc4baSyz147064 if (cnt == 0) { 853d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 854d62bc4baSyz147064 } else if (cnt > *val_cntp) { 855d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 856d62bc4baSyz147064 } else { 857d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 858d62bc4baSyz147064 (void) strcpy(prop_val[i], 859d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 860d62bc4baSyz147064 } 861d62bc4baSyz147064 *val_cntp = cnt; 862d62bc4baSyz147064 } 863d62bc4baSyz147064 break; 864d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 865d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 866d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 867d62bc4baSyz147064 status = i_dladm_get_linkprop_db(linkid, prop_name, 868d62bc4baSyz147064 prop_val, val_cntp); 869d62bc4baSyz147064 break; 870d62bc4baSyz147064 default: 871d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 872d62bc4baSyz147064 break; 873d62bc4baSyz147064 } 874d62bc4baSyz147064 875d62bc4baSyz147064 return (status); 876d62bc4baSyz147064 } 877d62bc4baSyz147064 878d62bc4baSyz147064 /*ARGSUSED*/ 879d62bc4baSyz147064 static int 880d62bc4baSyz147064 i_dladm_init_one_prop(datalink_id_t linkid, const char *prop_name, void *arg) 881d62bc4baSyz147064 { 882d62bc4baSyz147064 char *buf, **propvals; 883d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 884d62bc4baSyz147064 885d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 886d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 887d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 888d62bc4baSyz147064 } 889d62bc4baSyz147064 890d62bc4baSyz147064 propvals = (char **)(void *)buf; 891d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 892d62bc4baSyz147064 propvals[i] = buf + 893d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 894d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 895d62bc4baSyz147064 } 896d62bc4baSyz147064 897d62bc4baSyz147064 if (dladm_get_linkprop(linkid, DLADM_PROP_VAL_PERSISTENT, prop_name, 898d62bc4baSyz147064 propvals, &valcnt) != DLADM_STATUS_OK) { 899d62bc4baSyz147064 goto done; 900d62bc4baSyz147064 } 901d62bc4baSyz147064 902d62bc4baSyz147064 (void) dladm_set_linkprop(linkid, prop_name, propvals, valcnt, 903d62bc4baSyz147064 DLADM_OPT_ACTIVE); 904d62bc4baSyz147064 905d62bc4baSyz147064 done: 906d62bc4baSyz147064 if (buf != NULL) 907d62bc4baSyz147064 free(buf); 908d62bc4baSyz147064 909d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 910d62bc4baSyz147064 } 911d62bc4baSyz147064 912d62bc4baSyz147064 /*ARGSUSED*/ 913d62bc4baSyz147064 static int 914d62bc4baSyz147064 i_dladm_init_linkprop(datalink_id_t linkid, void *arg) 915d62bc4baSyz147064 { 916*da14cebeSEric Cheng datalink_class_t class; 917*da14cebeSEric Cheng dladm_status_t status; 918*da14cebeSEric Cheng 919*da14cebeSEric Cheng status = dladm_datalink_id2info(linkid, NULL, &class, NULL, NULL, 0); 920*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 921*da14cebeSEric Cheng return (DLADM_WALK_TERMINATE); 922*da14cebeSEric Cheng 923*da14cebeSEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 92430890389Sartem (void) dladm_init_linkprop(linkid, B_TRUE); 925*da14cebeSEric Cheng 926d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 9270ba2cbe9Sxc151355 } 9280ba2cbe9Sxc151355 9290ba2cbe9Sxc151355 dladm_status_t 93030890389Sartem dladm_init_linkprop(datalink_id_t linkid, boolean_t any_media) 9310ba2cbe9Sxc151355 { 93230890389Sartem datalink_media_t dmedia; 93330890389Sartem uint32_t media; 93430890389Sartem 93530890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 93630890389Sartem 937d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 938d62bc4baSyz147064 (void) dladm_walk_datalink_id(i_dladm_init_linkprop, NULL, 93930890389Sartem DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 94030890389Sartem } else if (any_media || ((dladm_datalink_id2info(linkid, NULL, NULL, 94130890389Sartem &media, NULL, 0) == DLADM_STATUS_OK) && 94230890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 943d62bc4baSyz147064 (void) dladm_walk_linkprop(linkid, NULL, i_dladm_init_one_prop); 944d62bc4baSyz147064 } 945d62bc4baSyz147064 return (DLADM_STATUS_OK); 9460ba2cbe9Sxc151355 } 947f4b3ec61Sdh155122 948e7801d59Ssowmini /* ARGSUSED */ 949f4b3ec61Sdh155122 static dladm_status_t 950*da14cebeSEric Cheng do_get_zone(prop_desc_t *pdp, datalink_id_t linkid, 951*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 952*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 953f4b3ec61Sdh155122 { 954d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 955d62bc4baSyz147064 zoneid_t zid; 956d62bc4baSyz147064 dladm_status_t status; 9573bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 9583bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 959f4b3ec61Sdh155122 9604045d941Ssowmini if (flags != 0) 9614045d941Ssowmini return (DLADM_STATUS_NOTSUP); 9624045d941Ssowmini 963*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 964*da14cebeSEric Cheng &status, perm_flags); 965d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 966d62bc4baSyz147064 return (status); 967d62bc4baSyz147064 9683bc21d0aSAruna Ramakrishna - Sun Microsystems cp = dip->pr_val; 9693bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&zid, cp, sizeof (zid)); 9703bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 9713bc21d0aSAruna Ramakrishna - Sun Microsystems 972d62bc4baSyz147064 *val_cnt = 1; 973d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 974afdda45fSVasumathi Sundaram - Sun Microsystems if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 975f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 976afdda45fSVasumathi Sundaram - Sun Microsystems } 977f4b3ec61Sdh155122 978d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 97947a01978Sbw } else { 980d62bc4baSyz147064 *prop_val[0] = '\0'; 98147a01978Sbw } 982f4b3ec61Sdh155122 983f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 984f4b3ec61Sdh155122 } 985f4b3ec61Sdh155122 986f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 987f4b3ec61Sdh155122 988f4b3ec61Sdh155122 static int 989f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 990f4b3ec61Sdh155122 { 991f4b3ec61Sdh155122 char root[MAXPATHLEN]; 992f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 993f4b3ec61Sdh155122 void *dlhandle; 994f4b3ec61Sdh155122 void *sym; 995f4b3ec61Sdh155122 int ret; 996f4b3ec61Sdh155122 997f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 998f4b3ec61Sdh155122 return (-1); 999f4b3ec61Sdh155122 1000f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 1001f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1002f4b3ec61Sdh155122 return (-1); 1003f4b3ec61Sdh155122 } 1004f4b3ec61Sdh155122 1005f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 1006f4b3ec61Sdh155122 1007f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 1008f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 1009f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1010f4b3ec61Sdh155122 return (ret); 1011f4b3ec61Sdh155122 } 1012f4b3ec61Sdh155122 1013f4b3ec61Sdh155122 static dladm_status_t 1014d62bc4baSyz147064 i_dladm_update_deventry(zoneid_t zid, datalink_id_t linkid, boolean_t add) 1015f4b3ec61Sdh155122 { 1016f4b3ec61Sdh155122 char path[MAXPATHLEN]; 1017d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1018f4b3ec61Sdh155122 di_prof_t prof = NULL; 1019f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 1020f4b3ec61Sdh155122 dladm_status_t status; 1021d62bc4baSyz147064 int ret; 1022f4b3ec61Sdh155122 1023f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 1024f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1025f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 1026f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1027f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 1028f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1029f4b3ec61Sdh155122 1030d62bc4baSyz147064 status = dladm_linkid2legacyname(linkid, name, MAXLINKNAMELEN); 1031f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1032d62bc4baSyz147064 goto cleanup; 1033f4b3ec61Sdh155122 1034d62bc4baSyz147064 if (add) 1035d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 1036d62bc4baSyz147064 else 1037d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 1038f4b3ec61Sdh155122 1039d62bc4baSyz147064 if (ret != 0) { 1040d62bc4baSyz147064 status = dladm_errno2status(errno); 1041d62bc4baSyz147064 goto cleanup; 1042f4b3ec61Sdh155122 } 1043f4b3ec61Sdh155122 1044d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 1045d62bc4baSyz147064 status = dladm_errno2status(errno); 1046d62bc4baSyz147064 cleanup: 1047d62bc4baSyz147064 if (prof) 1048d62bc4baSyz147064 di_prof_fini(prof); 1049d62bc4baSyz147064 1050d62bc4baSyz147064 return (status); 1051f4b3ec61Sdh155122 } 1052f4b3ec61Sdh155122 1053e7801d59Ssowmini /* ARGSUSED */ 1054f4b3ec61Sdh155122 static dladm_status_t 1055*da14cebeSEric Cheng do_set_zone(prop_desc_t *pdp, datalink_id_t linkid, val_desc_t *vdp, 10566b9e797cSsowmini uint_t val_cnt, uint_t flags, datalink_media_t media) 1057f4b3ec61Sdh155122 { 10583bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1059f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 1060d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 10613bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 10623bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 10633bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1064f4b3ec61Sdh155122 1065f4b3ec61Sdh155122 if (val_cnt != 1) 1066f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1067f4b3ec61Sdh155122 10683bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 10693bc21d0aSAruna Ramakrishna - Sun Microsystems 1070*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 1071*da14cebeSEric Cheng &status, NULL); 1072f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1073f4b3ec61Sdh155122 return (status); 1074f4b3ec61Sdh155122 10753bc21d0aSAruna Ramakrishna - Sun Microsystems cp = dip->pr_val; 10763bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&zid_old, cp, sizeof (zid_old)); 10773bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 1078f4b3ec61Sdh155122 10793bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 10803bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN); 10813bc21d0aSAruna Ramakrishna - Sun Microsystems 10823bc21d0aSAruna Ramakrishna - Sun Microsystems /* Do nothing if setting to current value */ 10833bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 10843bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 10853bc21d0aSAruna Ramakrishna - Sun Microsystems 1086d62bc4baSyz147064 if (zid_new != GLOBAL_ZONEID) { 1087d62bc4baSyz147064 /* 1088d62bc4baSyz147064 * If the new zoneid is the global zone, we could destroy 1089d62bc4baSyz147064 * the link (in the case of an implicitly-created VLAN) as a 10903bc21d0aSAruna Ramakrishna - Sun Microsystems * result of setting the zoneid. In that case, we defer the 10913bc21d0aSAruna Ramakrishna - Sun Microsystems * operation to the end of this function to avoid recreating 10923bc21d0aSAruna Ramakrishna - Sun Microsystems * the VLAN and getting a different linkid during the rollback 10933bc21d0aSAruna Ramakrishna - Sun Microsystems * if other operation fails. 1094d62bc4baSyz147064 * 10953bc21d0aSAruna Ramakrishna - Sun Microsystems * Otherwise, this operation will hold a reference to the 1096d62bc4baSyz147064 * link and prevent a link renaming, so we need to do it 1097d62bc4baSyz147064 * before other operations. 1098d62bc4baSyz147064 */ 1099*da14cebeSEric Cheng status = i_dladm_set_public_prop(pdp, linkid, vdp, val_cnt, 11003bc21d0aSAruna Ramakrishna - Sun Microsystems flags, media); 1101d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1102d62bc4baSyz147064 return (status); 1103d62bc4baSyz147064 } 1104d62bc4baSyz147064 1105d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 1106d62bc4baSyz147064 if (zone_remove_datalink(zid_old, link) != 0 && 1107f4b3ec61Sdh155122 errno != ENXIO) { 1108f4b3ec61Sdh155122 status = dladm_errno2status(errno); 1109f4b3ec61Sdh155122 goto rollback1; 1110f4b3ec61Sdh155122 } 1111f4b3ec61Sdh155122 1112d62bc4baSyz147064 /* 1113d62bc4baSyz147064 * It is okay to fail to update the /dev entry (some 1114d62bc4baSyz147064 * vanity-named links do not have a /dev entry). 1115d62bc4baSyz147064 */ 1116d62bc4baSyz147064 (void) i_dladm_update_deventry(zid_old, linkid, B_FALSE); 1117d62bc4baSyz147064 } 1118d62bc4baSyz147064 1119d62bc4baSyz147064 if (zid_new != GLOBAL_ZONEID) { 1120d62bc4baSyz147064 if (zone_add_datalink(zid_new, link) != 0) { 1121d62bc4baSyz147064 status = dladm_errno2status(errno); 1122d62bc4baSyz147064 goto rollback2; 1123d62bc4baSyz147064 } 1124d62bc4baSyz147064 1125d62bc4baSyz147064 (void) i_dladm_update_deventry(zid_new, linkid, B_TRUE); 1126d62bc4baSyz147064 } else { 1127*da14cebeSEric Cheng status = i_dladm_set_public_prop(pdp, linkid, vdp, val_cnt, 11283bc21d0aSAruna Ramakrishna - Sun Microsystems flags, media); 1129f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1130f4b3ec61Sdh155122 goto rollback2; 1131f4b3ec61Sdh155122 } 1132f4b3ec61Sdh155122 1133f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1134f4b3ec61Sdh155122 1135f4b3ec61Sdh155122 rollback2: 1136f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 1137d62bc4baSyz147064 (void) i_dladm_update_deventry(zid_old, linkid, B_TRUE); 1138d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) 1139d62bc4baSyz147064 (void) zone_add_datalink(zid_old, link); 1140f4b3ec61Sdh155122 rollback1: 11413bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new != GLOBAL_ZONEID) { 11423bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zid_old; 1143*da14cebeSEric Cheng (void) i_dladm_set_public_prop(pdp, linkid, vdp, val_cnt, 11443bc21d0aSAruna Ramakrishna - Sun Microsystems flags, media); 11453bc21d0aSAruna Ramakrishna - Sun Microsystems } 11463bc21d0aSAruna Ramakrishna - Sun Microsystems 1147f4b3ec61Sdh155122 return (status); 1148f4b3ec61Sdh155122 } 1149f4b3ec61Sdh155122 1150f4b3ec61Sdh155122 /* ARGSUSED */ 1151f4b3ec61Sdh155122 static dladm_status_t 1152*da14cebeSEric Cheng do_check_zone(prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, 11536b9e797cSsowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1154f4b3ec61Sdh155122 { 11553bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 11563bc21d0aSAruna Ramakrishna - Sun Microsystems char linkname[MAXLINKNAMELEN]; 11573bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 11583bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 11593bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1160f4b3ec61Sdh155122 1161f4b3ec61Sdh155122 if (val_cnt != 1) 1162f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1163f4b3ec61Sdh155122 11643bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 11653bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 11663bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1167f4b3ec61Sdh155122 11683bc21d0aSAruna Ramakrishna - Sun Microsystems if ((status = dladm_datalink_id2info(linkid, NULL, NULL, NULL, 11693bc21d0aSAruna Ramakrishna - Sun Microsystems linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 11703bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 11713bc21d0aSAruna Ramakrishna - Sun Microsystems } 11723bc21d0aSAruna Ramakrishna - Sun Microsystems 1173*da14cebeSEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 11743bc21d0aSAruna Ramakrishna - Sun Microsystems if (strlen(linkname) > MAXLINKNAMELEN) { 11753bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 11763bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 11773bc21d0aSAruna Ramakrishna - Sun Microsystems } 11783bc21d0aSAruna Ramakrishna - Sun Microsystems 11793bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 11803bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 11813bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 11823bc21d0aSAruna Ramakrishna - Sun Microsystems } 11833bc21d0aSAruna Ramakrishna - Sun Microsystems 11843bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1185f4b3ec61Sdh155122 ushort_t flags; 1186f4b3ec61Sdh155122 11873bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1188f4b3ec61Sdh155122 sizeof (flags)) < 0) { 11893bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 11903bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1191f4b3ec61Sdh155122 } 1192f4b3ec61Sdh155122 1193f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 11943bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 11953bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1196f4b3ec61Sdh155122 } 1197f4b3ec61Sdh155122 } 1198f4b3ec61Sdh155122 11993bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 12003bc21d0aSAruna Ramakrishna - Sun Microsystems 12013bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 12023bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN); 12033bc21d0aSAruna Ramakrishna - Sun Microsystems 12043bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1205f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 12063bc21d0aSAruna Ramakrishna - Sun Microsystems done: 12073bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 12083bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1209f4b3ec61Sdh155122 } 1210f4b3ec61Sdh155122 1211e7801d59Ssowmini /* ARGSUSED */ 1212f4b3ec61Sdh155122 static dladm_status_t 1213*da14cebeSEric Cheng dld_maxbw_get(prop_desc_t *pdp, datalink_id_t linkid, 1214*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1215*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1216*da14cebeSEric Cheng { 1217*da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1218*da14cebeSEric Cheng mac_resource_props_t mrp; 1219*da14cebeSEric Cheng dladm_status_t status; 1220*da14cebeSEric Cheng 1221*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 1222*da14cebeSEric Cheng &status, perm_flags); 1223*da14cebeSEric Cheng if (dip == NULL) 1224*da14cebeSEric Cheng return (status); 1225*da14cebeSEric Cheng 1226*da14cebeSEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 1227*da14cebeSEric Cheng free(dip); 1228*da14cebeSEric Cheng 1229*da14cebeSEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 1230*da14cebeSEric Cheng (*prop_val)[0] = '\0'; 1231*da14cebeSEric Cheng } else { 1232*da14cebeSEric Cheng (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 1233*da14cebeSEric Cheng } 1234*da14cebeSEric Cheng *val_cnt = 1; 1235*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1236*da14cebeSEric Cheng } 1237*da14cebeSEric Cheng 1238*da14cebeSEric Cheng /* ARGSUSED */ 1239*da14cebeSEric Cheng static dladm_status_t 1240*da14cebeSEric Cheng do_check_maxbw(prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, 1241*da14cebeSEric Cheng uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1242*da14cebeSEric Cheng { 1243*da14cebeSEric Cheng uint64_t *maxbw; 1244*da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1245*da14cebeSEric Cheng 1246*da14cebeSEric Cheng if (val_cnt != 1) 1247*da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1248*da14cebeSEric Cheng 1249*da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 1250*da14cebeSEric Cheng if (maxbw == NULL) 1251*da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1252*da14cebeSEric Cheng 1253*da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 1254*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1255*da14cebeSEric Cheng free(maxbw); 1256*da14cebeSEric Cheng return (status); 1257*da14cebeSEric Cheng } 1258*da14cebeSEric Cheng 1259*da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 1260*da14cebeSEric Cheng free(maxbw); 1261*da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 1262*da14cebeSEric Cheng } 1263*da14cebeSEric Cheng 1264*da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 1265*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1266*da14cebeSEric Cheng } 1267*da14cebeSEric Cheng 1268*da14cebeSEric Cheng /* ARGSUSED */ 1269*da14cebeSEric Cheng dladm_status_t 1270*da14cebeSEric Cheng do_extract_maxbw(val_desc_t *vdp, void *arg, uint_t cnt) 1271*da14cebeSEric Cheng { 1272*da14cebeSEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1273*da14cebeSEric Cheng 1274*da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 1275*da14cebeSEric Cheng mrp->mrp_mask |= MRP_MAXBW; 1276*da14cebeSEric Cheng 1277*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1278*da14cebeSEric Cheng } 1279*da14cebeSEric Cheng 1280*da14cebeSEric Cheng /* ARGSUSED */ 1281*da14cebeSEric Cheng static dladm_status_t 1282*da14cebeSEric Cheng dld_cpus_get(prop_desc_t *pdp, datalink_id_t linkid, 1283*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1284*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1285*da14cebeSEric Cheng { 1286*da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1287*da14cebeSEric Cheng mac_resource_props_t mrp; 1288*da14cebeSEric Cheng int i; 1289*da14cebeSEric Cheng uint32_t ncpus; 1290*da14cebeSEric Cheng uchar_t *cp; 1291*da14cebeSEric Cheng dladm_status_t status; 1292*da14cebeSEric Cheng 1293*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 1294*da14cebeSEric Cheng &status, perm_flags); 1295*da14cebeSEric Cheng if (dip == NULL) 1296*da14cebeSEric Cheng return (status); 1297*da14cebeSEric Cheng 1298*da14cebeSEric Cheng cp = (uchar_t *)dip->pr_val; 1299*da14cebeSEric Cheng (void) memcpy(&mrp, cp, sizeof (mac_resource_props_t)); 1300*da14cebeSEric Cheng free(dip); 1301*da14cebeSEric Cheng 1302*da14cebeSEric Cheng ncpus = mrp.mrp_ncpus; 1303*da14cebeSEric Cheng 1304*da14cebeSEric Cheng if (ncpus > *val_cnt) 1305*da14cebeSEric Cheng return (DLADM_STATUS_TOOSMALL); 1306*da14cebeSEric Cheng 1307*da14cebeSEric Cheng if (ncpus == 0) { 1308*da14cebeSEric Cheng (*prop_val)[0] = '\0'; 1309*da14cebeSEric Cheng *val_cnt = 1; 1310*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1311*da14cebeSEric Cheng } 1312*da14cebeSEric Cheng 1313*da14cebeSEric Cheng *val_cnt = ncpus; 1314*da14cebeSEric Cheng for (i = 0; i < ncpus; i++) { 1315*da14cebeSEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 1316*da14cebeSEric Cheng "%u", mrp.mrp_cpu[i]); 1317*da14cebeSEric Cheng } 1318*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1319*da14cebeSEric Cheng } 1320*da14cebeSEric Cheng 1321*da14cebeSEric Cheng /* ARGSUSED */ 1322*da14cebeSEric Cheng static dladm_status_t 1323*da14cebeSEric Cheng do_set_res(prop_desc_t *pdp, datalink_id_t linkid, val_desc_t *vdp, 1324*da14cebeSEric Cheng uint_t val_cnt, uint_t flags, datalink_media_t media) 1325*da14cebeSEric Cheng { 1326*da14cebeSEric Cheng mac_resource_props_t mrp; 1327*da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1328*da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1329*da14cebeSEric Cheng 1330*da14cebeSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 1331*da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 1332*da14cebeSEric Cheng flags, &status); 1333*da14cebeSEric Cheng 1334*da14cebeSEric Cheng if (dip == NULL) 1335*da14cebeSEric Cheng return (status); 1336*da14cebeSEric Cheng 1337*da14cebeSEric Cheng if (vdp->vd_val == RESET_VAL) { 1338*da14cebeSEric Cheng switch (dip->pr_num) { 1339*da14cebeSEric Cheng case MAC_PROP_MAXBW: 1340*da14cebeSEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 1341*da14cebeSEric Cheng mrp.mrp_mask = MRP_MAXBW; 1342*da14cebeSEric Cheng break; 1343*da14cebeSEric Cheng case MAC_PROP_PRIO: 1344*da14cebeSEric Cheng mrp.mrp_priority = MPL_RESET; 1345*da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY; 1346*da14cebeSEric Cheng break; 1347*da14cebeSEric Cheng default: 1348*da14cebeSEric Cheng free(dip); 1349*da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 1350*da14cebeSEric Cheng } 1351*da14cebeSEric Cheng } else { 1352*da14cebeSEric Cheng switch (dip->pr_num) { 1353*da14cebeSEric Cheng case MAC_PROP_MAXBW: 1354*da14cebeSEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_maxbw, 1355*da14cebeSEric Cheng sizeof (uint64_t)); 1356*da14cebeSEric Cheng mrp.mrp_mask = MRP_MAXBW; 1357*da14cebeSEric Cheng break; 1358*da14cebeSEric Cheng case MAC_PROP_PRIO: 1359*da14cebeSEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_priority, 1360*da14cebeSEric Cheng sizeof (mac_priority_level_t)); 1361*da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY; 1362*da14cebeSEric Cheng break; 1363*da14cebeSEric Cheng default: 1364*da14cebeSEric Cheng free(dip); 1365*da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 1366*da14cebeSEric Cheng } 1367*da14cebeSEric Cheng } 1368*da14cebeSEric Cheng 1369*da14cebeSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 1370*da14cebeSEric Cheng status = i_dladm_macprop(dip, B_TRUE); 1371*da14cebeSEric Cheng free(dip); 1372*da14cebeSEric Cheng return (status); 1373*da14cebeSEric Cheng } 1374*da14cebeSEric Cheng 1375*da14cebeSEric Cheng /* ARGSUSED */ 1376*da14cebeSEric Cheng static dladm_status_t 1377*da14cebeSEric Cheng do_set_cpus(prop_desc_t *pdp, datalink_id_t linkid, val_desc_t *vdp, 1378*da14cebeSEric Cheng uint_t val_cnt, uint_t flags, datalink_media_t media) 1379*da14cebeSEric Cheng { 1380*da14cebeSEric Cheng mac_resource_props_t mrp; 1381*da14cebeSEric Cheng dladm_status_t status; 1382*da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1383*da14cebeSEric Cheng datalink_class_t class; 1384*da14cebeSEric Cheng 1385*da14cebeSEric Cheng /* 1386*da14cebeSEric Cheng * CPU bindings can be set on VNIC and regular physical links. 1387*da14cebeSEric Cheng * However VNICs fails the dladm_phys_info test(). So apply 1388*da14cebeSEric Cheng * the phys_info test only on physical links. 1389*da14cebeSEric Cheng */ 1390*da14cebeSEric Cheng if ((status = dladm_datalink_id2info(linkid, NULL, &class, 1391*da14cebeSEric Cheng NULL, NULL, 0)) != DLADM_STATUS_OK) { 1392*da14cebeSEric Cheng return (status); 1393*da14cebeSEric Cheng } 1394*da14cebeSEric Cheng 1395*da14cebeSEric Cheng /* 1396*da14cebeSEric Cheng * We set intr_cpu to -1. The interrupt will be retargetted, 1397*da14cebeSEric Cheng * if possible when the setup is complete in MAC. 1398*da14cebeSEric Cheng */ 1399*da14cebeSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 1400*da14cebeSEric Cheng mrp.mrp_mask = MRP_CPUS; 1401*da14cebeSEric Cheng if (vdp != NULL && vdp->vd_val != RESET_VAL) { 1402*da14cebeSEric Cheng mac_resource_props_t *vmrp; 1403*da14cebeSEric Cheng 1404*da14cebeSEric Cheng vmrp = (mac_resource_props_t *)vdp->vd_val; 1405*da14cebeSEric Cheng if (vmrp->mrp_ncpus > 0) { 1406*da14cebeSEric Cheng bcopy(vmrp, &mrp, sizeof (mac_resource_props_t)); 1407*da14cebeSEric Cheng mrp.mrp_mask = MRP_CPUS; 1408*da14cebeSEric Cheng } 1409*da14cebeSEric Cheng mrp.mrp_mask |= MRP_CPUS_USERSPEC; 1410*da14cebeSEric Cheng mrp.mrp_fanout_mode = MCM_CPUS; 1411*da14cebeSEric Cheng mrp.mrp_intr_cpu = -1; 1412*da14cebeSEric Cheng } 1413*da14cebeSEric Cheng 1414*da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 1415*da14cebeSEric Cheng flags, &status); 1416*da14cebeSEric Cheng if (dip == NULL) 1417*da14cebeSEric Cheng return (status); 1418*da14cebeSEric Cheng 1419*da14cebeSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 1420*da14cebeSEric Cheng status = i_dladm_macprop(dip, B_TRUE); 1421*da14cebeSEric Cheng free(dip); 1422*da14cebeSEric Cheng return (status); 1423*da14cebeSEric Cheng } 1424*da14cebeSEric Cheng 1425*da14cebeSEric Cheng /* ARGSUSED */ 1426*da14cebeSEric Cheng static dladm_status_t 1427*da14cebeSEric Cheng do_check_cpus(prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, 1428*da14cebeSEric Cheng uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1429*da14cebeSEric Cheng { 1430*da14cebeSEric Cheng uint32_t cpuid; 1431*da14cebeSEric Cheng int i, j, rc; 1432*da14cebeSEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 1433*da14cebeSEric Cheng mac_resource_props_t *mrp; 1434*da14cebeSEric Cheng 1435*da14cebeSEric Cheng mrp = malloc(sizeof (mac_resource_props_t)); 1436*da14cebeSEric Cheng if (mrp == NULL) 1437*da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1438*da14cebeSEric Cheng 1439*da14cebeSEric Cheng for (i = 0; i < val_cnt; i++) { 1440*da14cebeSEric Cheng errno = 0; 1441*da14cebeSEric Cheng cpuid = strtol(prop_val[i], (char **)NULL, 10); 1442*da14cebeSEric Cheng if (errno != 0 || cpuid >= nproc) { 1443*da14cebeSEric Cheng free(mrp); 1444*da14cebeSEric Cheng return (DLADM_STATUS_CPUMAX); 1445*da14cebeSEric Cheng } 1446*da14cebeSEric Cheng rc = p_online(cpuid, P_STATUS); 1447*da14cebeSEric Cheng if (rc < 1) { 1448*da14cebeSEric Cheng free(mrp); 1449*da14cebeSEric Cheng return (DLADM_STATUS_CPUERR); 1450*da14cebeSEric Cheng } 1451*da14cebeSEric Cheng if (rc != P_ONLINE) { 1452*da14cebeSEric Cheng free(mrp); 1453*da14cebeSEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 1454*da14cebeSEric Cheng } 1455*da14cebeSEric Cheng mrp->mrp_cpu[i] = cpuid; 1456*da14cebeSEric Cheng } 1457*da14cebeSEric Cheng mrp->mrp_ncpus = (uint32_t)val_cnt; 1458*da14cebeSEric Cheng 1459*da14cebeSEric Cheng /* Check for duplicates */ 1460*da14cebeSEric Cheng for (i = 0; i < val_cnt; i++) { 1461*da14cebeSEric Cheng for (j = 0; j < val_cnt; j++) { 1462*da14cebeSEric Cheng if (i != j && mrp->mrp_cpu[i] == mrp->mrp_cpu[j]) { 1463*da14cebeSEric Cheng free(mrp); 1464*da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 1465*da14cebeSEric Cheng } 1466*da14cebeSEric Cheng } 1467*da14cebeSEric Cheng } 1468*da14cebeSEric Cheng vdp->vd_val = (uintptr_t)mrp; 1469*da14cebeSEric Cheng 1470*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1471*da14cebeSEric Cheng } 1472*da14cebeSEric Cheng 1473*da14cebeSEric Cheng /* ARGSUSED */ 1474*da14cebeSEric Cheng dladm_status_t 1475*da14cebeSEric Cheng do_extract_cpus(val_desc_t *vdp, void *arg, uint_t cnt) 1476*da14cebeSEric Cheng { 1477*da14cebeSEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1478*da14cebeSEric Cheng mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; 1479*da14cebeSEric Cheng int i; 1480*da14cebeSEric Cheng 1481*da14cebeSEric Cheng for (i = 0; i < vmrp->mrp_ncpus; i++) { 1482*da14cebeSEric Cheng mrp->mrp_cpu[i] = vmrp->mrp_cpu[i]; 1483*da14cebeSEric Cheng } 1484*da14cebeSEric Cheng mrp->mrp_ncpus = vmrp->mrp_ncpus; 1485*da14cebeSEric Cheng mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 1486*da14cebeSEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 1487*da14cebeSEric Cheng 1488*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1489*da14cebeSEric Cheng } 1490*da14cebeSEric Cheng 1491*da14cebeSEric Cheng /* ARGSUSED */ 1492*da14cebeSEric Cheng static dladm_status_t 1493*da14cebeSEric Cheng dld_priority_get(prop_desc_t *pdp, datalink_id_t linkid, 1494*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1495*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1496*da14cebeSEric Cheng { 1497*da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1498*da14cebeSEric Cheng mac_resource_props_t mrp; 1499*da14cebeSEric Cheng mac_priority_level_t pri; 1500*da14cebeSEric Cheng dladm_status_t status; 1501*da14cebeSEric Cheng 1502*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 1503*da14cebeSEric Cheng &status, perm_flags); 1504*da14cebeSEric Cheng if (dip == NULL) 1505*da14cebeSEric Cheng return (status); 1506*da14cebeSEric Cheng 1507*da14cebeSEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 1508*da14cebeSEric Cheng free(dip); 1509*da14cebeSEric Cheng 1510*da14cebeSEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 1511*da14cebeSEric Cheng mrp.mrp_priority; 1512*da14cebeSEric Cheng 1513*da14cebeSEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 1514*da14cebeSEric Cheng *val_cnt = 1; 1515*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1516*da14cebeSEric Cheng } 1517*da14cebeSEric Cheng 1518*da14cebeSEric Cheng /* ARGSUSED */ 1519*da14cebeSEric Cheng static dladm_status_t 1520*da14cebeSEric Cheng do_check_priority(prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, 1521*da14cebeSEric Cheng uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1522*da14cebeSEric Cheng { 1523*da14cebeSEric Cheng mac_priority_level_t *pri; 1524*da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1525*da14cebeSEric Cheng 1526*da14cebeSEric Cheng if (val_cnt != 1) 1527*da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1528*da14cebeSEric Cheng 1529*da14cebeSEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 1530*da14cebeSEric Cheng if (pri == NULL) 1531*da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1532*da14cebeSEric Cheng 1533*da14cebeSEric Cheng status = dladm_str2pri(*prop_val, pri); 1534*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1535*da14cebeSEric Cheng free(pri); 1536*da14cebeSEric Cheng return (status); 1537*da14cebeSEric Cheng } 1538*da14cebeSEric Cheng 1539*da14cebeSEric Cheng if (*pri < MPL_LOW || *pri > MPL_HIGH) { 1540*da14cebeSEric Cheng free(pri); 1541*da14cebeSEric Cheng return (DLADM_STATUS_BADVAL); 1542*da14cebeSEric Cheng } 1543*da14cebeSEric Cheng 1544*da14cebeSEric Cheng vdp->vd_val = (uintptr_t)pri; 1545*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1546*da14cebeSEric Cheng } 1547*da14cebeSEric Cheng 1548*da14cebeSEric Cheng /* ARGSUSED */ 1549*da14cebeSEric Cheng dladm_status_t 1550*da14cebeSEric Cheng do_extract_priority(val_desc_t *vdp, void *arg, uint_t cnt) 1551*da14cebeSEric Cheng { 1552*da14cebeSEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1553*da14cebeSEric Cheng 1554*da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_priority, 1555*da14cebeSEric Cheng sizeof (mac_priority_level_t)); 1556*da14cebeSEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 1557*da14cebeSEric Cheng 1558*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1559*da14cebeSEric Cheng } 1560*da14cebeSEric Cheng 1561*da14cebeSEric Cheng /* ARGSUSED */ 1562*da14cebeSEric Cheng static dladm_status_t 1563*da14cebeSEric Cheng do_get_autopush(prop_desc_t *pdp, datalink_id_t linkid, 1564*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1565*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1566d62bc4baSyz147064 { 15673bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 15683bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 15693bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 15703bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 1571d62bc4baSyz147064 15723fd94f8cSam223141 if (flags & MAC_PROP_DEFAULT) 1573149b7eb2SSowmini Varadhan return (DLADM_STATUS_NOTDEFINED); 15744045d941Ssowmini 1575d62bc4baSyz147064 *val_cnt = 1; 1576*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 1577*da14cebeSEric Cheng &status, perm_flags); 15783bc21d0aSAruna Ramakrishna - Sun Microsystems if (dip == NULL) { 1579d62bc4baSyz147064 (*prop_val)[0] = '\0'; 1580*da14cebeSEric Cheng return (DLADM_STATUS_OK); 1581d62bc4baSyz147064 } 15823bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 1583d62bc4baSyz147064 15843bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 1585d62bc4baSyz147064 if (i != 0) { 1586d62bc4baSyz147064 (void) snprintf(*prop_val + len, 1587d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 1588d62bc4baSyz147064 len += 1; 1589d62bc4baSyz147064 } 1590d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 15913bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 15923bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 15933bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 1594d62bc4baSyz147064 (void) snprintf(*prop_val + len, 1595d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 1596d62bc4baSyz147064 AP_ANCHOR); 1597d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 1598d62bc4baSyz147064 } 1599d62bc4baSyz147064 } 16003bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 1601d62bc4baSyz147064 done: 1602d62bc4baSyz147064 return (DLADM_STATUS_OK); 1603d62bc4baSyz147064 } 1604d62bc4baSyz147064 1605d62bc4baSyz147064 /* 1606d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 1607d62bc4baSyz147064 * DLADM_STATUS_* code. 1608d62bc4baSyz147064 */ 1609d62bc4baSyz147064 dladm_status_t 1610d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 1611d62bc4baSyz147064 { 1612d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 1613d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1614d62bc4baSyz147064 1615d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 1616d62bc4baSyz147064 /* 1617d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 1618d62bc4baSyz147064 * be after at least one module. 1619d62bc4baSyz147064 */ 1620d62bc4baSyz147064 if (dlap->dap_anchor != 0) 1621d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1622d62bc4baSyz147064 if (dlap->dap_npush == 0) 1623d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1624d62bc4baSyz147064 1625d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 1626d62bc4baSyz147064 return (DLADM_STATUS_OK); 1627d62bc4baSyz147064 } 1628d62bc4baSyz147064 if (dlap->dap_npush > MAXAPUSH) 1629d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1630d62bc4baSyz147064 1631d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 1632d62bc4baSyz147064 FMNAMESZ + 1); 1633d62bc4baSyz147064 1634d62bc4baSyz147064 return (DLADM_STATUS_OK); 1635d62bc4baSyz147064 } 1636d62bc4baSyz147064 1637d62bc4baSyz147064 /* 1638d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 1639d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 1640d62bc4baSyz147064 * latter is used in the autopush(1M) file. 1641d62bc4baSyz147064 */ 1642d62bc4baSyz147064 /* ARGSUSED */ 1643d62bc4baSyz147064 static dladm_status_t 1644*da14cebeSEric Cheng do_check_autopush(prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, 16456b9e797cSsowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1646d62bc4baSyz147064 { 1647d62bc4baSyz147064 char *module; 1648d62bc4baSyz147064 struct dlautopush *dlap; 1649d62bc4baSyz147064 dladm_status_t status; 1650d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 1651d62bc4baSyz147064 char delimiters[4]; 1652d62bc4baSyz147064 1653d62bc4baSyz147064 if (val_cnt != 1) 1654d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1655d62bc4baSyz147064 16563bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 1657d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 1658d62bc4baSyz147064 if (dlap == NULL) 1659d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1660d62bc4baSyz147064 1661d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 1662d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 1663d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 1664d62bc4baSyz147064 module = strtok(val, delimiters); 1665d62bc4baSyz147064 while (module != NULL) { 1666d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 1667d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1668d62bc4baSyz147064 return (status); 1669d62bc4baSyz147064 module = strtok(NULL, delimiters); 1670d62bc4baSyz147064 } 1671d62bc4baSyz147064 1672d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 16733bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 16743bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 16753bc21d0aSAruna Ramakrishna - Sun Microsystems } 1676d62bc4baSyz147064 return (DLADM_STATUS_OK); 1677d62bc4baSyz147064 } 1678d62bc4baSyz147064 1679bcb5c89dSSowmini Varadhan #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 1680bcb5c89dSSowmini Varadhan 1681e7801d59Ssowmini /* ARGSUSED */ 1682d62bc4baSyz147064 static dladm_status_t 1683*da14cebeSEric Cheng do_get_rate_common(prop_desc_t *pdp, datalink_id_t linkid, 1684*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, uint_t id, uint_t *perm_flags) 1685d62bc4baSyz147064 { 1686d62bc4baSyz147064 wl_rates_t *wrp; 1687d62bc4baSyz147064 uint_t i; 1688d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1689d62bc4baSyz147064 1690bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 1691bcb5c89dSSowmini Varadhan if (wrp == NULL) 1692bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 1693d62bc4baSyz147064 1694bcb5c89dSSowmini Varadhan status = i_dladm_wlan_param(linkid, wrp, id, WLDP_BUFSIZE, B_FALSE); 1695d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1696d62bc4baSyz147064 goto done; 1697d62bc4baSyz147064 1698d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 1699d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1700d62bc4baSyz147064 goto done; 1701d62bc4baSyz147064 } 1702d62bc4baSyz147064 1703d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 1704d62bc4baSyz147064 prop_val[0][0] = '\0'; 1705d62bc4baSyz147064 *val_cnt = 1; 1706d62bc4baSyz147064 goto done; 1707d62bc4baSyz147064 } 1708d62bc4baSyz147064 1709d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 1710d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 1711d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 1712d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 1713d62bc4baSyz147064 } 1714d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 1715*da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_RW; 1716d62bc4baSyz147064 1717d62bc4baSyz147064 done: 1718bcb5c89dSSowmini Varadhan free(wrp); 1719d62bc4baSyz147064 return (status); 1720d62bc4baSyz147064 } 1721d62bc4baSyz147064 1722d62bc4baSyz147064 static dladm_status_t 1723*da14cebeSEric Cheng do_get_rate_prop(prop_desc_t *pdp, datalink_id_t linkid, 1724*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1725*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1726d62bc4baSyz147064 { 1727afdda45fSVasumathi Sundaram - Sun Microsystems if (media != DL_WIFI) { 1728*da14cebeSEric Cheng return (i_dladm_speed_get(pdp, linkid, prop_val, 1729*da14cebeSEric Cheng val_cnt, flags, perm_flags)); 1730afdda45fSVasumathi Sundaram - Sun Microsystems } 17316b9e797cSsowmini 1732*da14cebeSEric Cheng return (do_get_rate_common(pdp, linkid, prop_val, val_cnt, 1733*da14cebeSEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 1734d62bc4baSyz147064 } 1735d62bc4baSyz147064 17364045d941Ssowmini /* ARGSUSED */ 1737d62bc4baSyz147064 static dladm_status_t 1738*da14cebeSEric Cheng do_get_rate_mod(prop_desc_t *pdp, datalink_id_t linkid, 1739*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1740*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1741d62bc4baSyz147064 { 17426b9e797cSsowmini switch (media) { 17436b9e797cSsowmini case DL_ETHER: 17444045d941Ssowmini /* 17454045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 17464045d941Ssowmini * links can have a speed of 5.5 Gbps. 17474045d941Ssowmini */ 17484045d941Ssowmini return (DLADM_STATUS_NOTSUP); 17496b9e797cSsowmini 17506b9e797cSsowmini case DL_WIFI: 1751*da14cebeSEric Cheng return (do_get_rate_common(pdp, linkid, prop_val, val_cnt, 1752*da14cebeSEric Cheng MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 17536b9e797cSsowmini default: 17546b9e797cSsowmini return (DLADM_STATUS_BADARG); 17556b9e797cSsowmini } 1756d62bc4baSyz147064 } 1757d62bc4baSyz147064 1758d62bc4baSyz147064 static dladm_status_t 1759d62bc4baSyz147064 do_set_rate(datalink_id_t linkid, dladm_wlan_rates_t *rates) 1760f4b3ec61Sdh155122 { 1761f4b3ec61Sdh155122 int i; 1762d62bc4baSyz147064 uint_t len; 1763d62bc4baSyz147064 wl_rates_t *wrp; 1764d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1765d62bc4baSyz147064 1766bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 1767bcb5c89dSSowmini Varadhan if (wrp == NULL) 1768d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1769d62bc4baSyz147064 1770bcb5c89dSSowmini Varadhan bzero(wrp, WLDP_BUFSIZE); 1771d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 1772d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 1773d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 1774d62bc4baSyz147064 1775d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 1776d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 1777bcb5c89dSSowmini Varadhan status = i_dladm_wlan_param(linkid, wrp, MAC_PROP_WL_DESIRED_RATES, 1778bcb5c89dSSowmini Varadhan len, B_TRUE); 1779d62bc4baSyz147064 1780bcb5c89dSSowmini Varadhan free(wrp); 1781d62bc4baSyz147064 return (status); 1782d62bc4baSyz147064 } 1783d62bc4baSyz147064 1784e7801d59Ssowmini /* ARGSUSED */ 1785d62bc4baSyz147064 static dladm_status_t 1786*da14cebeSEric Cheng do_set_rate_prop(prop_desc_t *pdp, datalink_id_t linkid, 17876b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1788d62bc4baSyz147064 { 1789d62bc4baSyz147064 dladm_wlan_rates_t rates; 1790f4b3ec61Sdh155122 dladm_status_t status; 1791f4b3ec61Sdh155122 17926b9e797cSsowmini /* 17936b9e797cSsowmini * can currently set rate on WIFI links only. 17946b9e797cSsowmini */ 17956b9e797cSsowmini if (media != DL_WIFI) 17966b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 17976b9e797cSsowmini 1798d62bc4baSyz147064 if (val_cnt != 1) 1799d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1800f4b3ec61Sdh155122 1801d62bc4baSyz147064 rates.wr_cnt = 1; 1802d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 1803f4b3ec61Sdh155122 1804d62bc4baSyz147064 status = do_set_rate(linkid, &rates); 1805f4b3ec61Sdh155122 1806d62bc4baSyz147064 done: 1807d62bc4baSyz147064 return (status); 1808d62bc4baSyz147064 } 1809d62bc4baSyz147064 1810d62bc4baSyz147064 /* ARGSUSED */ 1811d62bc4baSyz147064 static dladm_status_t 1812*da14cebeSEric Cheng do_check_rate(prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, 18136b9e797cSsowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1814d62bc4baSyz147064 { 1815d62bc4baSyz147064 int i; 1816d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 1817d62bc4baSyz147064 char *buf, **modval; 1818d62bc4baSyz147064 dladm_status_t status; 1819afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 1820d62bc4baSyz147064 1821d62bc4baSyz147064 if (val_cnt != 1) 1822d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1823d62bc4baSyz147064 1824d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 1825d62bc4baSyz147064 MAX_SUPPORT_RATES); 1826d62bc4baSyz147064 if (buf == NULL) { 1827d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 1828d62bc4baSyz147064 goto done; 1829d62bc4baSyz147064 } 1830d62bc4baSyz147064 1831d62bc4baSyz147064 modval = (char **)(void *)buf; 1832d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 1833d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 1834d62bc4baSyz147064 i * DLADM_STRSIZE; 1835d62bc4baSyz147064 } 1836d62bc4baSyz147064 1837afdda45fSVasumathi Sundaram - Sun Microsystems status = do_get_rate_mod(NULL, linkid, modval, &modval_cnt, media, 1838afdda45fSVasumathi Sundaram - Sun Microsystems 0, &perm_flags); 1839d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1840d62bc4baSyz147064 goto done; 1841d62bc4baSyz147064 1842d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 1843d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 1844e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 1845e7801d59Ssowmini (atof(*prop_val) * 2); 1846f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 1847f4b3ec61Sdh155122 break; 1848f4b3ec61Sdh155122 } 1849d62bc4baSyz147064 } 1850d62bc4baSyz147064 if (i == modval_cnt) 1851d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 1852d62bc4baSyz147064 done: 1853d62bc4baSyz147064 free(buf); 1854d62bc4baSyz147064 return (status); 1855d62bc4baSyz147064 } 1856f4b3ec61Sdh155122 1857d62bc4baSyz147064 static dladm_status_t 1858bcb5c89dSSowmini Varadhan do_get_phyconf(datalink_id_t linkid, void *buf, int buflen) 1859d62bc4baSyz147064 { 1860bcb5c89dSSowmini Varadhan return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG, 1861bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 1862d62bc4baSyz147064 } 1863d62bc4baSyz147064 1864e7801d59Ssowmini /* ARGSUSED */ 1865d62bc4baSyz147064 static dladm_status_t 1866*da14cebeSEric Cheng do_get_channel_prop(prop_desc_t *pdp, datalink_id_t linkid, 1867*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1868*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1869d62bc4baSyz147064 { 1870d62bc4baSyz147064 uint32_t channel; 1871bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 1872d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1873bcb5c89dSSowmini Varadhan wl_phy_conf_t wl_phy_conf; 1874d62bc4baSyz147064 1875bcb5c89dSSowmini Varadhan if ((status = do_get_phyconf(linkid, buf, sizeof (buf))) 1876bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 1877d62bc4baSyz147064 goto done; 1878d62bc4baSyz147064 1879bcb5c89dSSowmini Varadhan (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 1880bcb5c89dSSowmini Varadhan if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 1881d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1882d62bc4baSyz147064 goto done; 1883d62bc4baSyz147064 } 1884d62bc4baSyz147064 1885d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 1886d62bc4baSyz147064 *val_cnt = 1; 1887*da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 1888d62bc4baSyz147064 done: 1889d62bc4baSyz147064 return (status); 1890d62bc4baSyz147064 } 1891d62bc4baSyz147064 1892d62bc4baSyz147064 static dladm_status_t 1893bcb5c89dSSowmini Varadhan do_get_powermode(datalink_id_t linkid, void *buf, int buflen) 1894d62bc4baSyz147064 { 1895bcb5c89dSSowmini Varadhan return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_POWER_MODE, 1896bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 1897d62bc4baSyz147064 } 1898d62bc4baSyz147064 1899e7801d59Ssowmini /* ARGSUSED */ 1900d62bc4baSyz147064 static dladm_status_t 1901*da14cebeSEric Cheng do_get_powermode_prop(prop_desc_t *pdp, datalink_id_t linkid, 1902*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1903*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1904d62bc4baSyz147064 { 1905bcb5c89dSSowmini Varadhan wl_ps_mode_t mode; 1906d62bc4baSyz147064 const char *s; 1907bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 1908d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1909d62bc4baSyz147064 1910bcb5c89dSSowmini Varadhan if ((status = do_get_powermode(linkid, buf, sizeof (buf))) 1911bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 1912d62bc4baSyz147064 goto done; 1913d62bc4baSyz147064 1914bcb5c89dSSowmini Varadhan (void) memcpy(&mode, buf, sizeof (mode)); 1915bcb5c89dSSowmini Varadhan switch (mode.wl_ps_mode) { 1916d62bc4baSyz147064 case WL_PM_AM: 1917d62bc4baSyz147064 s = "off"; 1918f4b3ec61Sdh155122 break; 1919d62bc4baSyz147064 case WL_PM_MPS: 1920d62bc4baSyz147064 s = "max"; 1921d62bc4baSyz147064 break; 1922d62bc4baSyz147064 case WL_PM_FAST: 1923d62bc4baSyz147064 s = "fast"; 1924f4b3ec61Sdh155122 break; 1925f4b3ec61Sdh155122 default: 1926d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1927d62bc4baSyz147064 goto done; 1928f4b3ec61Sdh155122 } 1929d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 1930d62bc4baSyz147064 *val_cnt = 1; 1931afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 1932*da14cebeSEric Cheng done: 1933d62bc4baSyz147064 return (status); 1934d62bc4baSyz147064 } 1935d62bc4baSyz147064 1936d62bc4baSyz147064 static dladm_status_t 1937d62bc4baSyz147064 do_set_powermode(datalink_id_t linkid, dladm_wlan_powermode_t *pm) 1938d62bc4baSyz147064 { 1939d62bc4baSyz147064 wl_ps_mode_t ps_mode; 1940d62bc4baSyz147064 1941d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 1942d62bc4baSyz147064 1943d62bc4baSyz147064 switch (*pm) { 1944d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 1945d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 1946d62bc4baSyz147064 break; 1947d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 1948d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 1949d62bc4baSyz147064 break; 1950d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 1951d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 1952d62bc4baSyz147064 break; 1953d62bc4baSyz147064 default: 1954d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 1955d62bc4baSyz147064 } 1956bcb5c89dSSowmini Varadhan return (i_dladm_wlan_param(linkid, &ps_mode, MAC_PROP_WL_POWER_MODE, 1957bcb5c89dSSowmini Varadhan sizeof (ps_mode), B_TRUE)); 1958d62bc4baSyz147064 } 1959d62bc4baSyz147064 1960d62bc4baSyz147064 /* ARGSUSED */ 1961d62bc4baSyz147064 static dladm_status_t 1962*da14cebeSEric Cheng do_set_powermode_prop(prop_desc_t *pdp, datalink_id_t linkid, 19636b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1964d62bc4baSyz147064 { 1965d62bc4baSyz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 1966d62bc4baSyz147064 dladm_status_t status; 1967d62bc4baSyz147064 1968d62bc4baSyz147064 if (val_cnt != 1) 1969d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1970d62bc4baSyz147064 1971d62bc4baSyz147064 status = do_set_powermode(linkid, &powermode); 1972f4b3ec61Sdh155122 1973f4b3ec61Sdh155122 return (status); 1974f4b3ec61Sdh155122 } 1975f4b3ec61Sdh155122 1976f4b3ec61Sdh155122 static dladm_status_t 1977bcb5c89dSSowmini Varadhan do_get_radio(datalink_id_t linkid, void *buf, int buflen) 1978f4b3ec61Sdh155122 { 1979bcb5c89dSSowmini Varadhan return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RADIO, buflen, 1980bcb5c89dSSowmini Varadhan B_FALSE)); 1981d62bc4baSyz147064 } 1982d62bc4baSyz147064 1983e7801d59Ssowmini /* ARGSUSED */ 1984d62bc4baSyz147064 static dladm_status_t 1985*da14cebeSEric Cheng do_get_radio_prop(prop_desc_t *pdp, datalink_id_t linkid, 1986*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1987*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1988d62bc4baSyz147064 { 1989d62bc4baSyz147064 wl_radio_t radio; 1990d62bc4baSyz147064 const char *s; 1991bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 1992d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1993d62bc4baSyz147064 1994bcb5c89dSSowmini Varadhan if ((status = do_get_radio(linkid, buf, sizeof (buf))) 1995bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 1996d62bc4baSyz147064 goto done; 1997d62bc4baSyz147064 1998bcb5c89dSSowmini Varadhan (void) memcpy(&radio, buf, sizeof (radio)); 1999d62bc4baSyz147064 switch (radio) { 2000d62bc4baSyz147064 case B_TRUE: 2001d62bc4baSyz147064 s = "on"; 2002d62bc4baSyz147064 break; 2003d62bc4baSyz147064 case B_FALSE: 2004d62bc4baSyz147064 s = "off"; 2005d62bc4baSyz147064 break; 2006d62bc4baSyz147064 default: 2007d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 2008d62bc4baSyz147064 goto done; 2009d62bc4baSyz147064 } 2010d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 2011d62bc4baSyz147064 *val_cnt = 1; 2012afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 2013*da14cebeSEric Cheng done: 2014d62bc4baSyz147064 return (status); 2015d62bc4baSyz147064 } 2016d62bc4baSyz147064 2017d62bc4baSyz147064 static dladm_status_t 2018d62bc4baSyz147064 do_set_radio(datalink_id_t linkid, dladm_wlan_radio_t *radio) 2019d62bc4baSyz147064 { 2020d62bc4baSyz147064 wl_radio_t r; 2021d62bc4baSyz147064 2022d62bc4baSyz147064 switch (*radio) { 2023d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 2024d62bc4baSyz147064 r = B_TRUE; 2025d62bc4baSyz147064 break; 2026d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 2027d62bc4baSyz147064 r = B_FALSE; 2028d62bc4baSyz147064 break; 2029d62bc4baSyz147064 default: 2030d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 2031d62bc4baSyz147064 } 2032bcb5c89dSSowmini Varadhan return (i_dladm_wlan_param(linkid, &r, MAC_PROP_WL_RADIO, 2033bcb5c89dSSowmini Varadhan sizeof (r), B_TRUE)); 2034d62bc4baSyz147064 } 2035d62bc4baSyz147064 2036d62bc4baSyz147064 /* ARGSUSED */ 2037d62bc4baSyz147064 static dladm_status_t 2038*da14cebeSEric Cheng do_set_radio_prop(prop_desc_t *pdp, datalink_id_t linkid, 20396b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t fags, datalink_media_t media) 2040d62bc4baSyz147064 { 2041d62bc4baSyz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 2042f4b3ec61Sdh155122 dladm_status_t status; 2043f4b3ec61Sdh155122 2044d62bc4baSyz147064 if (val_cnt != 1) 2045d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2046f4b3ec61Sdh155122 2047d62bc4baSyz147064 status = do_set_radio(linkid, &radio); 2048f4b3ec61Sdh155122 2049d62bc4baSyz147064 return (status); 2050d62bc4baSyz147064 } 2051f4b3ec61Sdh155122 2052d62bc4baSyz147064 static dladm_status_t 2053d62bc4baSyz147064 i_dladm_set_linkprop_db(datalink_id_t linkid, const char *prop_name, 2054d62bc4baSyz147064 char **prop_val, uint_t val_cnt) 2055d62bc4baSyz147064 { 2056d62bc4baSyz147064 char buf[MAXLINELEN]; 2057d62bc4baSyz147064 int i; 2058d62bc4baSyz147064 dladm_conf_t conf; 2059d62bc4baSyz147064 dladm_status_t status; 2060d62bc4baSyz147064 2061d62bc4baSyz147064 status = dladm_read_conf(linkid, &conf); 2062f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 2063f4b3ec61Sdh155122 return (status); 2064f4b3ec61Sdh155122 2065d62bc4baSyz147064 /* 2066d62bc4baSyz147064 * reset case. 2067d62bc4baSyz147064 */ 2068d62bc4baSyz147064 if (val_cnt == 0) { 2069d62bc4baSyz147064 status = dladm_unset_conf_field(conf, prop_name); 2070d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 2071d62bc4baSyz147064 status = dladm_write_conf(conf); 2072d62bc4baSyz147064 goto done; 2073f4b3ec61Sdh155122 } 2074f4b3ec61Sdh155122 2075d62bc4baSyz147064 buf[0] = '\0'; 2076d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 2077d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 2078d62bc4baSyz147064 if (i != val_cnt - 1) 2079d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 2080d62bc4baSyz147064 } 2081f4b3ec61Sdh155122 2082d62bc4baSyz147064 status = dladm_set_conf_field(conf, prop_name, DLADM_TYPE_STR, buf); 2083d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 2084d62bc4baSyz147064 status = dladm_write_conf(conf); 2085d62bc4baSyz147064 2086d62bc4baSyz147064 done: 2087d62bc4baSyz147064 dladm_destroy_conf(conf); 2088f4b3ec61Sdh155122 return (status); 2089f4b3ec61Sdh155122 } 2090f4b3ec61Sdh155122 2091f4b3ec61Sdh155122 static dladm_status_t 2092d62bc4baSyz147064 i_dladm_get_linkprop_db(datalink_id_t linkid, const char *prop_name, 2093d62bc4baSyz147064 char **prop_val, uint_t *val_cntp) 2094f4b3ec61Sdh155122 { 2095d62bc4baSyz147064 char buf[MAXLINELEN], *str; 2096d62bc4baSyz147064 uint_t cnt = 0; 2097d62bc4baSyz147064 dladm_conf_t conf; 2098d62bc4baSyz147064 dladm_status_t status; 2099f4b3ec61Sdh155122 2100d62bc4baSyz147064 status = dladm_read_conf(linkid, &conf); 2101d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2102f4b3ec61Sdh155122 return (status); 2103d62bc4baSyz147064 2104d62bc4baSyz147064 status = dladm_get_conf_field(conf, prop_name, buf, MAXLINELEN); 2105d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2106d62bc4baSyz147064 goto done; 2107d62bc4baSyz147064 2108d62bc4baSyz147064 str = strtok(buf, ","); 2109d62bc4baSyz147064 while (str != NULL) { 2110d62bc4baSyz147064 if (cnt == *val_cntp) { 2111d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 2112d62bc4baSyz147064 goto done; 2113d62bc4baSyz147064 } 2114d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 2115d62bc4baSyz147064 str = strtok(NULL, ","); 2116f4b3ec61Sdh155122 } 2117f4b3ec61Sdh155122 2118d62bc4baSyz147064 *val_cntp = cnt; 2119f4b3ec61Sdh155122 2120d62bc4baSyz147064 done: 2121d62bc4baSyz147064 dladm_destroy_conf(conf); 2122d62bc4baSyz147064 return (status); 2123f4b3ec61Sdh155122 } 2124e7801d59Ssowmini 2125bcb5c89dSSowmini Varadhan static link_attr_t * 2126e7801d59Ssowmini dladm_name2prop(const char *prop_name) 2127e7801d59Ssowmini { 2128bcb5c89dSSowmini Varadhan link_attr_t *p; 2129e7801d59Ssowmini 2130bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 2131e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 2132e7801d59Ssowmini break; 2133e7801d59Ssowmini } 2134e7801d59Ssowmini return (p); 2135e7801d59Ssowmini } 2136e7801d59Ssowmini 2137bcb5c89dSSowmini Varadhan static link_attr_t * 2138bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid) 2139bcb5c89dSSowmini Varadhan { 2140bcb5c89dSSowmini Varadhan link_attr_t *p; 2141bcb5c89dSSowmini Varadhan 2142bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 2143bcb5c89dSSowmini Varadhan if (p->pp_id == propid) 2144bcb5c89dSSowmini Varadhan break; 2145bcb5c89dSSowmini Varadhan } 2146bcb5c89dSSowmini Varadhan return (p); 2147bcb5c89dSSowmini Varadhan } 2148e7801d59Ssowmini 21493fd94f8cSam223141 static dld_ioc_macprop_t * 2150bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 2151bcb5c89dSSowmini Varadhan const char *prop_name, mac_prop_id_t propid, uint_t flags, 2152bcb5c89dSSowmini Varadhan dladm_status_t *status) 2153e7801d59Ssowmini { 2154e7801d59Ssowmini int dsize; 21553fd94f8cSam223141 dld_ioc_macprop_t *dip; 2156e7801d59Ssowmini 2157e7801d59Ssowmini *status = DLADM_STATUS_OK; 21583fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 2159e7801d59Ssowmini dip = malloc(dsize); 2160e7801d59Ssowmini if (dip == NULL) { 2161e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 2162e7801d59Ssowmini return (NULL); 2163e7801d59Ssowmini } 2164e7801d59Ssowmini bzero(dip, dsize); 2165e7801d59Ssowmini dip->pr_valsize = valsize; 21664045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 21673fd94f8cSam223141 dip->pr_version = MAC_PROP_VERSION; 21686b9e797cSsowmini dip->pr_linkid = linkid; 2169bcb5c89dSSowmini Varadhan dip->pr_num = propid; 21704045d941Ssowmini dip->pr_flags = flags; 2171e7801d59Ssowmini return (dip); 2172e7801d59Ssowmini } 2173e7801d59Ssowmini 2174bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 2175bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 2176bcb5c89dSSowmini Varadhan const char *prop_name, uint_t flags, dladm_status_t *status) 2177bcb5c89dSSowmini Varadhan { 2178bcb5c89dSSowmini Varadhan link_attr_t *p; 2179bcb5c89dSSowmini Varadhan 2180bcb5c89dSSowmini Varadhan p = dladm_name2prop(prop_name); 2181bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 2182bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 2183bcb5c89dSSowmini Varadhan flags, status)); 2184bcb5c89dSSowmini Varadhan } 2185bcb5c89dSSowmini Varadhan 2186bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 2187bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 2188bcb5c89dSSowmini Varadhan mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 2189bcb5c89dSSowmini Varadhan { 2190bcb5c89dSSowmini Varadhan link_attr_t *p; 2191bcb5c89dSSowmini Varadhan 2192bcb5c89dSSowmini Varadhan p = dladm_id2prop(propid); 2193bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 2194bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 2195bcb5c89dSSowmini Varadhan flags, status)); 2196bcb5c89dSSowmini Varadhan } 2197bcb5c89dSSowmini Varadhan 2198e7801d59Ssowmini /* ARGSUSED */ 2199e7801d59Ssowmini static dladm_status_t 2200*da14cebeSEric Cheng i_dladm_set_public_prop(prop_desc_t *pdp, datalink_id_t linkid, 22016b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 2202e7801d59Ssowmini { 22033fd94f8cSam223141 dld_ioc_macprop_t *dip; 2204e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 2205e7801d59Ssowmini uint8_t u8; 2206e7801d59Ssowmini uint16_t u16; 2207e7801d59Ssowmini uint32_t u32; 2208e7801d59Ssowmini void *val; 2209e7801d59Ssowmini 2210*da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 2211e7801d59Ssowmini if (dip == NULL) 2212e7801d59Ssowmini return (status); 2213e7801d59Ssowmini 2214*da14cebeSEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 2215e7801d59Ssowmini val = (void *)vdp->vd_val; 2216e7801d59Ssowmini else { 2217e7801d59Ssowmini /* 2218e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 2219e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 2220e7801d59Ssowmini */ 2221e7801d59Ssowmini switch (dip->pr_valsize) { 2222e7801d59Ssowmini case 1: 2223e7801d59Ssowmini u8 = vdp->vd_val; 2224e7801d59Ssowmini val = &u8; 2225e7801d59Ssowmini break; 2226e7801d59Ssowmini case 2: 2227e7801d59Ssowmini u16 = vdp->vd_val; 2228e7801d59Ssowmini val = &u16; 2229e7801d59Ssowmini break; 2230e7801d59Ssowmini case 4: 2231e7801d59Ssowmini u32 = vdp->vd_val; 2232e7801d59Ssowmini val = &u32; 2233e7801d59Ssowmini break; 2234e7801d59Ssowmini default: 2235e7801d59Ssowmini val = &vdp->vd_val; 2236e7801d59Ssowmini break; 2237e7801d59Ssowmini } 2238e7801d59Ssowmini } 2239e7801d59Ssowmini 22403bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 2241e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 22423bc21d0aSAruna Ramakrishna - Sun Microsystems else 22433bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 22443bc21d0aSAruna Ramakrishna - Sun Microsystems 2245bcb5c89dSSowmini Varadhan status = i_dladm_macprop(dip, B_TRUE); 2246bcb5c89dSSowmini Varadhan 2247bcb5c89dSSowmini Varadhan done: 2248bcb5c89dSSowmini Varadhan free(dip); 2249bcb5c89dSSowmini Varadhan return (status); 2250bcb5c89dSSowmini Varadhan } 2251bcb5c89dSSowmini Varadhan 2252bcb5c89dSSowmini Varadhan dladm_status_t 2253bcb5c89dSSowmini Varadhan i_dladm_macprop(void *dip, boolean_t set) 2254bcb5c89dSSowmini Varadhan { 2255bcb5c89dSSowmini Varadhan int fd; 2256bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 2257bcb5c89dSSowmini Varadhan 2258e7801d59Ssowmini if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 2259e7801d59Ssowmini status = dladm_errno2status(errno); 2260bcb5c89dSSowmini Varadhan return (status); 2261e7801d59Ssowmini } 2262bcb5c89dSSowmini Varadhan if (ioctl(fd, (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 2263e7801d59Ssowmini status = dladm_errno2status(errno); 2264e7801d59Ssowmini 2265e7801d59Ssowmini (void) close(fd); 2266e7801d59Ssowmini return (status); 2267e7801d59Ssowmini } 2268e7801d59Ssowmini 22693fd94f8cSam223141 static dld_ioc_macprop_t * 22703bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags, 2271*da14cebeSEric Cheng dladm_status_t *status, uint_t *perm_flags) 2272e7801d59Ssowmini { 22733fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 22744045d941Ssowmini 2275bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 22764045d941Ssowmini if (dip == NULL) 22774045d941Ssowmini return (NULL); 2278e7801d59Ssowmini 2279bcb5c89dSSowmini Varadhan *status = i_dladm_macprop(dip, B_FALSE); 22804045d941Ssowmini if (*status != DLADM_STATUS_OK) { 22814045d941Ssowmini free(dip); 22824045d941Ssowmini return (NULL); 22834045d941Ssowmini } 2284*da14cebeSEric Cheng if (perm_flags != NULL) 2285*da14cebeSEric Cheng *perm_flags = dip->pr_perm_flags; 2286*da14cebeSEric Cheng 22874045d941Ssowmini return (dip); 2288e7801d59Ssowmini } 2289e7801d59Ssowmini 2290e7801d59Ssowmini /* ARGSUSED */ 2291e7801d59Ssowmini static dladm_status_t 2292*da14cebeSEric Cheng i_dladm_defmtu_check(prop_desc_t *pdp, datalink_id_t linkid, 22933bc21d0aSAruna Ramakrishna - Sun Microsystems char **prop_val, uint_t val_cnt, val_desc_t *v, datalink_media_t media) 2294e7801d59Ssowmini { 2295e7801d59Ssowmini if (val_cnt != 1) 2296e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 22974045d941Ssowmini v->vd_val = atoi(prop_val[0]); 2298e7801d59Ssowmini return (DLADM_STATUS_OK); 2299e7801d59Ssowmini } 2300e7801d59Ssowmini 2301e7801d59Ssowmini /* ARGSUSED */ 2302e7801d59Ssowmini static dladm_status_t 2303*da14cebeSEric Cheng i_dladm_duplex_get(prop_desc_t *pdp, datalink_id_t linkid, 2304*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2305*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2306e7801d59Ssowmini { 2307e7801d59Ssowmini link_duplex_t link_duplex; 2308e7801d59Ssowmini dladm_status_t status; 2309e7801d59Ssowmini 2310e7801d59Ssowmini if ((status = dladm_get_single_mac_stat(linkid, "link_duplex", 2311e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 2312e7801d59Ssowmini return (status); 2313e7801d59Ssowmini 2314e7801d59Ssowmini switch (link_duplex) { 2315e7801d59Ssowmini case LINK_DUPLEX_FULL: 2316e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 2317e7801d59Ssowmini break; 2318e7801d59Ssowmini case LINK_DUPLEX_HALF: 2319e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 2320e7801d59Ssowmini break; 2321e7801d59Ssowmini default: 2322e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 2323e7801d59Ssowmini break; 2324e7801d59Ssowmini } 2325e7801d59Ssowmini *val_cnt = 1; 2326e7801d59Ssowmini return (DLADM_STATUS_OK); 2327e7801d59Ssowmini } 2328e7801d59Ssowmini 2329e7801d59Ssowmini /* ARGSUSED */ 2330e7801d59Ssowmini static dladm_status_t 2331*da14cebeSEric Cheng i_dladm_speed_get(prop_desc_t *pdp, datalink_id_t linkid, 2332*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, uint_t flags, uint_t *perm_flags) 2333e7801d59Ssowmini { 2334e7801d59Ssowmini uint64_t ifspeed = 0; 2335e7801d59Ssowmini dladm_status_t status; 2336e7801d59Ssowmini 2337e7801d59Ssowmini if ((status = dladm_get_single_mac_stat(linkid, "ifspeed", 2338e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 2339e7801d59Ssowmini return (status); 23404045d941Ssowmini 23416b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 23426b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 23436b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 23446b9e797cSsowmini } else { 2345e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 2346e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 23476b9e797cSsowmini } 2348e7801d59Ssowmini *val_cnt = 1; 2349*da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 2350e7801d59Ssowmini return (DLADM_STATUS_OK); 2351e7801d59Ssowmini } 2352e7801d59Ssowmini 2353e7801d59Ssowmini /* ARGSUSED */ 2354e7801d59Ssowmini static dladm_status_t 2355*da14cebeSEric Cheng i_dladm_status_get(prop_desc_t *pdp, datalink_id_t linkid, 2356*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2357*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2358e7801d59Ssowmini { 2359e7801d59Ssowmini link_state_t link_state; 2360e7801d59Ssowmini dladm_status_t status; 23614045d941Ssowmini uchar_t *cp; 23623fd94f8cSam223141 dld_ioc_macprop_t *dip; 2363e7801d59Ssowmini 2364*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 2365*da14cebeSEric Cheng &status, perm_flags); 23664045d941Ssowmini if (status != DLADM_STATUS_OK) 2367e7801d59Ssowmini return (status); 2368*da14cebeSEric Cheng 23694045d941Ssowmini cp = (uchar_t *)dip->pr_val; 23704045d941Ssowmini (void) memcpy(&link_state, cp, sizeof (link_state)); 2371e7801d59Ssowmini 2372e7801d59Ssowmini switch (link_state) { 2373e7801d59Ssowmini case LINK_STATE_UP: 2374e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 2375e7801d59Ssowmini break; 2376e7801d59Ssowmini case LINK_STATE_DOWN: 2377e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 2378e7801d59Ssowmini break; 2379e7801d59Ssowmini default: 2380e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 2381e7801d59Ssowmini break; 2382e7801d59Ssowmini } 2383e7801d59Ssowmini *val_cnt = 1; 23844045d941Ssowmini free(dip); 2385e7801d59Ssowmini return (DLADM_STATUS_OK); 2386e7801d59Ssowmini } 2387e7801d59Ssowmini 2388e7801d59Ssowmini /* ARGSUSED */ 2389e7801d59Ssowmini static dladm_status_t 2390*da14cebeSEric Cheng i_dladm_binary_get(prop_desc_t *pdp, datalink_id_t linkid, 2391*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2392*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2393e7801d59Ssowmini { 23943fd94f8cSam223141 dld_ioc_macprop_t *dip; 2395e7801d59Ssowmini dladm_status_t status; 2396e7801d59Ssowmini 2397*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 2398*da14cebeSEric Cheng &status, perm_flags); 23994045d941Ssowmini if (dip == NULL) 2400e7801d59Ssowmini return (status); 2401*da14cebeSEric Cheng 2402e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 2403e7801d59Ssowmini free(dip); 2404e7801d59Ssowmini *val_cnt = 1; 2405e7801d59Ssowmini return (DLADM_STATUS_OK); 2406e7801d59Ssowmini } 2407e7801d59Ssowmini 24086b9e797cSsowmini /* ARGSUSED */ 2409e7801d59Ssowmini static dladm_status_t 2410*da14cebeSEric Cheng i_dladm_uint32_get(prop_desc_t *pdp, datalink_id_t linkid, 2411*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2412*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2413e7801d59Ssowmini { 24143fd94f8cSam223141 dld_ioc_macprop_t *dip; 24154045d941Ssowmini uint32_t v = 0; 2416e7801d59Ssowmini uchar_t *cp; 2417e7801d59Ssowmini dladm_status_t status; 2418e7801d59Ssowmini 2419*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 2420*da14cebeSEric Cheng &status, perm_flags); 24214045d941Ssowmini if (dip == NULL) 2422e7801d59Ssowmini return (status); 2423*da14cebeSEric Cheng 2424e7801d59Ssowmini cp = (uchar_t *)dip->pr_val; 2425e7801d59Ssowmini (void) memcpy(&v, cp, sizeof (v)); 24264045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 2427e7801d59Ssowmini free(dip); 2428e7801d59Ssowmini *val_cnt = 1; 2429e7801d59Ssowmini return (DLADM_STATUS_OK); 2430e7801d59Ssowmini } 2431e7801d59Ssowmini 24326b9e797cSsowmini /* ARGSUSED */ 2433e7801d59Ssowmini static dladm_status_t 2434*da14cebeSEric Cheng i_dladm_flowctl_get(prop_desc_t *pdp, datalink_id_t linkid, 2435*da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2436*da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2437e7801d59Ssowmini { 24383fd94f8cSam223141 dld_ioc_macprop_t *dip; 2439e7801d59Ssowmini link_flowctrl_t v; 2440e7801d59Ssowmini dladm_status_t status; 2441e7801d59Ssowmini uchar_t *cp; 2442e7801d59Ssowmini 2443*da14cebeSEric Cheng dip = i_dladm_get_public_prop(linkid, pdp->pd_name, flags, 2444*da14cebeSEric Cheng &status, perm_flags); 24454045d941Ssowmini if (dip == NULL) 2446e7801d59Ssowmini return (status); 2447*da14cebeSEric Cheng 2448e7801d59Ssowmini cp = (uchar_t *)dip->pr_val; 2449e7801d59Ssowmini (void) memcpy(&v, cp, sizeof (v)); 2450e7801d59Ssowmini switch (v) { 2451e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 2452e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 2453e7801d59Ssowmini break; 2454e7801d59Ssowmini case LINK_FLOWCTRL_RX: 2455e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 2456e7801d59Ssowmini break; 2457e7801d59Ssowmini case LINK_FLOWCTRL_TX: 2458e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 2459e7801d59Ssowmini break; 2460e7801d59Ssowmini case LINK_FLOWCTRL_BI: 2461e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 2462e7801d59Ssowmini break; 2463e7801d59Ssowmini } 2464e7801d59Ssowmini free(dip); 2465e7801d59Ssowmini *val_cnt = 1; 2466e7801d59Ssowmini return (DLADM_STATUS_OK); 2467e7801d59Ssowmini } 2468e7801d59Ssowmini 2469e7801d59Ssowmini 2470e7801d59Ssowmini /* ARGSUSED */ 2471e7801d59Ssowmini static dladm_status_t 24723bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, 2473e7801d59Ssowmini char **prop_val, uint_t val_cnt, uint_t flags) 2474e7801d59Ssowmini { 2475bcb5c89dSSowmini Varadhan int i, slen; 2476eae72b5bSSebastien Roy int bufsize = 0; 24773fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 2478e7801d59Ssowmini uchar_t *dp; 2479bcb5c89dSSowmini Varadhan link_attr_t *p; 24804045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 2481e7801d59Ssowmini 2482e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 2483e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 2484e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2485e7801d59Ssowmini p = dladm_name2prop(prop_name); 24863fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 2487e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2488e7801d59Ssowmini 2489e7801d59Ssowmini /* 2490e7801d59Ssowmini * private properties: all parsing is done in the kernel. 2491e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 2492e7801d59Ssowmini */ 2493e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 2494e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 2495e7801d59Ssowmini } 24964045d941Ssowmini 24974045d941Ssowmini if (prop_val == NULL) { 24984045d941Ssowmini /* 24994045d941Ssowmini * getting default value. so use more buffer space. 25004045d941Ssowmini */ 2501bcb5c89dSSowmini Varadhan bufsize += DLADM_PROP_BUF_CHUNK; 25024045d941Ssowmini } 25034045d941Ssowmini 2504bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 25053fd94f8cSam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 2506e7801d59Ssowmini if (dip == NULL) 2507e7801d59Ssowmini return (status); 2508e7801d59Ssowmini 2509e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 2510e7801d59Ssowmini slen = 0; 2511bcb5c89dSSowmini Varadhan 25124045d941Ssowmini if (prop_val == NULL) { 2513bcb5c89dSSowmini Varadhan status = i_dladm_macprop(dip, B_FALSE); 25144045d941Ssowmini } else { 2515e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 2516e7801d59Ssowmini int plen = 0; 2517e7801d59Ssowmini 2518e7801d59Ssowmini plen = strlen(prop_val[i]); 2519e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 2520e7801d59Ssowmini slen += plen; 2521e7801d59Ssowmini /* 2522e7801d59Ssowmini * add a "," separator and update dp. 2523e7801d59Ssowmini */ 2524e7801d59Ssowmini if (i != (val_cnt -1)) 2525e7801d59Ssowmini dp[slen++] = ','; 2526e7801d59Ssowmini dp += (plen + 1); 2527e7801d59Ssowmini } 2528bcb5c89dSSowmini Varadhan status = i_dladm_macprop(dip, B_TRUE); 2529e7801d59Ssowmini } 25304045d941Ssowmini 2531e7801d59Ssowmini free(dip); 2532e7801d59Ssowmini return (status); 2533e7801d59Ssowmini } 2534e7801d59Ssowmini 2535e7801d59Ssowmini static dladm_status_t 25363bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, 25374045d941Ssowmini char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags) 2538e7801d59Ssowmini { 2539e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 25403fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 2541bcb5c89dSSowmini Varadhan link_attr_t *p; 2542e7801d59Ssowmini char tmp = '\0'; 2543e7801d59Ssowmini 2544e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 2545e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 2546e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2547e7801d59Ssowmini 2548e7801d59Ssowmini p = dladm_name2prop(prop_name); 25493fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 2550e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2551e7801d59Ssowmini 25524045d941Ssowmini if (type == DLADM_PROP_VAL_MODIFIABLE) { 2553e7801d59Ssowmini *prop_val = &tmp; 2554e7801d59Ssowmini *val_cnt = 1; 2555e7801d59Ssowmini return (DLADM_STATUS_OK); 2556e7801d59Ssowmini } 2557e7801d59Ssowmini 2558e7801d59Ssowmini /* 2559e7801d59Ssowmini * private properties: all parsing is done in the kernel. 2560e7801d59Ssowmini */ 2561bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 2562bcb5c89dSSowmini Varadhan dld_flags, &status); 2563e7801d59Ssowmini if (dip == NULL) 2564e7801d59Ssowmini return (status); 2565e7801d59Ssowmini 2566bcb5c89dSSowmini Varadhan if ((status = i_dladm_macprop(dip, B_FALSE)) == DLADM_STATUS_OK) { 2567afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_PERM) { 2568*da14cebeSEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 2569afdda45fSVasumathi Sundaram - Sun Microsystems } else { 2570afdda45fSVasumathi Sundaram - Sun Microsystems (void) strncpy(*prop_val, dip->pr_val, 2571afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_MAX); 2572afdda45fSVasumathi Sundaram - Sun Microsystems } 2573e7801d59Ssowmini *val_cnt = 1; 2574e7801d59Ssowmini } 25754045d941Ssowmini free(dip); 25764045d941Ssowmini return (status); 25774045d941Ssowmini } 25784045d941Ssowmini 25794045d941Ssowmini 25804045d941Ssowmini static dladm_status_t 25814045d941Ssowmini i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid, 25824045d941Ssowmini datalink_media_t media, uint_t flags) 25834045d941Ssowmini { 25844045d941Ssowmini dladm_status_t status; 25854045d941Ssowmini char **prop_vals = NULL, *buf; 25864045d941Ssowmini size_t bufsize; 25874045d941Ssowmini uint_t cnt; 25884045d941Ssowmini int i; 2589afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 25904045d941Ssowmini 25914045d941Ssowmini /* 25924045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 25934045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 25944045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 25954045d941Ssowmini */ 25964045d941Ssowmini bufsize = 25974045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 25984045d941Ssowmini buf = malloc(bufsize); 25994045d941Ssowmini prop_vals = (char **)(void *)buf; 26004045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 26014045d941Ssowmini prop_vals[i] = buf + 26024045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 26034045d941Ssowmini i * DLADM_PROP_VAL_MAX; 26044045d941Ssowmini } 260513a55820Sar224390 260613a55820Sar224390 /* 26073bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 26083bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 26093bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 26103bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 26113bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 26123bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 26133bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 26143bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 261513a55820Sar224390 */ 26163fd94f8cSam223141 status = pdp->pd_get(pdp, linkid, prop_vals, &cnt, media, 2617afdda45fSVasumathi Sundaram - Sun Microsystems MAC_PROP_DEFAULT, &perm_flags); 26184045d941Ssowmini if (status == DLADM_STATUS_OK) { 2619afdda45fSVasumathi Sundaram - Sun Microsystems if (perm_flags == MAC_PROP_PERM_RW) { 26204045d941Ssowmini status = i_dladm_set_single_prop(linkid, pdp->pd_class, 26214045d941Ssowmini media, pdp, prop_vals, cnt, flags); 26224045d941Ssowmini } 2623afdda45fSVasumathi Sundaram - Sun Microsystems else 2624afdda45fSVasumathi Sundaram - Sun Microsystems status = DLADM_STATUS_NOTSUP; 2625afdda45fSVasumathi Sundaram - Sun Microsystems } 26264045d941Ssowmini free(buf); 2627e7801d59Ssowmini return (status); 2628e7801d59Ssowmini } 2629bcb5c89dSSowmini Varadhan 2630bcb5c89dSSowmini Varadhan int 2631bcb5c89dSSowmini Varadhan macprop_to_wifi(mac_prop_id_t wl_prop) 2632bcb5c89dSSowmini Varadhan { 2633bcb5c89dSSowmini Varadhan switch (wl_prop) { 2634bcb5c89dSSowmini Varadhan case MAC_PROP_WL_ESSID: 2635bcb5c89dSSowmini Varadhan return (WL_ESSID); 2636bcb5c89dSSowmini Varadhan case MAC_PROP_WL_BSSID: 2637bcb5c89dSSowmini Varadhan return (WL_BSSID); 2638bcb5c89dSSowmini Varadhan case MAC_PROP_WL_BSSTYPE: 2639bcb5c89dSSowmini Varadhan return (WL_BSS_TYPE); 2640bcb5c89dSSowmini Varadhan case MAC_PROP_WL_LINKSTATUS: 2641bcb5c89dSSowmini Varadhan return (WL_LINKSTATUS); 2642bcb5c89dSSowmini Varadhan case MAC_PROP_WL_DESIRED_RATES: 2643bcb5c89dSSowmini Varadhan return (WL_DESIRED_RATES); 2644bcb5c89dSSowmini Varadhan case MAC_PROP_WL_SUPPORTED_RATES: 2645bcb5c89dSSowmini Varadhan return (WL_SUPPORTED_RATES); 2646bcb5c89dSSowmini Varadhan case MAC_PROP_WL_AUTH_MODE: 2647bcb5c89dSSowmini Varadhan return (WL_AUTH_MODE); 2648bcb5c89dSSowmini Varadhan case MAC_PROP_WL_ENCRYPTION: 2649bcb5c89dSSowmini Varadhan return (WL_ENCRYPTION); 2650bcb5c89dSSowmini Varadhan case MAC_PROP_WL_RSSI: 2651bcb5c89dSSowmini Varadhan return (WL_RSSI); 2652bcb5c89dSSowmini Varadhan case MAC_PROP_WL_PHY_CONFIG: 2653bcb5c89dSSowmini Varadhan return (WL_PHY_CONFIG); 2654bcb5c89dSSowmini Varadhan case MAC_PROP_WL_CAPABILITY: 2655bcb5c89dSSowmini Varadhan return (WL_CAPABILITY); 2656bcb5c89dSSowmini Varadhan case MAC_PROP_WL_WPA: 2657bcb5c89dSSowmini Varadhan return (WL_WPA); 2658bcb5c89dSSowmini Varadhan case MAC_PROP_WL_SCANRESULTS: 2659bcb5c89dSSowmini Varadhan return (WL_SCANRESULTS); 2660bcb5c89dSSowmini Varadhan case MAC_PROP_WL_POWER_MODE: 2661bcb5c89dSSowmini Varadhan return (WL_POWER_MODE); 2662bcb5c89dSSowmini Varadhan case MAC_PROP_WL_RADIO: 2663bcb5c89dSSowmini Varadhan return (WL_RADIO); 2664bcb5c89dSSowmini Varadhan case MAC_PROP_WL_ESS_LIST: 2665bcb5c89dSSowmini Varadhan return (WL_ESS_LIST); 2666bcb5c89dSSowmini Varadhan case MAC_PROP_WL_KEY_TAB: 2667bcb5c89dSSowmini Varadhan return (WL_WEP_KEY_TAB); 2668bcb5c89dSSowmini Varadhan case MAC_PROP_WL_CREATE_IBSS: 2669bcb5c89dSSowmini Varadhan return (WL_CREATE_IBSS); 2670bcb5c89dSSowmini Varadhan case MAC_PROP_WL_SETOPTIE: 2671bcb5c89dSSowmini Varadhan return (WL_SETOPTIE); 2672bcb5c89dSSowmini Varadhan case MAC_PROP_WL_DELKEY: 2673bcb5c89dSSowmini Varadhan return (WL_DELKEY); 2674bcb5c89dSSowmini Varadhan case MAC_PROP_WL_KEY: 2675bcb5c89dSSowmini Varadhan return (WL_KEY); 2676bcb5c89dSSowmini Varadhan case MAC_PROP_WL_MLME: 2677bcb5c89dSSowmini Varadhan return (WL_MLME); 2678bcb5c89dSSowmini Varadhan default: 2679bcb5c89dSSowmini Varadhan return (-1); 2680bcb5c89dSSowmini Varadhan } 2681bcb5c89dSSowmini Varadhan } 2682bcb5c89dSSowmini Varadhan 2683bcb5c89dSSowmini Varadhan dladm_status_t 2684bcb5c89dSSowmini Varadhan i_dladm_wlan_param(datalink_id_t linkid, void *buf, mac_prop_id_t cmd, 2685bcb5c89dSSowmini Varadhan size_t len, boolean_t set) 2686bcb5c89dSSowmini Varadhan { 2687bcb5c89dSSowmini Varadhan uint32_t flags; 2688bcb5c89dSSowmini Varadhan dladm_status_t status; 2689bcb5c89dSSowmini Varadhan uint32_t media; 2690bcb5c89dSSowmini Varadhan dld_ioc_macprop_t *dip; 2691bcb5c89dSSowmini Varadhan void *dp; 2692bcb5c89dSSowmini Varadhan 2693bcb5c89dSSowmini Varadhan if ((status = dladm_datalink_id2info(linkid, &flags, NULL, &media, 2694bcb5c89dSSowmini Varadhan NULL, 0)) != DLADM_STATUS_OK) { 2695bcb5c89dSSowmini Varadhan return (status); 2696bcb5c89dSSowmini Varadhan } 2697bcb5c89dSSowmini Varadhan 2698bcb5c89dSSowmini Varadhan if (media != DL_WIFI) 2699bcb5c89dSSowmini Varadhan return (DLADM_STATUS_BADARG); 2700bcb5c89dSSowmini Varadhan 2701bcb5c89dSSowmini Varadhan if (!(flags & DLADM_OPT_ACTIVE)) 2702bcb5c89dSSowmini Varadhan return (DLADM_STATUS_TEMPONLY); 2703bcb5c89dSSowmini Varadhan 2704bcb5c89dSSowmini Varadhan if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 2705bcb5c89dSSowmini Varadhan len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 2706bcb5c89dSSowmini Varadhan 2707bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 2708bcb5c89dSSowmini Varadhan if (dip == NULL) 2709bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2710bcb5c89dSSowmini Varadhan 2711bcb5c89dSSowmini Varadhan dp = (uchar_t *)dip->pr_val; 2712bcb5c89dSSowmini Varadhan if (set) 2713bcb5c89dSSowmini Varadhan (void) memcpy(dp, buf, len); 2714bcb5c89dSSowmini Varadhan 2715bcb5c89dSSowmini Varadhan status = i_dladm_macprop(dip, set); 2716bcb5c89dSSowmini Varadhan if (status == DLADM_STATUS_NOTSUP) { 2717bcb5c89dSSowmini Varadhan if (set) { 2718bcb5c89dSSowmini Varadhan status = i_dladm_wlan_set_legacy_ioctl(linkid, 2719bcb5c89dSSowmini Varadhan buf, len, macprop_to_wifi(cmd)); 2720bcb5c89dSSowmini Varadhan } else { 2721bcb5c89dSSowmini Varadhan status = i_dladm_wlan_get_legacy_ioctl(linkid, 2722bcb5c89dSSowmini Varadhan buf, len, macprop_to_wifi(cmd)); 2723bcb5c89dSSowmini Varadhan } 2724bcb5c89dSSowmini Varadhan } else if (status == DLADM_STATUS_OK) { 2725bcb5c89dSSowmini Varadhan if (!set) 2726bcb5c89dSSowmini Varadhan (void) memcpy(buf, dp, len); 2727bcb5c89dSSowmini Varadhan } 2728bcb5c89dSSowmini Varadhan 2729bcb5c89dSSowmini Varadhan free(dip); 2730bcb5c89dSSowmini Varadhan return (status); 2731bcb5c89dSSowmini Varadhan } 2732bcb5c89dSSowmini Varadhan 2733bcb5c89dSSowmini Varadhan static dladm_status_t 2734bcb5c89dSSowmini Varadhan i_dladm_wlan_get_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen, 2735bcb5c89dSSowmini Varadhan uint_t id) 2736bcb5c89dSSowmini Varadhan { 2737bcb5c89dSSowmini Varadhan wldp_t *gbuf; 2738bcb5c89dSSowmini Varadhan dladm_status_t status; 2739bcb5c89dSSowmini Varadhan 2740bcb5c89dSSowmini Varadhan if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 2741bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2742bcb5c89dSSowmini Varadhan 2743bcb5c89dSSowmini Varadhan (void) memset(gbuf, 0, MAX_BUF_LEN); 2744bcb5c89dSSowmini Varadhan status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, MAX_BUF_LEN, 2745bcb5c89dSSowmini Varadhan WLAN_GET_PARAM, sizeof (wldp_t)); 2746bcb5c89dSSowmini Varadhan if (status == DLADM_STATUS_OK) 2747bcb5c89dSSowmini Varadhan (void) memcpy(buf, gbuf->wldp_buf, buflen); 2748bcb5c89dSSowmini Varadhan 2749bcb5c89dSSowmini Varadhan free(gbuf); 2750bcb5c89dSSowmini Varadhan return (status); 2751bcb5c89dSSowmini Varadhan } 2752bcb5c89dSSowmini Varadhan 2753bcb5c89dSSowmini Varadhan static dladm_status_t 2754bcb5c89dSSowmini Varadhan i_dladm_wlan_set_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen, 2755bcb5c89dSSowmini Varadhan uint_t id) 2756bcb5c89dSSowmini Varadhan { 2757bcb5c89dSSowmini Varadhan wldp_t *gbuf; 2758bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 2759bcb5c89dSSowmini Varadhan 2760bcb5c89dSSowmini Varadhan if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 2761bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2762bcb5c89dSSowmini Varadhan 2763bcb5c89dSSowmini Varadhan (void) memset(gbuf, 0, MAX_BUF_LEN); 2764bcb5c89dSSowmini Varadhan (void) memcpy(gbuf->wldp_buf, buf, buflen); 2765bcb5c89dSSowmini Varadhan buflen += WIFI_BUF_OFFSET; 2766bcb5c89dSSowmini Varadhan status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, buflen, 2767bcb5c89dSSowmini Varadhan WLAN_SET_PARAM, buflen); 2768bcb5c89dSSowmini Varadhan 2769bcb5c89dSSowmini Varadhan free(gbuf); 2770bcb5c89dSSowmini Varadhan return (status); 2771bcb5c89dSSowmini Varadhan } 2772*da14cebeSEric Cheng 2773*da14cebeSEric Cheng static dladm_status_t 2774*da14cebeSEric Cheng link_proplist_check(dladm_arg_list_t *proplist) 2775*da14cebeSEric Cheng { 2776*da14cebeSEric Cheng int i, j; 2777*da14cebeSEric Cheng boolean_t matched; 2778*da14cebeSEric Cheng 2779*da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 2780*da14cebeSEric Cheng matched = B_FALSE; 2781*da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_PROPS; j++) { 2782*da14cebeSEric Cheng if (strcmp(proplist->al_info[i].ai_name, 2783*da14cebeSEric Cheng prop_table[j].pd_name) == 0) 2784*da14cebeSEric Cheng matched = B_TRUE; 2785*da14cebeSEric Cheng } 2786*da14cebeSEric Cheng if (!matched) 2787*da14cebeSEric Cheng return (DLADM_STATUS_BADPROP); 2788*da14cebeSEric Cheng } 2789*da14cebeSEric Cheng return (DLADM_STATUS_OK); 2790*da14cebeSEric Cheng } 2791*da14cebeSEric Cheng 2792*da14cebeSEric Cheng dladm_status_t 2793*da14cebeSEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 2794*da14cebeSEric Cheng { 2795*da14cebeSEric Cheng dladm_status_t status; 2796*da14cebeSEric Cheng 2797*da14cebeSEric Cheng status = dladm_parse_args(str, listp, novalues); 2798*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2799*da14cebeSEric Cheng return (status); 2800*da14cebeSEric Cheng 2801*da14cebeSEric Cheng status = link_proplist_check(*listp); 2802*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 2803*da14cebeSEric Cheng dladm_free_props(*listp); 2804*da14cebeSEric Cheng return (status); 2805*da14cebeSEric Cheng } 2806*da14cebeSEric Cheng 2807*da14cebeSEric Cheng return (DLADM_STATUS_OK); 2808*da14cebeSEric Cheng } 2809*da14cebeSEric Cheng 2810*da14cebeSEric Cheng /* 2811*da14cebeSEric Cheng * Retrieve the one link property from the database 2812*da14cebeSEric Cheng */ 2813*da14cebeSEric Cheng /*ARGSUSED*/ 2814*da14cebeSEric Cheng static int 2815*da14cebeSEric Cheng i_dladm_get_one_prop(datalink_id_t linkid, const char *prop_name, void *arg) 2816*da14cebeSEric Cheng { 2817*da14cebeSEric Cheng dladm_arg_list_t *proplist = arg; 2818*da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 2819*da14cebeSEric Cheng 2820*da14cebeSEric Cheng aip = &proplist->al_info[proplist->al_count]; 2821*da14cebeSEric Cheng /* 2822*da14cebeSEric Cheng * it is fine to point to prop_name since prop_name points to the 2823*da14cebeSEric Cheng * prop_table[n].pd_name. 2824*da14cebeSEric Cheng */ 2825*da14cebeSEric Cheng aip->ai_name = prop_name; 2826*da14cebeSEric Cheng 2827*da14cebeSEric Cheng (void) dladm_get_linkprop(linkid, DLADM_PROP_VAL_PERSISTENT, prop_name, 2828*da14cebeSEric Cheng aip->ai_val, &aip->ai_count); 2829*da14cebeSEric Cheng 2830*da14cebeSEric Cheng if (aip->ai_count != 0) 2831*da14cebeSEric Cheng proplist->al_count++; 2832*da14cebeSEric Cheng 2833*da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 2834*da14cebeSEric Cheng } 2835*da14cebeSEric Cheng 2836*da14cebeSEric Cheng 2837*da14cebeSEric Cheng /* 2838*da14cebeSEric Cheng * Retrieve all link properties for a link from the database and 2839*da14cebeSEric Cheng * return a property list. 2840*da14cebeSEric Cheng */ 2841*da14cebeSEric Cheng dladm_status_t 2842*da14cebeSEric Cheng dladm_link_get_proplist(datalink_id_t linkid, dladm_arg_list_t **listp) 2843*da14cebeSEric Cheng { 2844*da14cebeSEric Cheng dladm_arg_list_t *list; 2845*da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 2846*da14cebeSEric Cheng 2847*da14cebeSEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 2848*da14cebeSEric Cheng if (list == NULL) 2849*da14cebeSEric Cheng return (dladm_errno2status(errno)); 2850*da14cebeSEric Cheng 2851*da14cebeSEric Cheng status = dladm_walk_linkprop(linkid, list, i_dladm_get_one_prop); 2852*da14cebeSEric Cheng 2853*da14cebeSEric Cheng *listp = list; 2854*da14cebeSEric Cheng return (status); 2855*da14cebeSEric Cheng } 2856*da14cebeSEric Cheng 2857*da14cebeSEric Cheng /* 2858*da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 2859*da14cebeSEric Cheng * convert to a kernel structure. 2860*da14cebeSEric Cheng */ 2861*da14cebeSEric Cheng static dladm_status_t 2862*da14cebeSEric Cheng i_dladm_link_proplist_extract_one(dladm_arg_list_t *proplist, 2863*da14cebeSEric Cheng const char *name, void *val) 2864*da14cebeSEric Cheng { 2865*da14cebeSEric Cheng dladm_status_t status; 2866*da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 2867*da14cebeSEric Cheng int i, j; 2868*da14cebeSEric Cheng 2869*da14cebeSEric Cheng /* Find named property in proplist */ 2870*da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 2871*da14cebeSEric Cheng aip = &proplist->al_info[i]; 2872*da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 2873*da14cebeSEric Cheng break; 2874*da14cebeSEric Cheng } 2875*da14cebeSEric Cheng 2876*da14cebeSEric Cheng /* Property not in list */ 2877*da14cebeSEric Cheng if (i == proplist->al_count) 2878*da14cebeSEric Cheng return (DLADM_STATUS_OK); 2879*da14cebeSEric Cheng 2880*da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 2881*da14cebeSEric Cheng prop_desc_t *pdp = &prop_table[i]; 2882*da14cebeSEric Cheng val_desc_t *vdp; 2883*da14cebeSEric Cheng 2884*da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 2885*da14cebeSEric Cheng if (vdp == NULL) 2886*da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 2887*da14cebeSEric Cheng 2888*da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 2889*da14cebeSEric Cheng continue; 2890*da14cebeSEric Cheng 2891*da14cebeSEric Cheng if (aip->ai_val == NULL) 2892*da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 2893*da14cebeSEric Cheng 2894*da14cebeSEric Cheng /* Check property value */ 2895*da14cebeSEric Cheng if (pdp->pd_check != NULL) { 2896*da14cebeSEric Cheng status = pdp->pd_check(pdp, 0, aip->ai_val, 2897*da14cebeSEric Cheng aip->ai_count, vdp, 0); 2898*da14cebeSEric Cheng } else { 2899*da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 2900*da14cebeSEric Cheng } 2901*da14cebeSEric Cheng 2902*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2903*da14cebeSEric Cheng return (status); 2904*da14cebeSEric Cheng 2905*da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 2906*da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 2907*da14cebeSEric Cheng 2908*da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 2909*da14cebeSEric Cheng continue; 2910*da14cebeSEric Cheng 2911*da14cebeSEric Cheng /* Extract kernel structure */ 2912*da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 2913*da14cebeSEric Cheng status = rpp->rp_extract(vdp, val, 2914*da14cebeSEric Cheng aip->ai_count); 2915*da14cebeSEric Cheng } else { 2916*da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 2917*da14cebeSEric Cheng } 2918*da14cebeSEric Cheng break; 2919*da14cebeSEric Cheng } 2920*da14cebeSEric Cheng 2921*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2922*da14cebeSEric Cheng return (status); 2923*da14cebeSEric Cheng 2924*da14cebeSEric Cheng break; 2925*da14cebeSEric Cheng } 2926*da14cebeSEric Cheng return (status); 2927*da14cebeSEric Cheng } 2928*da14cebeSEric Cheng 2929*da14cebeSEric Cheng /* 2930*da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 2931*da14cebeSEric Cheng */ 2932*da14cebeSEric Cheng dladm_status_t 2933*da14cebeSEric Cheng dladm_link_proplist_extract(dladm_arg_list_t *proplist, 2934*da14cebeSEric Cheng mac_resource_props_t *mrp) 2935*da14cebeSEric Cheng { 2936*da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 2937*da14cebeSEric Cheng 2938*da14cebeSEric Cheng status = i_dladm_link_proplist_extract_one(proplist, "maxbw", mrp); 2939*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2940*da14cebeSEric Cheng return (status); 2941*da14cebeSEric Cheng status = i_dladm_link_proplist_extract_one(proplist, "priority", mrp); 2942*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2943*da14cebeSEric Cheng return (status); 2944*da14cebeSEric Cheng status = i_dladm_link_proplist_extract_one(proplist, "cpus", mrp); 2945*da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2946*da14cebeSEric Cheng return (status); 2947*da14cebeSEric Cheng return (status); 2948*da14cebeSEric Cheng } 2949*da14cebeSEric Cheng 2950*da14cebeSEric Cheng static const char * 2951*da14cebeSEric Cheng dladm_perm2str(uint_t perm, char *buf) 2952*da14cebeSEric Cheng { 2953*da14cebeSEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 2954*da14cebeSEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 2955*da14cebeSEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 2956*da14cebeSEric Cheng return (buf); 2957*da14cebeSEric Cheng } 2958