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> 44f4b3ec61Sdh155122 #include <dlfcn.h> 45f4b3ec61Sdh155122 #include <link.h> 46d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 47e7801d59Ssowmini #include <libdladm.h> 48e7801d59Ssowmini #include <sys/param.h> 49e7801d59Ssowmini #include <inttypes.h> 50e7801d59Ssowmini #include <sys/ethernet.h> 51f4b3ec61Sdh155122 52d62bc4baSyz147064 /* 53d62bc4baSyz147064 * The linkprop get() callback. 54e7801d59Ssowmini * - pd: pointer to the struct prop_desc 55d62bc4baSyz147064 * - propstrp: a property string array to keep the returned property. 56d62bc4baSyz147064 * Caller allocated. 57d62bc4baSyz147064 * - cntp: number of returned properties. 58d62bc4baSyz147064 * Caller also uses it to indicate how many it expects. 59d62bc4baSyz147064 */ 60e7801d59Ssowmini struct prop_desc; 61e7801d59Ssowmini 62e7801d59Ssowmini typedef dladm_status_t pd_getf_t(struct prop_desc *pd, 636b9e797cSsowmini datalink_id_t, char **propstp, uint_t *cntp, 644045d941Ssowmini datalink_media_t, uint_t); 65f4b3ec61Sdh155122 66d62bc4baSyz147064 /* 67d62bc4baSyz147064 * The linkprop set() callback. 68d62bc4baSyz147064 * - propval: a val_desc_t array which keeps the property values to be set. 69d62bc4baSyz147064 * - cnt: number of properties to be set. 70e7801d59Ssowmini * - flags: additional flags passed down the system call. 71e7801d59Ssowmini * 72e7801d59Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 73e7801d59Ssowmini * a format suitable for kernel consumption. This may require allocation 74e7801d59Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 75e7801d59Ssowmini * by all other pd_sets) which invokes the ioctl. 76d62bc4baSyz147064 */ 77e7801d59Ssowmini typedef dladm_status_t pd_setf_t(struct prop_desc *, datalink_id_t, 786b9e797cSsowmini val_desc_t *propval, uint_t cnt, uint_t flags, 796b9e797cSsowmini datalink_media_t); 80f4b3ec61Sdh155122 81f4b3ec61Sdh155122 82d62bc4baSyz147064 /* 83d62bc4baSyz147064 * The linkprop check() callback. 84d62bc4baSyz147064 * - propstrp: property string array which keeps the property to be checked. 85d62bc4baSyz147064 * - cnt: number of properties. 86d62bc4baSyz147064 * - propval: return value; the property values of the given property strings. 87e7801d59Ssowmini * 88e7801d59Ssowmini * pd_check checks that the input values are valid. It does so by 89e7801d59Ssowmini * iteraring through the pd_modval list for the property. If 90e7801d59Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 91e7801d59Ssowmini * specific to this property can be used. If the input values are 92e7801d59Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 93e7801d59Ssowmini * with either a val_desc_t found on the pd_modval list or something 94e7801d59Ssowmini * generated on the fly. 95d62bc4baSyz147064 */ 96e7801d59Ssowmini typedef dladm_status_t pd_checkf_t(struct prop_desc *pd, 97e7801d59Ssowmini datalink_id_t, char **propstrp, 986b9e797cSsowmini uint_t cnt, val_desc_t *propval, 996b9e797cSsowmini datalink_media_t); 100f4b3ec61Sdh155122 101*3bc21d0aSAruna Ramakrishna - Sun Microsystems typedef struct dladm_public_prop_s { 1023fd94f8cSam223141 mac_prop_id_t pp_id; 103e7801d59Ssowmini size_t pp_valsize; 104e7801d59Ssowmini char *pp_name; 105e7801d59Ssowmini char *pp_desc; 106*3bc21d0aSAruna Ramakrishna - Sun Microsystems } dladm_public_prop_t; 107e7801d59Ssowmini 108*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dld_ioc_macprop_t *i_dladm_buf_alloc(size_t, datalink_id_t, const char *, 1094045d941Ssowmini uint_t, dladm_status_t *); 110*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **, 111e7801d59Ssowmini uint_t, uint_t); 112*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **, 1134045d941Ssowmini uint_t *, dladm_prop_type_t, uint_t); 114*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_public_prop_t *dladm_name2prop(const char *); 115*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t, 116*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t *); 117d62bc4baSyz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 118d62bc4baSyz147064 do_get_rate_prop, do_get_channel_prop, 119e7801d59Ssowmini do_get_powermode_prop, do_get_radio_prop, 120*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_duplex_get, i_dladm_status_get, 121*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_binary_get, i_dladm_uint32_get, 122*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_flowctl_get; 123*3bc21d0aSAruna Ramakrishna - Sun Microsystems static pd_setf_t do_set_zone, do_set_rate_prop, 124e7801d59Ssowmini do_set_powermode_prop, do_set_radio_prop, 125*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop; 126e7801d59Ssowmini static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 127*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_defmtu_check; 128f4b3ec61Sdh155122 129*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_speed_get(struct prop_desc *, datalink_id_t, 1304045d941Ssowmini char **, uint_t *, uint_t); 1316b9e797cSsowmini 132f4b3ec61Sdh155122 typedef struct prop_desc { 133d62bc4baSyz147064 /* 134d62bc4baSyz147064 * link property name 135d62bc4baSyz147064 */ 136f4b3ec61Sdh155122 char *pd_name; 137d62bc4baSyz147064 138d62bc4baSyz147064 /* 139d62bc4baSyz147064 * default property value, can be set to { "", NULL } 140d62bc4baSyz147064 */ 141f4b3ec61Sdh155122 val_desc_t pd_defval; 142d62bc4baSyz147064 143d62bc4baSyz147064 /* 144d62bc4baSyz147064 * list of optional property values, can be NULL. 145d62bc4baSyz147064 * 146d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 147d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 148d62bc4baSyz147064 */ 149d62bc4baSyz147064 val_desc_t *pd_optval; 150d62bc4baSyz147064 151d62bc4baSyz147064 /* 152d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 153d62bc4baSyz147064 */ 154d62bc4baSyz147064 uint_t pd_noptval; 155d62bc4baSyz147064 156d62bc4baSyz147064 /* 157d62bc4baSyz147064 * callback to set link property; 158d62bc4baSyz147064 * set to NULL if this property is read-only 159d62bc4baSyz147064 */ 160f4b3ec61Sdh155122 pd_setf_t *pd_set; 161d62bc4baSyz147064 162d62bc4baSyz147064 /* 163d62bc4baSyz147064 * callback to get modifiable link property 164d62bc4baSyz147064 */ 165f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 166d62bc4baSyz147064 167d62bc4baSyz147064 /* 168d62bc4baSyz147064 * callback to get current link property 169d62bc4baSyz147064 */ 170f4b3ec61Sdh155122 pd_getf_t *pd_get; 171d62bc4baSyz147064 172d62bc4baSyz147064 /* 173d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 174d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 175d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 176d62bc4baSyz147064 * valid. 177d62bc4baSyz147064 */ 178f4b3ec61Sdh155122 pd_checkf_t *pd_check; 179d62bc4baSyz147064 180d62bc4baSyz147064 uint_t pd_flags; 181e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 182e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 183d62bc4baSyz147064 /* 184d62bc4baSyz147064 * indicate link classes this property applies to. 185d62bc4baSyz147064 */ 186d62bc4baSyz147064 datalink_class_t pd_class; 187d62bc4baSyz147064 188d62bc4baSyz147064 /* 189d62bc4baSyz147064 * indicate link media type this property applies to. 190d62bc4baSyz147064 */ 191d62bc4baSyz147064 datalink_media_t pd_dmedia; 192f4b3ec61Sdh155122 } prop_desc_t; 193f4b3ec61Sdh155122 1943fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 195e7801d59Ssowmini 196e7801d59Ssowmini 197*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_public_prop_t dladm_prop[] = { 1983fd94f8cSam223141 { MAC_PROP_DUPLEX, sizeof (link_duplex_t), 1996b9e797cSsowmini "duplex", "link duplex mode" }, 200e7801d59Ssowmini 2013fd94f8cSam223141 {MAC_PROP_SPEED, sizeof (uint64_t), 2026b9e797cSsowmini "speed", "link speed (bps)" }, 203e7801d59Ssowmini 2043fd94f8cSam223141 { MAC_PROP_STATUS, sizeof (link_state_t), 2056b9e797cSsowmini "state", "link up/down" }, 206e7801d59Ssowmini 2073fd94f8cSam223141 { MAC_PROP_AUTONEG, sizeof (uint8_t), 208e7801d59Ssowmini "adv_autoneg_cap", "Advertised auto-negotiation" }, 209e7801d59Ssowmini 2103fd94f8cSam223141 { MAC_PROP_MTU, sizeof (uint32_t), 2116b9e797cSsowmini "mtu", "current link mtu" }, 212e7801d59Ssowmini 2133fd94f8cSam223141 { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), 214e7801d59Ssowmini "flowctrl", "flowcontrol" }, 215e7801d59Ssowmini 216*3bc21d0aSAruna Ramakrishna - Sun Microsystems { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), 217*3bc21d0aSAruna Ramakrishna - Sun Microsystems "zone", "non-global zones" }, 218*3bc21d0aSAruna Ramakrishna - Sun Microsystems 219*3bc21d0aSAruna Ramakrishna - Sun Microsystems { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), 220*3bc21d0aSAruna Ramakrishna - Sun Microsystems "autopush", "autopush modules" }, 221*3bc21d0aSAruna Ramakrishna - Sun Microsystems 2223fd94f8cSam223141 { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), 223e7801d59Ssowmini "adv_1000fdx_cap", "Adv 1000 Mbps fdx" }, 224e7801d59Ssowmini 2253fd94f8cSam223141 { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), 226e7801d59Ssowmini "en_1000fdx_cap", "Enable 1000 Mbps fdx" }, 227e7801d59Ssowmini 2283fd94f8cSam223141 { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), 229e7801d59Ssowmini "adv_1000hdx_cap", "Adv 1000 Mbps hdx" }, 230e7801d59Ssowmini 2313fd94f8cSam223141 { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), 232e7801d59Ssowmini "en_1000hdx_cap", "Enable 1000 Mbps hdx" }, 233e7801d59Ssowmini 2343fd94f8cSam223141 { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), 235e7801d59Ssowmini "adv_100fdx_cap", "Adv 100 Mbps fdx" }, 236e7801d59Ssowmini 2373fd94f8cSam223141 { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), 238e7801d59Ssowmini "en_100fdx_cap", "Enable 100 Mbps fdx" }, 239e7801d59Ssowmini 2403fd94f8cSam223141 { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), 241e7801d59Ssowmini "adv_100hdx_cap", "Adv 100 Mbps hdx" }, 242e7801d59Ssowmini 2433fd94f8cSam223141 { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), 244e7801d59Ssowmini "en_100hdx_cap", "Enable 100 Mbps hdx" }, 245e7801d59Ssowmini 2463fd94f8cSam223141 { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), 247e7801d59Ssowmini "adv_10fdx_cap", "Adv 10 Mbps fdx" }, 248e7801d59Ssowmini 2493fd94f8cSam223141 { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), 250e7801d59Ssowmini "en_10fdx_cap", "Enable 10 Mbps fdx" }, 251e7801d59Ssowmini 2523fd94f8cSam223141 { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), 253e7801d59Ssowmini "adv_10hdx_cap", "Adv 10 Mbps hdx" }, 254e7801d59Ssowmini 2553fd94f8cSam223141 { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), 256e7801d59Ssowmini "en_10hdx_cap", "Enable 10 Mbps hdx" }, 257e7801d59Ssowmini 2583fd94f8cSam223141 { MAC_PROP_PRIVATE, 0, 259e7801d59Ssowmini "driver-private", "" } 260e7801d59Ssowmini }; 261e7801d59Ssowmini 262e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 263e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 264e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 265e7801d59Ssowmini }; 266e7801d59Ssowmini static val_desc_t link_status_vals[] = { 267e7801d59Ssowmini { "up", LINK_STATE_UP }, 268e7801d59Ssowmini { "down", LINK_STATE_DOWN } 269e7801d59Ssowmini }; 270e7801d59Ssowmini static val_desc_t link_01_vals[] = { 271e7801d59Ssowmini { "1", 1 }, 272e7801d59Ssowmini { "0", 0 } 273e7801d59Ssowmini }; 274e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 275e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 276e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 277e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 278e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 279e7801d59Ssowmini }; 280e7801d59Ssowmini 281e7801d59Ssowmini #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 282e7801d59Ssowmini 283d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 284d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 285d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 286d62bc4baSyz147064 }; 287d62bc4baSyz147064 288d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 289d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 290d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 291d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 292d62bc4baSyz147064 }; 293d62bc4baSyz147064 294f4b3ec61Sdh155122 static prop_desc_t prop_table[] = { 295d62bc4baSyz147064 296e7801d59Ssowmini { "channel", { NULL, 0 }, 297e7801d59Ssowmini NULL, 0, NULL, NULL, 298d62bc4baSyz147064 do_get_channel_prop, NULL, 0, 299d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 300d62bc4baSyz147064 301d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 302d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 303d62bc4baSyz147064 do_set_powermode_prop, NULL, 304d62bc4baSyz147064 do_get_powermode_prop, NULL, 0, 305d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 306d62bc4baSyz147064 307d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 308d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 309d62bc4baSyz147064 do_set_radio_prop, NULL, 310d62bc4baSyz147064 do_get_radio_prop, NULL, 0, 311d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 312d62bc4baSyz147064 313d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 314d62bc4baSyz147064 do_set_rate_prop, do_get_rate_mod, 315d62bc4baSyz147064 do_get_rate_prop, do_check_rate, 0, 3166b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 317d62bc4baSyz147064 3184045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 319*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, 320*3bc21d0aSAruna Ramakrishna - Sun Microsystems do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 321d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 322d62bc4baSyz147064 3234045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 324f4b3ec61Sdh155122 do_set_zone, NULL, 325*3bc21d0aSAruna Ramakrishna - Sun Microsystems do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 326e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 327e7801d59Ssowmini 3284045d941Ssowmini { "duplex", { "", 0 }, 329e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 330*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_duplex_get, NULL, 331e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 332e7801d59Ssowmini 3336b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 334e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 335*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_status_get, NULL, 3364045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 337e7801d59Ssowmini 338e7801d59Ssowmini { "adv_autoneg_cap", { "1", 1 }, 339e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 340*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 341e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 342e7801d59Ssowmini 3434045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 344*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 345*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_defmtu_check, 0, DATALINK_CLASS_ALL, 346*3bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 347e7801d59Ssowmini 3484045d941Ssowmini { "flowctrl", { "", 0 }, 349e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 350*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 351e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 352e7801d59Ssowmini 3534045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 3544045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 355*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 356e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 357e7801d59Ssowmini 3584045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 359e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 360*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 361e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 362e7801d59Ssowmini 3634045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 364e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 365*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 366e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 367e7801d59Ssowmini 3684045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 369e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 370*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 371e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 372e7801d59Ssowmini 3734045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 374e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 375*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 376e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 377e7801d59Ssowmini 3784045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 379e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 380*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 381e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 382e7801d59Ssowmini 3834045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 384e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 385*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 386e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 387e7801d59Ssowmini 3884045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 389e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 390*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 391e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 392e7801d59Ssowmini 3934045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 394e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 395*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 396e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 397e7801d59Ssowmini 3984045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 399e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 400*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 401e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 402e7801d59Ssowmini 4034045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 404e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 405*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, NULL, i_dladm_binary_get, NULL, 406e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 407e7801d59Ssowmini 4084045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 409e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 410*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 411e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER } 412e7801d59Ssowmini 413f4b3ec61Sdh155122 }; 414f4b3ec61Sdh155122 415d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 4160ba2cbe9Sxc151355 417d62bc4baSyz147064 static dladm_status_t i_dladm_set_linkprop_db(datalink_id_t, const char *, 418d62bc4baSyz147064 char **, uint_t); 419d62bc4baSyz147064 static dladm_status_t i_dladm_get_linkprop_db(datalink_id_t, const char *, 420d62bc4baSyz147064 char **, uint_t *); 421d62bc4baSyz147064 static dladm_status_t i_dladm_set_single_prop(datalink_id_t, datalink_class_t, 422d62bc4baSyz147064 uint32_t, prop_desc_t *, char **, uint_t, uint_t); 423d62bc4baSyz147064 static dladm_status_t i_dladm_set_linkprop(datalink_id_t, const char *, 424d62bc4baSyz147064 char **, uint_t, uint_t); 4254045d941Ssowmini static dladm_status_t i_dladm_getset_defval(prop_desc_t *, datalink_id_t, 4264045d941Ssowmini datalink_media_t, uint_t); 427d62bc4baSyz147064 /* 428d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 429d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 430d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 431d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 432d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 433d62bc4baSyz147064 */ 434d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 435d62bc4baSyz147064 436d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 437d62bc4baSyz147064 #define AP_DELIMITER '.' 438d62bc4baSyz147064 439d62bc4baSyz147064 static dladm_status_t 440d62bc4baSyz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 441d62bc4baSyz147064 val_desc_t *vdp) 4420ba2cbe9Sxc151355 { 443d62bc4baSyz147064 int i, j; 4440ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 4450ba2cbe9Sxc151355 446d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 447d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 448d62bc4baSyz147064 if (strcasecmp(*prop_val, 449d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 4500ba2cbe9Sxc151355 break; 4510ba2cbe9Sxc151355 } 4520ba2cbe9Sxc151355 } 453d62bc4baSyz147064 if (i == pdp->pd_noptval) { 454d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 455d62bc4baSyz147064 goto done; 456d62bc4baSyz147064 } 457d62bc4baSyz147064 (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); 4580ba2cbe9Sxc151355 } 4590ba2cbe9Sxc151355 460d62bc4baSyz147064 done: 461d62bc4baSyz147064 return (status); 4620ba2cbe9Sxc151355 } 4630ba2cbe9Sxc151355 4640ba2cbe9Sxc151355 static dladm_status_t 465d62bc4baSyz147064 i_dladm_set_single_prop(datalink_id_t linkid, datalink_class_t class, 466d62bc4baSyz147064 uint32_t media, prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 467d62bc4baSyz147064 uint_t flags) 4680ba2cbe9Sxc151355 { 4690ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 470d62bc4baSyz147064 val_desc_t *vdp = NULL; 471d62bc4baSyz147064 boolean_t needfree = B_FALSE; 472d62bc4baSyz147064 uint_t cnt, i; 4730ba2cbe9Sxc151355 474d62bc4baSyz147064 if (!(pdp->pd_class & class)) 475d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 4760ba2cbe9Sxc151355 477d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 478d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 479d62bc4baSyz147064 480d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 481d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 482d62bc4baSyz147064 483d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 484d62bc4baSyz147064 return (DLADM_STATUS_OK); 485d62bc4baSyz147064 486d62bc4baSyz147064 if (pdp->pd_set == NULL) 487d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 488d62bc4baSyz147064 489e7801d59Ssowmini if (pdp->pd_flags & PD_CHECK_ALLOC) 490e7801d59Ssowmini needfree = B_TRUE; 491e7801d59Ssowmini else 492e7801d59Ssowmini needfree = B_FALSE; 493d62bc4baSyz147064 if (prop_val != NULL) { 494d62bc4baSyz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 495d62bc4baSyz147064 if (vdp == NULL) 496d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 497d62bc4baSyz147064 498e7801d59Ssowmini 499d62bc4baSyz147064 if (pdp->pd_check != NULL) { 500e7801d59Ssowmini status = pdp->pd_check(pdp, linkid, prop_val, val_cnt, 5016b9e797cSsowmini vdp, media); 502d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 503d62bc4baSyz147064 status = do_check_prop(pdp, prop_val, val_cnt, vdp); 504d62bc4baSyz147064 } else { 505d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 5060ba2cbe9Sxc151355 } 5070ba2cbe9Sxc151355 508d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 509d62bc4baSyz147064 goto done; 510d62bc4baSyz147064 511d62bc4baSyz147064 cnt = val_cnt; 512d62bc4baSyz147064 } else { 513d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 514d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 515d62bc4baSyz147064 516*3bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 517*3bc21d0aSAruna Ramakrishna - Sun Microsystems if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || 5184045d941Ssowmini strlen(pdp->pd_defval.vd_name) > 0) { 519d62bc4baSyz147064 if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 520d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 521*3bc21d0aSAruna Ramakrishna - Sun Microsystems 522*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (pdp->pd_check != NULL) { 523*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = pdp->pd_check(pdp, linkid, prop_val, 524*3bc21d0aSAruna Ramakrishna - Sun Microsystems cnt, vdp, media); 525*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 526*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 527*3bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 5284045d941Ssowmini (void) memcpy(vdp, &pdp->pd_defval, 5294045d941Ssowmini sizeof (val_desc_t)); 530*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 5314045d941Ssowmini } else { 5324045d941Ssowmini status = i_dladm_getset_defval(pdp, linkid, 5334045d941Ssowmini media, flags); 5344045d941Ssowmini return (status); 5354045d941Ssowmini } 536d62bc4baSyz147064 } 5376b9e797cSsowmini status = pdp->pd_set(pdp, linkid, vdp, cnt, flags, media); 538d62bc4baSyz147064 if (needfree) { 539d62bc4baSyz147064 for (i = 0; i < cnt; i++) 540e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 541d62bc4baSyz147064 } 542d62bc4baSyz147064 done: 543d62bc4baSyz147064 free(vdp); 544d62bc4baSyz147064 return (status); 545d62bc4baSyz147064 } 546d62bc4baSyz147064 547d62bc4baSyz147064 static dladm_status_t 548d62bc4baSyz147064 i_dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, 549d62bc4baSyz147064 char **prop_val, uint_t val_cnt, uint_t flags) 550d62bc4baSyz147064 { 551d62bc4baSyz147064 int i; 552d62bc4baSyz147064 boolean_t found = B_FALSE; 553d62bc4baSyz147064 datalink_class_t class; 554d62bc4baSyz147064 uint32_t media; 555d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 556d62bc4baSyz147064 557d62bc4baSyz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 558d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 5590ba2cbe9Sxc151355 return (status); 5600ba2cbe9Sxc151355 561d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 562d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 563d62bc4baSyz147064 dladm_status_t s; 5640ba2cbe9Sxc151355 565d62bc4baSyz147064 if (prop_name != NULL && 566d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 567d62bc4baSyz147064 continue; 568d62bc4baSyz147064 569d62bc4baSyz147064 found = B_TRUE; 570d62bc4baSyz147064 s = i_dladm_set_single_prop(linkid, class, media, pdp, prop_val, 571d62bc4baSyz147064 val_cnt, flags); 572d62bc4baSyz147064 573d62bc4baSyz147064 if (prop_name != NULL) { 574d62bc4baSyz147064 status = s; 575d62bc4baSyz147064 break; 576d62bc4baSyz147064 } else { 577d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 578d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 579d62bc4baSyz147064 status = s; 580d62bc4baSyz147064 } 581d62bc4baSyz147064 } 582e7801d59Ssowmini if (!found) { 583e7801d59Ssowmini if (prop_name[0] == '_') { 584e7801d59Ssowmini /* other private properties */ 585*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = i_dladm_set_prop(linkid, prop_name, prop_val, 586e7801d59Ssowmini val_cnt, flags); 587e7801d59Ssowmini } else { 5880ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 589e7801d59Ssowmini } 590e7801d59Ssowmini } 5910ba2cbe9Sxc151355 5920ba2cbe9Sxc151355 return (status); 5930ba2cbe9Sxc151355 } 5940ba2cbe9Sxc151355 595d62bc4baSyz147064 /* 596d62bc4baSyz147064 * Set/reset link property for specific link 597d62bc4baSyz147064 */ 598d62bc4baSyz147064 dladm_status_t 599d62bc4baSyz147064 dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, char **prop_val, 600d62bc4baSyz147064 uint_t val_cnt, uint_t flags) 6010ba2cbe9Sxc151355 { 602d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 6030ba2cbe9Sxc151355 604d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 605d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 606d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 607d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 608d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 6090ba2cbe9Sxc151355 } 6100ba2cbe9Sxc151355 611d62bc4baSyz147064 status = i_dladm_set_linkprop(linkid, prop_name, prop_val, 612d62bc4baSyz147064 val_cnt, flags); 613d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 614d62bc4baSyz147064 return (status); 615d62bc4baSyz147064 616d62bc4baSyz147064 if (flags & DLADM_OPT_PERSIST) { 617d62bc4baSyz147064 status = i_dladm_set_linkprop_db(linkid, prop_name, 618d62bc4baSyz147064 prop_val, val_cnt); 619d62bc4baSyz147064 } 620d62bc4baSyz147064 return (status); 621d62bc4baSyz147064 } 622d62bc4baSyz147064 623d62bc4baSyz147064 /* 624d62bc4baSyz147064 * Walk link properties of the given specific link. 625d62bc4baSyz147064 */ 626d62bc4baSyz147064 dladm_status_t 627d62bc4baSyz147064 dladm_walk_linkprop(datalink_id_t linkid, void *arg, 628d62bc4baSyz147064 int (*func)(datalink_id_t, const char *, void *)) 6290ba2cbe9Sxc151355 { 630d62bc4baSyz147064 dladm_status_t status; 631d62bc4baSyz147064 datalink_class_t class; 632d62bc4baSyz147064 uint_t media; 633d62bc4baSyz147064 int i; 6340ba2cbe9Sxc151355 635d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 636d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 6370ba2cbe9Sxc151355 638d62bc4baSyz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 639d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 640d62bc4baSyz147064 return (status); 641d62bc4baSyz147064 642d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 643d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 644d62bc4baSyz147064 continue; 645d62bc4baSyz147064 646d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 647d62bc4baSyz147064 continue; 648d62bc4baSyz147064 649d62bc4baSyz147064 if (func(linkid, prop_table[i].pd_name, arg) == 650d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 651d62bc4baSyz147064 break; 652d62bc4baSyz147064 } 653d62bc4baSyz147064 } 654d62bc4baSyz147064 655d62bc4baSyz147064 return (DLADM_STATUS_OK); 656d62bc4baSyz147064 } 657d62bc4baSyz147064 658d62bc4baSyz147064 /* 659d62bc4baSyz147064 * Get linkprop of the given specific link. 660d62bc4baSyz147064 */ 661d62bc4baSyz147064 dladm_status_t 662d62bc4baSyz147064 dladm_get_linkprop(datalink_id_t linkid, dladm_prop_type_t type, 663d62bc4baSyz147064 const char *prop_name, char **prop_val, uint_t *val_cntp) 664d62bc4baSyz147064 { 665d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 666d62bc4baSyz147064 datalink_class_t class; 667d62bc4baSyz147064 uint_t media; 668d62bc4baSyz147064 prop_desc_t *pdp; 6694045d941Ssowmini uint_t cnt, dld_flags = 0; 670d62bc4baSyz147064 int i; 671d62bc4baSyz147064 6724045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 6733fd94f8cSam223141 dld_flags = MAC_PROP_DEFAULT; 6744045d941Ssowmini 675d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 676d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 677d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 678d62bc4baSyz147064 679d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 680d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 681d62bc4baSyz147064 break; 682d62bc4baSyz147064 683e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 684e7801d59Ssowmini if (prop_name[0] == '_') { 685e7801d59Ssowmini /* 686e7801d59Ssowmini * private property. 687e7801d59Ssowmini */ 688*3bc21d0aSAruna Ramakrishna - Sun Microsystems return (i_dladm_get_prop(linkid, prop_name, 6894045d941Ssowmini prop_val, val_cntp, type, dld_flags)); 690e7801d59Ssowmini } else { 691d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 692e7801d59Ssowmini } 693e7801d59Ssowmini } 694d62bc4baSyz147064 695d62bc4baSyz147064 pdp = &prop_table[i]; 696d62bc4baSyz147064 697d62bc4baSyz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 698d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 699d62bc4baSyz147064 return (status); 700d62bc4baSyz147064 701d62bc4baSyz147064 if (!(pdp->pd_class & class)) 702d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 703d62bc4baSyz147064 704d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 705d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 706d62bc4baSyz147064 707d62bc4baSyz147064 switch (type) { 708d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 7094045d941Ssowmini status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, media, 7104045d941Ssowmini dld_flags); 711d62bc4baSyz147064 break; 712d62bc4baSyz147064 713d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 71413a55820Sar224390 /* 71513a55820Sar224390 * If defaults are not defined for the property, 71613a55820Sar224390 * pd_defval.vd_name should be null. If the driver 71713a55820Sar224390 * has to be contacted for the value, vd_name should 71813a55820Sar224390 * be the empty string (""). Otherwise, dladm will 71913a55820Sar224390 * just print whatever is in the table. 72013a55820Sar224390 */ 721d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 722d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 723d62bc4baSyz147064 break; 724d62bc4baSyz147064 } 7254045d941Ssowmini 7264045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 7274045d941Ssowmini status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, 7284045d941Ssowmini media, dld_flags); 7294045d941Ssowmini } else { 730d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 7314045d941Ssowmini } 732d62bc4baSyz147064 *val_cntp = 1; 733d62bc4baSyz147064 break; 734d62bc4baSyz147064 735d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 736d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 737e7801d59Ssowmini status = pdp->pd_getmod(pdp, linkid, prop_val, 7384045d941Ssowmini val_cntp, media, dld_flags); 739d62bc4baSyz147064 break; 740d62bc4baSyz147064 } 741d62bc4baSyz147064 cnt = pdp->pd_noptval; 742d62bc4baSyz147064 if (cnt == 0) { 743d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 744d62bc4baSyz147064 } else if (cnt > *val_cntp) { 745d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 746d62bc4baSyz147064 } else { 747d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 748d62bc4baSyz147064 (void) strcpy(prop_val[i], 749d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 750d62bc4baSyz147064 } 751d62bc4baSyz147064 *val_cntp = cnt; 752d62bc4baSyz147064 } 753d62bc4baSyz147064 break; 754d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 755d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 756d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 757d62bc4baSyz147064 status = i_dladm_get_linkprop_db(linkid, prop_name, 758d62bc4baSyz147064 prop_val, val_cntp); 759d62bc4baSyz147064 break; 760d62bc4baSyz147064 default: 761d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 762d62bc4baSyz147064 break; 763d62bc4baSyz147064 } 764d62bc4baSyz147064 765d62bc4baSyz147064 return (status); 766d62bc4baSyz147064 } 767d62bc4baSyz147064 768d62bc4baSyz147064 /*ARGSUSED*/ 769d62bc4baSyz147064 static int 770d62bc4baSyz147064 i_dladm_init_one_prop(datalink_id_t linkid, const char *prop_name, void *arg) 771d62bc4baSyz147064 { 772d62bc4baSyz147064 char *buf, **propvals; 773d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 774d62bc4baSyz147064 775d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 776d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 777d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 778d62bc4baSyz147064 } 779d62bc4baSyz147064 780d62bc4baSyz147064 propvals = (char **)(void *)buf; 781d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 782d62bc4baSyz147064 propvals[i] = buf + 783d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 784d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 785d62bc4baSyz147064 } 786d62bc4baSyz147064 787d62bc4baSyz147064 if (dladm_get_linkprop(linkid, DLADM_PROP_VAL_PERSISTENT, prop_name, 788d62bc4baSyz147064 propvals, &valcnt) != DLADM_STATUS_OK) { 789d62bc4baSyz147064 goto done; 790d62bc4baSyz147064 } 791d62bc4baSyz147064 792d62bc4baSyz147064 (void) dladm_set_linkprop(linkid, prop_name, propvals, valcnt, 793d62bc4baSyz147064 DLADM_OPT_ACTIVE); 794d62bc4baSyz147064 795d62bc4baSyz147064 done: 796d62bc4baSyz147064 if (buf != NULL) 797d62bc4baSyz147064 free(buf); 798d62bc4baSyz147064 799d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 800d62bc4baSyz147064 } 801d62bc4baSyz147064 802d62bc4baSyz147064 /*ARGSUSED*/ 803d62bc4baSyz147064 static int 804d62bc4baSyz147064 i_dladm_init_linkprop(datalink_id_t linkid, void *arg) 805d62bc4baSyz147064 { 80630890389Sartem (void) dladm_init_linkprop(linkid, B_TRUE); 807d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 8080ba2cbe9Sxc151355 } 8090ba2cbe9Sxc151355 8100ba2cbe9Sxc151355 dladm_status_t 81130890389Sartem dladm_init_linkprop(datalink_id_t linkid, boolean_t any_media) 8120ba2cbe9Sxc151355 { 81330890389Sartem datalink_media_t dmedia; 81430890389Sartem uint32_t media; 81530890389Sartem 81630890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 81730890389Sartem 818d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 819d62bc4baSyz147064 (void) dladm_walk_datalink_id(i_dladm_init_linkprop, NULL, 82030890389Sartem DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 82130890389Sartem } else if (any_media || ((dladm_datalink_id2info(linkid, NULL, NULL, 82230890389Sartem &media, NULL, 0) == DLADM_STATUS_OK) && 82330890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 824d62bc4baSyz147064 (void) dladm_walk_linkprop(linkid, NULL, i_dladm_init_one_prop); 825d62bc4baSyz147064 } 826d62bc4baSyz147064 return (DLADM_STATUS_OK); 8270ba2cbe9Sxc151355 } 828f4b3ec61Sdh155122 829e7801d59Ssowmini /* ARGSUSED */ 830f4b3ec61Sdh155122 static dladm_status_t 831e7801d59Ssowmini do_get_zone(struct prop_desc *pd, datalink_id_t linkid, 8324045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 833f4b3ec61Sdh155122 { 834d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 835d62bc4baSyz147064 zoneid_t zid; 836d62bc4baSyz147064 dladm_status_t status; 837*3bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 838*3bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 839f4b3ec61Sdh155122 8404045d941Ssowmini if (flags != 0) 8414045d941Ssowmini return (DLADM_STATUS_NOTSUP); 8424045d941Ssowmini 843*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 844d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 845d62bc4baSyz147064 return (status); 846d62bc4baSyz147064 847*3bc21d0aSAruna Ramakrishna - Sun Microsystems cp = dip->pr_val; 848*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&zid, cp, sizeof (zid)); 849*3bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 850*3bc21d0aSAruna Ramakrishna - Sun Microsystems 851d62bc4baSyz147064 *val_cnt = 1; 852d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 853d62bc4baSyz147064 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 854f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 855f4b3ec61Sdh155122 856d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 85747a01978Sbw } else { 858d62bc4baSyz147064 *prop_val[0] = '\0'; 85947a01978Sbw } 860f4b3ec61Sdh155122 861f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 862f4b3ec61Sdh155122 } 863f4b3ec61Sdh155122 864f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 865f4b3ec61Sdh155122 866f4b3ec61Sdh155122 static int 867f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 868f4b3ec61Sdh155122 { 869f4b3ec61Sdh155122 char root[MAXPATHLEN]; 870f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 871f4b3ec61Sdh155122 void *dlhandle; 872f4b3ec61Sdh155122 void *sym; 873f4b3ec61Sdh155122 int ret; 874f4b3ec61Sdh155122 875f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 876f4b3ec61Sdh155122 return (-1); 877f4b3ec61Sdh155122 878f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 879f4b3ec61Sdh155122 (void) dlclose(dlhandle); 880f4b3ec61Sdh155122 return (-1); 881f4b3ec61Sdh155122 } 882f4b3ec61Sdh155122 883f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 884f4b3ec61Sdh155122 885f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 886f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 887f4b3ec61Sdh155122 (void) dlclose(dlhandle); 888f4b3ec61Sdh155122 return (ret); 889f4b3ec61Sdh155122 } 890f4b3ec61Sdh155122 891f4b3ec61Sdh155122 static dladm_status_t 892d62bc4baSyz147064 i_dladm_update_deventry(zoneid_t zid, datalink_id_t linkid, boolean_t add) 893f4b3ec61Sdh155122 { 894f4b3ec61Sdh155122 char path[MAXPATHLEN]; 895d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 896f4b3ec61Sdh155122 di_prof_t prof = NULL; 897f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 898f4b3ec61Sdh155122 dladm_status_t status; 899d62bc4baSyz147064 int ret; 900f4b3ec61Sdh155122 901f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 902f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 903f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 904f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 905f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 906f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 907f4b3ec61Sdh155122 908d62bc4baSyz147064 status = dladm_linkid2legacyname(linkid, name, MAXLINKNAMELEN); 909f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 910d62bc4baSyz147064 goto cleanup; 911f4b3ec61Sdh155122 912d62bc4baSyz147064 if (add) 913d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 914d62bc4baSyz147064 else 915d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 916f4b3ec61Sdh155122 917d62bc4baSyz147064 if (ret != 0) { 918d62bc4baSyz147064 status = dladm_errno2status(errno); 919d62bc4baSyz147064 goto cleanup; 920f4b3ec61Sdh155122 } 921f4b3ec61Sdh155122 922d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 923d62bc4baSyz147064 status = dladm_errno2status(errno); 924d62bc4baSyz147064 cleanup: 925d62bc4baSyz147064 if (prof) 926d62bc4baSyz147064 di_prof_fini(prof); 927d62bc4baSyz147064 928d62bc4baSyz147064 return (status); 929f4b3ec61Sdh155122 } 930f4b3ec61Sdh155122 931e7801d59Ssowmini /* ARGSUSED */ 932f4b3ec61Sdh155122 static dladm_status_t 9336b9e797cSsowmini do_set_zone(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp, 9346b9e797cSsowmini uint_t val_cnt, uint_t flags, datalink_media_t media) 935f4b3ec61Sdh155122 { 936*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 937f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 938d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 939*3bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 940*3bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 941*3bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 942f4b3ec61Sdh155122 943f4b3ec61Sdh155122 if (val_cnt != 1) 944f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 945f4b3ec61Sdh155122 946*3bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 947*3bc21d0aSAruna Ramakrishna - Sun Microsystems 948*3bc21d0aSAruna Ramakrishna - Sun Microsystems /* 949*3bc21d0aSAruna Ramakrishna - Sun Microsystems * If diz_is_ppa_hack is set, then an implicit vlan must be created. 950*3bc21d0aSAruna Ramakrishna - Sun Microsystems * There is no old value to compare against, and vdp->vd_val is 951*3bc21d0aSAruna Ramakrishna - Sun Microsystems * already populated with the zoneid and linkname in the function 952*3bc21d0aSAruna Ramakrishna - Sun Microsystems * do_check_zone(). 953*3bc21d0aSAruna Ramakrishna - Sun Microsystems */ 954*3bc21d0aSAruna Ramakrishna - Sun Microsystems 955*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp->diz_is_ppa_hack) { 956*3bc21d0aSAruna Ramakrishna - Sun Microsystems zid_old = GLOBAL_ZONEID; 957*3bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 958*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, 959*3bc21d0aSAruna Ramakrishna - Sun Microsystems flags, &status); 960f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 961f4b3ec61Sdh155122 return (status); 962f4b3ec61Sdh155122 963*3bc21d0aSAruna Ramakrishna - Sun Microsystems cp = dip->pr_val; 964*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&zid_old, cp, sizeof (zid_old)); 965*3bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 966d62bc4baSyz147064 } 967f4b3ec61Sdh155122 968*3bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 969*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN); 970*3bc21d0aSAruna Ramakrishna - Sun Microsystems 971*3bc21d0aSAruna Ramakrishna - Sun Microsystems /* Do nothing if setting to current value */ 972*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 973*3bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 974*3bc21d0aSAruna Ramakrishna - Sun Microsystems 975d62bc4baSyz147064 if (zid_new != GLOBAL_ZONEID) { 976d62bc4baSyz147064 /* 977d62bc4baSyz147064 * If the new zoneid is the global zone, we could destroy 978d62bc4baSyz147064 * the link (in the case of an implicitly-created VLAN) as a 979*3bc21d0aSAruna Ramakrishna - Sun Microsystems * result of setting the zoneid. In that case, we defer the 980*3bc21d0aSAruna Ramakrishna - Sun Microsystems * operation to the end of this function to avoid recreating 981*3bc21d0aSAruna Ramakrishna - Sun Microsystems * the VLAN and getting a different linkid during the rollback 982*3bc21d0aSAruna Ramakrishna - Sun Microsystems * if other operation fails. 983d62bc4baSyz147064 * 984*3bc21d0aSAruna Ramakrishna - Sun Microsystems * Otherwise, this operation will hold a reference to the 985d62bc4baSyz147064 * link and prevent a link renaming, so we need to do it 986d62bc4baSyz147064 * before other operations. 987d62bc4baSyz147064 */ 988*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt, 989*3bc21d0aSAruna Ramakrishna - Sun Microsystems flags, media); 990d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 991d62bc4baSyz147064 return (status); 992d62bc4baSyz147064 } 993d62bc4baSyz147064 994d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 995d62bc4baSyz147064 if (zone_remove_datalink(zid_old, link) != 0 && 996f4b3ec61Sdh155122 errno != ENXIO) { 997f4b3ec61Sdh155122 status = dladm_errno2status(errno); 998f4b3ec61Sdh155122 goto rollback1; 999f4b3ec61Sdh155122 } 1000f4b3ec61Sdh155122 1001d62bc4baSyz147064 /* 1002d62bc4baSyz147064 * It is okay to fail to update the /dev entry (some 1003d62bc4baSyz147064 * vanity-named links do not have a /dev entry). 1004d62bc4baSyz147064 */ 1005d62bc4baSyz147064 (void) i_dladm_update_deventry(zid_old, linkid, B_FALSE); 1006d62bc4baSyz147064 } 1007d62bc4baSyz147064 1008d62bc4baSyz147064 if (zid_new != GLOBAL_ZONEID) { 1009d62bc4baSyz147064 if (zone_add_datalink(zid_new, link) != 0) { 1010d62bc4baSyz147064 status = dladm_errno2status(errno); 1011d62bc4baSyz147064 goto rollback2; 1012d62bc4baSyz147064 } 1013d62bc4baSyz147064 1014*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp->diz_is_ppa_hack) { 1015*3bc21d0aSAruna Ramakrishna - Sun Microsystems if ((status = dladm_name2info(link, &linkid, NULL, NULL, 1016*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL)) != DLADM_STATUS_OK) { 1017*3bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1018*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1019*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1020*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1021d62bc4baSyz147064 (void) i_dladm_update_deventry(zid_new, linkid, B_TRUE); 1022d62bc4baSyz147064 } else { 1023*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt, 1024*3bc21d0aSAruna Ramakrishna - Sun Microsystems flags, media); 1025f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1026f4b3ec61Sdh155122 goto rollback2; 1027f4b3ec61Sdh155122 } 1028f4b3ec61Sdh155122 1029f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1030f4b3ec61Sdh155122 1031f4b3ec61Sdh155122 rollback2: 1032f4b3ec61Sdh155122 if (zid_old != GLOBAL_ZONEID) 1033d62bc4baSyz147064 (void) i_dladm_update_deventry(zid_old, linkid, B_TRUE); 1034d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) 1035d62bc4baSyz147064 (void) zone_add_datalink(zid_old, link); 1036f4b3ec61Sdh155122 rollback1: 1037*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new != GLOBAL_ZONEID) { 1038*3bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zid_old; 1039*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) i_dladm_set_public_prop(pd, linkid, vdp, val_cnt, 1040*3bc21d0aSAruna Ramakrishna - Sun Microsystems flags, media); 1041*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1042*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1043f4b3ec61Sdh155122 return (status); 1044f4b3ec61Sdh155122 } 1045f4b3ec61Sdh155122 1046f4b3ec61Sdh155122 /* ARGSUSED */ 1047f4b3ec61Sdh155122 static dladm_status_t 1048e7801d59Ssowmini do_check_zone(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, 10496b9e797cSsowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1050f4b3ec61Sdh155122 { 1051*3bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 1052*3bc21d0aSAruna Ramakrishna - Sun Microsystems char linkname[MAXLINKNAMELEN]; 1053*3bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 1054*3bc21d0aSAruna Ramakrishna - Sun Microsystems char *cp; 1055*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1056*3bc21d0aSAruna Ramakrishna - Sun Microsystems boolean_t is_ppa_hack = B_FALSE; 1057*3bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1058f4b3ec61Sdh155122 1059f4b3ec61Sdh155122 if (val_cnt != 1) 1060f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1061f4b3ec61Sdh155122 1062*3bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 1063*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 1064*3bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1065f4b3ec61Sdh155122 1066*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val) { 1067*3bc21d0aSAruna Ramakrishna - Sun Microsystems /* 1068*3bc21d0aSAruna Ramakrishna - Sun Microsystems * The prop_val contains zone_name{:linkname}. The linkname is 1069*3bc21d0aSAruna Ramakrishna - Sun Microsystems * present only when the link is a ppa-hacked vlan. 1070*3bc21d0aSAruna Ramakrishna - Sun Microsystems */ 1071*3bc21d0aSAruna Ramakrishna - Sun Microsystems cp = strchr(*prop_val, ':'); 1072*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (cp) { 1073*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(linkname, cp + 1, MAXLINKNAMELEN); 1074*3bc21d0aSAruna Ramakrishna - Sun Microsystems *cp = '\0'; 1075*3bc21d0aSAruna Ramakrishna - Sun Microsystems is_ppa_hack = B_TRUE; 1076*3bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 1077*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_datalink_id2info(linkid, NULL, NULL, 1078*3bc21d0aSAruna Ramakrishna - Sun Microsystems NULL, linkname, MAXLINKNAMELEN); 1079*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) { 1080*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1081*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1082*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1083*3bc21d0aSAruna Ramakrishna - Sun Microsystems zone_name = *prop_val; 1084*3bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 1085*3bc21d0aSAruna Ramakrishna - Sun Microsystems zone_name = GLOBAL_ZONENAME; 1086*3bc21d0aSAruna Ramakrishna - Sun Microsystems if ((status = dladm_datalink_id2info(linkid, NULL, NULL, NULL, 1087*3bc21d0aSAruna Ramakrishna - Sun Microsystems linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 1088*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1089*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1090*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1091*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1092*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (strlen(linkname) > MAXLINKNAMELEN) { 1093*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 1094*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1095*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1096*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1097*3bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 1098*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 1099*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1100*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1101*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1102*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1103f4b3ec61Sdh155122 ushort_t flags; 1104f4b3ec61Sdh155122 1105*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1106f4b3ec61Sdh155122 sizeof (flags)) < 0) { 1107*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 1108*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1109f4b3ec61Sdh155122 } 1110f4b3ec61Sdh155122 1111f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 1112*3bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 1113*3bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1114f4b3ec61Sdh155122 } 1115f4b3ec61Sdh155122 } 1116f4b3ec61Sdh155122 1117*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 1118*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1119*3bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 1120*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN); 1121*3bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_is_ppa_hack = is_ppa_hack; 1122*3bc21d0aSAruna Ramakrishna - Sun Microsystems 1123*3bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1124f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1125*3bc21d0aSAruna Ramakrishna - Sun Microsystems done: 1126*3bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 1127*3bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1128f4b3ec61Sdh155122 } 1129f4b3ec61Sdh155122 1130e7801d59Ssowmini /* ARGSUSED */ 1131f4b3ec61Sdh155122 static dladm_status_t 1132e7801d59Ssowmini do_get_autopush(struct prop_desc *pd, datalink_id_t linkid, 11334045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1134d62bc4baSyz147064 { 1135*3bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 1136*3bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 1137*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 1138*3bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_macprop_t *dip; 1139d62bc4baSyz147064 11403fd94f8cSam223141 if (flags & MAC_PROP_DEFAULT) 11414045d941Ssowmini return (DLADM_STATUS_NOTSUP); 11424045d941Ssowmini 1143d62bc4baSyz147064 *val_cnt = 1; 1144*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 1145*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (dip == NULL) { 1146d62bc4baSyz147064 (*prop_val)[0] = '\0'; 1147d62bc4baSyz147064 goto done; 1148d62bc4baSyz147064 } 1149*3bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 1150d62bc4baSyz147064 1151*3bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 1152d62bc4baSyz147064 if (i != 0) { 1153d62bc4baSyz147064 (void) snprintf(*prop_val + len, 1154d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 1155d62bc4baSyz147064 len += 1; 1156d62bc4baSyz147064 } 1157d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 1158*3bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 1159*3bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 1160*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 1161d62bc4baSyz147064 (void) snprintf(*prop_val + len, 1162d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 1163d62bc4baSyz147064 AP_ANCHOR); 1164d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 1165d62bc4baSyz147064 } 1166d62bc4baSyz147064 } 1167d62bc4baSyz147064 1168*3bc21d0aSAruna Ramakrishna - Sun Microsystems free(dip); 1169d62bc4baSyz147064 done: 1170d62bc4baSyz147064 return (DLADM_STATUS_OK); 1171d62bc4baSyz147064 } 1172d62bc4baSyz147064 1173d62bc4baSyz147064 /* 1174d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 1175d62bc4baSyz147064 * DLADM_STATUS_* code. 1176d62bc4baSyz147064 */ 1177d62bc4baSyz147064 dladm_status_t 1178d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 1179d62bc4baSyz147064 { 1180d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 1181d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1182d62bc4baSyz147064 1183d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 1184d62bc4baSyz147064 /* 1185d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 1186d62bc4baSyz147064 * be after at least one module. 1187d62bc4baSyz147064 */ 1188d62bc4baSyz147064 if (dlap->dap_anchor != 0) 1189d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1190d62bc4baSyz147064 if (dlap->dap_npush == 0) 1191d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 1192d62bc4baSyz147064 1193d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 1194d62bc4baSyz147064 return (DLADM_STATUS_OK); 1195d62bc4baSyz147064 } 1196d62bc4baSyz147064 if (dlap->dap_npush > MAXAPUSH) 1197d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1198d62bc4baSyz147064 1199d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 1200d62bc4baSyz147064 FMNAMESZ + 1); 1201d62bc4baSyz147064 1202d62bc4baSyz147064 return (DLADM_STATUS_OK); 1203d62bc4baSyz147064 } 1204d62bc4baSyz147064 1205d62bc4baSyz147064 /* 1206d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 1207d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 1208d62bc4baSyz147064 * latter is used in the autopush(1M) file. 1209d62bc4baSyz147064 */ 1210d62bc4baSyz147064 /* ARGSUSED */ 1211d62bc4baSyz147064 static dladm_status_t 1212e7801d59Ssowmini do_check_autopush(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, 12136b9e797cSsowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1214d62bc4baSyz147064 { 1215d62bc4baSyz147064 char *module; 1216d62bc4baSyz147064 struct dlautopush *dlap; 1217d62bc4baSyz147064 dladm_status_t status; 1218d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 1219d62bc4baSyz147064 char delimiters[4]; 1220d62bc4baSyz147064 1221d62bc4baSyz147064 if (val_cnt != 1) 1222d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1223d62bc4baSyz147064 1224*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 1225d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 1226d62bc4baSyz147064 if (dlap == NULL) 1227d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1228d62bc4baSyz147064 1229d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 1230d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 1231d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 1232d62bc4baSyz147064 module = strtok(val, delimiters); 1233d62bc4baSyz147064 while (module != NULL) { 1234d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 1235d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1236d62bc4baSyz147064 return (status); 1237d62bc4baSyz147064 module = strtok(NULL, delimiters); 1238d62bc4baSyz147064 } 1239d62bc4baSyz147064 1240d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 1241*3bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 1242*3bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 1243*3bc21d0aSAruna Ramakrishna - Sun Microsystems } 1244d62bc4baSyz147064 return (DLADM_STATUS_OK); 1245d62bc4baSyz147064 } 1246d62bc4baSyz147064 1247e7801d59Ssowmini /* ARGSUSED */ 1248d62bc4baSyz147064 static dladm_status_t 1249e7801d59Ssowmini do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid, 1250e7801d59Ssowmini char **prop_val, uint_t *val_cnt, uint_t id) 1251d62bc4baSyz147064 { 1252d62bc4baSyz147064 wl_rates_t *wrp; 1253d62bc4baSyz147064 uint_t i; 1254d62bc4baSyz147064 wldp_t *gbuf = NULL; 1255d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1256d62bc4baSyz147064 1257d62bc4baSyz147064 if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { 1258d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 1259d62bc4baSyz147064 goto done; 1260d62bc4baSyz147064 } 1261d62bc4baSyz147064 1262d62bc4baSyz147064 status = i_dladm_wlan_get_ioctl(linkid, gbuf, id); 1263d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1264d62bc4baSyz147064 goto done; 1265d62bc4baSyz147064 1266d62bc4baSyz147064 wrp = (wl_rates_t *)gbuf->wldp_buf; 1267d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 1268d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1269d62bc4baSyz147064 goto done; 1270d62bc4baSyz147064 } 1271d62bc4baSyz147064 1272d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 1273d62bc4baSyz147064 prop_val[0][0] = '\0'; 1274d62bc4baSyz147064 *val_cnt = 1; 1275d62bc4baSyz147064 goto done; 1276d62bc4baSyz147064 } 1277d62bc4baSyz147064 1278d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 1279d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 1280d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 1281d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 1282d62bc4baSyz147064 } 1283d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 1284d62bc4baSyz147064 1285d62bc4baSyz147064 done: 1286d62bc4baSyz147064 free(gbuf); 1287d62bc4baSyz147064 return (status); 1288d62bc4baSyz147064 } 1289d62bc4baSyz147064 1290d62bc4baSyz147064 static dladm_status_t 1291e7801d59Ssowmini do_get_rate_prop(struct prop_desc *pd, datalink_id_t linkid, 12924045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1293d62bc4baSyz147064 { 12946b9e797cSsowmini if (media != DL_WIFI) 1295*3bc21d0aSAruna Ramakrishna - Sun Microsystems return (i_dladm_speed_get(pd, linkid, prop_val, 1296*3bc21d0aSAruna Ramakrishna - Sun Microsystems val_cnt, flags)); 12976b9e797cSsowmini 1298e7801d59Ssowmini return (do_get_rate_common(pd, linkid, prop_val, val_cnt, 1299d62bc4baSyz147064 WL_DESIRED_RATES)); 1300d62bc4baSyz147064 } 1301d62bc4baSyz147064 13024045d941Ssowmini /* ARGSUSED */ 1303d62bc4baSyz147064 static dladm_status_t 1304e7801d59Ssowmini do_get_rate_mod(struct prop_desc *pd, datalink_id_t linkid, 13054045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1306d62bc4baSyz147064 { 13076b9e797cSsowmini switch (media) { 13086b9e797cSsowmini case DL_ETHER: 13094045d941Ssowmini /* 13104045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 13114045d941Ssowmini * links can have a speed of 5.5 Gbps. 13124045d941Ssowmini */ 13134045d941Ssowmini return (DLADM_STATUS_NOTSUP); 13146b9e797cSsowmini 13156b9e797cSsowmini case DL_WIFI: 1316e7801d59Ssowmini return (do_get_rate_common(pd, linkid, prop_val, val_cnt, 1317d62bc4baSyz147064 WL_SUPPORTED_RATES)); 13186b9e797cSsowmini default: 13196b9e797cSsowmini return (DLADM_STATUS_BADARG); 13206b9e797cSsowmini } 1321d62bc4baSyz147064 } 1322d62bc4baSyz147064 1323d62bc4baSyz147064 static dladm_status_t 1324d62bc4baSyz147064 do_set_rate(datalink_id_t linkid, dladm_wlan_rates_t *rates) 1325f4b3ec61Sdh155122 { 1326f4b3ec61Sdh155122 int i; 1327d62bc4baSyz147064 uint_t len; 1328d62bc4baSyz147064 wldp_t *gbuf; 1329d62bc4baSyz147064 wl_rates_t *wrp; 1330d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1331d62bc4baSyz147064 1332d62bc4baSyz147064 if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 1333d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1334d62bc4baSyz147064 1335d62bc4baSyz147064 (void) memset(gbuf, 0, MAX_BUF_LEN); 1336d62bc4baSyz147064 1337d62bc4baSyz147064 wrp = (wl_rates_t *)gbuf->wldp_buf; 1338d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 1339d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 1340d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 1341d62bc4baSyz147064 1342d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 1343d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 1344d62bc4baSyz147064 status = i_dladm_wlan_ioctl(linkid, gbuf, WL_DESIRED_RATES, len, 1345d62bc4baSyz147064 WLAN_SET_PARAM, len); 1346d62bc4baSyz147064 1347d62bc4baSyz147064 free(gbuf); 1348d62bc4baSyz147064 return (status); 1349d62bc4baSyz147064 } 1350d62bc4baSyz147064 1351e7801d59Ssowmini /* ARGSUSED */ 1352d62bc4baSyz147064 static dladm_status_t 1353e7801d59Ssowmini do_set_rate_prop(prop_desc_t *pd, datalink_id_t linkid, 13546b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1355d62bc4baSyz147064 { 1356d62bc4baSyz147064 dladm_wlan_rates_t rates; 1357f4b3ec61Sdh155122 dladm_status_t status; 1358f4b3ec61Sdh155122 13596b9e797cSsowmini /* 13606b9e797cSsowmini * can currently set rate on WIFI links only. 13616b9e797cSsowmini */ 13626b9e797cSsowmini if (media != DL_WIFI) 13636b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 13646b9e797cSsowmini 1365d62bc4baSyz147064 if (val_cnt != 1) 1366d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1367f4b3ec61Sdh155122 1368d62bc4baSyz147064 rates.wr_cnt = 1; 1369d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 1370f4b3ec61Sdh155122 1371d62bc4baSyz147064 status = do_set_rate(linkid, &rates); 1372f4b3ec61Sdh155122 1373d62bc4baSyz147064 done: 1374d62bc4baSyz147064 return (status); 1375d62bc4baSyz147064 } 1376d62bc4baSyz147064 1377d62bc4baSyz147064 /* ARGSUSED */ 1378d62bc4baSyz147064 static dladm_status_t 1379e7801d59Ssowmini do_check_rate(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, 13806b9e797cSsowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 1381d62bc4baSyz147064 { 1382d62bc4baSyz147064 int i; 1383d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 1384d62bc4baSyz147064 char *buf, **modval; 1385d62bc4baSyz147064 dladm_status_t status; 1386d62bc4baSyz147064 1387d62bc4baSyz147064 if (val_cnt != 1) 1388d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1389d62bc4baSyz147064 1390d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 1391d62bc4baSyz147064 MAX_SUPPORT_RATES); 1392d62bc4baSyz147064 if (buf == NULL) { 1393d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 1394d62bc4baSyz147064 goto done; 1395d62bc4baSyz147064 } 1396d62bc4baSyz147064 1397d62bc4baSyz147064 modval = (char **)(void *)buf; 1398d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 1399d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 1400d62bc4baSyz147064 i * DLADM_STRSIZE; 1401d62bc4baSyz147064 } 1402d62bc4baSyz147064 14034045d941Ssowmini status = do_get_rate_mod(NULL, linkid, modval, &modval_cnt, media, 0); 1404d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1405d62bc4baSyz147064 goto done; 1406d62bc4baSyz147064 1407d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 1408d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 1409e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 1410e7801d59Ssowmini (atof(*prop_val) * 2); 1411f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 1412f4b3ec61Sdh155122 break; 1413f4b3ec61Sdh155122 } 1414d62bc4baSyz147064 } 1415d62bc4baSyz147064 if (i == modval_cnt) 1416d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 1417d62bc4baSyz147064 done: 1418d62bc4baSyz147064 free(buf); 1419d62bc4baSyz147064 return (status); 1420d62bc4baSyz147064 } 1421f4b3ec61Sdh155122 1422d62bc4baSyz147064 static dladm_status_t 1423d62bc4baSyz147064 do_get_phyconf(datalink_id_t linkid, wldp_t *gbuf) 1424d62bc4baSyz147064 { 1425d62bc4baSyz147064 return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_PHY_CONFIG)); 1426d62bc4baSyz147064 } 1427d62bc4baSyz147064 1428e7801d59Ssowmini /* ARGSUSED */ 1429d62bc4baSyz147064 static dladm_status_t 1430e7801d59Ssowmini do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid, 14314045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1432d62bc4baSyz147064 { 1433d62bc4baSyz147064 uint32_t channel; 1434d62bc4baSyz147064 wldp_t *gbuf; 1435d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1436d62bc4baSyz147064 1437d62bc4baSyz147064 if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 1438d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1439d62bc4baSyz147064 1440d62bc4baSyz147064 if ((status = do_get_phyconf(linkid, gbuf)) != DLADM_STATUS_OK) 1441d62bc4baSyz147064 goto done; 1442d62bc4baSyz147064 1443d62bc4baSyz147064 if (!i_dladm_wlan_convert_chan((wl_phy_conf_t *)gbuf->wldp_buf, 1444d62bc4baSyz147064 &channel)) { 1445d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1446d62bc4baSyz147064 goto done; 1447d62bc4baSyz147064 } 1448d62bc4baSyz147064 1449d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 1450d62bc4baSyz147064 *val_cnt = 1; 1451d62bc4baSyz147064 1452d62bc4baSyz147064 done: 1453d62bc4baSyz147064 free(gbuf); 1454d62bc4baSyz147064 return (status); 1455d62bc4baSyz147064 } 1456d62bc4baSyz147064 1457d62bc4baSyz147064 static dladm_status_t 1458d62bc4baSyz147064 do_get_powermode(datalink_id_t linkid, wldp_t *gbuf) 1459d62bc4baSyz147064 { 1460d62bc4baSyz147064 return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_POWER_MODE)); 1461d62bc4baSyz147064 } 1462d62bc4baSyz147064 1463e7801d59Ssowmini /* ARGSUSED */ 1464d62bc4baSyz147064 static dladm_status_t 1465e7801d59Ssowmini do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid, 14664045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1467d62bc4baSyz147064 { 1468d62bc4baSyz147064 wl_ps_mode_t *mode; 1469d62bc4baSyz147064 const char *s; 1470d62bc4baSyz147064 wldp_t *gbuf; 1471d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1472d62bc4baSyz147064 1473d62bc4baSyz147064 if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 1474d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1475d62bc4baSyz147064 1476d62bc4baSyz147064 if ((status = do_get_powermode(linkid, gbuf)) != DLADM_STATUS_OK) 1477d62bc4baSyz147064 goto done; 1478d62bc4baSyz147064 1479d62bc4baSyz147064 mode = (wl_ps_mode_t *)(gbuf->wldp_buf); 1480d62bc4baSyz147064 switch (mode->wl_ps_mode) { 1481d62bc4baSyz147064 case WL_PM_AM: 1482d62bc4baSyz147064 s = "off"; 1483f4b3ec61Sdh155122 break; 1484d62bc4baSyz147064 case WL_PM_MPS: 1485d62bc4baSyz147064 s = "max"; 1486d62bc4baSyz147064 break; 1487d62bc4baSyz147064 case WL_PM_FAST: 1488d62bc4baSyz147064 s = "fast"; 1489f4b3ec61Sdh155122 break; 1490f4b3ec61Sdh155122 default: 1491d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1492d62bc4baSyz147064 goto done; 1493f4b3ec61Sdh155122 } 1494d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 1495d62bc4baSyz147064 *val_cnt = 1; 1496d62bc4baSyz147064 1497d62bc4baSyz147064 done: 1498d62bc4baSyz147064 free(gbuf); 1499d62bc4baSyz147064 return (status); 1500d62bc4baSyz147064 } 1501d62bc4baSyz147064 1502d62bc4baSyz147064 static dladm_status_t 1503d62bc4baSyz147064 do_set_powermode(datalink_id_t linkid, dladm_wlan_powermode_t *pm) 1504d62bc4baSyz147064 { 1505d62bc4baSyz147064 wl_ps_mode_t ps_mode; 1506d62bc4baSyz147064 1507d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 1508d62bc4baSyz147064 1509d62bc4baSyz147064 switch (*pm) { 1510d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 1511d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 1512d62bc4baSyz147064 break; 1513d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 1514d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 1515d62bc4baSyz147064 break; 1516d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 1517d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 1518d62bc4baSyz147064 break; 1519d62bc4baSyz147064 default: 1520d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 1521d62bc4baSyz147064 } 1522d62bc4baSyz147064 return (i_dladm_wlan_set_ioctl(linkid, WL_POWER_MODE, &ps_mode, 1523d62bc4baSyz147064 sizeof (ps_mode))); 1524d62bc4baSyz147064 } 1525d62bc4baSyz147064 1526d62bc4baSyz147064 /* ARGSUSED */ 1527d62bc4baSyz147064 static dladm_status_t 1528e7801d59Ssowmini do_set_powermode_prop(prop_desc_t *pd, datalink_id_t linkid, 15296b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1530d62bc4baSyz147064 { 1531d62bc4baSyz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 1532d62bc4baSyz147064 dladm_status_t status; 1533d62bc4baSyz147064 1534d62bc4baSyz147064 if (val_cnt != 1) 1535d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1536d62bc4baSyz147064 1537d62bc4baSyz147064 status = do_set_powermode(linkid, &powermode); 1538f4b3ec61Sdh155122 1539f4b3ec61Sdh155122 return (status); 1540f4b3ec61Sdh155122 } 1541f4b3ec61Sdh155122 1542f4b3ec61Sdh155122 static dladm_status_t 1543d62bc4baSyz147064 do_get_radio(datalink_id_t linkid, wldp_t *gbuf) 1544f4b3ec61Sdh155122 { 1545d62bc4baSyz147064 return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_RADIO)); 1546d62bc4baSyz147064 } 1547d62bc4baSyz147064 1548e7801d59Ssowmini /* ARGSUSED */ 1549d62bc4baSyz147064 static dladm_status_t 1550e7801d59Ssowmini do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid, 15514045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1552d62bc4baSyz147064 { 1553d62bc4baSyz147064 wl_radio_t radio; 1554d62bc4baSyz147064 const char *s; 1555d62bc4baSyz147064 wldp_t *gbuf; 1556d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1557d62bc4baSyz147064 1558d62bc4baSyz147064 if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 1559d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 1560d62bc4baSyz147064 1561d62bc4baSyz147064 if ((status = do_get_radio(linkid, gbuf)) != DLADM_STATUS_OK) 1562d62bc4baSyz147064 goto done; 1563d62bc4baSyz147064 1564d62bc4baSyz147064 radio = *(wl_radio_t *)(gbuf->wldp_buf); 1565d62bc4baSyz147064 switch (radio) { 1566d62bc4baSyz147064 case B_TRUE: 1567d62bc4baSyz147064 s = "on"; 1568d62bc4baSyz147064 break; 1569d62bc4baSyz147064 case B_FALSE: 1570d62bc4baSyz147064 s = "off"; 1571d62bc4baSyz147064 break; 1572d62bc4baSyz147064 default: 1573d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 1574d62bc4baSyz147064 goto done; 1575d62bc4baSyz147064 } 1576d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 1577d62bc4baSyz147064 *val_cnt = 1; 1578d62bc4baSyz147064 1579d62bc4baSyz147064 done: 1580d62bc4baSyz147064 free(gbuf); 1581d62bc4baSyz147064 return (status); 1582d62bc4baSyz147064 } 1583d62bc4baSyz147064 1584d62bc4baSyz147064 static dladm_status_t 1585d62bc4baSyz147064 do_set_radio(datalink_id_t linkid, dladm_wlan_radio_t *radio) 1586d62bc4baSyz147064 { 1587d62bc4baSyz147064 wl_radio_t r; 1588d62bc4baSyz147064 1589d62bc4baSyz147064 switch (*radio) { 1590d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 1591d62bc4baSyz147064 r = B_TRUE; 1592d62bc4baSyz147064 break; 1593d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 1594d62bc4baSyz147064 r = B_FALSE; 1595d62bc4baSyz147064 break; 1596d62bc4baSyz147064 default: 1597d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 1598d62bc4baSyz147064 } 1599d62bc4baSyz147064 return (i_dladm_wlan_set_ioctl(linkid, WL_RADIO, &r, sizeof (r))); 1600d62bc4baSyz147064 } 1601d62bc4baSyz147064 1602d62bc4baSyz147064 /* ARGSUSED */ 1603d62bc4baSyz147064 static dladm_status_t 1604e7801d59Ssowmini do_set_radio_prop(prop_desc_t *pd, datalink_id_t linkid, 16056b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t fags, datalink_media_t media) 1606d62bc4baSyz147064 { 1607d62bc4baSyz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 1608f4b3ec61Sdh155122 dladm_status_t status; 1609f4b3ec61Sdh155122 1610d62bc4baSyz147064 if (val_cnt != 1) 1611d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 1612f4b3ec61Sdh155122 1613d62bc4baSyz147064 status = do_set_radio(linkid, &radio); 1614f4b3ec61Sdh155122 1615d62bc4baSyz147064 return (status); 1616d62bc4baSyz147064 } 1617f4b3ec61Sdh155122 1618d62bc4baSyz147064 static dladm_status_t 1619d62bc4baSyz147064 i_dladm_set_linkprop_db(datalink_id_t linkid, const char *prop_name, 1620d62bc4baSyz147064 char **prop_val, uint_t val_cnt) 1621d62bc4baSyz147064 { 1622d62bc4baSyz147064 char buf[MAXLINELEN]; 1623d62bc4baSyz147064 int i; 1624d62bc4baSyz147064 dladm_conf_t conf; 1625d62bc4baSyz147064 dladm_status_t status; 1626d62bc4baSyz147064 1627d62bc4baSyz147064 status = dladm_read_conf(linkid, &conf); 1628f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1629f4b3ec61Sdh155122 return (status); 1630f4b3ec61Sdh155122 1631d62bc4baSyz147064 /* 1632d62bc4baSyz147064 * reset case. 1633d62bc4baSyz147064 */ 1634d62bc4baSyz147064 if (val_cnt == 0) { 1635d62bc4baSyz147064 status = dladm_unset_conf_field(conf, prop_name); 1636d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 1637d62bc4baSyz147064 status = dladm_write_conf(conf); 1638d62bc4baSyz147064 goto done; 1639f4b3ec61Sdh155122 } 1640f4b3ec61Sdh155122 1641d62bc4baSyz147064 buf[0] = '\0'; 1642d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 1643d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 1644d62bc4baSyz147064 if (i != val_cnt - 1) 1645d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 1646d62bc4baSyz147064 } 1647f4b3ec61Sdh155122 1648d62bc4baSyz147064 status = dladm_set_conf_field(conf, prop_name, DLADM_TYPE_STR, buf); 1649d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 1650d62bc4baSyz147064 status = dladm_write_conf(conf); 1651d62bc4baSyz147064 1652d62bc4baSyz147064 done: 1653d62bc4baSyz147064 dladm_destroy_conf(conf); 1654f4b3ec61Sdh155122 return (status); 1655f4b3ec61Sdh155122 } 1656f4b3ec61Sdh155122 1657f4b3ec61Sdh155122 static dladm_status_t 1658d62bc4baSyz147064 i_dladm_get_linkprop_db(datalink_id_t linkid, const char *prop_name, 1659d62bc4baSyz147064 char **prop_val, uint_t *val_cntp) 1660f4b3ec61Sdh155122 { 1661d62bc4baSyz147064 char buf[MAXLINELEN], *str; 1662d62bc4baSyz147064 uint_t cnt = 0; 1663d62bc4baSyz147064 dladm_conf_t conf; 1664d62bc4baSyz147064 dladm_status_t status; 1665f4b3ec61Sdh155122 1666d62bc4baSyz147064 status = dladm_read_conf(linkid, &conf); 1667d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1668f4b3ec61Sdh155122 return (status); 1669d62bc4baSyz147064 1670d62bc4baSyz147064 status = dladm_get_conf_field(conf, prop_name, buf, MAXLINELEN); 1671d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1672d62bc4baSyz147064 goto done; 1673d62bc4baSyz147064 1674d62bc4baSyz147064 str = strtok(buf, ","); 1675d62bc4baSyz147064 while (str != NULL) { 1676d62bc4baSyz147064 if (cnt == *val_cntp) { 1677d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1678d62bc4baSyz147064 goto done; 1679d62bc4baSyz147064 } 1680d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 1681d62bc4baSyz147064 str = strtok(NULL, ","); 1682f4b3ec61Sdh155122 } 1683f4b3ec61Sdh155122 1684d62bc4baSyz147064 *val_cntp = cnt; 1685f4b3ec61Sdh155122 1686d62bc4baSyz147064 done: 1687d62bc4baSyz147064 dladm_destroy_conf(conf); 1688d62bc4baSyz147064 return (status); 1689f4b3ec61Sdh155122 } 1690e7801d59Ssowmini 1691*3bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_public_prop_t * 1692e7801d59Ssowmini dladm_name2prop(const char *prop_name) 1693e7801d59Ssowmini { 1694*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_public_prop_t *p; 1695e7801d59Ssowmini 1696*3bc21d0aSAruna Ramakrishna - Sun Microsystems for (p = dladm_prop; p->pp_id != MAC_PROP_PRIVATE; p++) { 1697e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 1698e7801d59Ssowmini break; 1699e7801d59Ssowmini } 1700e7801d59Ssowmini return (p); 1701e7801d59Ssowmini } 1702e7801d59Ssowmini 1703e7801d59Ssowmini 17043fd94f8cSam223141 static dld_ioc_macprop_t * 1705*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name, 17064045d941Ssowmini uint_t flags, dladm_status_t *status) 1707e7801d59Ssowmini { 1708e7801d59Ssowmini int dsize; 17093fd94f8cSam223141 dld_ioc_macprop_t *dip; 1710*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_public_prop_t *p; 1711e7801d59Ssowmini 1712e7801d59Ssowmini *status = DLADM_STATUS_OK; 1713e7801d59Ssowmini p = dladm_name2prop(prop_name); 17143fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 1715e7801d59Ssowmini valsize = p->pp_valsize; 1716e7801d59Ssowmini 17173fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 1718e7801d59Ssowmini dip = malloc(dsize); 1719e7801d59Ssowmini if (dip == NULL) { 1720e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 1721e7801d59Ssowmini return (NULL); 1722e7801d59Ssowmini } 1723e7801d59Ssowmini bzero(dip, dsize); 1724e7801d59Ssowmini dip->pr_valsize = valsize; 17254045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 17263fd94f8cSam223141 dip->pr_version = MAC_PROP_VERSION; 17276b9e797cSsowmini dip->pr_linkid = linkid; 1728e7801d59Ssowmini dip->pr_num = p->pp_id; 17294045d941Ssowmini dip->pr_flags = flags; 1730e7801d59Ssowmini return (dip); 1731e7801d59Ssowmini } 1732e7801d59Ssowmini 1733e7801d59Ssowmini /* ARGSUSED */ 1734e7801d59Ssowmini static dladm_status_t 1735*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid, 17366b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1737e7801d59Ssowmini { 17383fd94f8cSam223141 dld_ioc_macprop_t *dip; 1739e7801d59Ssowmini int fd, dsize; 1740e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 1741e7801d59Ssowmini uint8_t u8; 1742e7801d59Ssowmini uint16_t u16; 1743e7801d59Ssowmini uint32_t u32; 1744e7801d59Ssowmini void *val; 1745e7801d59Ssowmini 1746*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_buf_alloc(0, linkid, pd->pd_name, 0, &status); 1747e7801d59Ssowmini if (dip == NULL) 1748e7801d59Ssowmini return (status); 1749e7801d59Ssowmini 1750e7801d59Ssowmini if (pd->pd_flags & PD_CHECK_ALLOC) 1751e7801d59Ssowmini val = (void *)vdp->vd_val; 1752e7801d59Ssowmini else { 1753e7801d59Ssowmini /* 1754e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 1755e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 1756e7801d59Ssowmini */ 1757e7801d59Ssowmini switch (dip->pr_valsize) { 1758e7801d59Ssowmini case 1: 1759e7801d59Ssowmini u8 = vdp->vd_val; 1760e7801d59Ssowmini val = &u8; 1761e7801d59Ssowmini break; 1762e7801d59Ssowmini case 2: 1763e7801d59Ssowmini u16 = vdp->vd_val; 1764e7801d59Ssowmini val = &u16; 1765e7801d59Ssowmini break; 1766e7801d59Ssowmini case 4: 1767e7801d59Ssowmini u32 = vdp->vd_val; 1768e7801d59Ssowmini val = &u32; 1769e7801d59Ssowmini break; 1770e7801d59Ssowmini default: 1771e7801d59Ssowmini val = &vdp->vd_val; 1772e7801d59Ssowmini break; 1773e7801d59Ssowmini } 1774e7801d59Ssowmini } 1775e7801d59Ssowmini 1776*3bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 1777e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 1778*3bc21d0aSAruna Ramakrishna - Sun Microsystems else 1779*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 1780*3bc21d0aSAruna Ramakrishna - Sun Microsystems 17813fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(dip->pr_valsize); 1782e7801d59Ssowmini if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 1783e7801d59Ssowmini status = dladm_errno2status(errno); 1784e7801d59Ssowmini goto done; 1785e7801d59Ssowmini } 17863fd94f8cSam223141 if (i_dladm_ioctl(fd, DLDIOC_SETMACPROP, dip, dsize) < 0) 1787e7801d59Ssowmini status = dladm_errno2status(errno); 1788e7801d59Ssowmini 1789e7801d59Ssowmini (void) close(fd); 1790e7801d59Ssowmini done: 17914045d941Ssowmini free(dip); 1792e7801d59Ssowmini return (status); 1793e7801d59Ssowmini } 1794e7801d59Ssowmini 17953fd94f8cSam223141 static dld_ioc_macprop_t * 1796*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags, 17974045d941Ssowmini dladm_status_t *status) 1798e7801d59Ssowmini { 1799e7801d59Ssowmini int fd, dsize; 18003fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 18014045d941Ssowmini 18024045d941Ssowmini *status = DLADM_STATUS_OK; 18034045d941Ssowmini 1804*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_buf_alloc(0, linkid, prop_name, flags, status); 18054045d941Ssowmini if (dip == NULL) 18064045d941Ssowmini return (NULL); 1807e7801d59Ssowmini 18083fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(dip->pr_valsize); 1809e7801d59Ssowmini 1810e7801d59Ssowmini if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 18114045d941Ssowmini *status = dladm_errno2status(errno); 1812e7801d59Ssowmini goto done; 1813e7801d59Ssowmini } 18143fd94f8cSam223141 if (i_dladm_ioctl(fd, DLDIOC_GETMACPROP, dip, dsize) < 0) { 18154045d941Ssowmini *status = dladm_errno2status(errno); 1816e7801d59Ssowmini } 18174045d941Ssowmini 18184045d941Ssowmini (void) close(fd); 1819e7801d59Ssowmini done: 18204045d941Ssowmini if (*status != DLADM_STATUS_OK) { 18214045d941Ssowmini free(dip); 18224045d941Ssowmini return (NULL); 18234045d941Ssowmini } 18244045d941Ssowmini return (dip); 1825e7801d59Ssowmini } 1826e7801d59Ssowmini 1827e7801d59Ssowmini /* ARGSUSED */ 1828e7801d59Ssowmini static dladm_status_t 1829*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_defmtu_check(struct prop_desc *pd, datalink_id_t linkid, 1830*3bc21d0aSAruna Ramakrishna - Sun Microsystems char **prop_val, uint_t val_cnt, val_desc_t *v, datalink_media_t media) 1831e7801d59Ssowmini { 1832e7801d59Ssowmini if (val_cnt != 1) 1833e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 18344045d941Ssowmini v->vd_val = atoi(prop_val[0]); 1835e7801d59Ssowmini return (DLADM_STATUS_OK); 1836e7801d59Ssowmini } 1837e7801d59Ssowmini 1838e7801d59Ssowmini /* ARGSUSED */ 1839e7801d59Ssowmini static dladm_status_t 1840*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_duplex_get(struct prop_desc *pd, datalink_id_t linkid, 18414045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1842e7801d59Ssowmini { 1843e7801d59Ssowmini link_duplex_t link_duplex; 1844e7801d59Ssowmini dladm_status_t status; 1845e7801d59Ssowmini 18463fd94f8cSam223141 if (flags & MAC_PROP_DEFAULT) 18474045d941Ssowmini return (DLADM_STATUS_NOTSUP); 18484045d941Ssowmini 1849e7801d59Ssowmini if ((status = dladm_get_single_mac_stat(linkid, "link_duplex", 1850e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 1851e7801d59Ssowmini return (status); 1852e7801d59Ssowmini 1853e7801d59Ssowmini switch (link_duplex) { 1854e7801d59Ssowmini case LINK_DUPLEX_FULL: 1855e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 1856e7801d59Ssowmini break; 1857e7801d59Ssowmini case LINK_DUPLEX_HALF: 1858e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 1859e7801d59Ssowmini break; 1860e7801d59Ssowmini default: 1861e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 1862e7801d59Ssowmini break; 1863e7801d59Ssowmini } 1864e7801d59Ssowmini *val_cnt = 1; 1865e7801d59Ssowmini return (DLADM_STATUS_OK); 1866e7801d59Ssowmini } 1867e7801d59Ssowmini 1868e7801d59Ssowmini /* ARGSUSED */ 1869e7801d59Ssowmini static dladm_status_t 1870*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_speed_get(struct prop_desc *pd, datalink_id_t linkid, 18714045d941Ssowmini char **prop_val, uint_t *val_cnt, uint_t flags) 1872e7801d59Ssowmini { 1873e7801d59Ssowmini uint64_t ifspeed = 0; 1874e7801d59Ssowmini dladm_status_t status; 1875e7801d59Ssowmini 18763fd94f8cSam223141 if (flags & MAC_PROP_DEFAULT) 18774045d941Ssowmini return (DLADM_STATUS_NOTSUP); 18784045d941Ssowmini 1879e7801d59Ssowmini if ((status = dladm_get_single_mac_stat(linkid, "ifspeed", 1880e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 1881e7801d59Ssowmini return (status); 18824045d941Ssowmini 18836b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 18846b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 18856b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 18866b9e797cSsowmini } else { 1887e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 1888e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 18896b9e797cSsowmini } 1890e7801d59Ssowmini *val_cnt = 1; 1891e7801d59Ssowmini return (DLADM_STATUS_OK); 1892e7801d59Ssowmini } 1893e7801d59Ssowmini 1894e7801d59Ssowmini /* ARGSUSED */ 1895e7801d59Ssowmini static dladm_status_t 1896*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_status_get(struct prop_desc *pd, datalink_id_t linkid, 18974045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1898e7801d59Ssowmini { 1899e7801d59Ssowmini link_state_t link_state; 1900e7801d59Ssowmini dladm_status_t status; 19014045d941Ssowmini uchar_t *cp; 19023fd94f8cSam223141 dld_ioc_macprop_t *dip; 1903e7801d59Ssowmini 19043fd94f8cSam223141 if (flags & MAC_PROP_DEFAULT) 19054045d941Ssowmini return (DLADM_STATUS_NOTSUP); 1906*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 19074045d941Ssowmini if (status != DLADM_STATUS_OK) 1908e7801d59Ssowmini return (status); 19094045d941Ssowmini cp = (uchar_t *)dip->pr_val; 19104045d941Ssowmini (void) memcpy(&link_state, cp, sizeof (link_state)); 1911e7801d59Ssowmini 1912e7801d59Ssowmini switch (link_state) { 1913e7801d59Ssowmini case LINK_STATE_UP: 1914e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 1915e7801d59Ssowmini break; 1916e7801d59Ssowmini case LINK_STATE_DOWN: 1917e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 1918e7801d59Ssowmini break; 1919e7801d59Ssowmini default: 1920e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 1921e7801d59Ssowmini break; 1922e7801d59Ssowmini } 1923e7801d59Ssowmini *val_cnt = 1; 19244045d941Ssowmini free(dip); 1925e7801d59Ssowmini return (DLADM_STATUS_OK); 1926e7801d59Ssowmini } 1927e7801d59Ssowmini 1928e7801d59Ssowmini /* ARGSUSED */ 1929e7801d59Ssowmini static dladm_status_t 1930*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_binary_get(struct prop_desc *pd, datalink_id_t linkid, 19314045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1932e7801d59Ssowmini { 19333fd94f8cSam223141 dld_ioc_macprop_t *dip; 1934e7801d59Ssowmini dladm_status_t status; 1935e7801d59Ssowmini 1936*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 19374045d941Ssowmini if (dip == NULL) 1938e7801d59Ssowmini return (status); 1939e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 1940e7801d59Ssowmini free(dip); 1941e7801d59Ssowmini *val_cnt = 1; 1942e7801d59Ssowmini return (DLADM_STATUS_OK); 1943e7801d59Ssowmini } 1944e7801d59Ssowmini 19456b9e797cSsowmini /* ARGSUSED */ 1946e7801d59Ssowmini static dladm_status_t 1947*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_uint32_get(struct prop_desc *pd, datalink_id_t linkid, 19484045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1949e7801d59Ssowmini { 19503fd94f8cSam223141 dld_ioc_macprop_t *dip; 19514045d941Ssowmini uint32_t v = 0; 1952e7801d59Ssowmini uchar_t *cp; 1953e7801d59Ssowmini dladm_status_t status; 1954e7801d59Ssowmini 1955*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 19564045d941Ssowmini if (dip == NULL) 1957e7801d59Ssowmini return (status); 1958e7801d59Ssowmini cp = (uchar_t *)dip->pr_val; 1959e7801d59Ssowmini (void) memcpy(&v, cp, sizeof (v)); 19604045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 1961e7801d59Ssowmini free(dip); 1962e7801d59Ssowmini *val_cnt = 1; 1963e7801d59Ssowmini return (DLADM_STATUS_OK); 1964e7801d59Ssowmini } 1965e7801d59Ssowmini 19666b9e797cSsowmini /* ARGSUSED */ 1967e7801d59Ssowmini static dladm_status_t 1968*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_flowctl_get(struct prop_desc *pd, datalink_id_t linkid, 19694045d941Ssowmini char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) 1970e7801d59Ssowmini { 19713fd94f8cSam223141 dld_ioc_macprop_t *dip; 1972e7801d59Ssowmini link_flowctrl_t v; 1973e7801d59Ssowmini dladm_status_t status; 1974e7801d59Ssowmini uchar_t *cp; 1975e7801d59Ssowmini 1976*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 19774045d941Ssowmini if (dip == NULL) 1978e7801d59Ssowmini return (status); 1979e7801d59Ssowmini cp = (uchar_t *)dip->pr_val; 1980e7801d59Ssowmini (void) memcpy(&v, cp, sizeof (v)); 1981e7801d59Ssowmini switch (v) { 1982e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 1983e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 1984e7801d59Ssowmini break; 1985e7801d59Ssowmini case LINK_FLOWCTRL_RX: 1986e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 1987e7801d59Ssowmini break; 1988e7801d59Ssowmini case LINK_FLOWCTRL_TX: 1989e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 1990e7801d59Ssowmini break; 1991e7801d59Ssowmini case LINK_FLOWCTRL_BI: 1992e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 1993e7801d59Ssowmini break; 1994e7801d59Ssowmini } 1995e7801d59Ssowmini free(dip); 1996e7801d59Ssowmini *val_cnt = 1; 1997e7801d59Ssowmini return (DLADM_STATUS_OK); 1998e7801d59Ssowmini } 1999e7801d59Ssowmini 2000e7801d59Ssowmini 2001e7801d59Ssowmini /* ARGSUSED */ 2002e7801d59Ssowmini static dladm_status_t 2003*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, 2004e7801d59Ssowmini char **prop_val, uint_t val_cnt, uint_t flags) 2005e7801d59Ssowmini { 2006e7801d59Ssowmini int fd, i, slen; 2007e7801d59Ssowmini int bufsize = 0, dsize; 20083fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 2009e7801d59Ssowmini uchar_t *dp; 2010*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_public_prop_t *p; 20114045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 2012e7801d59Ssowmini 2013e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 2014e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 2015e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2016e7801d59Ssowmini p = dladm_name2prop(prop_name); 20173fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 2018e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2019e7801d59Ssowmini 2020e7801d59Ssowmini /* 2021e7801d59Ssowmini * private properties: all parsing is done in the kernel. 2022e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 2023e7801d59Ssowmini */ 2024e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 2025e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 2026e7801d59Ssowmini } 20274045d941Ssowmini 20284045d941Ssowmini if (prop_val == NULL) { 20294045d941Ssowmini /* 20304045d941Ssowmini * getting default value. so use more buffer space. 20314045d941Ssowmini */ 20324045d941Ssowmini bufsize += 1024; 20334045d941Ssowmini } 20344045d941Ssowmini 2035*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_buf_alloc(bufsize + 1, linkid, prop_name, 20363fd94f8cSam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 2037e7801d59Ssowmini if (dip == NULL) 2038e7801d59Ssowmini return (status); 2039e7801d59Ssowmini 2040e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 20413fd94f8cSam223141 dsize = sizeof (dld_ioc_macprop_t) + bufsize; 2042e7801d59Ssowmini slen = 0; 20434045d941Ssowmini if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 20444045d941Ssowmini status = dladm_errno2status(errno); 20454045d941Ssowmini goto done; 20464045d941Ssowmini } 20474045d941Ssowmini if (prop_val == NULL) { 20483fd94f8cSam223141 if (i_dladm_ioctl(fd, DLDIOC_GETMACPROP, dip, dsize) < 0) { 20494045d941Ssowmini status = dladm_errno2status(errno); 20504045d941Ssowmini goto done; 20514045d941Ssowmini } 20524045d941Ssowmini } else { 2053e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 2054e7801d59Ssowmini int plen = 0; 2055e7801d59Ssowmini 2056e7801d59Ssowmini plen = strlen(prop_val[i]); 2057e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 2058e7801d59Ssowmini slen += plen; 2059e7801d59Ssowmini /* 2060e7801d59Ssowmini * add a "," separator and update dp. 2061e7801d59Ssowmini */ 2062e7801d59Ssowmini if (i != (val_cnt -1)) 2063e7801d59Ssowmini dp[slen++] = ','; 2064e7801d59Ssowmini dp += (plen + 1); 2065e7801d59Ssowmini } 2066e7801d59Ssowmini } 20673fd94f8cSam223141 if (i_dladm_ioctl(fd, DLDIOC_SETMACPROP, dip, dsize) < 0) { 20684045d941Ssowmini status = dladm_errno2status(errno); 20694045d941Ssowmini } 20704045d941Ssowmini 20714045d941Ssowmini done: 20724045d941Ssowmini if (fd > 0) 20734045d941Ssowmini (void) close(fd); 2074e7801d59Ssowmini free(dip); 2075e7801d59Ssowmini return (status); 2076e7801d59Ssowmini } 2077e7801d59Ssowmini 2078e7801d59Ssowmini static dladm_status_t 2079*3bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, 20804045d941Ssowmini char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags) 2081e7801d59Ssowmini { 2082e7801d59Ssowmini int fd; 2083e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 2084e7801d59Ssowmini uint_t dsize; 20853fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 2086*3bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_public_prop_t *p; 2087e7801d59Ssowmini char tmp = '\0'; 2088e7801d59Ssowmini 2089e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 2090e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 2091e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2092e7801d59Ssowmini 2093e7801d59Ssowmini p = dladm_name2prop(prop_name); 20943fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 2095e7801d59Ssowmini return (DLADM_STATUS_BADARG); 2096e7801d59Ssowmini 20974045d941Ssowmini if (type == DLADM_PROP_VAL_MODIFIABLE) { 2098e7801d59Ssowmini *prop_val = &tmp; 2099e7801d59Ssowmini *val_cnt = 1; 2100e7801d59Ssowmini return (DLADM_STATUS_OK); 2101e7801d59Ssowmini } 2102e7801d59Ssowmini 2103e7801d59Ssowmini /* 2104e7801d59Ssowmini * private properties: all parsing is done in the kernel. 2105e7801d59Ssowmini */ 2106*3bc21d0aSAruna Ramakrishna - Sun Microsystems dip = i_dladm_buf_alloc(1024, linkid, prop_name, dld_flags, &status); 2107e7801d59Ssowmini if (dip == NULL) 2108e7801d59Ssowmini return (status); 21093fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(dip->pr_valsize); 2110e7801d59Ssowmini 21114045d941Ssowmini if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 21124045d941Ssowmini free(dip); 2113e7801d59Ssowmini return (DLADM_STATUS_BADARG); 21144045d941Ssowmini } 2115e7801d59Ssowmini 21163fd94f8cSam223141 if ((status = i_dladm_ioctl(fd, DLDIOC_GETMACPROP, dip, dsize)) < 0) { 2117e7801d59Ssowmini status = dladm_errno2status(errno); 2118e7801d59Ssowmini } else { 2119e7801d59Ssowmini (void) strncpy(*prop_val, dip->pr_val, DLADM_PROP_VAL_MAX); 2120e7801d59Ssowmini *val_cnt = 1; 2121e7801d59Ssowmini } 21224045d941Ssowmini 21234045d941Ssowmini (void) close(fd); 21244045d941Ssowmini free(dip); 21254045d941Ssowmini return (status); 21264045d941Ssowmini } 21274045d941Ssowmini 21284045d941Ssowmini 21294045d941Ssowmini static dladm_status_t 21304045d941Ssowmini i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid, 21314045d941Ssowmini datalink_media_t media, uint_t flags) 21324045d941Ssowmini { 21334045d941Ssowmini dladm_status_t status; 21344045d941Ssowmini char **prop_vals = NULL, *buf; 21354045d941Ssowmini size_t bufsize; 21364045d941Ssowmini uint_t cnt; 21374045d941Ssowmini int i; 21384045d941Ssowmini 21394045d941Ssowmini /* 21404045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 21414045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 21424045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 21434045d941Ssowmini */ 21444045d941Ssowmini bufsize = 21454045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 21464045d941Ssowmini buf = malloc(bufsize); 21474045d941Ssowmini prop_vals = (char **)(void *)buf; 21484045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 21494045d941Ssowmini prop_vals[i] = buf + 21504045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 21514045d941Ssowmini i * DLADM_PROP_VAL_MAX; 21524045d941Ssowmini } 215313a55820Sar224390 215413a55820Sar224390 /* 2155*3bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 2156*3bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 2157*3bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 2158*3bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 2159*3bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 2160*3bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 2161*3bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 2162*3bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 216313a55820Sar224390 */ 21643fd94f8cSam223141 status = pdp->pd_get(pdp, linkid, prop_vals, &cnt, media, 21653fd94f8cSam223141 MAC_PROP_DEFAULT); 21664045d941Ssowmini if (status == DLADM_STATUS_OK) { 21674045d941Ssowmini status = i_dladm_set_single_prop(linkid, pdp->pd_class, 21684045d941Ssowmini media, pdp, prop_vals, cnt, flags); 21694045d941Ssowmini } 21704045d941Ssowmini free(buf); 2171e7801d59Ssowmini return (status); 2172e7801d59Ssowmini } 2173