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> 44da14cebeSEric Cheng #include <libdlvnic.h> 45da14cebeSEric Cheng #include <libintl.h> 46f4b3ec61Sdh155122 #include <dlfcn.h> 47f4b3ec61Sdh155122 #include <link.h> 48d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 49e7801d59Ssowmini #include <libdladm.h> 50da14cebeSEric Cheng #include <libdlstat.h> 51e7801d59Ssowmini #include <sys/param.h> 52da14cebeSEric Cheng #include <sys/debug.h> 53da14cebeSEric Cheng #include <sys/dld.h> 54da14cebeSEric 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. 62da14cebeSEric 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; 69da14cebeSEric Cheng typedef struct prop_desc prop_desc_t; 70e7801d59Ssowmini 71*4ac67f02SAnurag S. Maskey typedef dladm_status_t pd_getf_t(dladm_handle_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*4ac67f02SAnurag S. Maskey typedef dladm_status_t pd_setf_t(dladm_handle_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*4ac67f02SAnurag S. Maskey typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 105*4ac67f02SAnurag S. Maskey datalink_id_t, char **propstrp, uint_t cnt, 106*4ac67f02SAnurag S. Maskey val_desc_t *propval, 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, 117da14cebeSEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 118*4ac67f02SAnurag S. Maskey static dld_ioc_macprop_t *i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 119*4ac67f02SAnurag S. Maskey char *, uint_t, dladm_status_t *, uint_t *); 120da14cebeSEric Cheng 121*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_prop(dladm_handle_t, datalink_id_t, 122*4ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 123*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_prop(dladm_handle_t, datalink_id_t, 124*4ac67f02SAnurag S. Maskey const char *, char **, uint_t *, dladm_prop_type_t, 125*4ac67f02SAnurag S. Maskey uint_t); 126bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *); 127bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t); 128da14cebeSEric Cheng 129d62bc4baSyz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 130d62bc4baSyz147064 do_get_rate_prop, do_get_channel_prop, 131e7801d59Ssowmini do_get_powermode_prop, do_get_radio_prop, 1323bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_duplex_get, i_dladm_status_get, 1333bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_binary_get, i_dladm_uint32_get, 134da14cebeSEric Cheng i_dladm_flowctl_get, dld_maxbw_get, dld_cpus_get, 135da14cebeSEric Cheng dld_priority_get; 136da14cebeSEric Cheng 1373bc21d0aSAruna Ramakrishna - Sun Microsystems static pd_setf_t do_set_zone, do_set_rate_prop, 138e7801d59Ssowmini do_set_powermode_prop, do_set_radio_prop, 139da14cebeSEric Cheng i_dladm_set_public_prop, do_set_res, do_set_cpus; 140f4b3ec61Sdh155122 141da14cebeSEric Cheng static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 142da14cebeSEric Cheng i_dladm_defmtu_check, do_check_maxbw, do_check_cpus, 143da14cebeSEric Cheng do_check_priority; 144da14cebeSEric Cheng 145*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_speed_get(dladm_handle_t, prop_desc_t *, 146*4ac67f02SAnurag S. Maskey datalink_id_t, char **, uint_t *, uint_t, uint_t *); 147*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_wlan_get_legacy_ioctl(dladm_handle_t, 148*4ac67f02SAnurag S. Maskey datalink_id_t, void *, uint_t, uint_t); 149*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_wlan_set_legacy_ioctl(dladm_handle_t, 150*4ac67f02SAnurag S. Maskey datalink_id_t, void *, uint_t, uint_t); 151*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 152da14cebeSEric Cheng static const char *dladm_perm2str(uint_t, char *); 1536b9e797cSsowmini 154da14cebeSEric Cheng struct prop_desc { 155d62bc4baSyz147064 /* 156d62bc4baSyz147064 * link property name 157d62bc4baSyz147064 */ 158f4b3ec61Sdh155122 char *pd_name; 159d62bc4baSyz147064 160d62bc4baSyz147064 /* 161d62bc4baSyz147064 * default property value, can be set to { "", NULL } 162d62bc4baSyz147064 */ 163f4b3ec61Sdh155122 val_desc_t pd_defval; 164d62bc4baSyz147064 165d62bc4baSyz147064 /* 166d62bc4baSyz147064 * list of optional property values, can be NULL. 167d62bc4baSyz147064 * 168d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 169d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 170d62bc4baSyz147064 */ 171d62bc4baSyz147064 val_desc_t *pd_optval; 172d62bc4baSyz147064 173d62bc4baSyz147064 /* 174d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 175d62bc4baSyz147064 */ 176d62bc4baSyz147064 uint_t pd_noptval; 177d62bc4baSyz147064 178d62bc4baSyz147064 /* 179d62bc4baSyz147064 * callback to set link property; 180d62bc4baSyz147064 * set to NULL if this property is read-only 181d62bc4baSyz147064 */ 182f4b3ec61Sdh155122 pd_setf_t *pd_set; 183d62bc4baSyz147064 184d62bc4baSyz147064 /* 185d62bc4baSyz147064 * callback to get modifiable link property 186d62bc4baSyz147064 */ 187f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 188d62bc4baSyz147064 189d62bc4baSyz147064 /* 190d62bc4baSyz147064 * callback to get current link property 191d62bc4baSyz147064 */ 192f4b3ec61Sdh155122 pd_getf_t *pd_get; 193d62bc4baSyz147064 194d62bc4baSyz147064 /* 195d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 196d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 197d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 198d62bc4baSyz147064 * valid. 199d62bc4baSyz147064 */ 200f4b3ec61Sdh155122 pd_checkf_t *pd_check; 201d62bc4baSyz147064 202d62bc4baSyz147064 uint_t pd_flags; 203e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 204e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 205d62bc4baSyz147064 /* 206d62bc4baSyz147064 * indicate link classes this property applies to. 207d62bc4baSyz147064 */ 208d62bc4baSyz147064 datalink_class_t pd_class; 209d62bc4baSyz147064 210d62bc4baSyz147064 /* 211d62bc4baSyz147064 * indicate link media type this property applies to. 212d62bc4baSyz147064 */ 213d62bc4baSyz147064 datalink_media_t pd_dmedia; 214da14cebeSEric Cheng }; 215f4b3ec61Sdh155122 2163fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 217e7801d59Ssowmini 218bcb5c89dSSowmini Varadhan /* 219bcb5c89dSSowmini Varadhan * Supported link properties enumerated in the prop_table[] array are 220bcb5c89dSSowmini Varadhan * computed using the callback functions in that array. To compute the 221bcb5c89dSSowmini Varadhan * property value, multiple distinct system calls may be needed (e.g., 222bcb5c89dSSowmini Varadhan * for wifi speed, we need to issue system calls to get desired/supported 223bcb5c89dSSowmini Varadhan * rates). The link_attr[] table enumerates the interfaces to the kernel, 224bcb5c89dSSowmini Varadhan * and the type/size of the data passed in the user-kernel interface. 225bcb5c89dSSowmini Varadhan */ 226bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = { 227bcb5c89dSSowmini Varadhan { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 228e7801d59Ssowmini 229bcb5c89dSSowmini Varadhan { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 230e7801d59Ssowmini 231bcb5c89dSSowmini Varadhan { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 232e7801d59Ssowmini 233bcb5c89dSSowmini Varadhan { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 234e7801d59Ssowmini 235bcb5c89dSSowmini Varadhan { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 236e7801d59Ssowmini 237bcb5c89dSSowmini Varadhan { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 238e7801d59Ssowmini 239bcb5c89dSSowmini Varadhan { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 240e7801d59Ssowmini 241bcb5c89dSSowmini Varadhan { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2423bc21d0aSAruna Ramakrishna - Sun Microsystems 243bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2443bc21d0aSAruna Ramakrishna - Sun Microsystems 245bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 246e7801d59Ssowmini 247bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 248e7801d59Ssowmini 249bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 250e7801d59Ssowmini 251bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 252e7801d59Ssowmini 253bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 254e7801d59Ssowmini 255bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 256e7801d59Ssowmini 257bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 258e7801d59Ssowmini 259bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 260e7801d59Ssowmini 261bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 262e7801d59Ssowmini 263bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 264e7801d59Ssowmini 265bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 266e7801d59Ssowmini 267bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 268e7801d59Ssowmini 269bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 270bcb5c89dSSowmini Varadhan 271bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 272bcb5c89dSSowmini Varadhan 273bcb5c89dSSowmini Varadhan { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 274bcb5c89dSSowmini Varadhan 275bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 276bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 277bcb5c89dSSowmini Varadhan 278bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 279bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 280bcb5c89dSSowmini Varadhan 281bcb5c89dSSowmini Varadhan { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 282bcb5c89dSSowmini Varadhan 283bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 284bcb5c89dSSowmini Varadhan 285bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 286bcb5c89dSSowmini Varadhan 287bcb5c89dSSowmini Varadhan { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 288bcb5c89dSSowmini Varadhan 289bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 290bcb5c89dSSowmini Varadhan 291bcb5c89dSSowmini Varadhan { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 292bcb5c89dSSowmini Varadhan 293bcb5c89dSSowmini Varadhan /* wl_wpa_ess_t has variable length */ 294bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 295bcb5c89dSSowmini Varadhan 296bcb5c89dSSowmini Varadhan { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 297bcb5c89dSSowmini Varadhan 298bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 299bcb5c89dSSowmini Varadhan 300bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 301bcb5c89dSSowmini Varadhan 302bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 303bcb5c89dSSowmini Varadhan 304bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 305bcb5c89dSSowmini Varadhan 306bcb5c89dSSowmini Varadhan /* wl_wpa_ie_t has variable length */ 307bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 308bcb5c89dSSowmini Varadhan 309bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 310bcb5c89dSSowmini Varadhan 311bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 312bcb5c89dSSowmini Varadhan 313bcb5c89dSSowmini Varadhan { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 314bcb5c89dSSowmini Varadhan 315da14cebeSEric Cheng { MAC_PROP_MAXBW, sizeof (mac_resource_props_t), "maxbw"}, 316da14cebeSEric Cheng 317da14cebeSEric Cheng { MAC_PROP_PRIO, sizeof (mac_resource_props_t), "priority"}, 318da14cebeSEric Cheng 319da14cebeSEric Cheng { MAC_PROP_BIND_CPU, sizeof (mac_resource_props_t), "cpus"}, 320da14cebeSEric Cheng 321bcb5c89dSSowmini Varadhan { MAC_PROP_PRIVATE, 0, "driver-private"} 322da14cebeSEric Cheng 323e7801d59Ssowmini }; 324e7801d59Ssowmini 325e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 326e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 327e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 328e7801d59Ssowmini }; 329e7801d59Ssowmini static val_desc_t link_status_vals[] = { 330e7801d59Ssowmini { "up", LINK_STATE_UP }, 331e7801d59Ssowmini { "down", LINK_STATE_DOWN } 332e7801d59Ssowmini }; 333e7801d59Ssowmini static val_desc_t link_01_vals[] = { 334e7801d59Ssowmini { "1", 1 }, 335e7801d59Ssowmini { "0", 0 } 336e7801d59Ssowmini }; 337e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 338e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 339e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 340e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 341e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 342e7801d59Ssowmini }; 343da14cebeSEric Cheng static val_desc_t link_priority_vals[] = { 344da14cebeSEric Cheng { "low", MPL_LOW }, 345da14cebeSEric Cheng { "medium", MPL_MEDIUM }, 346da14cebeSEric Cheng { "high", MPL_HIGH } 347da14cebeSEric Cheng }; 348e7801d59Ssowmini 349d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 350d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 351d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 352d62bc4baSyz147064 }; 353d62bc4baSyz147064 354d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 355d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 356d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 357d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 358d62bc4baSyz147064 }; 359d62bc4baSyz147064 360da14cebeSEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 361da14cebeSEric Cheng #define RESET_VAL ((uintptr_t)-1) 362d62bc4baSyz147064 363da14cebeSEric Cheng static prop_desc_t prop_table[] = { 364e7801d59Ssowmini { "channel", { NULL, 0 }, 365e7801d59Ssowmini NULL, 0, NULL, NULL, 366d62bc4baSyz147064 do_get_channel_prop, NULL, 0, 367d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 368d62bc4baSyz147064 369d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 370d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 371d62bc4baSyz147064 do_set_powermode_prop, NULL, 372d62bc4baSyz147064 do_get_powermode_prop, NULL, 0, 373d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 374d62bc4baSyz147064 375d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 376d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 377d62bc4baSyz147064 do_set_radio_prop, NULL, 378d62bc4baSyz147064 do_get_radio_prop, NULL, 0, 379d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 380d62bc4baSyz147064 381d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 382d62bc4baSyz147064 do_set_rate_prop, do_get_rate_mod, 383d62bc4baSyz147064 do_get_rate_prop, do_check_rate, 0, 3846b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 385d62bc4baSyz147064 3864045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 3873bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, 3883bc21d0aSAruna Ramakrishna - Sun Microsystems do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 389d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 390d62bc4baSyz147064 3914045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 392f4b3ec61Sdh155122 do_set_zone, NULL, 3933bc21d0aSAruna Ramakrishna - Sun Microsystems do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 394e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 395e7801d59Ssowmini 3964045d941Ssowmini { "duplex", { "", 0 }, 397e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 3983bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_duplex_get, NULL, 399e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 400e7801d59Ssowmini 4016b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 402e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 4033bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_status_get, NULL, 4044045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 405e7801d59Ssowmini 406e7801d59Ssowmini { "adv_autoneg_cap", { "1", 1 }, 407e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4083bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 409e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 410e7801d59Ssowmini 4114045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 4123bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 4133bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_defmtu_check, 0, DATALINK_CLASS_ALL, 4143bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 415e7801d59Ssowmini 4164045d941Ssowmini { "flowctrl", { "", 0 }, 417e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 4183bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 419e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 420e7801d59Ssowmini 4214045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 4224045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 4233bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 424e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 425e7801d59Ssowmini 4264045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 427e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4283bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 429e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 430e7801d59Ssowmini 4314045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 432e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4333bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 434e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 435e7801d59Ssowmini 4364045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 437e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4383bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 439e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 440e7801d59Ssowmini 4414045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 442e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4433bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 444e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 445e7801d59Ssowmini 4464045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 447e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4483bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 449e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 450e7801d59Ssowmini 4514045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 452e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4533bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 454e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 455e7801d59Ssowmini 4564045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 457e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4583bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 459e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 460e7801d59Ssowmini 4614045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 462e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4633bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 464e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 465e7801d59Ssowmini 4664045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 467e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4683bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 469e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 470e7801d59Ssowmini 4714045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 472e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4733bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 474e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 475e7801d59Ssowmini 4764045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 477e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4783bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 479da14cebeSEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 480e7801d59Ssowmini 481da14cebeSEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 482da14cebeSEric Cheng do_set_res, NULL, 483da14cebeSEric Cheng dld_maxbw_get, do_check_maxbw, PD_CHECK_ALLOC, 484da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 485da14cebeSEric Cheng 486da14cebeSEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 487da14cebeSEric Cheng do_set_cpus, NULL, 488da14cebeSEric Cheng dld_cpus_get, do_check_cpus, 0, 489da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 490da14cebeSEric Cheng 491da14cebeSEric Cheng { "priority", { "high", RESET_VAL }, 492da14cebeSEric Cheng link_priority_vals, VALCNT(link_priority_vals), do_set_res, NULL, 493da14cebeSEric Cheng dld_priority_get, do_check_priority, PD_CHECK_ALLOC, 494da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 495f4b3ec61Sdh155122 }; 496f4b3ec61Sdh155122 497d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 4980ba2cbe9Sxc151355 499da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 500da14cebeSEric Cheng {"maxbw", do_extract_maxbw}, 501da14cebeSEric Cheng {"priority", do_extract_priority}, 502da14cebeSEric Cheng {"cpus", do_extract_cpus} 503da14cebeSEric Cheng }; 504da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 505da14cebeSEric Cheng sizeof (resource_prop_t)) 506da14cebeSEric Cheng 507bcb5c89dSSowmini Varadhan /* 508bcb5c89dSSowmini Varadhan * when retrieving private properties, we pass down a buffer with 509bcb5c89dSSowmini Varadhan * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 510bcb5c89dSSowmini Varadhan */ 511bcb5c89dSSowmini Varadhan #define DLADM_PROP_BUF_CHUNK 1024 512bcb5c89dSSowmini Varadhan 513*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 514*4ac67f02SAnurag S. Maskey const char *, char **, uint_t); 515*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 516*4ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 517*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 518*4ac67f02SAnurag S. Maskey datalink_class_t, uint32_t, prop_desc_t *, char **, 519*4ac67f02SAnurag S. Maskey uint_t, uint_t); 520*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 521*4ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 522*4ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 523*4ac67f02SAnurag S. Maskey datalink_id_t, datalink_media_t, uint_t); 524da14cebeSEric Cheng 525da14cebeSEric Cheng static dladm_status_t link_proplist_check(dladm_arg_list_t *); 526da14cebeSEric Cheng 527d62bc4baSyz147064 /* 528d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 529d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 530d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 531d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 532d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 533d62bc4baSyz147064 */ 534d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 535d62bc4baSyz147064 536d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 537d62bc4baSyz147064 #define AP_DELIMITER '.' 538d62bc4baSyz147064 539d62bc4baSyz147064 static dladm_status_t 540d62bc4baSyz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 541d62bc4baSyz147064 val_desc_t *vdp) 5420ba2cbe9Sxc151355 { 543d62bc4baSyz147064 int i, j; 5440ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 5450ba2cbe9Sxc151355 546d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 547d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 548d62bc4baSyz147064 if (strcasecmp(*prop_val, 549d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 5500ba2cbe9Sxc151355 break; 5510ba2cbe9Sxc151355 } 5520ba2cbe9Sxc151355 } 553d62bc4baSyz147064 if (i == pdp->pd_noptval) { 554d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 555d62bc4baSyz147064 goto done; 556d62bc4baSyz147064 } 557d62bc4baSyz147064 (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); 5580ba2cbe9Sxc151355 } 5590ba2cbe9Sxc151355 560d62bc4baSyz147064 done: 561d62bc4baSyz147064 return (status); 5620ba2cbe9Sxc151355 } 5630ba2cbe9Sxc151355 5640ba2cbe9Sxc151355 static dladm_status_t 565*4ac67f02SAnurag S. Maskey i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 566*4ac67f02SAnurag S. Maskey datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 567*4ac67f02SAnurag S. Maskey uint_t val_cnt, uint_t flags) 5680ba2cbe9Sxc151355 { 5690ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 570d62bc4baSyz147064 val_desc_t *vdp = NULL; 571d62bc4baSyz147064 boolean_t needfree = B_FALSE; 572d62bc4baSyz147064 uint_t cnt, i; 5730ba2cbe9Sxc151355 574d62bc4baSyz147064 if (!(pdp->pd_class & class)) 575d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 5760ba2cbe9Sxc151355 577d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 578d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 579d62bc4baSyz147064 580d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 581d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 582d62bc4baSyz147064 583d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 584d62bc4baSyz147064 return (DLADM_STATUS_OK); 585d62bc4baSyz147064 586d62bc4baSyz147064 if (pdp->pd_set == NULL) 587d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 588d62bc4baSyz147064 589d62bc4baSyz147064 if (prop_val != NULL) { 590d62bc4baSyz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 591d62bc4baSyz147064 if (vdp == NULL) 592d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 593d62bc4baSyz147064 594d62bc4baSyz147064 if (pdp->pd_check != NULL) { 595da14cebeSEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 596*4ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, prop_val, 597*4ac67f02SAnurag S. Maskey val_cnt, vdp, media); 598d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 599d62bc4baSyz147064 status = do_check_prop(pdp, prop_val, val_cnt, vdp); 600d62bc4baSyz147064 } else { 601d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 6020ba2cbe9Sxc151355 } 6030ba2cbe9Sxc151355 604d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 605d62bc4baSyz147064 goto done; 606d62bc4baSyz147064 607d62bc4baSyz147064 cnt = val_cnt; 608d62bc4baSyz147064 } else { 609da14cebeSEric Cheng boolean_t defval = B_FALSE; 610da14cebeSEric Cheng 611d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 612d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 613d62bc4baSyz147064 6143bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 615da14cebeSEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 616da14cebeSEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 617d62bc4baSyz147064 if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 618d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 6193bc21d0aSAruna Ramakrishna - Sun Microsystems 620da14cebeSEric Cheng if (defval) { 621da14cebeSEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 622da14cebeSEric Cheng sizeof (val_desc_t)); 623da14cebeSEric Cheng } else if (pdp->pd_check != NULL) { 624*4ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, 625*4ac67f02SAnurag S. Maskey prop_val, cnt, vdp, media); 6263bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 6273bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 6283bc21d0aSAruna Ramakrishna - Sun Microsystems } 6294045d941Ssowmini } else { 630*4ac67f02SAnurag S. Maskey status = i_dladm_getset_defval(handle, pdp, linkid, 6314045d941Ssowmini media, flags); 6324045d941Ssowmini return (status); 6334045d941Ssowmini } 634d62bc4baSyz147064 } 635*4ac67f02SAnurag S. Maskey status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, media); 636d62bc4baSyz147064 if (needfree) { 637d62bc4baSyz147064 for (i = 0; i < cnt; i++) 638e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 639d62bc4baSyz147064 } 640d62bc4baSyz147064 done: 641d62bc4baSyz147064 free(vdp); 642d62bc4baSyz147064 return (status); 643d62bc4baSyz147064 } 644d62bc4baSyz147064 645d62bc4baSyz147064 static dladm_status_t 646*4ac67f02SAnurag S. Maskey i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 647*4ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 648d62bc4baSyz147064 { 649d62bc4baSyz147064 int i; 650d62bc4baSyz147064 boolean_t found = B_FALSE; 651d62bc4baSyz147064 datalink_class_t class; 652d62bc4baSyz147064 uint32_t media; 653d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 654d62bc4baSyz147064 655*4ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 656*4ac67f02SAnurag S. Maskey NULL, 0); 657d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 6580ba2cbe9Sxc151355 return (status); 6590ba2cbe9Sxc151355 660d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 661d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 662d62bc4baSyz147064 dladm_status_t s; 6630ba2cbe9Sxc151355 664d62bc4baSyz147064 if (prop_name != NULL && 665d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 666d62bc4baSyz147064 continue; 667d62bc4baSyz147064 found = B_TRUE; 668*4ac67f02SAnurag S. Maskey s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 669*4ac67f02SAnurag S. Maskey prop_val, val_cnt, flags); 670d62bc4baSyz147064 671d62bc4baSyz147064 if (prop_name != NULL) { 672d62bc4baSyz147064 status = s; 673d62bc4baSyz147064 break; 674d62bc4baSyz147064 } else { 675d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 676d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 677d62bc4baSyz147064 status = s; 678d62bc4baSyz147064 } 679d62bc4baSyz147064 } 680e7801d59Ssowmini if (!found) { 681e7801d59Ssowmini if (prop_name[0] == '_') { 682e7801d59Ssowmini /* other private properties */ 683*4ac67f02SAnurag S. Maskey status = i_dladm_set_prop(handle, linkid, prop_name, 684*4ac67f02SAnurag S. Maskey prop_val, val_cnt, flags); 685e7801d59Ssowmini } else { 6860ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 687e7801d59Ssowmini } 688e7801d59Ssowmini } 6890ba2cbe9Sxc151355 6900ba2cbe9Sxc151355 return (status); 6910ba2cbe9Sxc151355 } 6920ba2cbe9Sxc151355 693d62bc4baSyz147064 /* 694d62bc4baSyz147064 * Set/reset link property for specific link 695d62bc4baSyz147064 */ 696d62bc4baSyz147064 dladm_status_t 697*4ac67f02SAnurag S. Maskey dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 698*4ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 6990ba2cbe9Sxc151355 { 700d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 7010ba2cbe9Sxc151355 702d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 703d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 704d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 705d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 706d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 7070ba2cbe9Sxc151355 } 7080ba2cbe9Sxc151355 709*4ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 710d62bc4baSyz147064 val_cnt, flags); 711d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 712d62bc4baSyz147064 return (status); 713d62bc4baSyz147064 714d62bc4baSyz147064 if (flags & DLADM_OPT_PERSIST) { 715*4ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 716d62bc4baSyz147064 prop_val, val_cnt); 717d62bc4baSyz147064 } 718d62bc4baSyz147064 return (status); 719d62bc4baSyz147064 } 720d62bc4baSyz147064 721d62bc4baSyz147064 /* 722d62bc4baSyz147064 * Walk link properties of the given specific link. 723d62bc4baSyz147064 */ 724d62bc4baSyz147064 dladm_status_t 725*4ac67f02SAnurag S. Maskey dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 726*4ac67f02SAnurag S. Maskey int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 7270ba2cbe9Sxc151355 { 728d62bc4baSyz147064 dladm_status_t status; 729d62bc4baSyz147064 datalink_class_t class; 730d62bc4baSyz147064 uint_t media; 731d62bc4baSyz147064 int i; 7320ba2cbe9Sxc151355 733d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 734d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 7350ba2cbe9Sxc151355 736*4ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 737*4ac67f02SAnurag S. Maskey NULL, 0); 738d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 739d62bc4baSyz147064 return (status); 740d62bc4baSyz147064 741d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 742d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 743d62bc4baSyz147064 continue; 744d62bc4baSyz147064 745d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 746d62bc4baSyz147064 continue; 747d62bc4baSyz147064 748*4ac67f02SAnurag S. Maskey if (func(handle, linkid, prop_table[i].pd_name, arg) == 749d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 750d62bc4baSyz147064 break; 751d62bc4baSyz147064 } 752d62bc4baSyz147064 } 753d62bc4baSyz147064 754d62bc4baSyz147064 return (DLADM_STATUS_OK); 755d62bc4baSyz147064 } 756d62bc4baSyz147064 757d62bc4baSyz147064 /* 758d62bc4baSyz147064 * Get linkprop of the given specific link. 759d62bc4baSyz147064 */ 760d62bc4baSyz147064 dladm_status_t 761*4ac67f02SAnurag S. Maskey dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 762*4ac67f02SAnurag S. Maskey dladm_prop_type_t type, const char *prop_name, char **prop_val, 763*4ac67f02SAnurag S. Maskey uint_t *val_cntp) 764d62bc4baSyz147064 { 765d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 766d62bc4baSyz147064 datalink_class_t class; 767d62bc4baSyz147064 uint_t media; 768d62bc4baSyz147064 prop_desc_t *pdp; 7694045d941Ssowmini uint_t cnt, dld_flags = 0; 770d62bc4baSyz147064 int i; 771afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 772d62bc4baSyz147064 7734045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 7743fd94f8cSam223141 dld_flags = MAC_PROP_DEFAULT; 7754045d941Ssowmini 776d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 777d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 778d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 779d62bc4baSyz147064 780d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 781d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 782d62bc4baSyz147064 break; 783d62bc4baSyz147064 784e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 785e7801d59Ssowmini if (prop_name[0] == '_') { 786e7801d59Ssowmini /* 787e7801d59Ssowmini * private property. 788e7801d59Ssowmini */ 789*4ac67f02SAnurag S. Maskey return (i_dladm_get_prop(handle, linkid, prop_name, 7904045d941Ssowmini prop_val, val_cntp, type, dld_flags)); 791e7801d59Ssowmini } else { 792d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 793e7801d59Ssowmini } 794e7801d59Ssowmini } 795d62bc4baSyz147064 796d62bc4baSyz147064 pdp = &prop_table[i]; 797d62bc4baSyz147064 798*4ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 799*4ac67f02SAnurag S. Maskey NULL, 0); 800d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 801d62bc4baSyz147064 return (status); 802d62bc4baSyz147064 803d62bc4baSyz147064 if (!(pdp->pd_class & class)) 804d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 805d62bc4baSyz147064 806d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 807d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 808d62bc4baSyz147064 809d62bc4baSyz147064 switch (type) { 810d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 811*4ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 812*4ac67f02SAnurag S. Maskey media, dld_flags, &perm_flags); 813afdda45fSVasumathi Sundaram - Sun Microsystems break; 814afdda45fSVasumathi Sundaram - Sun Microsystems 815afdda45fSVasumathi Sundaram - Sun Microsystems case DLADM_PROP_VAL_PERM: 816afdda45fSVasumathi Sundaram - Sun Microsystems if (pdp->pd_set == NULL) { 817afdda45fSVasumathi Sundaram - Sun Microsystems perm_flags = MAC_PROP_PERM_READ; 818afdda45fSVasumathi Sundaram - Sun Microsystems *val_cntp = 1; 819afdda45fSVasumathi Sundaram - Sun Microsystems } else { 820*4ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 821*4ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 822afdda45fSVasumathi Sundaram - Sun Microsystems } 823afdda45fSVasumathi Sundaram - Sun Microsystems 824afdda45fSVasumathi Sundaram - Sun Microsystems *prop_val[0] = '\0'; 825da14cebeSEric Cheng if (status == DLADM_STATUS_OK) 826da14cebeSEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 827d62bc4baSyz147064 break; 828d62bc4baSyz147064 829d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 83013a55820Sar224390 /* 83113a55820Sar224390 * If defaults are not defined for the property, 83213a55820Sar224390 * pd_defval.vd_name should be null. If the driver 83313a55820Sar224390 * has to be contacted for the value, vd_name should 83413a55820Sar224390 * be the empty string (""). Otherwise, dladm will 83513a55820Sar224390 * just print whatever is in the table. 83613a55820Sar224390 */ 837d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 838d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 839d62bc4baSyz147064 break; 840d62bc4baSyz147064 } 8414045d941Ssowmini 8424045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 843*4ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 844*4ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 8454045d941Ssowmini } else { 846d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 8474045d941Ssowmini } 848d62bc4baSyz147064 *val_cntp = 1; 849d62bc4baSyz147064 break; 850d62bc4baSyz147064 851d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 852d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 853*4ac67f02SAnurag S. Maskey status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 854afdda45fSVasumathi Sundaram - Sun Microsystems val_cntp, media, dld_flags, &perm_flags); 855d62bc4baSyz147064 break; 856d62bc4baSyz147064 } 857d62bc4baSyz147064 cnt = pdp->pd_noptval; 858d62bc4baSyz147064 if (cnt == 0) { 859d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 860d62bc4baSyz147064 } else if (cnt > *val_cntp) { 861d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 862d62bc4baSyz147064 } else { 863d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 864d62bc4baSyz147064 (void) strcpy(prop_val[i], 865d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 866d62bc4baSyz147064 } 867d62bc4baSyz147064 *val_cntp = cnt; 868d62bc4baSyz147064 } 869d62bc4baSyz147064 break; 870d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 871d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 872d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 873*4ac67f02SAnurag S. Maskey status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 874d62bc4baSyz147064 prop_val, val_cntp); 875d62bc4baSyz147064 break; 876d62bc4baSyz147064 default: 877d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 878d62bc4baSyz147064 break; 879d62bc4baSyz147064 } 880d62bc4baSyz147064 881d62bc4baSyz147064 return (status); 882d62bc4baSyz147064 } 883d62bc4baSyz147064 884d62bc4baSyz147064 /*ARGSUSED*/ 885d62bc4baSyz147064 static int 886*4ac67f02SAnurag S. Maskey i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 887*4ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 888d62bc4baSyz147064 { 889d62bc4baSyz147064 char *buf, **propvals; 890d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 891d62bc4baSyz147064 892d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 893d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 894d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 895d62bc4baSyz147064 } 896d62bc4baSyz147064 897d62bc4baSyz147064 propvals = (char **)(void *)buf; 898d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 899d62bc4baSyz147064 propvals[i] = buf + 900d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 901d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 902d62bc4baSyz147064 } 903d62bc4baSyz147064 904*4ac67f02SAnurag S. Maskey if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 905*4ac67f02SAnurag S. Maskey prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 906d62bc4baSyz147064 goto done; 907d62bc4baSyz147064 } 908d62bc4baSyz147064 909*4ac67f02SAnurag S. Maskey (void) dladm_set_linkprop(handle, linkid, prop_name, propvals, valcnt, 910d62bc4baSyz147064 DLADM_OPT_ACTIVE); 911d62bc4baSyz147064 912d62bc4baSyz147064 done: 913d62bc4baSyz147064 if (buf != NULL) 914d62bc4baSyz147064 free(buf); 915d62bc4baSyz147064 916d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 917d62bc4baSyz147064 } 918d62bc4baSyz147064 919d62bc4baSyz147064 /*ARGSUSED*/ 920d62bc4baSyz147064 static int 921*4ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 922d62bc4baSyz147064 { 923da14cebeSEric Cheng datalink_class_t class; 924da14cebeSEric Cheng dladm_status_t status; 925da14cebeSEric Cheng 926*4ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 927*4ac67f02SAnurag S. Maskey NULL, 0); 928da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 929da14cebeSEric Cheng return (DLADM_WALK_TERMINATE); 930da14cebeSEric Cheng 931da14cebeSEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 932*4ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, B_TRUE); 933da14cebeSEric Cheng 934d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 9350ba2cbe9Sxc151355 } 9360ba2cbe9Sxc151355 9370ba2cbe9Sxc151355 dladm_status_t 938*4ac67f02SAnurag S. Maskey dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 939*4ac67f02SAnurag S. Maskey boolean_t any_media) 9400ba2cbe9Sxc151355 { 94130890389Sartem datalink_media_t dmedia; 94230890389Sartem uint32_t media; 94330890389Sartem 94430890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 94530890389Sartem 946d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 947*4ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 948*4ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 949*4ac67f02SAnurag S. Maskey } else if (any_media || 950*4ac67f02SAnurag S. Maskey ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 951*4ac67f02SAnurag S. Maskey 0) == DLADM_STATUS_OK) && 95230890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 953*4ac67f02SAnurag S. Maskey (void) dladm_walk_linkprop(handle, linkid, NULL, 954*4ac67f02SAnurag S. Maskey i_dladm_init_one_prop); 955d62bc4baSyz147064 } 956d62bc4baSyz147064 return (DLADM_STATUS_OK); 9570ba2cbe9Sxc151355 } 958f4b3ec61Sdh155122 959e7801d59Ssowmini /* ARGSUSED */ 960f4b3ec61Sdh155122 static dladm_status_t 961*4ac67f02SAnurag S. Maskey do_get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 962da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 963da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 964f4b3ec61Sdh155122 { 965d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 966d62bc4baSyz147064 zoneid_t zid; 967d62bc4baSyz147064 dladm_status_t status; 9683bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 9693bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 970f4b3ec61Sdh155122 9714045d941Ssowmini if (flags != 0) 9724045d941Ssowmini return (DLADM_STATUS_NOTSUP); 9734045d941Ssowmini 974*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 975da14cebeSEric Cheng &status, perm_flags); 976d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 977d62bc4baSyz147064 return (status); 978d62bc4baSyz147064 9793bc21d0aSAruna Ramakrishna - Sun Microsystems cp = dip->pr_val; 9803bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&zid, cp, sizeof (zid)); 9813bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 9823bc21d0aSAruna Ramakrishna - Sun Microsystems 983d62bc4baSyz147064 *val_cnt = 1; 984d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 985afdda45fSVasumathi Sundaram - Sun Microsystems if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 986f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 987afdda45fSVasumathi Sundaram - Sun Microsystems } 988f4b3ec61Sdh155122 989d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 99047a01978Sbw } else { 991d62bc4baSyz147064 *prop_val[0] = '\0'; 99247a01978Sbw } 993f4b3ec61Sdh155122 994f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 995f4b3ec61Sdh155122 } 996f4b3ec61Sdh155122 997f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 998f4b3ec61Sdh155122 999f4b3ec61Sdh155122 static int 1000f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 1001f4b3ec61Sdh155122 { 1002f4b3ec61Sdh155122 char root[MAXPATHLEN]; 1003f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 1004f4b3ec61Sdh155122 void *dlhandle; 1005f4b3ec61Sdh155122 void *sym; 1006f4b3ec61Sdh155122 int ret; 1007f4b3ec61Sdh155122 1008f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 1009f4b3ec61Sdh155122 return (-1); 1010f4b3ec61Sdh155122 1011f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 1012f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1013f4b3ec61Sdh155122 return (-1); 1014f4b3ec61Sdh155122 } 1015f4b3ec61Sdh155122 1016f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 1017f4b3ec61Sdh155122 1018f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 1019f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 1020f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1021f4b3ec61Sdh155122 return (ret); 1022f4b3ec61Sdh155122 } 1023f4b3ec61Sdh155122 1024f4b3ec61Sdh155122 static dladm_status_t 1025*4ac67f02SAnurag S. Maskey i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 1026*4ac67f02SAnurag S. Maskey datalink_id_t linkid, boolean_t add) 1027f4b3ec61Sdh155122 { 1028f4b3ec61Sdh155122 char path[MAXPATHLEN]; 1029d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1030f4b3ec61Sdh155122 di_prof_t prof = NULL; 1031f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 1032f4b3ec61Sdh155122 dladm_status_t status; 1033d62bc4baSyz147064 int ret; 1034f4b3ec61Sdh155122 1035f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 1036f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1037f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 1038f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1039f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 1040f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1041f4b3ec61Sdh155122 1042*4ac67f02SAnurag S. Maskey status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 1043f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1044d62bc4baSyz147064 goto cleanup; 1045f4b3ec61Sdh155122 1046d62bc4baSyz147064 if (add) 1047d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 1048d62bc4baSyz147064 else 1049d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 1050f4b3ec61Sdh155122 1051d62bc4baSyz147064 if (ret != 0) { 1052d62bc4baSyz147064 status = dladm_errno2status(errno); 1053d62bc4baSyz147064 goto cleanup; 1054f4b3ec61Sdh155122 } 1055f4b3ec61Sdh155122 1056d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 1057d62bc4baSyz147064 status = dladm_errno2status(errno); 1058d62bc4baSyz147064 cleanup: 1059d62bc4baSyz147064 if (prof) 1060d62bc4baSyz147064 di_prof_fini(prof); 1061d62bc4baSyz147064 1062d62bc4baSyz147064 return (status); 1063f4b3ec61Sdh155122 } 1064f4b3ec61Sdh155122 1065e7801d59Ssowmini /* ARGSUSED */ 1066f4b3ec61Sdh155122 static dladm_status_t 1067*4ac67f02SAnurag S. Maskey do_set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1068*4ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1069f4b3ec61Sdh155122 { 10703bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1071f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 1072d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 10733bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 10743bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 10753bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1076f4b3ec61Sdh155122 1077f4b3ec61Sdh155122 if (val_cnt != 1) 1078f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1079f4b3ec61Sdh155122 10803bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 10813bc21d0aSAruna Ramakrishna - Sun Microsystems 1082*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1083da14cebeSEric Cheng &status, NULL); 1084f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1085f4b3ec61Sdh155122 return (status); 1086f4b3ec61Sdh155122 10873bc21d0aSAruna Ramakrishna - Sun Microsystems cp = dip->pr_val; 10883bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&zid_old, cp, sizeof (zid_old)); 10893bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 1090f4b3ec61Sdh155122 10913bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 10923bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN); 10933bc21d0aSAruna Ramakrishna - Sun Microsystems 10943bc21d0aSAruna Ramakrishna - Sun Microsystems /* Do nothing if setting to current value */ 10953bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 10963bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 10973bc21d0aSAruna Ramakrishna - Sun Microsystems 1098d62bc4baSyz147064 if (zid_new != GLOBAL_ZONEID) { 1099d62bc4baSyz147064 /* 1100d62bc4baSyz147064 * If the new zoneid is the global zone, we could destroy 1101d62bc4baSyz147064 * the link (in the case of an implicitly-created VLAN) as a 11023bc21d0aSAruna Ramakrishna - Sun Microsystems * result of setting the zoneid. In that case, we defer the 11033bc21d0aSAruna Ramakrishna - Sun Microsystems * operation to the end of this function to avoid recreating 11043bc21d0aSAruna Ramakrishna - Sun Microsystems * the VLAN and getting a different linkid during the rollback 11053bc21d0aSAruna Ramakrishna - Sun Microsystems * if other operation fails. 1106d62bc4baSyz147064 * 11073bc21d0aSAruna Ramakrishna - Sun Microsystems * Otherwise, this operation will hold a reference to the 1108d62bc4baSyz147064 * link and prevent a link renaming, so we need to do it 1109d62bc4baSyz147064 * before other operations. 1110d62bc4baSyz147064 */ 1111*4ac67f02SAnurag S. Maskey status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, 1112*4ac67f02SAnurag S. Maskey val_cnt, flags, media); 1113d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1114d62bc4baSyz147064 return (status); 1115d62bc4baSyz147064 } 1116d62bc4baSyz147064 1117d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 1118d62bc4baSyz147064 if (zone_remove_datalink(zid_old, link) != 0 && 1119f4b3ec61Sdh155122 errno != ENXIO) { 1120f4b3ec61Sdh155122 status = dladm_errno2status(errno); 1121f4b3ec61Sdh155122 goto rollback1; 1122f4b3ec61Sdh155122 } 1123f4b3ec61Sdh155122 1124d62bc4baSyz147064 /* 1125d62bc4baSyz147064 * It is okay to fail to update the /dev entry (some 1126d62bc4baSyz147064 * vanity-named links do not have a /dev entry). 1127d62bc4baSyz147064 */ 1128*4ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_old, linkid, 1129*4ac67f02SAnurag S. Maskey B_FALSE); 1130d62bc4baSyz147064 } 1131d62bc4baSyz147064 1132d62bc4baSyz147064 if (zid_new != GLOBAL_ZONEID) { 1133d62bc4baSyz147064 if (zone_add_datalink(zid_new, link) != 0) { 1134d62bc4baSyz147064 status = dladm_errno2status(errno); 1135d62bc4baSyz147064 goto rollback2; 1136d62bc4baSyz147064 } 1137d62bc4baSyz147064 1138*4ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 1139d62bc4baSyz147064 } else { 1140*4ac67f02SAnurag S. Maskey status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, 1141*4ac67f02SAnurag S. Maskey val_cnt, flags, media); 1142f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1143f4b3ec61Sdh155122 goto rollback2; 1144f4b3ec61Sdh155122 } 1145f4b3ec61Sdh155122 1146f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1147f4b3ec61Sdh155122 1148f4b3ec61Sdh155122 rollback2: 1149f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 1150*4ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_old, linkid, B_TRUE); 1151d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) 1152d62bc4baSyz147064 (void) zone_add_datalink(zid_old, link); 1153f4b3ec61Sdh155122 rollback1: 11543bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new != GLOBAL_ZONEID) { 11553bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zid_old; 1156*4ac67f02SAnurag S. Maskey (void) i_dladm_set_public_prop(handle, pdp, linkid, vdp, 1157*4ac67f02SAnurag S. Maskey val_cnt, flags, media); 11583bc21d0aSAruna Ramakrishna - Sun Microsystems } 11593bc21d0aSAruna Ramakrishna - Sun Microsystems 1160f4b3ec61Sdh155122 return (status); 1161f4b3ec61Sdh155122 } 1162f4b3ec61Sdh155122 1163f4b3ec61Sdh155122 /* ARGSUSED */ 1164f4b3ec61Sdh155122 static dladm_status_t 1165*4ac67f02SAnurag S. Maskey do_check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1166*4ac67f02SAnurag S. Maskey char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1167f4b3ec61Sdh155122 { 11683bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 11693bc21d0aSAruna Ramakrishna - Sun Microsystems char linkname[MAXLINKNAMELEN]; 11703bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 11713bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 11723bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1173f4b3ec61Sdh155122 1174f4b3ec61Sdh155122 if (val_cnt != 1) 1175f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1176f4b3ec61Sdh155122 11773bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 11783bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 11793bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1180f4b3ec61Sdh155122 1181*4ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL, 11823bc21d0aSAruna Ramakrishna - Sun Microsystems linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 11833bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 11843bc21d0aSAruna Ramakrishna - Sun Microsystems } 11853bc21d0aSAruna Ramakrishna - Sun Microsystems 1186da14cebeSEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 11873bc21d0aSAruna Ramakrishna - Sun Microsystems if (strlen(linkname) > MAXLINKNAMELEN) { 11883bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 11893bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 11903bc21d0aSAruna Ramakrishna - Sun Microsystems } 11913bc21d0aSAruna Ramakrishna - Sun Microsystems 11923bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 11933bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 11943bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 11953bc21d0aSAruna Ramakrishna - Sun Microsystems } 11963bc21d0aSAruna Ramakrishna - Sun Microsystems 11973bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1198f4b3ec61Sdh155122 ushort_t flags; 1199f4b3ec61Sdh155122 12003bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1201f4b3ec61Sdh155122 sizeof (flags)) < 0) { 12023bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 12033bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1204f4b3ec61Sdh155122 } 1205f4b3ec61Sdh155122 1206f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 12073bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 12083bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1209f4b3ec61Sdh155122 } 1210f4b3ec61Sdh155122 } 1211f4b3ec61Sdh155122 12123bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 12133bc21d0aSAruna Ramakrishna - Sun Microsystems 12143bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 12153bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN); 12163bc21d0aSAruna Ramakrishna - Sun Microsystems 12173bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1218f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 12193bc21d0aSAruna Ramakrishna - Sun Microsystems done: 12203bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 12213bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1222f4b3ec61Sdh155122 } 1223f4b3ec61Sdh155122 1224e7801d59Ssowmini /* ARGSUSED */ 1225f4b3ec61Sdh155122 static dladm_status_t 1226*4ac67f02SAnurag S. Maskey dld_maxbw_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1227da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1228da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1229da14cebeSEric Cheng { 1230da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1231da14cebeSEric Cheng mac_resource_props_t mrp; 1232da14cebeSEric Cheng dladm_status_t status; 1233da14cebeSEric Cheng 1234*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1235da14cebeSEric Cheng &status, perm_flags); 1236da14cebeSEric Cheng if (dip == NULL) 1237da14cebeSEric Cheng return (status); 1238da14cebeSEric Cheng 1239da14cebeSEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 1240da14cebeSEric Cheng free(dip); 1241da14cebeSEric Cheng 1242da14cebeSEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 1243da14cebeSEric Cheng (*prop_val)[0] = '\0'; 1244da14cebeSEric Cheng } else { 1245da14cebeSEric Cheng (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 1246da14cebeSEric Cheng } 1247da14cebeSEric Cheng *val_cnt = 1; 1248da14cebeSEric Cheng return (DLADM_STATUS_OK); 1249da14cebeSEric Cheng } 1250da14cebeSEric Cheng 1251da14cebeSEric Cheng /* ARGSUSED */ 1252da14cebeSEric Cheng static dladm_status_t 1253*4ac67f02SAnurag S. Maskey do_check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1254*4ac67f02SAnurag S. Maskey char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1255da14cebeSEric Cheng { 1256da14cebeSEric Cheng uint64_t *maxbw; 1257da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1258da14cebeSEric Cheng 1259da14cebeSEric Cheng if (val_cnt != 1) 1260da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1261da14cebeSEric Cheng 1262da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 1263da14cebeSEric Cheng if (maxbw == NULL) 1264da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1265da14cebeSEric Cheng 1266da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 1267da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1268da14cebeSEric Cheng free(maxbw); 1269da14cebeSEric Cheng return (status); 1270da14cebeSEric Cheng } 1271da14cebeSEric Cheng 1272da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 1273da14cebeSEric Cheng free(maxbw); 1274da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 1275da14cebeSEric Cheng } 1276da14cebeSEric Cheng 1277da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 1278da14cebeSEric Cheng return (DLADM_STATUS_OK); 1279da14cebeSEric Cheng } 1280da14cebeSEric Cheng 1281da14cebeSEric Cheng /* ARGSUSED */ 1282da14cebeSEric Cheng dladm_status_t 1283da14cebeSEric Cheng do_extract_maxbw(val_desc_t *vdp, void *arg, uint_t cnt) 1284da14cebeSEric Cheng { 1285da14cebeSEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1286da14cebeSEric Cheng 1287da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 1288da14cebeSEric Cheng mrp->mrp_mask |= MRP_MAXBW; 1289da14cebeSEric Cheng 1290da14cebeSEric Cheng return (DLADM_STATUS_OK); 1291da14cebeSEric Cheng } 1292da14cebeSEric Cheng 1293da14cebeSEric Cheng /* ARGSUSED */ 1294da14cebeSEric Cheng static dladm_status_t 1295*4ac67f02SAnurag S. Maskey dld_cpus_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1296da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1297da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1298da14cebeSEric Cheng { 1299da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1300da14cebeSEric Cheng mac_resource_props_t mrp; 1301da14cebeSEric Cheng int i; 1302da14cebeSEric Cheng uint32_t ncpus; 1303da14cebeSEric Cheng uchar_t *cp; 1304da14cebeSEric Cheng dladm_status_t status; 1305da14cebeSEric Cheng 1306*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1307da14cebeSEric Cheng &status, perm_flags); 1308da14cebeSEric Cheng if (dip == NULL) 1309da14cebeSEric Cheng return (status); 1310da14cebeSEric Cheng 1311da14cebeSEric Cheng cp = (uchar_t *)dip->pr_val; 1312da14cebeSEric Cheng (void) memcpy(&mrp, cp, sizeof (mac_resource_props_t)); 1313da14cebeSEric Cheng free(dip); 1314da14cebeSEric Cheng 1315da14cebeSEric Cheng ncpus = mrp.mrp_ncpus; 1316da14cebeSEric Cheng 1317da14cebeSEric Cheng if (ncpus > *val_cnt) 1318da14cebeSEric Cheng return (DLADM_STATUS_TOOSMALL); 1319da14cebeSEric Cheng 1320da14cebeSEric Cheng if (ncpus == 0) { 1321da14cebeSEric Cheng (*prop_val)[0] = '\0'; 1322da14cebeSEric Cheng *val_cnt = 1; 1323da14cebeSEric Cheng return (DLADM_STATUS_OK); 1324da14cebeSEric Cheng } 1325da14cebeSEric Cheng 1326da14cebeSEric Cheng *val_cnt = ncpus; 1327da14cebeSEric Cheng for (i = 0; i < ncpus; i++) { 1328da14cebeSEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 1329da14cebeSEric Cheng "%u", mrp.mrp_cpu[i]); 1330da14cebeSEric Cheng } 1331da14cebeSEric Cheng return (DLADM_STATUS_OK); 1332da14cebeSEric Cheng } 1333da14cebeSEric Cheng 1334da14cebeSEric Cheng /* ARGSUSED */ 1335da14cebeSEric Cheng static dladm_status_t 1336*4ac67f02SAnurag S. Maskey do_set_res(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1337*4ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1338da14cebeSEric Cheng { 1339da14cebeSEric Cheng mac_resource_props_t mrp; 1340da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1341da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1342da14cebeSEric Cheng 1343da14cebeSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 1344da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 1345da14cebeSEric Cheng flags, &status); 1346da14cebeSEric Cheng 1347da14cebeSEric Cheng if (dip == NULL) 1348da14cebeSEric Cheng return (status); 1349da14cebeSEric Cheng 1350da14cebeSEric Cheng if (vdp->vd_val == RESET_VAL) { 1351da14cebeSEric Cheng switch (dip->pr_num) { 1352da14cebeSEric Cheng case MAC_PROP_MAXBW: 1353da14cebeSEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 1354da14cebeSEric Cheng mrp.mrp_mask = MRP_MAXBW; 1355da14cebeSEric Cheng break; 1356da14cebeSEric Cheng case MAC_PROP_PRIO: 1357da14cebeSEric Cheng mrp.mrp_priority = MPL_RESET; 1358da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY; 1359da14cebeSEric Cheng break; 1360da14cebeSEric Cheng default: 1361da14cebeSEric Cheng free(dip); 1362da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 1363da14cebeSEric Cheng } 1364da14cebeSEric Cheng } else { 1365da14cebeSEric Cheng switch (dip->pr_num) { 1366da14cebeSEric Cheng case MAC_PROP_MAXBW: 1367da14cebeSEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_maxbw, 1368da14cebeSEric Cheng sizeof (uint64_t)); 1369da14cebeSEric Cheng mrp.mrp_mask = MRP_MAXBW; 1370da14cebeSEric Cheng break; 1371da14cebeSEric Cheng case MAC_PROP_PRIO: 1372da14cebeSEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_priority, 1373da14cebeSEric Cheng sizeof (mac_priority_level_t)); 1374da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY; 1375da14cebeSEric Cheng break; 1376da14cebeSEric Cheng default: 1377da14cebeSEric Cheng free(dip); 1378da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 1379da14cebeSEric Cheng } 1380da14cebeSEric Cheng } 1381da14cebeSEric Cheng 1382da14cebeSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 1383*4ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 1384da14cebeSEric Cheng free(dip); 1385da14cebeSEric Cheng return (status); 1386da14cebeSEric Cheng } 1387da14cebeSEric Cheng 1388da14cebeSEric Cheng /* ARGSUSED */ 1389da14cebeSEric Cheng static dladm_status_t 1390*4ac67f02SAnurag S. Maskey do_set_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1391*4ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1392da14cebeSEric Cheng { 1393da14cebeSEric Cheng mac_resource_props_t mrp; 1394da14cebeSEric Cheng dladm_status_t status; 1395da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1396da14cebeSEric Cheng datalink_class_t class; 1397da14cebeSEric Cheng 1398da14cebeSEric Cheng /* 1399da14cebeSEric Cheng * CPU bindings can be set on VNIC and regular physical links. 1400da14cebeSEric Cheng * However VNICs fails the dladm_phys_info test(). So apply 1401da14cebeSEric Cheng * the phys_info test only on physical links. 1402da14cebeSEric Cheng */ 1403*4ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, 1404da14cebeSEric Cheng NULL, NULL, 0)) != DLADM_STATUS_OK) { 1405da14cebeSEric Cheng return (status); 1406da14cebeSEric Cheng } 1407da14cebeSEric Cheng 1408da14cebeSEric Cheng /* 1409da14cebeSEric Cheng * We set intr_cpu to -1. The interrupt will be retargetted, 1410da14cebeSEric Cheng * if possible when the setup is complete in MAC. 1411da14cebeSEric Cheng */ 1412da14cebeSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 1413da14cebeSEric Cheng mrp.mrp_mask = MRP_CPUS; 1414da14cebeSEric Cheng if (vdp != NULL && vdp->vd_val != RESET_VAL) { 1415da14cebeSEric Cheng mac_resource_props_t *vmrp; 1416da14cebeSEric Cheng 1417da14cebeSEric Cheng vmrp = (mac_resource_props_t *)vdp->vd_val; 1418da14cebeSEric Cheng if (vmrp->mrp_ncpus > 0) { 1419da14cebeSEric Cheng bcopy(vmrp, &mrp, sizeof (mac_resource_props_t)); 1420da14cebeSEric Cheng mrp.mrp_mask = MRP_CPUS; 1421da14cebeSEric Cheng } 1422da14cebeSEric Cheng mrp.mrp_mask |= MRP_CPUS_USERSPEC; 1423da14cebeSEric Cheng mrp.mrp_fanout_mode = MCM_CPUS; 1424da14cebeSEric Cheng mrp.mrp_intr_cpu = -1; 1425da14cebeSEric Cheng } 1426da14cebeSEric Cheng 1427da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 1428da14cebeSEric Cheng flags, &status); 1429da14cebeSEric Cheng if (dip == NULL) 1430da14cebeSEric Cheng return (status); 1431da14cebeSEric Cheng 1432da14cebeSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 1433*4ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 1434da14cebeSEric Cheng free(dip); 1435da14cebeSEric Cheng return (status); 1436da14cebeSEric Cheng } 1437da14cebeSEric Cheng 1438da14cebeSEric Cheng /* ARGSUSED */ 1439da14cebeSEric Cheng static dladm_status_t 1440*4ac67f02SAnurag S. Maskey do_check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1441*4ac67f02SAnurag S. Maskey char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1442da14cebeSEric Cheng { 1443da14cebeSEric Cheng uint32_t cpuid; 1444da14cebeSEric Cheng int i, j, rc; 1445da14cebeSEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 1446da14cebeSEric Cheng mac_resource_props_t *mrp; 1447da14cebeSEric Cheng 1448da14cebeSEric Cheng mrp = malloc(sizeof (mac_resource_props_t)); 1449da14cebeSEric Cheng if (mrp == NULL) 1450da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1451da14cebeSEric Cheng 1452da14cebeSEric Cheng for (i = 0; i < val_cnt; i++) { 1453da14cebeSEric Cheng errno = 0; 1454da14cebeSEric Cheng cpuid = strtol(prop_val[i], (char **)NULL, 10); 1455da14cebeSEric Cheng if (errno != 0 || cpuid >= nproc) { 1456da14cebeSEric Cheng free(mrp); 1457da14cebeSEric Cheng return (DLADM_STATUS_CPUMAX); 1458da14cebeSEric Cheng } 1459da14cebeSEric Cheng rc = p_online(cpuid, P_STATUS); 1460da14cebeSEric Cheng if (rc < 1) { 1461da14cebeSEric Cheng free(mrp); 1462da14cebeSEric Cheng return (DLADM_STATUS_CPUERR); 1463da14cebeSEric Cheng } 1464da14cebeSEric Cheng if (rc != P_ONLINE) { 1465da14cebeSEric Cheng free(mrp); 1466da14cebeSEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 1467da14cebeSEric Cheng } 1468da14cebeSEric Cheng mrp->mrp_cpu[i] = cpuid; 1469da14cebeSEric Cheng } 1470da14cebeSEric Cheng mrp->mrp_ncpus = (uint32_t)val_cnt; 1471da14cebeSEric Cheng 1472da14cebeSEric Cheng /* Check for duplicates */ 1473da14cebeSEric Cheng for (i = 0; i < val_cnt; i++) { 1474da14cebeSEric Cheng for (j = 0; j < val_cnt; j++) { 1475da14cebeSEric Cheng if (i != j && mrp->mrp_cpu[i] == mrp->mrp_cpu[j]) { 1476da14cebeSEric Cheng free(mrp); 1477da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 1478da14cebeSEric Cheng } 1479da14cebeSEric Cheng } 1480da14cebeSEric Cheng } 1481da14cebeSEric Cheng vdp->vd_val = (uintptr_t)mrp; 1482da14cebeSEric Cheng 1483da14cebeSEric Cheng return (DLADM_STATUS_OK); 1484da14cebeSEric Cheng } 1485da14cebeSEric Cheng 1486da14cebeSEric Cheng /* ARGSUSED */ 1487da14cebeSEric Cheng dladm_status_t 1488da14cebeSEric Cheng do_extract_cpus(val_desc_t *vdp, void *arg, uint_t cnt) 1489da14cebeSEric Cheng { 1490da14cebeSEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1491da14cebeSEric Cheng mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; 1492da14cebeSEric Cheng int i; 1493da14cebeSEric Cheng 1494da14cebeSEric Cheng for (i = 0; i < vmrp->mrp_ncpus; i++) { 1495da14cebeSEric Cheng mrp->mrp_cpu[i] = vmrp->mrp_cpu[i]; 1496da14cebeSEric Cheng } 1497da14cebeSEric Cheng mrp->mrp_ncpus = vmrp->mrp_ncpus; 1498da14cebeSEric Cheng mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 1499da14cebeSEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 1500da14cebeSEric Cheng 1501da14cebeSEric Cheng return (DLADM_STATUS_OK); 1502da14cebeSEric Cheng } 1503da14cebeSEric Cheng 1504da14cebeSEric Cheng /* ARGSUSED */ 1505da14cebeSEric Cheng static dladm_status_t 1506*4ac67f02SAnurag S. Maskey dld_priority_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1507da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1508da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1509da14cebeSEric Cheng { 1510da14cebeSEric Cheng dld_ioc_macprop_t *dip; 1511da14cebeSEric Cheng mac_resource_props_t mrp; 1512da14cebeSEric Cheng mac_priority_level_t pri; 1513da14cebeSEric Cheng dladm_status_t status; 1514da14cebeSEric Cheng 1515*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1516da14cebeSEric Cheng &status, perm_flags); 1517da14cebeSEric Cheng if (dip == NULL) 1518da14cebeSEric Cheng return (status); 1519da14cebeSEric Cheng 1520da14cebeSEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 1521da14cebeSEric Cheng free(dip); 1522da14cebeSEric Cheng 1523da14cebeSEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 1524da14cebeSEric Cheng mrp.mrp_priority; 1525da14cebeSEric Cheng 1526da14cebeSEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 1527da14cebeSEric Cheng *val_cnt = 1; 1528da14cebeSEric Cheng return (DLADM_STATUS_OK); 1529da14cebeSEric Cheng } 1530da14cebeSEric Cheng 1531da14cebeSEric Cheng /* ARGSUSED */ 1532da14cebeSEric Cheng static dladm_status_t 1533*4ac67f02SAnurag S. Maskey do_check_priority(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1534*4ac67f02SAnurag S. Maskey char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1535da14cebeSEric Cheng { 1536da14cebeSEric Cheng mac_priority_level_t *pri; 1537da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1538da14cebeSEric Cheng 1539da14cebeSEric Cheng if (val_cnt != 1) 1540da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1541da14cebeSEric Cheng 1542da14cebeSEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 1543da14cebeSEric Cheng if (pri == NULL) 1544da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1545da14cebeSEric Cheng 1546da14cebeSEric Cheng status = dladm_str2pri(*prop_val, pri); 1547da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1548da14cebeSEric Cheng free(pri); 1549da14cebeSEric Cheng return (status); 1550da14cebeSEric Cheng } 1551da14cebeSEric Cheng 1552da14cebeSEric Cheng if (*pri < MPL_LOW || *pri > MPL_HIGH) { 1553da14cebeSEric Cheng free(pri); 1554da14cebeSEric Cheng return (DLADM_STATUS_BADVAL); 1555da14cebeSEric Cheng } 1556da14cebeSEric Cheng 1557da14cebeSEric Cheng vdp->vd_val = (uintptr_t)pri; 1558da14cebeSEric Cheng return (DLADM_STATUS_OK); 1559da14cebeSEric Cheng } 1560da14cebeSEric Cheng 1561da14cebeSEric Cheng /* ARGSUSED */ 1562da14cebeSEric Cheng dladm_status_t 1563da14cebeSEric Cheng do_extract_priority(val_desc_t *vdp, void *arg, uint_t cnt) 1564da14cebeSEric Cheng { 1565da14cebeSEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1566da14cebeSEric Cheng 1567da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_priority, 1568da14cebeSEric Cheng sizeof (mac_priority_level_t)); 1569da14cebeSEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 1570da14cebeSEric Cheng 1571da14cebeSEric Cheng return (DLADM_STATUS_OK); 1572da14cebeSEric Cheng } 1573da14cebeSEric Cheng 1574da14cebeSEric Cheng /* ARGSUSED */ 1575da14cebeSEric Cheng static dladm_status_t 1576*4ac67f02SAnurag S. Maskey do_get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1577da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1578da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1579d62bc4baSyz147064 { 15803bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 15813bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 15823bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 15833bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 1584d62bc4baSyz147064 15853fd94f8cSam223141 if (flags & MAC_PROP_DEFAULT) 1586149b7eb2SSowmini Varadhan return (DLADM_STATUS_NOTDEFINED); 15874045d941Ssowmini 1588d62bc4baSyz147064 *val_cnt = 1; 1589*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1590da14cebeSEric Cheng &status, perm_flags); 15913bc21d0aSAruna Ramakrishna - Sun Microsystems if (dip == NULL) { 1592d62bc4baSyz147064 (*prop_val)[0] = '\0'; 1593da14cebeSEric Cheng return (DLADM_STATUS_OK); 1594d62bc4baSyz147064 } 15953bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 1596d62bc4baSyz147064 15973bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 1598d62bc4baSyz147064 if (i != 0) { 1599d62bc4baSyz147064 (void) snprintf(*prop_val + len, 1600d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 1601d62bc4baSyz147064 len += 1; 1602d62bc4baSyz147064 } 1603d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 16043bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 16053bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 16063bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 1607d62bc4baSyz147064 (void) snprintf(*prop_val + len, 1608d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 1609d62bc4baSyz147064 AP_ANCHOR); 1610d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 1611d62bc4baSyz147064 } 1612d62bc4baSyz147064 } 16133bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 1614d62bc4baSyz147064 done: 1615d62bc4baSyz147064 return (DLADM_STATUS_OK); 1616d62bc4baSyz147064 } 1617d62bc4baSyz147064 1618d62bc4baSyz147064 /* 1619d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 1620d62bc4baSyz147064 * DLADM_STATUS_* code. 1621d62bc4baSyz147064 */ 1622d62bc4baSyz147064 dladm_status_t 1623d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 1624d62bc4baSyz147064 { 1625d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 1626d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1627d62bc4baSyz147064 1628d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 1629d62bc4baSyz147064 /* 1630d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 1631d62bc4baSyz147064 * be after at least one module. 1632d62bc4baSyz147064 */ 1633d62bc4baSyz147064 if (dlap->dap_anchor != 0) 1634d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1635d62bc4baSyz147064 if (dlap->dap_npush == 0) 1636d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1637d62bc4baSyz147064 1638d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 1639d62bc4baSyz147064 return (DLADM_STATUS_OK); 1640d62bc4baSyz147064 } 1641d62bc4baSyz147064 if (dlap->dap_npush > MAXAPUSH) 1642d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1643d62bc4baSyz147064 1644d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 1645d62bc4baSyz147064 FMNAMESZ + 1); 1646d62bc4baSyz147064 1647d62bc4baSyz147064 return (DLADM_STATUS_OK); 1648d62bc4baSyz147064 } 1649d62bc4baSyz147064 1650d62bc4baSyz147064 /* 1651d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 1652d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 1653d62bc4baSyz147064 * latter is used in the autopush(1M) file. 1654d62bc4baSyz147064 */ 1655d62bc4baSyz147064 /* ARGSUSED */ 1656d62bc4baSyz147064 static dladm_status_t 1657*4ac67f02SAnurag S. Maskey do_check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1658*4ac67f02SAnurag S. Maskey char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1659d62bc4baSyz147064 { 1660d62bc4baSyz147064 char *module; 1661d62bc4baSyz147064 struct dlautopush *dlap; 1662d62bc4baSyz147064 dladm_status_t status; 1663d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 1664d62bc4baSyz147064 char delimiters[4]; 1665d62bc4baSyz147064 1666d62bc4baSyz147064 if (val_cnt != 1) 1667d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1668d62bc4baSyz147064 16693bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 1670d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 1671d62bc4baSyz147064 if (dlap == NULL) 1672d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1673d62bc4baSyz147064 1674d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 1675d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 1676d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 1677d62bc4baSyz147064 module = strtok(val, delimiters); 1678d62bc4baSyz147064 while (module != NULL) { 1679d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 1680d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1681d62bc4baSyz147064 return (status); 1682d62bc4baSyz147064 module = strtok(NULL, delimiters); 1683d62bc4baSyz147064 } 1684d62bc4baSyz147064 1685d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 16863bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 16873bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 16883bc21d0aSAruna Ramakrishna - Sun Microsystems } 1689d62bc4baSyz147064 return (DLADM_STATUS_OK); 1690d62bc4baSyz147064 } 1691d62bc4baSyz147064 1692bcb5c89dSSowmini Varadhan #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 1693bcb5c89dSSowmini Varadhan 1694e7801d59Ssowmini /* ARGSUSED */ 1695d62bc4baSyz147064 static dladm_status_t 1696*4ac67f02SAnurag S. Maskey do_get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 1697*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 1698*4ac67f02SAnurag S. Maskey uint_t *perm_flags) 1699d62bc4baSyz147064 { 1700d62bc4baSyz147064 wl_rates_t *wrp; 1701d62bc4baSyz147064 uint_t i; 1702d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1703d62bc4baSyz147064 1704bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 1705bcb5c89dSSowmini Varadhan if (wrp == NULL) 1706bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 1707d62bc4baSyz147064 1708*4ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 1709*4ac67f02SAnurag S. Maskey B_FALSE); 1710d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1711d62bc4baSyz147064 goto done; 1712d62bc4baSyz147064 1713d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 1714d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1715d62bc4baSyz147064 goto done; 1716d62bc4baSyz147064 } 1717d62bc4baSyz147064 1718d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 1719d62bc4baSyz147064 prop_val[0][0] = '\0'; 1720d62bc4baSyz147064 *val_cnt = 1; 1721d62bc4baSyz147064 goto done; 1722d62bc4baSyz147064 } 1723d62bc4baSyz147064 1724d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 1725d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 1726d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 1727d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 1728d62bc4baSyz147064 } 1729d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 1730da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_RW; 1731d62bc4baSyz147064 1732d62bc4baSyz147064 done: 1733bcb5c89dSSowmini Varadhan free(wrp); 1734d62bc4baSyz147064 return (status); 1735d62bc4baSyz147064 } 1736d62bc4baSyz147064 1737d62bc4baSyz147064 static dladm_status_t 1738*4ac67f02SAnurag S. Maskey do_get_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1739da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1740da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1741d62bc4baSyz147064 { 1742afdda45fSVasumathi Sundaram - Sun Microsystems if (media != DL_WIFI) { 1743*4ac67f02SAnurag S. Maskey return (i_dladm_speed_get(handle, pdp, linkid, prop_val, 1744da14cebeSEric Cheng val_cnt, flags, perm_flags)); 1745afdda45fSVasumathi Sundaram - Sun Microsystems } 17466b9e797cSsowmini 1747*4ac67f02SAnurag S. Maskey return (do_get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 1748da14cebeSEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 1749d62bc4baSyz147064 } 1750d62bc4baSyz147064 17514045d941Ssowmini /* ARGSUSED */ 1752d62bc4baSyz147064 static dladm_status_t 1753*4ac67f02SAnurag S. Maskey do_get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1754da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1755da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1756d62bc4baSyz147064 { 17576b9e797cSsowmini switch (media) { 17586b9e797cSsowmini case DL_ETHER: 17594045d941Ssowmini /* 17604045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 17614045d941Ssowmini * links can have a speed of 5.5 Gbps. 17624045d941Ssowmini */ 17634045d941Ssowmini return (DLADM_STATUS_NOTSUP); 17646b9e797cSsowmini 17656b9e797cSsowmini case DL_WIFI: 1766*4ac67f02SAnurag S. Maskey return (do_get_rate_common(handle, pdp, linkid, prop_val, 1767*4ac67f02SAnurag S. Maskey val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 17686b9e797cSsowmini default: 17696b9e797cSsowmini return (DLADM_STATUS_BADARG); 17706b9e797cSsowmini } 1771d62bc4baSyz147064 } 1772d62bc4baSyz147064 1773d62bc4baSyz147064 static dladm_status_t 1774*4ac67f02SAnurag S. Maskey do_set_rate(dladm_handle_t handle, datalink_id_t linkid, 1775*4ac67f02SAnurag S. Maskey dladm_wlan_rates_t *rates) 1776f4b3ec61Sdh155122 { 1777f4b3ec61Sdh155122 int i; 1778d62bc4baSyz147064 uint_t len; 1779d62bc4baSyz147064 wl_rates_t *wrp; 1780d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1781d62bc4baSyz147064 1782bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 1783bcb5c89dSSowmini Varadhan if (wrp == NULL) 1784d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1785d62bc4baSyz147064 1786bcb5c89dSSowmini Varadhan bzero(wrp, WLDP_BUFSIZE); 1787d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 1788d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 1789d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 1790d62bc4baSyz147064 1791d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 1792d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 1793*4ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, 1794*4ac67f02SAnurag S. Maskey MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 1795d62bc4baSyz147064 1796bcb5c89dSSowmini Varadhan free(wrp); 1797d62bc4baSyz147064 return (status); 1798d62bc4baSyz147064 } 1799d62bc4baSyz147064 1800e7801d59Ssowmini /* ARGSUSED */ 1801d62bc4baSyz147064 static dladm_status_t 1802*4ac67f02SAnurag S. Maskey do_set_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18036b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1804d62bc4baSyz147064 { 1805d62bc4baSyz147064 dladm_wlan_rates_t rates; 1806f4b3ec61Sdh155122 dladm_status_t status; 1807f4b3ec61Sdh155122 18086b9e797cSsowmini /* 18096b9e797cSsowmini * can currently set rate on WIFI links only. 18106b9e797cSsowmini */ 18116b9e797cSsowmini if (media != DL_WIFI) 18126b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 18136b9e797cSsowmini 1814d62bc4baSyz147064 if (val_cnt != 1) 1815d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1816f4b3ec61Sdh155122 1817d62bc4baSyz147064 rates.wr_cnt = 1; 1818d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 1819f4b3ec61Sdh155122 1820*4ac67f02SAnurag S. Maskey status = do_set_rate(handle, linkid, &rates); 1821f4b3ec61Sdh155122 1822d62bc4baSyz147064 done: 1823d62bc4baSyz147064 return (status); 1824d62bc4baSyz147064 } 1825d62bc4baSyz147064 1826d62bc4baSyz147064 /* ARGSUSED */ 1827d62bc4baSyz147064 static dladm_status_t 1828*4ac67f02SAnurag S. Maskey do_check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1829*4ac67f02SAnurag S. Maskey char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1830d62bc4baSyz147064 { 1831d62bc4baSyz147064 int i; 1832d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 1833d62bc4baSyz147064 char *buf, **modval; 1834d62bc4baSyz147064 dladm_status_t status; 1835afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 1836d62bc4baSyz147064 1837d62bc4baSyz147064 if (val_cnt != 1) 1838d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1839d62bc4baSyz147064 1840d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 1841d62bc4baSyz147064 MAX_SUPPORT_RATES); 1842d62bc4baSyz147064 if (buf == NULL) { 1843d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 1844d62bc4baSyz147064 goto done; 1845d62bc4baSyz147064 } 1846d62bc4baSyz147064 1847d62bc4baSyz147064 modval = (char **)(void *)buf; 1848d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 1849d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 1850d62bc4baSyz147064 i * DLADM_STRSIZE; 1851d62bc4baSyz147064 } 1852d62bc4baSyz147064 1853*4ac67f02SAnurag S. Maskey status = do_get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 1854*4ac67f02SAnurag S. Maskey media, 0, &perm_flags); 1855d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1856d62bc4baSyz147064 goto done; 1857d62bc4baSyz147064 1858d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 1859d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 1860e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 1861e7801d59Ssowmini (atof(*prop_val) * 2); 1862f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 1863f4b3ec61Sdh155122 break; 1864f4b3ec61Sdh155122 } 1865d62bc4baSyz147064 } 1866d62bc4baSyz147064 if (i == modval_cnt) 1867d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 1868d62bc4baSyz147064 done: 1869d62bc4baSyz147064 free(buf); 1870d62bc4baSyz147064 return (status); 1871d62bc4baSyz147064 } 1872f4b3ec61Sdh155122 1873d62bc4baSyz147064 static dladm_status_t 1874*4ac67f02SAnurag S. Maskey do_get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 1875*4ac67f02SAnurag S. Maskey int buflen) 1876d62bc4baSyz147064 { 1877*4ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 1878bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 1879d62bc4baSyz147064 } 1880d62bc4baSyz147064 1881e7801d59Ssowmini /* ARGSUSED */ 1882d62bc4baSyz147064 static dladm_status_t 1883*4ac67f02SAnurag S. Maskey do_get_channel_prop(dladm_handle_t handle, prop_desc_t *pdp, 1884*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 1885*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 1886d62bc4baSyz147064 { 1887d62bc4baSyz147064 uint32_t channel; 1888bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 1889d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1890bcb5c89dSSowmini Varadhan wl_phy_conf_t wl_phy_conf; 1891d62bc4baSyz147064 1892*4ac67f02SAnurag S. Maskey if ((status = do_get_phyconf(handle, linkid, buf, sizeof (buf))) 1893bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 1894d62bc4baSyz147064 goto done; 1895d62bc4baSyz147064 1896bcb5c89dSSowmini Varadhan (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 1897bcb5c89dSSowmini Varadhan if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 1898d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1899d62bc4baSyz147064 goto done; 1900d62bc4baSyz147064 } 1901d62bc4baSyz147064 1902d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 1903d62bc4baSyz147064 *val_cnt = 1; 1904da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 1905d62bc4baSyz147064 done: 1906d62bc4baSyz147064 return (status); 1907d62bc4baSyz147064 } 1908d62bc4baSyz147064 1909d62bc4baSyz147064 static dladm_status_t 1910*4ac67f02SAnurag S. Maskey do_get_powermode(dladm_handle_t handle, datalink_id_t linkid, void *buf, 1911*4ac67f02SAnurag S. Maskey int buflen) 1912d62bc4baSyz147064 { 1913*4ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_POWER_MODE, 1914bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 1915d62bc4baSyz147064 } 1916d62bc4baSyz147064 1917e7801d59Ssowmini /* ARGSUSED */ 1918d62bc4baSyz147064 static dladm_status_t 1919*4ac67f02SAnurag S. Maskey do_get_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 1920*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 1921*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 1922d62bc4baSyz147064 { 1923bcb5c89dSSowmini Varadhan wl_ps_mode_t mode; 1924d62bc4baSyz147064 const char *s; 1925bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 1926d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1927d62bc4baSyz147064 1928*4ac67f02SAnurag S. Maskey if ((status = do_get_powermode(handle, linkid, buf, sizeof (buf))) 1929bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 1930d62bc4baSyz147064 goto done; 1931d62bc4baSyz147064 1932bcb5c89dSSowmini Varadhan (void) memcpy(&mode, buf, sizeof (mode)); 1933bcb5c89dSSowmini Varadhan switch (mode.wl_ps_mode) { 1934d62bc4baSyz147064 case WL_PM_AM: 1935d62bc4baSyz147064 s = "off"; 1936f4b3ec61Sdh155122 break; 1937d62bc4baSyz147064 case WL_PM_MPS: 1938d62bc4baSyz147064 s = "max"; 1939d62bc4baSyz147064 break; 1940d62bc4baSyz147064 case WL_PM_FAST: 1941d62bc4baSyz147064 s = "fast"; 1942f4b3ec61Sdh155122 break; 1943f4b3ec61Sdh155122 default: 1944d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1945d62bc4baSyz147064 goto done; 1946f4b3ec61Sdh155122 } 1947d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 1948d62bc4baSyz147064 *val_cnt = 1; 1949afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 1950da14cebeSEric Cheng done: 1951d62bc4baSyz147064 return (status); 1952d62bc4baSyz147064 } 1953d62bc4baSyz147064 1954d62bc4baSyz147064 static dladm_status_t 1955*4ac67f02SAnurag S. Maskey do_set_powermode(dladm_handle_t handle, datalink_id_t linkid, 1956*4ac67f02SAnurag S. Maskey dladm_wlan_powermode_t *pm) 1957d62bc4baSyz147064 { 1958d62bc4baSyz147064 wl_ps_mode_t ps_mode; 1959d62bc4baSyz147064 1960d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 1961d62bc4baSyz147064 1962d62bc4baSyz147064 switch (*pm) { 1963d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 1964d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 1965d62bc4baSyz147064 break; 1966d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 1967d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 1968d62bc4baSyz147064 break; 1969d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 1970d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 1971d62bc4baSyz147064 break; 1972d62bc4baSyz147064 default: 1973d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 1974d62bc4baSyz147064 } 1975*4ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &ps_mode, 1976*4ac67f02SAnurag S. Maskey MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 1977d62bc4baSyz147064 } 1978d62bc4baSyz147064 1979d62bc4baSyz147064 /* ARGSUSED */ 1980d62bc4baSyz147064 static dladm_status_t 1981*4ac67f02SAnurag S. Maskey do_set_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 1982*4ac67f02SAnurag S. Maskey datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 1983*4ac67f02SAnurag S. Maskey datalink_media_t media) 1984d62bc4baSyz147064 { 1985d62bc4baSyz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 1986d62bc4baSyz147064 dladm_status_t status; 1987d62bc4baSyz147064 1988d62bc4baSyz147064 if (val_cnt != 1) 1989d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1990d62bc4baSyz147064 1991*4ac67f02SAnurag S. Maskey status = do_set_powermode(handle, linkid, &powermode); 1992f4b3ec61Sdh155122 1993f4b3ec61Sdh155122 return (status); 1994f4b3ec61Sdh155122 } 1995f4b3ec61Sdh155122 1996f4b3ec61Sdh155122 static dladm_status_t 1997*4ac67f02SAnurag S. Maskey do_get_radio(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen) 1998f4b3ec61Sdh155122 { 1999*4ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_RADIO, 2000*4ac67f02SAnurag S. Maskey buflen, B_FALSE)); 2001d62bc4baSyz147064 } 2002d62bc4baSyz147064 2003e7801d59Ssowmini /* ARGSUSED */ 2004d62bc4baSyz147064 static dladm_status_t 2005*4ac67f02SAnurag S. Maskey do_get_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2006da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2007da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2008d62bc4baSyz147064 { 2009d62bc4baSyz147064 wl_radio_t radio; 2010d62bc4baSyz147064 const char *s; 2011bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 2012d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 2013d62bc4baSyz147064 2014*4ac67f02SAnurag S. Maskey if ((status = do_get_radio(handle, linkid, buf, sizeof (buf))) 2015bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 2016d62bc4baSyz147064 goto done; 2017d62bc4baSyz147064 2018bcb5c89dSSowmini Varadhan (void) memcpy(&radio, buf, sizeof (radio)); 2019d62bc4baSyz147064 switch (radio) { 2020d62bc4baSyz147064 case B_TRUE: 2021d62bc4baSyz147064 s = "on"; 2022d62bc4baSyz147064 break; 2023d62bc4baSyz147064 case B_FALSE: 2024d62bc4baSyz147064 s = "off"; 2025d62bc4baSyz147064 break; 2026d62bc4baSyz147064 default: 2027d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 2028d62bc4baSyz147064 goto done; 2029d62bc4baSyz147064 } 2030d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 2031d62bc4baSyz147064 *val_cnt = 1; 2032afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 2033da14cebeSEric Cheng done: 2034d62bc4baSyz147064 return (status); 2035d62bc4baSyz147064 } 2036d62bc4baSyz147064 2037d62bc4baSyz147064 static dladm_status_t 2038*4ac67f02SAnurag S. Maskey do_set_radio(dladm_handle_t handle, datalink_id_t linkid, 2039*4ac67f02SAnurag S. Maskey dladm_wlan_radio_t *radio) 2040d62bc4baSyz147064 { 2041d62bc4baSyz147064 wl_radio_t r; 2042d62bc4baSyz147064 2043d62bc4baSyz147064 switch (*radio) { 2044d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 2045d62bc4baSyz147064 r = B_TRUE; 2046d62bc4baSyz147064 break; 2047d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 2048d62bc4baSyz147064 r = B_FALSE; 2049d62bc4baSyz147064 break; 2050d62bc4baSyz147064 default: 2051d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 2052d62bc4baSyz147064 } 2053*4ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 2054bcb5c89dSSowmini Varadhan sizeof (r), B_TRUE)); 2055d62bc4baSyz147064 } 2056d62bc4baSyz147064 2057d62bc4baSyz147064 /* ARGSUSED */ 2058d62bc4baSyz147064 static dladm_status_t 2059*4ac67f02SAnurag S. Maskey do_set_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20606b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t fags, datalink_media_t media) 2061d62bc4baSyz147064 { 2062d62bc4baSyz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 2063f4b3ec61Sdh155122 dladm_status_t status; 2064f4b3ec61Sdh155122 2065d62bc4baSyz147064 if (val_cnt != 1) 2066d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2067f4b3ec61Sdh155122 2068*4ac67f02SAnurag S. Maskey status = do_set_radio(handle, linkid, &radio); 2069f4b3ec61Sdh155122 2070d62bc4baSyz147064 return (status); 2071d62bc4baSyz147064 } 2072f4b3ec61Sdh155122 2073d62bc4baSyz147064 static dladm_status_t 2074*4ac67f02SAnurag S. Maskey i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 2075*4ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 2076d62bc4baSyz147064 { 2077d62bc4baSyz147064 char buf[MAXLINELEN]; 2078d62bc4baSyz147064 int i; 2079d62bc4baSyz147064 dladm_conf_t conf; 2080d62bc4baSyz147064 dladm_status_t status; 2081d62bc4baSyz147064 2082*4ac67f02SAnurag S. Maskey status = dladm_read_conf(handle, linkid, &conf); 2083f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 2084f4b3ec61Sdh155122 return (status); 2085f4b3ec61Sdh155122 2086d62bc4baSyz147064 /* 2087d62bc4baSyz147064 * reset case. 2088d62bc4baSyz147064 */ 2089d62bc4baSyz147064 if (val_cnt == 0) { 2090*4ac67f02SAnurag S. Maskey status = dladm_unset_conf_field(handle, conf, prop_name); 2091d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 2092*4ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 2093d62bc4baSyz147064 goto done; 2094f4b3ec61Sdh155122 } 2095f4b3ec61Sdh155122 2096d62bc4baSyz147064 buf[0] = '\0'; 2097d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 2098d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 2099d62bc4baSyz147064 if (i != val_cnt - 1) 2100d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 2101d62bc4baSyz147064 } 2102f4b3ec61Sdh155122 2103*4ac67f02SAnurag S. Maskey status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 2104*4ac67f02SAnurag S. Maskey buf); 2105d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 2106*4ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 2107d62bc4baSyz147064 2108d62bc4baSyz147064 done: 2109*4ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 2110f4b3ec61Sdh155122 return (status); 2111f4b3ec61Sdh155122 } 2112f4b3ec61Sdh155122 2113f4b3ec61Sdh155122 static dladm_status_t 2114*4ac67f02SAnurag S. Maskey i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 2115*4ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 2116f4b3ec61Sdh155122 { 2117d62bc4baSyz147064 char buf[MAXLINELEN], *str; 2118d62bc4baSyz147064 uint_t cnt = 0; 2119d62bc4baSyz147064 dladm_conf_t conf; 2120d62bc4baSyz147064 dladm_status_t status; 2121f4b3ec61Sdh155122 2122*4ac67f02SAnurag S. Maskey status = dladm_read_conf(handle, linkid, &conf); 2123d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2124f4b3ec61Sdh155122 return (status); 2125d62bc4baSyz147064 2126*4ac67f02SAnurag S. Maskey status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 2127d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2128d62bc4baSyz147064 goto done; 2129d62bc4baSyz147064 2130d62bc4baSyz147064 str = strtok(buf, ","); 2131d62bc4baSyz147064 while (str != NULL) { 2132d62bc4baSyz147064 if (cnt == *val_cntp) { 2133d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 2134d62bc4baSyz147064 goto done; 2135d62bc4baSyz147064 } 2136d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 2137d62bc4baSyz147064 str = strtok(NULL, ","); 2138f4b3ec61Sdh155122 } 2139f4b3ec61Sdh155122 2140d62bc4baSyz147064 *val_cntp = cnt; 2141f4b3ec61Sdh155122 2142d62bc4baSyz147064 done: 2143*4ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 2144d62bc4baSyz147064 return (status); 2145f4b3ec61Sdh155122 } 2146e7801d59Ssowmini 2147bcb5c89dSSowmini Varadhan static link_attr_t * 2148e7801d59Ssowmini dladm_name2prop(const char *prop_name) 2149e7801d59Ssowmini { 2150bcb5c89dSSowmini Varadhan link_attr_t *p; 2151e7801d59Ssowmini 2152bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 2153e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 2154e7801d59Ssowmini break; 2155e7801d59Ssowmini } 2156e7801d59Ssowmini return (p); 2157e7801d59Ssowmini } 2158e7801d59Ssowmini 2159bcb5c89dSSowmini Varadhan static link_attr_t * 2160bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid) 2161bcb5c89dSSowmini Varadhan { 2162bcb5c89dSSowmini Varadhan link_attr_t *p; 2163bcb5c89dSSowmini Varadhan 2164bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 2165bcb5c89dSSowmini Varadhan if (p->pp_id == propid) 2166bcb5c89dSSowmini Varadhan break; 2167bcb5c89dSSowmini Varadhan } 2168bcb5c89dSSowmini Varadhan return (p); 2169bcb5c89dSSowmini Varadhan } 2170e7801d59Ssowmini 21713fd94f8cSam223141 static dld_ioc_macprop_t * 2172bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 2173bcb5c89dSSowmini Varadhan const char *prop_name, mac_prop_id_t propid, uint_t flags, 2174bcb5c89dSSowmini Varadhan dladm_status_t *status) 2175e7801d59Ssowmini { 2176e7801d59Ssowmini int dsize; 21773fd94f8cSam223141 dld_ioc_macprop_t *dip; 2178e7801d59Ssowmini 2179e7801d59Ssowmini *status = DLADM_STATUS_OK; 21803fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 2181e7801d59Ssowmini dip = malloc(dsize); 2182e7801d59Ssowmini if (dip == NULL) { 2183e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 2184e7801d59Ssowmini return (NULL); 2185e7801d59Ssowmini } 2186e7801d59Ssowmini bzero(dip, dsize); 2187e7801d59Ssowmini dip->pr_valsize = valsize; 21884045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 21893fd94f8cSam223141 dip->pr_version = MAC_PROP_VERSION; 21906b9e797cSsowmini dip->pr_linkid = linkid; 2191bcb5c89dSSowmini Varadhan dip->pr_num = propid; 21924045d941Ssowmini dip->pr_flags = flags; 2193e7801d59Ssowmini return (dip); 2194e7801d59Ssowmini } 2195e7801d59Ssowmini 2196bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 2197bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 2198bcb5c89dSSowmini Varadhan const char *prop_name, uint_t flags, dladm_status_t *status) 2199bcb5c89dSSowmini Varadhan { 2200bcb5c89dSSowmini Varadhan link_attr_t *p; 2201bcb5c89dSSowmini Varadhan 2202bcb5c89dSSowmini Varadhan p = dladm_name2prop(prop_name); 2203bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 2204bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 2205bcb5c89dSSowmini Varadhan flags, status)); 2206bcb5c89dSSowmini Varadhan } 2207bcb5c89dSSowmini Varadhan 2208bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 2209bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 2210bcb5c89dSSowmini Varadhan mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 2211bcb5c89dSSowmini Varadhan { 2212bcb5c89dSSowmini Varadhan link_attr_t *p; 2213bcb5c89dSSowmini Varadhan 2214bcb5c89dSSowmini Varadhan p = dladm_id2prop(propid); 2215bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 2216bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 2217bcb5c89dSSowmini Varadhan flags, status)); 2218bcb5c89dSSowmini Varadhan } 2219bcb5c89dSSowmini Varadhan 2220e7801d59Ssowmini /* ARGSUSED */ 2221e7801d59Ssowmini static dladm_status_t 2222*4ac67f02SAnurag S. Maskey i_dladm_set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 2223*4ac67f02SAnurag S. Maskey datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 2224*4ac67f02SAnurag S. Maskey datalink_media_t media) 2225e7801d59Ssowmini { 22263fd94f8cSam223141 dld_ioc_macprop_t *dip; 2227e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 2228e7801d59Ssowmini uint8_t u8; 2229e7801d59Ssowmini uint16_t u16; 2230e7801d59Ssowmini uint32_t u32; 2231e7801d59Ssowmini void *val; 2232e7801d59Ssowmini 2233da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 2234e7801d59Ssowmini if (dip == NULL) 2235e7801d59Ssowmini return (status); 2236e7801d59Ssowmini 2237da14cebeSEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 2238e7801d59Ssowmini val = (void *)vdp->vd_val; 2239e7801d59Ssowmini else { 2240e7801d59Ssowmini /* 2241e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 2242e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 2243e7801d59Ssowmini */ 2244e7801d59Ssowmini switch (dip->pr_valsize) { 2245e7801d59Ssowmini case 1: 2246e7801d59Ssowmini u8 = vdp->vd_val; 2247e7801d59Ssowmini val = &u8; 2248e7801d59Ssowmini break; 2249e7801d59Ssowmini case 2: 2250e7801d59Ssowmini u16 = vdp->vd_val; 2251e7801d59Ssowmini val = &u16; 2252e7801d59Ssowmini break; 2253e7801d59Ssowmini case 4: 2254e7801d59Ssowmini u32 = vdp->vd_val; 2255e7801d59Ssowmini val = &u32; 2256e7801d59Ssowmini break; 2257e7801d59Ssowmini default: 2258e7801d59Ssowmini val = &vdp->vd_val; 2259e7801d59Ssowmini break; 2260e7801d59Ssowmini } 2261e7801d59Ssowmini } 2262e7801d59Ssowmini 22633bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 2264e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 22653bc21d0aSAruna Ramakrishna - Sun Microsystems else 22663bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 22673bc21d0aSAruna Ramakrishna - Sun Microsystems 2268*4ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 2269bcb5c89dSSowmini Varadhan 2270bcb5c89dSSowmini Varadhan done: 2271bcb5c89dSSowmini Varadhan free(dip); 2272bcb5c89dSSowmini Varadhan return (status); 2273bcb5c89dSSowmini Varadhan } 2274bcb5c89dSSowmini Varadhan 2275bcb5c89dSSowmini Varadhan dladm_status_t 2276*4ac67f02SAnurag S. Maskey i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 2277bcb5c89dSSowmini Varadhan { 2278bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 2279bcb5c89dSSowmini Varadhan 2280*4ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), 2281*4ac67f02SAnurag S. Maskey (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 2282e7801d59Ssowmini status = dladm_errno2status(errno); 2283e7801d59Ssowmini 2284e7801d59Ssowmini return (status); 2285e7801d59Ssowmini } 2286e7801d59Ssowmini 22873fd94f8cSam223141 static dld_ioc_macprop_t * 2288*4ac67f02SAnurag S. Maskey i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 2289*4ac67f02SAnurag S. Maskey char *prop_name, uint_t flags, dladm_status_t *status, uint_t *perm_flags) 2290e7801d59Ssowmini { 22913fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 22924045d941Ssowmini 2293bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 22944045d941Ssowmini if (dip == NULL) 22954045d941Ssowmini return (NULL); 2296e7801d59Ssowmini 2297*4ac67f02SAnurag S. Maskey *status = i_dladm_macprop(handle, dip, B_FALSE); 22984045d941Ssowmini if (*status != DLADM_STATUS_OK) { 22994045d941Ssowmini free(dip); 23004045d941Ssowmini return (NULL); 23014045d941Ssowmini } 2302da14cebeSEric Cheng if (perm_flags != NULL) 2303da14cebeSEric Cheng *perm_flags = dip->pr_perm_flags; 2304da14cebeSEric Cheng 23054045d941Ssowmini return (dip); 2306e7801d59Ssowmini } 2307e7801d59Ssowmini 2308e7801d59Ssowmini /* ARGSUSED */ 2309e7801d59Ssowmini static dladm_status_t 2310*4ac67f02SAnurag S. Maskey i_dladm_defmtu_check(dladm_handle_t handle, prop_desc_t *pdp, 2311*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *v, 2312*4ac67f02SAnurag S. Maskey datalink_media_t media) 2313e7801d59Ssowmini { 2314e7801d59Ssowmini if (val_cnt != 1) 2315e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 23164045d941Ssowmini v->vd_val = atoi(prop_val[0]); 2317e7801d59Ssowmini return (DLADM_STATUS_OK); 2318e7801d59Ssowmini } 2319e7801d59Ssowmini 2320e7801d59Ssowmini /* ARGSUSED */ 2321e7801d59Ssowmini static dladm_status_t 2322*4ac67f02SAnurag S. Maskey i_dladm_duplex_get(dladm_handle_t handle, prop_desc_t *pdp, 2323*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2324*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 2325e7801d59Ssowmini { 2326e7801d59Ssowmini link_duplex_t link_duplex; 2327e7801d59Ssowmini dladm_status_t status; 2328e7801d59Ssowmini 2329*4ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 2330e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 2331e7801d59Ssowmini return (status); 2332e7801d59Ssowmini 2333e7801d59Ssowmini switch (link_duplex) { 2334e7801d59Ssowmini case LINK_DUPLEX_FULL: 2335e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 2336e7801d59Ssowmini break; 2337e7801d59Ssowmini case LINK_DUPLEX_HALF: 2338e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 2339e7801d59Ssowmini break; 2340e7801d59Ssowmini default: 2341e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 2342e7801d59Ssowmini break; 2343e7801d59Ssowmini } 2344e7801d59Ssowmini *val_cnt = 1; 2345e7801d59Ssowmini return (DLADM_STATUS_OK); 2346e7801d59Ssowmini } 2347e7801d59Ssowmini 2348e7801d59Ssowmini /* ARGSUSED */ 2349e7801d59Ssowmini static dladm_status_t 2350*4ac67f02SAnurag S. Maskey i_dladm_speed_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2351da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, uint_t flags, uint_t *perm_flags) 2352e7801d59Ssowmini { 2353e7801d59Ssowmini uint64_t ifspeed = 0; 2354e7801d59Ssowmini dladm_status_t status; 2355e7801d59Ssowmini 2356*4ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 2357e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 2358e7801d59Ssowmini return (status); 23594045d941Ssowmini 23606b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 23616b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 23626b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 23636b9e797cSsowmini } else { 2364e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 2365e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 23666b9e797cSsowmini } 2367e7801d59Ssowmini *val_cnt = 1; 2368da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 2369e7801d59Ssowmini return (DLADM_STATUS_OK); 2370e7801d59Ssowmini } 2371e7801d59Ssowmini 2372e7801d59Ssowmini /* ARGSUSED */ 2373e7801d59Ssowmini static dladm_status_t 2374*4ac67f02SAnurag S. Maskey i_dladm_status_get(dladm_handle_t handle, prop_desc_t *pdp, 2375*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2376*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 2377e7801d59Ssowmini { 2378e7801d59Ssowmini link_state_t link_state; 2379e7801d59Ssowmini dladm_status_t status; 2380e7801d59Ssowmini 2381*4ac67f02SAnurag S. Maskey status = i_dladm_get_state(handle, linkid, &link_state); 23824045d941Ssowmini if (status != DLADM_STATUS_OK) 2383e7801d59Ssowmini return (status); 2384da14cebeSEric Cheng 2385e7801d59Ssowmini switch (link_state) { 2386e7801d59Ssowmini case LINK_STATE_UP: 2387e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 2388e7801d59Ssowmini break; 2389e7801d59Ssowmini case LINK_STATE_DOWN: 2390e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 2391e7801d59Ssowmini break; 2392e7801d59Ssowmini default: 2393e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 2394e7801d59Ssowmini break; 2395e7801d59Ssowmini } 2396e7801d59Ssowmini *val_cnt = 1; 23974784fcbdSSowmini Varadhan *perm_flags = MAC_PROP_PERM_READ; 2398e7801d59Ssowmini return (DLADM_STATUS_OK); 2399e7801d59Ssowmini } 2400e7801d59Ssowmini 2401e7801d59Ssowmini /* ARGSUSED */ 2402e7801d59Ssowmini static dladm_status_t 2403*4ac67f02SAnurag S. Maskey i_dladm_binary_get(dladm_handle_t handle, prop_desc_t *pdp, 2404*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2405*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 2406e7801d59Ssowmini { 24073fd94f8cSam223141 dld_ioc_macprop_t *dip; 2408e7801d59Ssowmini dladm_status_t status; 2409e7801d59Ssowmini 2410*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 2411da14cebeSEric Cheng &status, perm_flags); 24124045d941Ssowmini if (dip == NULL) 2413e7801d59Ssowmini return (status); 2414da14cebeSEric Cheng 2415e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 2416e7801d59Ssowmini free(dip); 2417e7801d59Ssowmini *val_cnt = 1; 2418e7801d59Ssowmini return (DLADM_STATUS_OK); 2419e7801d59Ssowmini } 2420e7801d59Ssowmini 24216b9e797cSsowmini /* ARGSUSED */ 2422e7801d59Ssowmini static dladm_status_t 2423*4ac67f02SAnurag S. Maskey i_dladm_uint32_get(dladm_handle_t handle, prop_desc_t *pdp, 2424*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2425*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 2426e7801d59Ssowmini { 24273fd94f8cSam223141 dld_ioc_macprop_t *dip; 24284045d941Ssowmini uint32_t v = 0; 2429e7801d59Ssowmini uchar_t *cp; 2430e7801d59Ssowmini dladm_status_t status; 2431e7801d59Ssowmini 2432*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 2433da14cebeSEric Cheng &status, perm_flags); 24344045d941Ssowmini if (dip == NULL) 2435e7801d59Ssowmini return (status); 2436da14cebeSEric Cheng 2437e7801d59Ssowmini cp = (uchar_t *)dip->pr_val; 2438e7801d59Ssowmini (void) memcpy(&v, cp, sizeof (v)); 24394045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 2440e7801d59Ssowmini free(dip); 2441e7801d59Ssowmini *val_cnt = 1; 2442e7801d59Ssowmini return (DLADM_STATUS_OK); 2443e7801d59Ssowmini } 2444e7801d59Ssowmini 24456b9e797cSsowmini /* ARGSUSED */ 2446e7801d59Ssowmini static dladm_status_t 2447*4ac67f02SAnurag S. Maskey i_dladm_flowctl_get(dladm_handle_t handle, prop_desc_t *pdp, 2448*4ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2449*4ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 2450e7801d59Ssowmini { 24513fd94f8cSam223141 dld_ioc_macprop_t *dip; 2452e7801d59Ssowmini link_flowctrl_t v; 2453e7801d59Ssowmini dladm_status_t status; 2454e7801d59Ssowmini uchar_t *cp; 2455e7801d59Ssowmini 2456*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 2457da14cebeSEric Cheng &status, perm_flags); 24584045d941Ssowmini if (dip == NULL) 2459e7801d59Ssowmini return (status); 2460da14cebeSEric Cheng 2461e7801d59Ssowmini cp = (uchar_t *)dip->pr_val; 2462e7801d59Ssowmini (void) memcpy(&v, cp, sizeof (v)); 2463e7801d59Ssowmini switch (v) { 2464e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 2465e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 2466e7801d59Ssowmini break; 2467e7801d59Ssowmini case LINK_FLOWCTRL_RX: 2468e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 2469e7801d59Ssowmini break; 2470e7801d59Ssowmini case LINK_FLOWCTRL_TX: 2471e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 2472e7801d59Ssowmini break; 2473e7801d59Ssowmini case LINK_FLOWCTRL_BI: 2474e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 2475e7801d59Ssowmini break; 2476e7801d59Ssowmini } 2477e7801d59Ssowmini free(dip); 2478e7801d59Ssowmini *val_cnt = 1; 2479e7801d59Ssowmini return (DLADM_STATUS_OK); 2480e7801d59Ssowmini } 2481e7801d59Ssowmini 2482e7801d59Ssowmini 2483e7801d59Ssowmini /* ARGSUSED */ 2484e7801d59Ssowmini static dladm_status_t 2485*4ac67f02SAnurag S. Maskey i_dladm_set_prop(dladm_handle_t handle, datalink_id_t linkid, 2486*4ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 2487*4ac67f02SAnurag S. Maskey 2488e7801d59Ssowmini { 2489bcb5c89dSSowmini Varadhan int i, slen; 2490eae72b5bSSebastien Roy int bufsize = 0; 24913fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 2492e7801d59Ssowmini uchar_t *dp; 2493bcb5c89dSSowmini Varadhan link_attr_t *p; 24944045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 2495e7801d59Ssowmini 2496e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 2497e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 2498e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2499e7801d59Ssowmini p = dladm_name2prop(prop_name); 25003fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 2501e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2502e7801d59Ssowmini 2503e7801d59Ssowmini /* 2504e7801d59Ssowmini * private properties: all parsing is done in the kernel. 2505e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 2506e7801d59Ssowmini */ 2507e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 2508e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 2509e7801d59Ssowmini } 25104045d941Ssowmini 25114045d941Ssowmini if (prop_val == NULL) { 25124045d941Ssowmini /* 25134045d941Ssowmini * getting default value. so use more buffer space. 25144045d941Ssowmini */ 2515bcb5c89dSSowmini Varadhan bufsize += DLADM_PROP_BUF_CHUNK; 25164045d941Ssowmini } 25174045d941Ssowmini 2518bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 25193fd94f8cSam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 2520e7801d59Ssowmini if (dip == NULL) 2521e7801d59Ssowmini return (status); 2522e7801d59Ssowmini 2523e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 2524e7801d59Ssowmini slen = 0; 2525bcb5c89dSSowmini Varadhan 25264045d941Ssowmini if (prop_val == NULL) { 2527*4ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_FALSE); 25284045d941Ssowmini } else { 2529e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 2530e7801d59Ssowmini int plen = 0; 2531e7801d59Ssowmini 2532e7801d59Ssowmini plen = strlen(prop_val[i]); 2533e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 2534e7801d59Ssowmini slen += plen; 2535e7801d59Ssowmini /* 2536e7801d59Ssowmini * add a "," separator and update dp. 2537e7801d59Ssowmini */ 2538e7801d59Ssowmini if (i != (val_cnt -1)) 2539e7801d59Ssowmini dp[slen++] = ','; 2540e7801d59Ssowmini dp += (plen + 1); 2541e7801d59Ssowmini } 2542*4ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 2543e7801d59Ssowmini } 25444045d941Ssowmini 2545e7801d59Ssowmini free(dip); 2546e7801d59Ssowmini return (status); 2547e7801d59Ssowmini } 2548e7801d59Ssowmini 2549e7801d59Ssowmini static dladm_status_t 2550*4ac67f02SAnurag S. Maskey i_dladm_get_prop(dladm_handle_t handle, datalink_id_t linkid, 2551*4ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cnt, 2552*4ac67f02SAnurag S. Maskey dladm_prop_type_t type, uint_t dld_flags) 2553e7801d59Ssowmini { 2554e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 25553fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 2556bcb5c89dSSowmini Varadhan link_attr_t *p; 2557e7801d59Ssowmini char tmp = '\0'; 2558e7801d59Ssowmini 2559e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 2560e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 2561e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2562e7801d59Ssowmini 2563e7801d59Ssowmini p = dladm_name2prop(prop_name); 25643fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 2565e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2566e7801d59Ssowmini 25674045d941Ssowmini if (type == DLADM_PROP_VAL_MODIFIABLE) { 2568e7801d59Ssowmini *prop_val = &tmp; 2569e7801d59Ssowmini *val_cnt = 1; 2570e7801d59Ssowmini return (DLADM_STATUS_OK); 2571e7801d59Ssowmini } 2572e7801d59Ssowmini 2573e7801d59Ssowmini /* 2574e7801d59Ssowmini * private properties: all parsing is done in the kernel. 2575e7801d59Ssowmini */ 2576bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 2577bcb5c89dSSowmini Varadhan dld_flags, &status); 2578e7801d59Ssowmini if (dip == NULL) 2579e7801d59Ssowmini return (status); 2580e7801d59Ssowmini 2581*4ac67f02SAnurag S. Maskey if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 2582*4ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 2583afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_PERM) { 2584da14cebeSEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 2585afdda45fSVasumathi Sundaram - Sun Microsystems } else { 2586afdda45fSVasumathi Sundaram - Sun Microsystems (void) strncpy(*prop_val, dip->pr_val, 2587afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_MAX); 2588afdda45fSVasumathi Sundaram - Sun Microsystems } 2589e7801d59Ssowmini *val_cnt = 1; 2590e7801d59Ssowmini } 25914045d941Ssowmini free(dip); 25924045d941Ssowmini return (status); 25934045d941Ssowmini } 25944045d941Ssowmini 25954045d941Ssowmini 25964045d941Ssowmini static dladm_status_t 2597*4ac67f02SAnurag S. Maskey i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 2598*4ac67f02SAnurag S. Maskey datalink_id_t linkid, datalink_media_t media, uint_t flags) 25994045d941Ssowmini { 26004045d941Ssowmini dladm_status_t status; 26014045d941Ssowmini char **prop_vals = NULL, *buf; 26024045d941Ssowmini size_t bufsize; 26034045d941Ssowmini uint_t cnt; 26044045d941Ssowmini int i; 2605afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 26064045d941Ssowmini 26074045d941Ssowmini /* 26084045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 26094045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 26104045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 26114045d941Ssowmini */ 26124045d941Ssowmini bufsize = 26134045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 26144045d941Ssowmini buf = malloc(bufsize); 26154045d941Ssowmini prop_vals = (char **)(void *)buf; 26164045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 26174045d941Ssowmini prop_vals[i] = buf + 26184045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 26194045d941Ssowmini i * DLADM_PROP_VAL_MAX; 26204045d941Ssowmini } 262113a55820Sar224390 262213a55820Sar224390 /* 26233bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 26243bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 26253bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 26263bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 26273bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 26283bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 26293bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 26303bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 263113a55820Sar224390 */ 2632*4ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 2633afdda45fSVasumathi Sundaram - Sun Microsystems MAC_PROP_DEFAULT, &perm_flags); 26344045d941Ssowmini if (status == DLADM_STATUS_OK) { 2635afdda45fSVasumathi Sundaram - Sun Microsystems if (perm_flags == MAC_PROP_PERM_RW) { 2636*4ac67f02SAnurag S. Maskey status = i_dladm_set_single_prop(handle, linkid, 2637*4ac67f02SAnurag S. Maskey pdp->pd_class, media, pdp, prop_vals, cnt, flags); 26384045d941Ssowmini } 2639afdda45fSVasumathi Sundaram - Sun Microsystems else 2640afdda45fSVasumathi Sundaram - Sun Microsystems status = DLADM_STATUS_NOTSUP; 2641afdda45fSVasumathi Sundaram - Sun Microsystems } 26424045d941Ssowmini free(buf); 2643e7801d59Ssowmini return (status); 2644e7801d59Ssowmini } 2645bcb5c89dSSowmini Varadhan 2646bcb5c89dSSowmini Varadhan int 2647bcb5c89dSSowmini Varadhan macprop_to_wifi(mac_prop_id_t wl_prop) 2648bcb5c89dSSowmini Varadhan { 2649bcb5c89dSSowmini Varadhan switch (wl_prop) { 2650bcb5c89dSSowmini Varadhan case MAC_PROP_WL_ESSID: 2651bcb5c89dSSowmini Varadhan return (WL_ESSID); 2652bcb5c89dSSowmini Varadhan case MAC_PROP_WL_BSSID: 2653bcb5c89dSSowmini Varadhan return (WL_BSSID); 2654bcb5c89dSSowmini Varadhan case MAC_PROP_WL_BSSTYPE: 2655bcb5c89dSSowmini Varadhan return (WL_BSS_TYPE); 2656bcb5c89dSSowmini Varadhan case MAC_PROP_WL_LINKSTATUS: 2657bcb5c89dSSowmini Varadhan return (WL_LINKSTATUS); 2658bcb5c89dSSowmini Varadhan case MAC_PROP_WL_DESIRED_RATES: 2659bcb5c89dSSowmini Varadhan return (WL_DESIRED_RATES); 2660bcb5c89dSSowmini Varadhan case MAC_PROP_WL_SUPPORTED_RATES: 2661bcb5c89dSSowmini Varadhan return (WL_SUPPORTED_RATES); 2662bcb5c89dSSowmini Varadhan case MAC_PROP_WL_AUTH_MODE: 2663bcb5c89dSSowmini Varadhan return (WL_AUTH_MODE); 2664bcb5c89dSSowmini Varadhan case MAC_PROP_WL_ENCRYPTION: 2665bcb5c89dSSowmini Varadhan return (WL_ENCRYPTION); 2666bcb5c89dSSowmini Varadhan case MAC_PROP_WL_RSSI: 2667bcb5c89dSSowmini Varadhan return (WL_RSSI); 2668bcb5c89dSSowmini Varadhan case MAC_PROP_WL_PHY_CONFIG: 2669bcb5c89dSSowmini Varadhan return (WL_PHY_CONFIG); 2670bcb5c89dSSowmini Varadhan case MAC_PROP_WL_CAPABILITY: 2671bcb5c89dSSowmini Varadhan return (WL_CAPABILITY); 2672bcb5c89dSSowmini Varadhan case MAC_PROP_WL_WPA: 2673bcb5c89dSSowmini Varadhan return (WL_WPA); 2674bcb5c89dSSowmini Varadhan case MAC_PROP_WL_SCANRESULTS: 2675bcb5c89dSSowmini Varadhan return (WL_SCANRESULTS); 2676bcb5c89dSSowmini Varadhan case MAC_PROP_WL_POWER_MODE: 2677bcb5c89dSSowmini Varadhan return (WL_POWER_MODE); 2678bcb5c89dSSowmini Varadhan case MAC_PROP_WL_RADIO: 2679bcb5c89dSSowmini Varadhan return (WL_RADIO); 2680bcb5c89dSSowmini Varadhan case MAC_PROP_WL_ESS_LIST: 2681bcb5c89dSSowmini Varadhan return (WL_ESS_LIST); 2682bcb5c89dSSowmini Varadhan case MAC_PROP_WL_KEY_TAB: 2683bcb5c89dSSowmini Varadhan return (WL_WEP_KEY_TAB); 2684bcb5c89dSSowmini Varadhan case MAC_PROP_WL_CREATE_IBSS: 2685bcb5c89dSSowmini Varadhan return (WL_CREATE_IBSS); 2686bcb5c89dSSowmini Varadhan case MAC_PROP_WL_SETOPTIE: 2687bcb5c89dSSowmini Varadhan return (WL_SETOPTIE); 2688bcb5c89dSSowmini Varadhan case MAC_PROP_WL_DELKEY: 2689bcb5c89dSSowmini Varadhan return (WL_DELKEY); 2690bcb5c89dSSowmini Varadhan case MAC_PROP_WL_KEY: 2691bcb5c89dSSowmini Varadhan return (WL_KEY); 2692bcb5c89dSSowmini Varadhan case MAC_PROP_WL_MLME: 2693bcb5c89dSSowmini Varadhan return (WL_MLME); 2694bcb5c89dSSowmini Varadhan default: 2695bcb5c89dSSowmini Varadhan return (-1); 2696bcb5c89dSSowmini Varadhan } 2697bcb5c89dSSowmini Varadhan } 2698bcb5c89dSSowmini Varadhan 2699bcb5c89dSSowmini Varadhan dladm_status_t 2700*4ac67f02SAnurag S. Maskey i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 2701*4ac67f02SAnurag S. Maskey mac_prop_id_t cmd, size_t len, boolean_t set) 2702bcb5c89dSSowmini Varadhan { 2703bcb5c89dSSowmini Varadhan uint32_t flags; 2704bcb5c89dSSowmini Varadhan dladm_status_t status; 2705bcb5c89dSSowmini Varadhan uint32_t media; 2706bcb5c89dSSowmini Varadhan dld_ioc_macprop_t *dip; 2707bcb5c89dSSowmini Varadhan void *dp; 2708bcb5c89dSSowmini Varadhan 2709*4ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 2710*4ac67f02SAnurag S. Maskey &media, NULL, 0)) != DLADM_STATUS_OK) { 2711bcb5c89dSSowmini Varadhan return (status); 2712bcb5c89dSSowmini Varadhan } 2713bcb5c89dSSowmini Varadhan 2714bcb5c89dSSowmini Varadhan if (media != DL_WIFI) 2715bcb5c89dSSowmini Varadhan return (DLADM_STATUS_BADARG); 2716bcb5c89dSSowmini Varadhan 2717bcb5c89dSSowmini Varadhan if (!(flags & DLADM_OPT_ACTIVE)) 2718bcb5c89dSSowmini Varadhan return (DLADM_STATUS_TEMPONLY); 2719bcb5c89dSSowmini Varadhan 2720bcb5c89dSSowmini Varadhan if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 2721bcb5c89dSSowmini Varadhan len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 2722bcb5c89dSSowmini Varadhan 2723bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 2724bcb5c89dSSowmini Varadhan if (dip == NULL) 2725bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2726bcb5c89dSSowmini Varadhan 2727bcb5c89dSSowmini Varadhan dp = (uchar_t *)dip->pr_val; 2728bcb5c89dSSowmini Varadhan if (set) 2729bcb5c89dSSowmini Varadhan (void) memcpy(dp, buf, len); 2730bcb5c89dSSowmini Varadhan 2731*4ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, set); 2732bcb5c89dSSowmini Varadhan if (status == DLADM_STATUS_NOTSUP) { 2733bcb5c89dSSowmini Varadhan if (set) { 2734*4ac67f02SAnurag S. Maskey status = i_dladm_wlan_set_legacy_ioctl(handle, linkid, 2735bcb5c89dSSowmini Varadhan buf, len, macprop_to_wifi(cmd)); 2736bcb5c89dSSowmini Varadhan } else { 2737*4ac67f02SAnurag S. Maskey status = i_dladm_wlan_get_legacy_ioctl(handle, linkid, 2738bcb5c89dSSowmini Varadhan buf, len, macprop_to_wifi(cmd)); 2739bcb5c89dSSowmini Varadhan } 2740bcb5c89dSSowmini Varadhan } else if (status == DLADM_STATUS_OK) { 2741bcb5c89dSSowmini Varadhan if (!set) 2742bcb5c89dSSowmini Varadhan (void) memcpy(buf, dp, len); 2743bcb5c89dSSowmini Varadhan } 2744bcb5c89dSSowmini Varadhan 2745bcb5c89dSSowmini Varadhan free(dip); 2746bcb5c89dSSowmini Varadhan return (status); 2747bcb5c89dSSowmini Varadhan } 2748bcb5c89dSSowmini Varadhan 2749bcb5c89dSSowmini Varadhan static dladm_status_t 2750*4ac67f02SAnurag S. Maskey i_dladm_wlan_get_legacy_ioctl(dladm_handle_t handle, datalink_id_t linkid, 2751*4ac67f02SAnurag S. Maskey void *buf, uint_t buflen, uint_t id) 2752bcb5c89dSSowmini Varadhan { 2753bcb5c89dSSowmini Varadhan wldp_t *gbuf; 2754bcb5c89dSSowmini Varadhan dladm_status_t status; 2755bcb5c89dSSowmini Varadhan 2756bcb5c89dSSowmini Varadhan if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 2757bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2758bcb5c89dSSowmini Varadhan 2759bcb5c89dSSowmini Varadhan (void) memset(gbuf, 0, MAX_BUF_LEN); 2760*4ac67f02SAnurag S. Maskey status = i_dladm_wlan_legacy_ioctl(handle, linkid, gbuf, id, 2761*4ac67f02SAnurag S. Maskey MAX_BUF_LEN, WLAN_GET_PARAM, sizeof (wldp_t)); 2762bcb5c89dSSowmini Varadhan if (status == DLADM_STATUS_OK) 2763bcb5c89dSSowmini Varadhan (void) memcpy(buf, gbuf->wldp_buf, buflen); 2764bcb5c89dSSowmini Varadhan 2765bcb5c89dSSowmini Varadhan free(gbuf); 2766bcb5c89dSSowmini Varadhan return (status); 2767bcb5c89dSSowmini Varadhan } 2768bcb5c89dSSowmini Varadhan 2769bcb5c89dSSowmini Varadhan static dladm_status_t 2770*4ac67f02SAnurag S. Maskey i_dladm_wlan_set_legacy_ioctl(dladm_handle_t handle, datalink_id_t linkid, 2771*4ac67f02SAnurag S. Maskey void *buf, uint_t buflen, uint_t id) 2772bcb5c89dSSowmini Varadhan { 2773bcb5c89dSSowmini Varadhan wldp_t *gbuf; 2774bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 2775bcb5c89dSSowmini Varadhan 2776bcb5c89dSSowmini Varadhan if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 2777bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2778bcb5c89dSSowmini Varadhan 2779bcb5c89dSSowmini Varadhan (void) memset(gbuf, 0, MAX_BUF_LEN); 2780bcb5c89dSSowmini Varadhan (void) memcpy(gbuf->wldp_buf, buf, buflen); 2781bcb5c89dSSowmini Varadhan buflen += WIFI_BUF_OFFSET; 2782*4ac67f02SAnurag S. Maskey status = i_dladm_wlan_legacy_ioctl(handle, linkid, gbuf, id, buflen, 2783bcb5c89dSSowmini Varadhan WLAN_SET_PARAM, buflen); 2784bcb5c89dSSowmini Varadhan 2785bcb5c89dSSowmini Varadhan free(gbuf); 2786bcb5c89dSSowmini Varadhan return (status); 2787bcb5c89dSSowmini Varadhan } 2788da14cebeSEric Cheng 2789da14cebeSEric Cheng static dladm_status_t 2790da14cebeSEric Cheng link_proplist_check(dladm_arg_list_t *proplist) 2791da14cebeSEric Cheng { 2792da14cebeSEric Cheng int i, j; 2793da14cebeSEric Cheng boolean_t matched; 2794da14cebeSEric Cheng 2795da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 2796da14cebeSEric Cheng matched = B_FALSE; 2797da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_PROPS; j++) { 2798da14cebeSEric Cheng if (strcmp(proplist->al_info[i].ai_name, 2799da14cebeSEric Cheng prop_table[j].pd_name) == 0) 2800da14cebeSEric Cheng matched = B_TRUE; 2801da14cebeSEric Cheng } 2802da14cebeSEric Cheng if (!matched) 2803da14cebeSEric Cheng return (DLADM_STATUS_BADPROP); 2804da14cebeSEric Cheng } 2805da14cebeSEric Cheng return (DLADM_STATUS_OK); 2806da14cebeSEric Cheng } 2807da14cebeSEric Cheng 2808da14cebeSEric Cheng dladm_status_t 2809da14cebeSEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 2810da14cebeSEric Cheng { 2811da14cebeSEric Cheng dladm_status_t status; 2812da14cebeSEric Cheng 2813da14cebeSEric Cheng status = dladm_parse_args(str, listp, novalues); 2814da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2815da14cebeSEric Cheng return (status); 2816da14cebeSEric Cheng 2817da14cebeSEric Cheng status = link_proplist_check(*listp); 2818da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 2819da14cebeSEric Cheng dladm_free_props(*listp); 2820da14cebeSEric Cheng return (status); 2821da14cebeSEric Cheng } 2822da14cebeSEric Cheng 2823da14cebeSEric Cheng return (DLADM_STATUS_OK); 2824da14cebeSEric Cheng } 2825da14cebeSEric Cheng 2826da14cebeSEric Cheng /* 2827da14cebeSEric Cheng * Retrieve the one link property from the database 2828da14cebeSEric Cheng */ 2829da14cebeSEric Cheng /*ARGSUSED*/ 2830da14cebeSEric Cheng static int 2831*4ac67f02SAnurag S. Maskey i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 2832*4ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 2833da14cebeSEric Cheng { 2834da14cebeSEric Cheng dladm_arg_list_t *proplist = arg; 2835da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 2836da14cebeSEric Cheng 2837da14cebeSEric Cheng aip = &proplist->al_info[proplist->al_count]; 2838da14cebeSEric Cheng /* 2839da14cebeSEric Cheng * it is fine to point to prop_name since prop_name points to the 2840da14cebeSEric Cheng * prop_table[n].pd_name. 2841da14cebeSEric Cheng */ 2842da14cebeSEric Cheng aip->ai_name = prop_name; 2843da14cebeSEric Cheng 2844*4ac67f02SAnurag S. Maskey (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 2845*4ac67f02SAnurag S. Maskey prop_name, aip->ai_val, &aip->ai_count); 2846da14cebeSEric Cheng 2847da14cebeSEric Cheng if (aip->ai_count != 0) 2848da14cebeSEric Cheng proplist->al_count++; 2849da14cebeSEric Cheng 2850da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 2851da14cebeSEric Cheng } 2852da14cebeSEric Cheng 2853da14cebeSEric Cheng 2854da14cebeSEric Cheng /* 2855da14cebeSEric Cheng * Retrieve all link properties for a link from the database and 2856da14cebeSEric Cheng * return a property list. 2857da14cebeSEric Cheng */ 2858da14cebeSEric Cheng dladm_status_t 2859*4ac67f02SAnurag S. Maskey dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 2860*4ac67f02SAnurag S. Maskey dladm_arg_list_t **listp) 2861da14cebeSEric Cheng { 2862da14cebeSEric Cheng dladm_arg_list_t *list; 2863da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 2864da14cebeSEric Cheng 2865da14cebeSEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 2866da14cebeSEric Cheng if (list == NULL) 2867da14cebeSEric Cheng return (dladm_errno2status(errno)); 2868da14cebeSEric Cheng 2869*4ac67f02SAnurag S. Maskey status = dladm_walk_linkprop(handle, linkid, list, 2870*4ac67f02SAnurag S. Maskey i_dladm_get_one_prop); 2871da14cebeSEric Cheng 2872da14cebeSEric Cheng *listp = list; 2873da14cebeSEric Cheng return (status); 2874da14cebeSEric Cheng } 2875da14cebeSEric Cheng 2876da14cebeSEric Cheng /* 2877da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 2878da14cebeSEric Cheng * convert to a kernel structure. 2879da14cebeSEric Cheng */ 2880da14cebeSEric Cheng static dladm_status_t 2881*4ac67f02SAnurag S. Maskey i_dladm_link_proplist_extract_one(dladm_handle_t handle, 2882*4ac67f02SAnurag S. Maskey dladm_arg_list_t *proplist, const char *name, void *val) 2883da14cebeSEric Cheng { 2884da14cebeSEric Cheng dladm_status_t status; 2885da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 2886da14cebeSEric Cheng int i, j; 2887da14cebeSEric Cheng 2888da14cebeSEric Cheng /* Find named property in proplist */ 2889da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 2890da14cebeSEric Cheng aip = &proplist->al_info[i]; 2891da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 2892da14cebeSEric Cheng break; 2893da14cebeSEric Cheng } 2894da14cebeSEric Cheng 2895da14cebeSEric Cheng /* Property not in list */ 2896da14cebeSEric Cheng if (i == proplist->al_count) 2897da14cebeSEric Cheng return (DLADM_STATUS_OK); 2898da14cebeSEric Cheng 2899da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 2900da14cebeSEric Cheng prop_desc_t *pdp = &prop_table[i]; 2901da14cebeSEric Cheng val_desc_t *vdp; 2902da14cebeSEric Cheng 2903da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 2904da14cebeSEric Cheng if (vdp == NULL) 2905da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 2906da14cebeSEric Cheng 2907da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 2908da14cebeSEric Cheng continue; 2909da14cebeSEric Cheng 2910da14cebeSEric Cheng if (aip->ai_val == NULL) 2911da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 2912da14cebeSEric Cheng 2913da14cebeSEric Cheng /* Check property value */ 2914da14cebeSEric Cheng if (pdp->pd_check != NULL) { 2915*4ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 2916da14cebeSEric Cheng aip->ai_count, vdp, 0); 2917da14cebeSEric Cheng } else { 2918da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 2919da14cebeSEric Cheng } 2920da14cebeSEric Cheng 2921da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2922da14cebeSEric Cheng return (status); 2923da14cebeSEric Cheng 2924da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 2925da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 2926da14cebeSEric Cheng 2927da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 2928da14cebeSEric Cheng continue; 2929da14cebeSEric Cheng 2930da14cebeSEric Cheng /* Extract kernel structure */ 2931da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 2932da14cebeSEric Cheng status = rpp->rp_extract(vdp, val, 2933da14cebeSEric Cheng aip->ai_count); 2934da14cebeSEric Cheng } else { 2935da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 2936da14cebeSEric Cheng } 2937da14cebeSEric Cheng break; 2938da14cebeSEric Cheng } 2939da14cebeSEric Cheng 2940da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2941da14cebeSEric Cheng return (status); 2942da14cebeSEric Cheng 2943da14cebeSEric Cheng break; 2944da14cebeSEric Cheng } 2945da14cebeSEric Cheng return (status); 2946da14cebeSEric Cheng } 2947da14cebeSEric Cheng 2948da14cebeSEric Cheng /* 2949da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 2950da14cebeSEric Cheng */ 2951da14cebeSEric Cheng dladm_status_t 2952*4ac67f02SAnurag S. Maskey dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 2953da14cebeSEric Cheng mac_resource_props_t *mrp) 2954da14cebeSEric Cheng { 2955da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 2956da14cebeSEric Cheng 2957*4ac67f02SAnurag S. Maskey status = i_dladm_link_proplist_extract_one(handle, proplist, "maxbw", 2958*4ac67f02SAnurag S. Maskey mrp); 2959da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2960da14cebeSEric Cheng return (status); 2961*4ac67f02SAnurag S. Maskey status = i_dladm_link_proplist_extract_one(handle, proplist, "priority", 2962*4ac67f02SAnurag S. Maskey mrp); 2963da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2964da14cebeSEric Cheng return (status); 2965*4ac67f02SAnurag S. Maskey status = i_dladm_link_proplist_extract_one(handle, proplist, "cpus", 2966*4ac67f02SAnurag S. Maskey mrp); 2967da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 2968da14cebeSEric Cheng return (status); 2969da14cebeSEric Cheng return (status); 2970da14cebeSEric Cheng } 2971da14cebeSEric Cheng 2972da14cebeSEric Cheng static const char * 2973da14cebeSEric Cheng dladm_perm2str(uint_t perm, char *buf) 2974da14cebeSEric Cheng { 2975da14cebeSEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 2976da14cebeSEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 2977da14cebeSEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 2978da14cebeSEric Cheng return (buf); 2979da14cebeSEric Cheng } 29804784fcbdSSowmini Varadhan 29814784fcbdSSowmini Varadhan dladm_status_t 2982*4ac67f02SAnurag S. Maskey i_dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 2983*4ac67f02SAnurag S. Maskey link_state_t *state) 29844784fcbdSSowmini Varadhan { 29854784fcbdSSowmini Varadhan dld_ioc_macprop_t *dip; 29864784fcbdSSowmini Varadhan dladm_status_t status; 29874784fcbdSSowmini Varadhan uint_t perms; 29884784fcbdSSowmini Varadhan 2989*4ac67f02SAnurag S. Maskey dip = i_dladm_get_public_prop(handle, linkid, "state", 0, &status, 2990*4ac67f02SAnurag S. Maskey &perms); 29914784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 29924784fcbdSSowmini Varadhan return (status); 29934784fcbdSSowmini Varadhan (void) memcpy(state, dip->pr_val, sizeof (*state)); 29944784fcbdSSowmini Varadhan free(dip); 29954784fcbdSSowmini Varadhan return (status); 29964784fcbdSSowmini Varadhan } 2997