13147Sxc151355 /* 23147Sxc151355 * CDDL HEADER START 33147Sxc151355 * 43147Sxc151355 * The contents of this file are subject to the terms of the 53147Sxc151355 * Common Development and Distribution License (the "License"). 63147Sxc151355 * You may not use this file except in compliance with the License. 73147Sxc151355 * 83147Sxc151355 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93147Sxc151355 * or http://www.opensolaris.org/os/licensing. 103147Sxc151355 * See the License for the specific language governing permissions 113147Sxc151355 * and limitations under the License. 123147Sxc151355 * 133147Sxc151355 * When distributing Covered Code, include this CDDL HEADER in each 143147Sxc151355 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153147Sxc151355 * If applicable, add the following below this CDDL HEADER, with the 163147Sxc151355 * fields enclosed by brackets "[]" replaced with your own identifying 173147Sxc151355 * information: Portions Copyright [yyyy] [name of copyright owner] 183147Sxc151355 * 193147Sxc151355 * CDDL HEADER END 203147Sxc151355 */ 213147Sxc151355 /* 225895Syz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 233147Sxc151355 * Use is subject to license terms. 243147Sxc151355 */ 253147Sxc151355 263147Sxc151355 #include <stdlib.h> 273147Sxc151355 #include <strings.h> 283147Sxc151355 #include <errno.h> 293147Sxc151355 #include <ctype.h> 305895Syz147064 #include <stddef.h> 313448Sdh155122 #include <sys/types.h> 323147Sxc151355 #include <sys/stat.h> 333448Sdh155122 #include <sys/dld.h> 343448Sdh155122 #include <sys/zone.h> 353448Sdh155122 #include <fcntl.h> 363448Sdh155122 #include <unistd.h> 373448Sdh155122 #include <libdevinfo.h> 383448Sdh155122 #include <zone.h> 393871Syz147064 #include <libdllink.h> 403147Sxc151355 #include <libdladm_impl.h> 415895Syz147064 #include <libdlwlan_impl.h> 423871Syz147064 #include <libdlwlan.h> 435895Syz147064 #include <libdlvlan.h> 443448Sdh155122 #include <dlfcn.h> 453448Sdh155122 #include <link.h> 465895Syz147064 #include <inet/wifi_ioctl.h> 475903Ssowmini #include <libdladm.h> 485903Ssowmini #include <sys/param.h> 495903Ssowmini #include <inttypes.h> 505903Ssowmini #include <sys/ethernet.h> 517663SSowmini.Varadhan@Sun.COM #include <net/wpa.h> 527663SSowmini.Varadhan@Sun.COM #include <sys/sysmacros.h> 533448Sdh155122 54*8118SVasumathi.Sundaram@Sun.COM #define PERM_READ_ONLY "r-" 55*8118SVasumathi.Sundaram@Sun.COM #define PERM_READ_WRITE "rw" 56*8118SVasumathi.Sundaram@Sun.COM 575895Syz147064 /* 585895Syz147064 * The linkprop get() callback. 595903Ssowmini * - pd: pointer to the struct prop_desc 605895Syz147064 * - propstrp: a property string array to keep the returned property. 615895Syz147064 * Caller allocated. 625895Syz147064 * - cntp: number of returned properties. 635895Syz147064 * Caller also uses it to indicate how many it expects. 645895Syz147064 */ 655903Ssowmini struct prop_desc; 665903Ssowmini 675903Ssowmini typedef dladm_status_t pd_getf_t(struct prop_desc *pd, 685960Ssowmini datalink_id_t, char **propstp, uint_t *cntp, 69*8118SVasumathi.Sundaram@Sun.COM datalink_media_t, uint_t, uint_t *); 705895Syz147064 715895Syz147064 /* 725895Syz147064 * The linkprop set() callback. 735895Syz147064 * - propval: a val_desc_t array which keeps the property values to be set. 745895Syz147064 * - cnt: number of properties to be set. 755903Ssowmini * - flags: additional flags passed down the system call. 765903Ssowmini * 775903Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 785903Ssowmini * a format suitable for kernel consumption. This may require allocation 795903Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 805903Ssowmini * by all other pd_sets) which invokes the ioctl. 815895Syz147064 */ 825903Ssowmini typedef dladm_status_t pd_setf_t(struct prop_desc *, datalink_id_t, 835960Ssowmini val_desc_t *propval, uint_t cnt, uint_t flags, 845960Ssowmini datalink_media_t); 853448Sdh155122 863448Sdh155122 875895Syz147064 /* 885895Syz147064 * The linkprop check() callback. 895895Syz147064 * - propstrp: property string array which keeps the property to be checked. 905895Syz147064 * - cnt: number of properties. 915895Syz147064 * - propval: return value; the property values of the given property strings. 925903Ssowmini * 935903Ssowmini * pd_check checks that the input values are valid. It does so by 945903Ssowmini * iteraring through the pd_modval list for the property. If 955903Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 965903Ssowmini * specific to this property can be used. If the input values are 975903Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 985903Ssowmini * with either a val_desc_t found on the pd_modval list or something 995903Ssowmini * generated on the fly. 1005895Syz147064 */ 1015903Ssowmini typedef dladm_status_t pd_checkf_t(struct prop_desc *pd, 1025903Ssowmini datalink_id_t, char **propstrp, 1035960Ssowmini uint_t cnt, val_desc_t *propval, 1045960Ssowmini datalink_media_t); 1053448Sdh155122 1067663SSowmini.Varadhan@Sun.COM typedef struct link_attr_s { 1076789Sam223141 mac_prop_id_t pp_id; 1085903Ssowmini size_t pp_valsize; 1095903Ssowmini char *pp_name; 1107663SSowmini.Varadhan@Sun.COM } link_attr_t; 1115903Ssowmini 1127663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 1137663SSowmini.Varadhan@Sun.COM const char *, uint_t, dladm_status_t *); 1147663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 1157663SSowmini.Varadhan@Sun.COM mac_prop_id_t, uint_t, 1167663SSowmini.Varadhan@Sun.COM dladm_status_t *); 1177342SAruna.Ramakrishna@Sun.COM static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **, 1185903Ssowmini uint_t, uint_t); 1197342SAruna.Ramakrishna@Sun.COM static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **, 1206512Ssowmini uint_t *, dladm_prop_type_t, uint_t); 1217663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_name2prop(const char *); 1227663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 1237342SAruna.Ramakrishna@Sun.COM static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t, 1247342SAruna.Ramakrishna@Sun.COM dladm_status_t *); 1255895Syz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 1265895Syz147064 do_get_rate_prop, do_get_channel_prop, 1275903Ssowmini do_get_powermode_prop, do_get_radio_prop, 1287342SAruna.Ramakrishna@Sun.COM i_dladm_duplex_get, i_dladm_status_get, 1297342SAruna.Ramakrishna@Sun.COM i_dladm_binary_get, i_dladm_uint32_get, 1307342SAruna.Ramakrishna@Sun.COM i_dladm_flowctl_get; 1317342SAruna.Ramakrishna@Sun.COM static pd_setf_t do_set_zone, do_set_rate_prop, 1325903Ssowmini do_set_powermode_prop, do_set_radio_prop, 1337342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop; 1345903Ssowmini static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 1357342SAruna.Ramakrishna@Sun.COM i_dladm_defmtu_check; 1363448Sdh155122 1377342SAruna.Ramakrishna@Sun.COM static dladm_status_t i_dladm_speed_get(struct prop_desc *, datalink_id_t, 1386512Ssowmini char **, uint_t *, uint_t); 1397663SSowmini.Varadhan@Sun.COM static dladm_status_t i_dladm_wlan_get_legacy_ioctl(datalink_id_t, void *, 1407663SSowmini.Varadhan@Sun.COM uint_t, uint_t); 1417663SSowmini.Varadhan@Sun.COM static dladm_status_t i_dladm_wlan_set_legacy_ioctl(datalink_id_t, void *, 1427663SSowmini.Varadhan@Sun.COM uint_t, uint_t); 1437663SSowmini.Varadhan@Sun.COM static dladm_status_t i_dladm_macprop(void *, boolean_t); 1445960Ssowmini 1453448Sdh155122 typedef struct prop_desc { 1465895Syz147064 /* 1475895Syz147064 * link property name 1485895Syz147064 */ 1495895Syz147064 char *pd_name; 1505895Syz147064 1515895Syz147064 /* 1525895Syz147064 * default property value, can be set to { "", NULL } 1535895Syz147064 */ 1545895Syz147064 val_desc_t pd_defval; 1555895Syz147064 1565895Syz147064 /* 1575895Syz147064 * list of optional property values, can be NULL. 1585895Syz147064 * 1595895Syz147064 * This is set to non-NULL if there is a list of possible property 1605895Syz147064 * values. pd_optval would point to the array of possible values. 1615895Syz147064 */ 1625895Syz147064 val_desc_t *pd_optval; 1635895Syz147064 1645895Syz147064 /* 1655895Syz147064 * count of the above optional property values. 0 if pd_optval is NULL. 1665895Syz147064 */ 1675895Syz147064 uint_t pd_noptval; 1685895Syz147064 1695895Syz147064 /* 1705895Syz147064 * callback to set link property; 1715895Syz147064 * set to NULL if this property is read-only 1725895Syz147064 */ 1735895Syz147064 pd_setf_t *pd_set; 1745895Syz147064 1755895Syz147064 /* 1765895Syz147064 * callback to get modifiable link property 1775895Syz147064 */ 1785895Syz147064 pd_getf_t *pd_getmod; 1795895Syz147064 1805895Syz147064 /* 1815895Syz147064 * callback to get current link property 1825895Syz147064 */ 1835895Syz147064 pd_getf_t *pd_get; 1845895Syz147064 1855895Syz147064 /* 1865895Syz147064 * callback to validate link property value, set to NULL if pd_optval 1875895Syz147064 * is not NULL. In that case, validate the value by comparing it with 1885895Syz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 1895895Syz147064 * valid. 1905895Syz147064 */ 1915895Syz147064 pd_checkf_t *pd_check; 1925895Syz147064 1935895Syz147064 uint_t pd_flags; 1945903Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 1955903Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 1965895Syz147064 /* 1975895Syz147064 * indicate link classes this property applies to. 1985895Syz147064 */ 1995895Syz147064 datalink_class_t pd_class; 2005895Syz147064 2015895Syz147064 /* 2025895Syz147064 * indicate link media type this property applies to. 2035895Syz147064 */ 2045895Syz147064 datalink_media_t pd_dmedia; 2053448Sdh155122 } prop_desc_t; 2063448Sdh155122 2076789Sam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 2085903Ssowmini 2097663SSowmini.Varadhan@Sun.COM /* 2107663SSowmini.Varadhan@Sun.COM * Supported link properties enumerated in the prop_table[] array are 2117663SSowmini.Varadhan@Sun.COM * computed using the callback functions in that array. To compute the 2127663SSowmini.Varadhan@Sun.COM * property value, multiple distinct system calls may be needed (e.g., 2137663SSowmini.Varadhan@Sun.COM * for wifi speed, we need to issue system calls to get desired/supported 2147663SSowmini.Varadhan@Sun.COM * rates). The link_attr[] table enumerates the interfaces to the kernel, 2157663SSowmini.Varadhan@Sun.COM * and the type/size of the data passed in the user-kernel interface. 2167663SSowmini.Varadhan@Sun.COM */ 2177663SSowmini.Varadhan@Sun.COM static link_attr_t link_attr[] = { 2187663SSowmini.Varadhan@Sun.COM { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 2195903Ssowmini 2207663SSowmini.Varadhan@Sun.COM { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 2217663SSowmini.Varadhan@Sun.COM 2227663SSowmini.Varadhan@Sun.COM { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 2237663SSowmini.Varadhan@Sun.COM 2247663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 2255903Ssowmini 2267663SSowmini.Varadhan@Sun.COM { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 2275903Ssowmini 2287663SSowmini.Varadhan@Sun.COM { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 2297663SSowmini.Varadhan@Sun.COM 2307663SSowmini.Varadhan@Sun.COM { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 2315903Ssowmini 2327663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2337663SSowmini.Varadhan@Sun.COM 2347663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2357663SSowmini.Varadhan@Sun.COM 2367663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 2375903Ssowmini 2387663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 2395903Ssowmini 2407663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 2417663SSowmini.Varadhan@Sun.COM 2427663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 2437342SAruna.Ramakrishna@Sun.COM 2447663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 2457663SSowmini.Varadhan@Sun.COM 2467663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 2477663SSowmini.Varadhan@Sun.COM 2487663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 2497342SAruna.Ramakrishna@Sun.COM 2507663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 2517663SSowmini.Varadhan@Sun.COM 2527663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 2535903Ssowmini 2547663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 2557663SSowmini.Varadhan@Sun.COM 2567663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 2575903Ssowmini 2587663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 2597663SSowmini.Varadhan@Sun.COM 2607663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 2615903Ssowmini 2627663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 2637663SSowmini.Varadhan@Sun.COM 2647663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 2657663SSowmini.Varadhan@Sun.COM 2667663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2677663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 2685903Ssowmini 2697663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2707663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 2717663SSowmini.Varadhan@Sun.COM 2727663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 2735903Ssowmini 2747663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 2757663SSowmini.Varadhan@Sun.COM 2767663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 2775903Ssowmini 2787663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 2797663SSowmini.Varadhan@Sun.COM 2807663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 2815903Ssowmini 2827663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 2837663SSowmini.Varadhan@Sun.COM 2847663SSowmini.Varadhan@Sun.COM /* wl_wpa_ess_t has variable length */ 2857663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 2865903Ssowmini 2877663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 2887663SSowmini.Varadhan@Sun.COM 2897663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 2905903Ssowmini 2917663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 2927663SSowmini.Varadhan@Sun.COM 2937663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 2945903Ssowmini 2957663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 2967663SSowmini.Varadhan@Sun.COM 2977663SSowmini.Varadhan@Sun.COM /* wl_wpa_ie_t has variable length */ 2987663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 2995903Ssowmini 3007663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 3017663SSowmini.Varadhan@Sun.COM 3027663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 3035903Ssowmini 3047663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 3057663SSowmini.Varadhan@Sun.COM 3067663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3075903Ssowmini }; 3085903Ssowmini 3095903Ssowmini static val_desc_t link_duplex_vals[] = { 3105903Ssowmini { "half", LINK_DUPLEX_HALF }, 3115903Ssowmini { "full", LINK_DUPLEX_HALF } 3125903Ssowmini }; 3135903Ssowmini static val_desc_t link_status_vals[] = { 3145903Ssowmini { "up", LINK_STATE_UP }, 3155903Ssowmini { "down", LINK_STATE_DOWN } 3165903Ssowmini }; 3175903Ssowmini static val_desc_t link_01_vals[] = { 3185903Ssowmini { "1", 1 }, 3195903Ssowmini { "0", 0 } 3205903Ssowmini }; 3215903Ssowmini static val_desc_t link_flow_vals[] = { 3225903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3235903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3245903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 3255903Ssowmini { "bi", LINK_FLOWCTRL_BI } 3265903Ssowmini }; 3275903Ssowmini 3285903Ssowmini #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 3295903Ssowmini 3305895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 3315895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 3325895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 3335895Syz147064 }; 3345895Syz147064 3355895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 3365895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 3375895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 3385895Syz147064 { "max", DLADM_WLAN_PM_MAX } 3395895Syz147064 }; 3405895Syz147064 3413448Sdh155122 static prop_desc_t prop_table[] = { 3425895Syz147064 3435903Ssowmini { "channel", { NULL, 0 }, 3445903Ssowmini NULL, 0, NULL, NULL, 3455895Syz147064 do_get_channel_prop, NULL, 0, 3465903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 3475895Syz147064 3485895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 3495895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 3505895Syz147064 do_set_powermode_prop, NULL, 3515895Syz147064 do_get_powermode_prop, NULL, 0, 3525903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 3535895Syz147064 3545895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 3555895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 3565895Syz147064 do_set_radio_prop, NULL, 3575895Syz147064 do_get_radio_prop, NULL, 0, 3585903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 3595895Syz147064 3605895Syz147064 { "speed", { "", 0 }, NULL, 0, 3615895Syz147064 do_set_rate_prop, do_get_rate_mod, 3625895Syz147064 do_get_rate_prop, do_check_rate, 0, 3635960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 3645895Syz147064 3656512Ssowmini { "autopush", { "", 0 }, NULL, 0, 3667342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, 3677342SAruna.Ramakrishna@Sun.COM do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 3685903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 3695895Syz147064 3706512Ssowmini { "zone", { "", 0 }, NULL, 0, 3713448Sdh155122 do_set_zone, NULL, 3727342SAruna.Ramakrishna@Sun.COM do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 3735903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 3745903Ssowmini 3756512Ssowmini { "duplex", { "", 0 }, 3765903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 3777342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_duplex_get, NULL, 3785903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 3795903Ssowmini 3805960Ssowmini { "state", { "up", LINK_STATE_UP }, 3815903Ssowmini link_status_vals, VALCNT(link_status_vals), 3827342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_status_get, NULL, 3836512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 3845903Ssowmini 3855903Ssowmini { "adv_autoneg_cap", { "1", 1 }, 3865903Ssowmini link_01_vals, VALCNT(link_01_vals), 3877342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 3885903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 3895903Ssowmini 3906512Ssowmini { "mtu", { "", 0 }, NULL, 0, 3917342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 3927342SAruna.Ramakrishna@Sun.COM i_dladm_defmtu_check, 0, DATALINK_CLASS_ALL, 3937342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 3945903Ssowmini 3956512Ssowmini { "flowctrl", { "", 0 }, 3965903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 3977342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 3985903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 3995903Ssowmini 4006512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 4016512Ssowmini link_01_vals, VALCNT(link_01_vals), 4027342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4035903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4045903Ssowmini 4056512Ssowmini { "en_1000fdx_cap", { "", 0 }, 4065903Ssowmini link_01_vals, VALCNT(link_01_vals), 4077342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4085903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4095903Ssowmini 4106512Ssowmini { "adv_1000hdx_cap", { "", 0 }, 4115903Ssowmini link_01_vals, VALCNT(link_01_vals), 4127342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4135903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4145903Ssowmini 4156512Ssowmini { "en_1000hdx_cap", { "", 0 }, 4165903Ssowmini link_01_vals, VALCNT(link_01_vals), 4177342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4185903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4195903Ssowmini 4206512Ssowmini { "adv_100fdx_cap", { "", 0 }, 4215903Ssowmini link_01_vals, VALCNT(link_01_vals), 4227342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4235903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4245903Ssowmini 4256512Ssowmini { "en_100fdx_cap", { "", 0 }, 4265903Ssowmini link_01_vals, VALCNT(link_01_vals), 4277342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4285903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4295903Ssowmini 4306512Ssowmini { "adv_100hdx_cap", { "", 0 }, 4315903Ssowmini link_01_vals, VALCNT(link_01_vals), 4327342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4335903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4345903Ssowmini 4356512Ssowmini { "en_100hdx_cap", { "", 0 }, 4365903Ssowmini link_01_vals, VALCNT(link_01_vals), 4377342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4385903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4395903Ssowmini 4406512Ssowmini { "adv_10fdx_cap", { "", 0 }, 4415903Ssowmini link_01_vals, VALCNT(link_01_vals), 4427342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4435903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4445903Ssowmini 4456512Ssowmini { "en_10fdx_cap", { "", 0 }, 4465903Ssowmini link_01_vals, VALCNT(link_01_vals), 4477342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4485903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4495903Ssowmini 4506512Ssowmini { "adv_10hdx_cap", { "", 0 }, 4515903Ssowmini link_01_vals, VALCNT(link_01_vals), 4527342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4535903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4545903Ssowmini 4556512Ssowmini { "en_10hdx_cap", { "", 0 }, 4565903Ssowmini link_01_vals, VALCNT(link_01_vals), 4577342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4585903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER } 4595903Ssowmini 4603448Sdh155122 }; 4613448Sdh155122 4625895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 4635895Syz147064 4647663SSowmini.Varadhan@Sun.COM /* 4657663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 4667663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 4677663SSowmini.Varadhan@Sun.COM */ 4687663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 4697663SSowmini.Varadhan@Sun.COM 4705895Syz147064 static dladm_status_t i_dladm_set_linkprop_db(datalink_id_t, const char *, 4715895Syz147064 char **, uint_t); 4725895Syz147064 static dladm_status_t i_dladm_get_linkprop_db(datalink_id_t, const char *, 4735895Syz147064 char **, uint_t *); 4745895Syz147064 static dladm_status_t i_dladm_set_single_prop(datalink_id_t, datalink_class_t, 4755895Syz147064 uint32_t, prop_desc_t *, char **, uint_t, uint_t); 4765895Syz147064 static dladm_status_t i_dladm_set_linkprop(datalink_id_t, const char *, 4775895Syz147064 char **, uint_t, uint_t); 4786512Ssowmini static dladm_status_t i_dladm_getset_defval(prop_desc_t *, datalink_id_t, 4796512Ssowmini datalink_media_t, uint_t); 4805895Syz147064 /* 4815895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 4825895Syz147064 * rates to be retrieved. However, we cannot increase it at this 4835895Syz147064 * time because it will break binary compatibility with unbundled 4845895Syz147064 * WiFi drivers and utilities. So for now we define an additional 4855895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 4865895Syz147064 */ 4875895Syz147064 #define MAX_SUPPORT_RATES 64 4885895Syz147064 4895895Syz147064 #define AP_ANCHOR "[anchor]" 4905895Syz147064 #define AP_DELIMITER '.' 4915895Syz147064 4925895Syz147064 static dladm_status_t 4935895Syz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 4945895Syz147064 val_desc_t *vdp) 4955895Syz147064 { 4965895Syz147064 int i, j; 4975895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 4983147Sxc151355 4995895Syz147064 for (j = 0; j < val_cnt; j++) { 5005895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 5015895Syz147064 if (strcasecmp(*prop_val, 5025895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 5035895Syz147064 break; 5045895Syz147064 } 5055895Syz147064 } 5065895Syz147064 if (i == pdp->pd_noptval) { 5075895Syz147064 status = DLADM_STATUS_BADVAL; 5085895Syz147064 goto done; 5095895Syz147064 } 5105895Syz147064 (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); 5115895Syz147064 } 5125895Syz147064 5135895Syz147064 done: 5145895Syz147064 return (status); 5155895Syz147064 } 5165895Syz147064 5175895Syz147064 static dladm_status_t 5185895Syz147064 i_dladm_set_single_prop(datalink_id_t linkid, datalink_class_t class, 5195895Syz147064 uint32_t media, prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 5205895Syz147064 uint_t flags) 5213147Sxc151355 { 5225895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 5235895Syz147064 val_desc_t *vdp = NULL; 5245895Syz147064 boolean_t needfree = B_FALSE; 5255895Syz147064 uint_t cnt, i; 5263147Sxc151355 5275895Syz147064 if (!(pdp->pd_class & class)) 5285895Syz147064 return (DLADM_STATUS_BADARG); 5295895Syz147064 5305895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 5313147Sxc151355 return (DLADM_STATUS_BADARG); 5323147Sxc151355 5335895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 5345895Syz147064 return (DLADM_STATUS_TEMPONLY); 5355895Syz147064 5365895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 5375895Syz147064 return (DLADM_STATUS_OK); 5385895Syz147064 5395895Syz147064 if (pdp->pd_set == NULL) 5405895Syz147064 return (DLADM_STATUS_PROPRDONLY); 5413448Sdh155122 5425903Ssowmini if (pdp->pd_flags & PD_CHECK_ALLOC) 5435903Ssowmini needfree = B_TRUE; 5445903Ssowmini else 5455903Ssowmini needfree = B_FALSE; 5465895Syz147064 if (prop_val != NULL) { 5475895Syz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 5485895Syz147064 if (vdp == NULL) 5495895Syz147064 return (DLADM_STATUS_NOMEM); 5505895Syz147064 5515903Ssowmini 5525895Syz147064 if (pdp->pd_check != NULL) { 5535903Ssowmini status = pdp->pd_check(pdp, linkid, prop_val, val_cnt, 5545960Ssowmini vdp, media); 5555895Syz147064 } else if (pdp->pd_optval != NULL) { 5565895Syz147064 status = do_check_prop(pdp, prop_val, val_cnt, vdp); 5575895Syz147064 } else { 5583448Sdh155122 status = DLADM_STATUS_BADARG; 5593147Sxc151355 } 5605895Syz147064 5613147Sxc151355 if (status != DLADM_STATUS_OK) 5625895Syz147064 goto done; 5635895Syz147064 5645895Syz147064 cnt = val_cnt; 5655895Syz147064 } else { 5665895Syz147064 if (pdp->pd_defval.vd_name == NULL) 5675895Syz147064 return (DLADM_STATUS_NOTSUP); 5685895Syz147064 5697342SAruna.Ramakrishna@Sun.COM cnt = 1; 5707342SAruna.Ramakrishna@Sun.COM if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || 5716512Ssowmini strlen(pdp->pd_defval.vd_name) > 0) { 5726512Ssowmini if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 5736512Ssowmini return (DLADM_STATUS_NOMEM); 5747342SAruna.Ramakrishna@Sun.COM 5757342SAruna.Ramakrishna@Sun.COM if (pdp->pd_check != NULL) { 5767342SAruna.Ramakrishna@Sun.COM status = pdp->pd_check(pdp, linkid, prop_val, 5777342SAruna.Ramakrishna@Sun.COM cnt, vdp, media); 5787342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 5797342SAruna.Ramakrishna@Sun.COM goto done; 5807342SAruna.Ramakrishna@Sun.COM } else { 5817342SAruna.Ramakrishna@Sun.COM (void) memcpy(vdp, &pdp->pd_defval, 5827342SAruna.Ramakrishna@Sun.COM sizeof (val_desc_t)); 5837342SAruna.Ramakrishna@Sun.COM } 5846512Ssowmini } else { 5856512Ssowmini status = i_dladm_getset_defval(pdp, linkid, 5866512Ssowmini media, flags); 5876512Ssowmini return (status); 5886512Ssowmini } 5895895Syz147064 } 5905960Ssowmini status = pdp->pd_set(pdp, linkid, vdp, cnt, flags, media); 5915895Syz147064 if (needfree) { 5925895Syz147064 for (i = 0; i < cnt; i++) 5935903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 5943147Sxc151355 } 5955895Syz147064 done: 5965895Syz147064 free(vdp); 5975895Syz147064 return (status); 5985895Syz147064 } 5995895Syz147064 6005895Syz147064 static dladm_status_t 6015895Syz147064 i_dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, 6025895Syz147064 char **prop_val, uint_t val_cnt, uint_t flags) 6035895Syz147064 { 6045895Syz147064 int i; 6055895Syz147064 boolean_t found = B_FALSE; 6065895Syz147064 datalink_class_t class; 6075895Syz147064 uint32_t media; 6085895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 6095895Syz147064 6105895Syz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 6115895Syz147064 if (status != DLADM_STATUS_OK) 6125895Syz147064 return (status); 6135895Syz147064 6145895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 6155895Syz147064 prop_desc_t *pdp = &prop_table[i]; 6165895Syz147064 dladm_status_t s; 6175895Syz147064 6185895Syz147064 if (prop_name != NULL && 6195895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 6205895Syz147064 continue; 6215895Syz147064 6225895Syz147064 found = B_TRUE; 6235895Syz147064 s = i_dladm_set_single_prop(linkid, class, media, pdp, prop_val, 6245895Syz147064 val_cnt, flags); 6253448Sdh155122 6265895Syz147064 if (prop_name != NULL) { 6275895Syz147064 status = s; 6285895Syz147064 break; 6295895Syz147064 } else { 6305895Syz147064 if (s != DLADM_STATUS_OK && 6315895Syz147064 s != DLADM_STATUS_NOTSUP) 6325895Syz147064 status = s; 6335895Syz147064 } 6345895Syz147064 } 6355903Ssowmini if (!found) { 6365903Ssowmini if (prop_name[0] == '_') { 6375903Ssowmini /* other private properties */ 6387342SAruna.Ramakrishna@Sun.COM status = i_dladm_set_prop(linkid, prop_name, prop_val, 6395903Ssowmini val_cnt, flags); 6405903Ssowmini } else { 6415903Ssowmini status = DLADM_STATUS_NOTFOUND; 6425903Ssowmini } 6435903Ssowmini } 6445895Syz147064 6455895Syz147064 return (status); 6465895Syz147064 } 6475895Syz147064 6485895Syz147064 /* 6495895Syz147064 * Set/reset link property for specific link 6505895Syz147064 */ 6515895Syz147064 dladm_status_t 6525895Syz147064 dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, char **prop_val, 6535895Syz147064 uint_t val_cnt, uint_t flags) 6545895Syz147064 { 6555895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 6565895Syz147064 6575895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 6585895Syz147064 (prop_val == NULL && val_cnt > 0) || 6595895Syz147064 (prop_val != NULL && val_cnt == 0) || 6605895Syz147064 (prop_name == NULL && prop_val != NULL)) { 6615895Syz147064 return (DLADM_STATUS_BADARG); 6625895Syz147064 } 6635895Syz147064 6645895Syz147064 status = i_dladm_set_linkprop(linkid, prop_name, prop_val, 6655895Syz147064 val_cnt, flags); 6665895Syz147064 if (status != DLADM_STATUS_OK) 6675895Syz147064 return (status); 6685895Syz147064 6695895Syz147064 if (flags & DLADM_OPT_PERSIST) { 6705895Syz147064 status = i_dladm_set_linkprop_db(linkid, prop_name, 6713147Sxc151355 prop_val, val_cnt); 6723147Sxc151355 } 6733147Sxc151355 return (status); 6743147Sxc151355 } 6753147Sxc151355 6765895Syz147064 /* 6775895Syz147064 * Walk link properties of the given specific link. 6785895Syz147064 */ 6793147Sxc151355 dladm_status_t 6805895Syz147064 dladm_walk_linkprop(datalink_id_t linkid, void *arg, 6815895Syz147064 int (*func)(datalink_id_t, const char *, void *)) 6823147Sxc151355 { 6835895Syz147064 dladm_status_t status; 6845895Syz147064 datalink_class_t class; 6855895Syz147064 uint_t media; 6865895Syz147064 int i; 6875895Syz147064 6885895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 6895895Syz147064 return (DLADM_STATUS_BADARG); 6905895Syz147064 6915895Syz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 6925895Syz147064 if (status != DLADM_STATUS_OK) 6935895Syz147064 return (status); 6945895Syz147064 6955895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 6965895Syz147064 if (!(prop_table[i].pd_class & class)) 6975895Syz147064 continue; 6985895Syz147064 6995895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 7005895Syz147064 continue; 7015895Syz147064 7025895Syz147064 if (func(linkid, prop_table[i].pd_name, arg) == 7035895Syz147064 DLADM_WALK_TERMINATE) { 7045895Syz147064 break; 7055895Syz147064 } 7065895Syz147064 } 7075895Syz147064 7085895Syz147064 return (DLADM_STATUS_OK); 7095895Syz147064 } 7103448Sdh155122 7115895Syz147064 /* 7125895Syz147064 * Get linkprop of the given specific link. 7135895Syz147064 */ 7145895Syz147064 dladm_status_t 7155895Syz147064 dladm_get_linkprop(datalink_id_t linkid, dladm_prop_type_t type, 7165895Syz147064 const char *prop_name, char **prop_val, uint_t *val_cntp) 7175895Syz147064 { 7185895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 7195895Syz147064 datalink_class_t class; 7205895Syz147064 uint_t media; 7215895Syz147064 prop_desc_t *pdp; 7226512Ssowmini uint_t cnt, dld_flags = 0; 7235895Syz147064 int i; 724*8118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 7255895Syz147064 7266512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 7276789Sam223141 dld_flags = MAC_PROP_DEFAULT; 7286512Ssowmini 7295895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 7305895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 7315895Syz147064 return (DLADM_STATUS_BADARG); 7325895Syz147064 7335895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 7345895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 7355895Syz147064 break; 7365895Syz147064 7375903Ssowmini if (i == DLADM_MAX_PROPS) { 7385903Ssowmini if (prop_name[0] == '_') { 7395903Ssowmini /* 7405903Ssowmini * private property. 7415903Ssowmini */ 7427342SAruna.Ramakrishna@Sun.COM return (i_dladm_get_prop(linkid, prop_name, 7436512Ssowmini prop_val, val_cntp, type, dld_flags)); 7445903Ssowmini } else { 7455903Ssowmini return (DLADM_STATUS_NOTFOUND); 7465903Ssowmini } 7475903Ssowmini } 7485895Syz147064 7495895Syz147064 pdp = &prop_table[i]; 7505895Syz147064 7515895Syz147064 status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0); 7525895Syz147064 if (status != DLADM_STATUS_OK) 7535895Syz147064 return (status); 7545895Syz147064 7555895Syz147064 if (!(pdp->pd_class & class)) 7565895Syz147064 return (DLADM_STATUS_BADARG); 7575895Syz147064 7585895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 7593147Sxc151355 return (DLADM_STATUS_BADARG); 7603147Sxc151355 7615895Syz147064 switch (type) { 7625895Syz147064 case DLADM_PROP_VAL_CURRENT: 7636512Ssowmini status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, media, 764*8118SVasumathi.Sundaram@Sun.COM dld_flags, &perm_flags); 765*8118SVasumathi.Sundaram@Sun.COM break; 766*8118SVasumathi.Sundaram@Sun.COM 767*8118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 768*8118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 769*8118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 770*8118SVasumathi.Sundaram@Sun.COM *val_cntp = 1; 771*8118SVasumathi.Sundaram@Sun.COM } else { 772*8118SVasumathi.Sundaram@Sun.COM status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, 773*8118SVasumathi.Sundaram@Sun.COM media, dld_flags, &perm_flags); 774*8118SVasumathi.Sundaram@Sun.COM } 775*8118SVasumathi.Sundaram@Sun.COM 776*8118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 777*8118SVasumathi.Sundaram@Sun.COM switch (perm_flags) { 778*8118SVasumathi.Sundaram@Sun.COM case MAC_PROP_PERM_READ: 779*8118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, PERM_READ_ONLY, 780*8118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 781*8118SVasumathi.Sundaram@Sun.COM break; 782*8118SVasumathi.Sundaram@Sun.COM case MAC_PROP_PERM_RW: 783*8118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, PERM_READ_WRITE, 784*8118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 785*8118SVasumathi.Sundaram@Sun.COM break; 786*8118SVasumathi.Sundaram@Sun.COM } 7875895Syz147064 break; 7885895Syz147064 7895895Syz147064 case DLADM_PROP_VAL_DEFAULT: 7906768Sar224390 /* 7916768Sar224390 * If defaults are not defined for the property, 7926768Sar224390 * pd_defval.vd_name should be null. If the driver 7936768Sar224390 * has to be contacted for the value, vd_name should 7946768Sar224390 * be the empty string (""). Otherwise, dladm will 7956768Sar224390 * just print whatever is in the table. 7966768Sar224390 */ 7975895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 7985895Syz147064 status = DLADM_STATUS_NOTSUP; 7995895Syz147064 break; 8005895Syz147064 } 8016512Ssowmini 8026512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 8036512Ssowmini status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, 804*8118SVasumathi.Sundaram@Sun.COM media, dld_flags, &perm_flags); 8056512Ssowmini } else { 8066512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 8076512Ssowmini } 8085895Syz147064 *val_cntp = 1; 8095895Syz147064 break; 8103448Sdh155122 8115895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 8125895Syz147064 if (pdp->pd_getmod != NULL) { 8135903Ssowmini status = pdp->pd_getmod(pdp, linkid, prop_val, 814*8118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 8155895Syz147064 break; 8165895Syz147064 } 8175895Syz147064 cnt = pdp->pd_noptval; 8185895Syz147064 if (cnt == 0) { 8195895Syz147064 status = DLADM_STATUS_NOTSUP; 8205895Syz147064 } else if (cnt > *val_cntp) { 8215895Syz147064 status = DLADM_STATUS_TOOSMALL; 8225895Syz147064 } else { 8235895Syz147064 for (i = 0; i < cnt; i++) { 8245895Syz147064 (void) strcpy(prop_val[i], 8255895Syz147064 pdp->pd_optval[i].vd_name); 8265895Syz147064 } 8275895Syz147064 *val_cntp = cnt; 8285895Syz147064 } 8295895Syz147064 break; 8305895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 8315895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 8325895Syz147064 return (DLADM_STATUS_TEMPONLY); 8335895Syz147064 status = i_dladm_get_linkprop_db(linkid, prop_name, 8345895Syz147064 prop_val, val_cntp); 8355895Syz147064 break; 8365895Syz147064 default: 8375895Syz147064 status = DLADM_STATUS_BADARG; 8385895Syz147064 break; 8393147Sxc151355 } 8403448Sdh155122 8415895Syz147064 return (status); 8425895Syz147064 } 8435895Syz147064 8445895Syz147064 /*ARGSUSED*/ 8455895Syz147064 static int 8465895Syz147064 i_dladm_init_one_prop(datalink_id_t linkid, const char *prop_name, void *arg) 8475895Syz147064 { 8485895Syz147064 char *buf, **propvals; 8495895Syz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 8505895Syz147064 8515895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 8525895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 8535895Syz147064 return (DLADM_WALK_CONTINUE); 8545895Syz147064 } 8555895Syz147064 8565895Syz147064 propvals = (char **)(void *)buf; 8575895Syz147064 for (i = 0; i < valcnt; i++) { 8585895Syz147064 propvals[i] = buf + 8595895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 8605895Syz147064 i * DLADM_PROP_VAL_MAX; 8615895Syz147064 } 8625895Syz147064 8635895Syz147064 if (dladm_get_linkprop(linkid, DLADM_PROP_VAL_PERSISTENT, prop_name, 8645895Syz147064 propvals, &valcnt) != DLADM_STATUS_OK) { 8655895Syz147064 goto done; 8665895Syz147064 } 8675895Syz147064 8685895Syz147064 (void) dladm_set_linkprop(linkid, prop_name, propvals, valcnt, 8695895Syz147064 DLADM_OPT_ACTIVE); 8705895Syz147064 8715895Syz147064 done: 8725895Syz147064 if (buf != NULL) 8735895Syz147064 free(buf); 8745895Syz147064 8755895Syz147064 return (DLADM_WALK_CONTINUE); 8765895Syz147064 } 8775895Syz147064 8785895Syz147064 /*ARGSUSED*/ 8795895Syz147064 static int 8805895Syz147064 i_dladm_init_linkprop(datalink_id_t linkid, void *arg) 8815895Syz147064 { 8826916Sartem (void) dladm_init_linkprop(linkid, B_TRUE); 8835895Syz147064 return (DLADM_WALK_CONTINUE); 8845895Syz147064 } 8855895Syz147064 8865895Syz147064 dladm_status_t 8876916Sartem dladm_init_linkprop(datalink_id_t linkid, boolean_t any_media) 8885895Syz147064 { 8896916Sartem datalink_media_t dmedia; 8906916Sartem uint32_t media; 8916916Sartem 8926916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 8936916Sartem 8945895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 8955895Syz147064 (void) dladm_walk_datalink_id(i_dladm_init_linkprop, NULL, 8966916Sartem DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 8976916Sartem } else if (any_media || ((dladm_datalink_id2info(linkid, NULL, NULL, 8986916Sartem &media, NULL, 0) == DLADM_STATUS_OK) && 8996916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 9005895Syz147064 (void) dladm_walk_linkprop(linkid, NULL, i_dladm_init_one_prop); 9013448Sdh155122 } 9023448Sdh155122 return (DLADM_STATUS_OK); 9033147Sxc151355 } 9043147Sxc151355 9055903Ssowmini /* ARGSUSED */ 9065895Syz147064 static dladm_status_t 9075903Ssowmini do_get_zone(struct prop_desc *pd, datalink_id_t linkid, 908*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 909*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 9103147Sxc151355 { 9115895Syz147064 char zone_name[ZONENAME_MAX]; 9125895Syz147064 zoneid_t zid; 9135895Syz147064 dladm_status_t status; 9147342SAruna.Ramakrishna@Sun.COM char *cp; 9157342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 9163147Sxc151355 9176512Ssowmini if (flags != 0) 9186512Ssowmini return (DLADM_STATUS_NOTSUP); 9196512Ssowmini 9207342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 9215895Syz147064 if (status != DLADM_STATUS_OK) 9223448Sdh155122 return (status); 9233448Sdh155122 924*8118SVasumathi.Sundaram@Sun.COM *perm_flags = dip->pr_perm_flags; 9257342SAruna.Ramakrishna@Sun.COM cp = dip->pr_val; 9267342SAruna.Ramakrishna@Sun.COM (void) memcpy(&zid, cp, sizeof (zid)); 9277342SAruna.Ramakrishna@Sun.COM free(dip); 9287342SAruna.Ramakrishna@Sun.COM 9295895Syz147064 *val_cnt = 1; 9305895Syz147064 if (zid != GLOBAL_ZONEID) { 931*8118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 932*8118SVasumathi.Sundaram@Sun.COM *perm_flags = 0; 9335895Syz147064 return (dladm_errno2status(errno)); 934*8118SVasumathi.Sundaram@Sun.COM } 9353147Sxc151355 9365895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 9373147Sxc151355 } else { 9385895Syz147064 *prop_val[0] = '\0'; 939*8118SVasumathi.Sundaram@Sun.COM *perm_flags = 0; 9403147Sxc151355 } 9413147Sxc151355 9423448Sdh155122 return (DLADM_STATUS_OK); 9433448Sdh155122 } 9443448Sdh155122 9453448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 9463448Sdh155122 9473448Sdh155122 static int 9483448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 9493448Sdh155122 { 9503448Sdh155122 char root[MAXPATHLEN]; 9513448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 9523448Sdh155122 void *dlhandle; 9533448Sdh155122 void *sym; 9543448Sdh155122 int ret; 9553448Sdh155122 9563448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 9573448Sdh155122 return (-1); 9583448Sdh155122 9593448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 9603448Sdh155122 (void) dlclose(dlhandle); 9613448Sdh155122 return (-1); 9623448Sdh155122 } 9633448Sdh155122 9643448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 9653448Sdh155122 9663448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 9673448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 9683448Sdh155122 (void) dlclose(dlhandle); 9693448Sdh155122 return (ret); 9703448Sdh155122 } 9713448Sdh155122 9723448Sdh155122 static dladm_status_t 9735895Syz147064 i_dladm_update_deventry(zoneid_t zid, datalink_id_t linkid, boolean_t add) 9743448Sdh155122 { 9753448Sdh155122 char path[MAXPATHLEN]; 9765895Syz147064 char name[MAXLINKNAMELEN]; 9773448Sdh155122 di_prof_t prof = NULL; 9783448Sdh155122 char zone_name[ZONENAME_MAX]; 9793448Sdh155122 dladm_status_t status; 9805895Syz147064 int ret; 9813448Sdh155122 9823448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 9833448Sdh155122 return (dladm_errno2status(errno)); 9843448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 9853448Sdh155122 return (dladm_errno2status(errno)); 9863448Sdh155122 if (di_prof_init(path, &prof) != 0) 9873448Sdh155122 return (dladm_errno2status(errno)); 9883448Sdh155122 9895895Syz147064 status = dladm_linkid2legacyname(linkid, name, MAXLINKNAMELEN); 9905895Syz147064 if (status != DLADM_STATUS_OK) 9915895Syz147064 goto cleanup; 9925895Syz147064 9935895Syz147064 if (add) 9945895Syz147064 ret = di_prof_add_dev(prof, name); 9955895Syz147064 else 9965895Syz147064 ret = di_prof_add_exclude(prof, name); 9975895Syz147064 9985895Syz147064 if (ret != 0) { 9993448Sdh155122 status = dladm_errno2status(errno); 10003448Sdh155122 goto cleanup; 10013448Sdh155122 } 10023448Sdh155122 10033448Sdh155122 if (di_prof_commit(prof) != 0) 10043448Sdh155122 status = dladm_errno2status(errno); 10053448Sdh155122 cleanup: 10063448Sdh155122 if (prof) 10073448Sdh155122 di_prof_fini(prof); 10083448Sdh155122 10093448Sdh155122 return (status); 10103448Sdh155122 } 10113448Sdh155122 10125903Ssowmini /* ARGSUSED */ 10133448Sdh155122 static dladm_status_t 10145960Ssowmini do_set_zone(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp, 10155960Ssowmini uint_t val_cnt, uint_t flags, datalink_media_t media) 10163448Sdh155122 { 10177342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 10183448Sdh155122 zoneid_t zid_old, zid_new; 10195895Syz147064 char link[MAXLINKNAMELEN]; 10207342SAruna.Ramakrishna@Sun.COM char *cp; 10217342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 10227342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 10233448Sdh155122 10243448Sdh155122 if (val_cnt != 1) 10253448Sdh155122 return (DLADM_STATUS_BADVALCNT); 10263448Sdh155122 10277342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 10287342SAruna.Ramakrishna@Sun.COM 10297342SAruna.Ramakrishna@Sun.COM /* 10307342SAruna.Ramakrishna@Sun.COM * If diz_is_ppa_hack is set, then an implicit vlan must be created. 10317342SAruna.Ramakrishna@Sun.COM * There is no old value to compare against, and vdp->vd_val is 10327342SAruna.Ramakrishna@Sun.COM * already populated with the zoneid and linkname in the function 10337342SAruna.Ramakrishna@Sun.COM * do_check_zone(). 10347342SAruna.Ramakrishna@Sun.COM */ 10357342SAruna.Ramakrishna@Sun.COM 10367342SAruna.Ramakrishna@Sun.COM if (dzp->diz_is_ppa_hack) { 10377342SAruna.Ramakrishna@Sun.COM zid_old = GLOBAL_ZONEID; 10387342SAruna.Ramakrishna@Sun.COM } else { 10397342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, 10407342SAruna.Ramakrishna@Sun.COM flags, &status); 10417342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 10427342SAruna.Ramakrishna@Sun.COM return (status); 10437342SAruna.Ramakrishna@Sun.COM 10447342SAruna.Ramakrishna@Sun.COM cp = dip->pr_val; 10457342SAruna.Ramakrishna@Sun.COM (void) memcpy(&zid_old, cp, sizeof (zid_old)); 10467342SAruna.Ramakrishna@Sun.COM free(dip); 10477342SAruna.Ramakrishna@Sun.COM } 10487342SAruna.Ramakrishna@Sun.COM 10497342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 10507342SAruna.Ramakrishna@Sun.COM (void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN); 10513448Sdh155122 10523448Sdh155122 /* Do nothing if setting to current value */ 10533448Sdh155122 if (zid_new == zid_old) 10545895Syz147064 return (status); 10555895Syz147064 10565895Syz147064 if (zid_new != GLOBAL_ZONEID) { 10575895Syz147064 /* 10585895Syz147064 * If the new zoneid is the global zone, we could destroy 10595895Syz147064 * the link (in the case of an implicitly-created VLAN) as a 10607342SAruna.Ramakrishna@Sun.COM * result of setting the zoneid. In that case, we defer the 10617342SAruna.Ramakrishna@Sun.COM * operation to the end of this function to avoid recreating 10627342SAruna.Ramakrishna@Sun.COM * the VLAN and getting a different linkid during the rollback 10637342SAruna.Ramakrishna@Sun.COM * if other operation fails. 10645895Syz147064 * 10657342SAruna.Ramakrishna@Sun.COM * Otherwise, this operation will hold a reference to the 10665895Syz147064 * link and prevent a link renaming, so we need to do it 10675895Syz147064 * before other operations. 10685895Syz147064 */ 10697342SAruna.Ramakrishna@Sun.COM status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt, 10707342SAruna.Ramakrishna@Sun.COM flags, media); 10715895Syz147064 if (status != DLADM_STATUS_OK) 10725895Syz147064 return (status); 10735895Syz147064 } 10745895Syz147064 10753448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 10765895Syz147064 if (zone_remove_datalink(zid_old, link) != 0 && 10773448Sdh155122 errno != ENXIO) { 10783448Sdh155122 status = dladm_errno2status(errno); 10793448Sdh155122 goto rollback1; 10803448Sdh155122 } 10813448Sdh155122 10825895Syz147064 /* 10835895Syz147064 * It is okay to fail to update the /dev entry (some 10845895Syz147064 * vanity-named links do not have a /dev entry). 10855895Syz147064 */ 10865895Syz147064 (void) i_dladm_update_deventry(zid_old, linkid, B_FALSE); 10875895Syz147064 } 10885895Syz147064 10895895Syz147064 if (zid_new != GLOBAL_ZONEID) { 10905895Syz147064 if (zone_add_datalink(zid_new, link) != 0) { 10915895Syz147064 status = dladm_errno2status(errno); 10925895Syz147064 goto rollback2; 10935895Syz147064 } 10945895Syz147064 10957342SAruna.Ramakrishna@Sun.COM if (dzp->diz_is_ppa_hack) { 10967342SAruna.Ramakrishna@Sun.COM if ((status = dladm_name2info(link, &linkid, NULL, NULL, 10977342SAruna.Ramakrishna@Sun.COM NULL)) != DLADM_STATUS_OK) { 10987342SAruna.Ramakrishna@Sun.COM return (status); 10997342SAruna.Ramakrishna@Sun.COM } 11007342SAruna.Ramakrishna@Sun.COM } 11017342SAruna.Ramakrishna@Sun.COM 11025895Syz147064 (void) i_dladm_update_deventry(zid_new, linkid, B_TRUE); 11035895Syz147064 } else { 11047342SAruna.Ramakrishna@Sun.COM status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt, 11057342SAruna.Ramakrishna@Sun.COM flags, media); 11063448Sdh155122 if (status != DLADM_STATUS_OK) 11073448Sdh155122 goto rollback2; 11083448Sdh155122 } 11093448Sdh155122 11103448Sdh155122 return (DLADM_STATUS_OK); 11113448Sdh155122 11123448Sdh155122 rollback2: 11133448Sdh155122 if (zid_old != GLOBAL_ZONEID) 11145895Syz147064 (void) i_dladm_update_deventry(zid_old, linkid, B_TRUE); 11155895Syz147064 if (zid_old != GLOBAL_ZONEID) 11165895Syz147064 (void) zone_add_datalink(zid_old, link); 11173448Sdh155122 rollback1: 11187342SAruna.Ramakrishna@Sun.COM if (zid_new != GLOBAL_ZONEID) { 11197342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zid_old; 11207342SAruna.Ramakrishna@Sun.COM (void) i_dladm_set_public_prop(pd, linkid, vdp, val_cnt, 11217342SAruna.Ramakrishna@Sun.COM flags, media); 11227342SAruna.Ramakrishna@Sun.COM } 11237342SAruna.Ramakrishna@Sun.COM 11243448Sdh155122 return (status); 11253448Sdh155122 } 11263448Sdh155122 11273448Sdh155122 /* ARGSUSED */ 11283448Sdh155122 static dladm_status_t 11295903Ssowmini do_check_zone(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, 11305960Ssowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 11313448Sdh155122 { 11327342SAruna.Ramakrishna@Sun.COM char *zone_name; 11337342SAruna.Ramakrishna@Sun.COM char linkname[MAXLINKNAMELEN]; 11347342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 11357342SAruna.Ramakrishna@Sun.COM char *cp; 11367342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 11377342SAruna.Ramakrishna@Sun.COM boolean_t is_ppa_hack = B_FALSE; 11387342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 11393448Sdh155122 11403448Sdh155122 if (val_cnt != 1) 11413448Sdh155122 return (DLADM_STATUS_BADVALCNT); 11423448Sdh155122 11437342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 11447342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 11457342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 11463448Sdh155122 11477342SAruna.Ramakrishna@Sun.COM if (prop_val) { 11487342SAruna.Ramakrishna@Sun.COM /* 11497342SAruna.Ramakrishna@Sun.COM * The prop_val contains zone_name{:linkname}. The linkname is 11507342SAruna.Ramakrishna@Sun.COM * present only when the link is a ppa-hacked vlan. 11517342SAruna.Ramakrishna@Sun.COM */ 11527342SAruna.Ramakrishna@Sun.COM cp = strchr(*prop_val, ':'); 11537342SAruna.Ramakrishna@Sun.COM if (cp) { 11547342SAruna.Ramakrishna@Sun.COM (void) strlcpy(linkname, cp + 1, MAXLINKNAMELEN); 11557342SAruna.Ramakrishna@Sun.COM *cp = '\0'; 11567342SAruna.Ramakrishna@Sun.COM is_ppa_hack = B_TRUE; 11577342SAruna.Ramakrishna@Sun.COM } else { 11587342SAruna.Ramakrishna@Sun.COM status = dladm_datalink_id2info(linkid, NULL, NULL, 11597342SAruna.Ramakrishna@Sun.COM NULL, linkname, MAXLINKNAMELEN); 11607342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) { 11617342SAruna.Ramakrishna@Sun.COM goto done; 11627342SAruna.Ramakrishna@Sun.COM } 11637342SAruna.Ramakrishna@Sun.COM } 11647342SAruna.Ramakrishna@Sun.COM zone_name = *prop_val; 11657342SAruna.Ramakrishna@Sun.COM } else { 11667342SAruna.Ramakrishna@Sun.COM zone_name = GLOBAL_ZONENAME; 11677342SAruna.Ramakrishna@Sun.COM if ((status = dladm_datalink_id2info(linkid, NULL, NULL, NULL, 11687342SAruna.Ramakrishna@Sun.COM linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 11697342SAruna.Ramakrishna@Sun.COM goto done; 11707342SAruna.Ramakrishna@Sun.COM } 11717342SAruna.Ramakrishna@Sun.COM } 11727342SAruna.Ramakrishna@Sun.COM 11737342SAruna.Ramakrishna@Sun.COM if (strlen(linkname) > MAXLINKNAMELEN) { 11747342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 11757342SAruna.Ramakrishna@Sun.COM goto done; 11767342SAruna.Ramakrishna@Sun.COM } 11777342SAruna.Ramakrishna@Sun.COM 11787342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 11797342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 11807342SAruna.Ramakrishna@Sun.COM goto done; 11817342SAruna.Ramakrishna@Sun.COM } 11827342SAruna.Ramakrishna@Sun.COM 11837342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 11843448Sdh155122 ushort_t flags; 11853448Sdh155122 11867342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 11873448Sdh155122 sizeof (flags)) < 0) { 11887342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 11897342SAruna.Ramakrishna@Sun.COM goto done; 11903448Sdh155122 } 11913448Sdh155122 11923448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 11937342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 11947342SAruna.Ramakrishna@Sun.COM goto done; 11953448Sdh155122 } 11963448Sdh155122 } 11973448Sdh155122 11987342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 11997342SAruna.Ramakrishna@Sun.COM 12007342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 12017342SAruna.Ramakrishna@Sun.COM (void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN); 12027342SAruna.Ramakrishna@Sun.COM dzp->diz_is_ppa_hack = is_ppa_hack; 12037342SAruna.Ramakrishna@Sun.COM 12047342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 12055895Syz147064 return (DLADM_STATUS_OK); 12067342SAruna.Ramakrishna@Sun.COM done: 12077342SAruna.Ramakrishna@Sun.COM free(dzp); 12087342SAruna.Ramakrishna@Sun.COM return (status); 12095895Syz147064 } 12105895Syz147064 12115903Ssowmini /* ARGSUSED */ 12125895Syz147064 static dladm_status_t 12135903Ssowmini do_get_autopush(struct prop_desc *pd, datalink_id_t linkid, 1214*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1215*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 12165895Syz147064 { 12177342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 12187342SAruna.Ramakrishna@Sun.COM int i, len; 12197342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 12207342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 12215895Syz147064 12226789Sam223141 if (flags & MAC_PROP_DEFAULT) 12237776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 12246512Ssowmini 12255895Syz147064 *val_cnt = 1; 12267342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 12277342SAruna.Ramakrishna@Sun.COM if (dip == NULL) { 12285895Syz147064 (*prop_val)[0] = '\0'; 12295895Syz147064 goto done; 12305895Syz147064 } 12317342SAruna.Ramakrishna@Sun.COM (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 12325895Syz147064 12337342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 12345895Syz147064 if (i != 0) { 12355895Syz147064 (void) snprintf(*prop_val + len, 12365895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 12375895Syz147064 len += 1; 12385895Syz147064 } 12395895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 12407342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 12417342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 12427342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 12435895Syz147064 (void) snprintf(*prop_val + len, 12445895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 12455895Syz147064 AP_ANCHOR); 12465895Syz147064 len += (strlen(AP_ANCHOR) + 1); 12475895Syz147064 } 12485895Syz147064 } 12495895Syz147064 1250*8118SVasumathi.Sundaram@Sun.COM *perm_flags = dip->pr_perm_flags; 12517342SAruna.Ramakrishna@Sun.COM free(dip); 12525895Syz147064 done: 12535895Syz147064 return (DLADM_STATUS_OK); 12545895Syz147064 } 12555895Syz147064 12565895Syz147064 /* 12575895Syz147064 * Add the specified module to the dlautopush structure; returns a 12585895Syz147064 * DLADM_STATUS_* code. 12595895Syz147064 */ 12605895Syz147064 dladm_status_t 12615895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 12625895Syz147064 { 12635895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 12645895Syz147064 return (DLADM_STATUS_BADVAL); 12655895Syz147064 12665895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 12675895Syz147064 /* 12685895Syz147064 * We don't allow multiple anchors, and the anchor must 12695895Syz147064 * be after at least one module. 12705895Syz147064 */ 12715895Syz147064 if (dlap->dap_anchor != 0) 12725895Syz147064 return (DLADM_STATUS_BADVAL); 12735895Syz147064 if (dlap->dap_npush == 0) 12745895Syz147064 return (DLADM_STATUS_BADVAL); 12755895Syz147064 12765895Syz147064 dlap->dap_anchor = dlap->dap_npush; 12775895Syz147064 return (DLADM_STATUS_OK); 12785895Syz147064 } 12795895Syz147064 if (dlap->dap_npush > MAXAPUSH) 12805895Syz147064 return (DLADM_STATUS_BADVALCNT); 12815895Syz147064 12825895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 12835895Syz147064 FMNAMESZ + 1); 12845895Syz147064 12855895Syz147064 return (DLADM_STATUS_OK); 12865895Syz147064 } 12875895Syz147064 12885895Syz147064 /* 12895895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 12905895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 12915895Syz147064 * latter is used in the autopush(1M) file. 12925895Syz147064 */ 12935895Syz147064 /* ARGSUSED */ 12945895Syz147064 static dladm_status_t 12955903Ssowmini do_check_autopush(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, 12965960Ssowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 12975895Syz147064 { 12985895Syz147064 char *module; 12995895Syz147064 struct dlautopush *dlap; 13005895Syz147064 dladm_status_t status; 13015895Syz147064 char val[DLADM_PROP_VAL_MAX]; 13025895Syz147064 char delimiters[4]; 13035895Syz147064 13045895Syz147064 if (val_cnt != 1) 13055895Syz147064 return (DLADM_STATUS_BADVALCNT); 13065895Syz147064 13077342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 13087342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 13097342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 13107342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 13113448Sdh155122 13127342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 13137342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 13147342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 13157342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 13167342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 13177342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 13187342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 13197342SAruna.Ramakrishna@Sun.COM return (status); 13207342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 13217342SAruna.Ramakrishna@Sun.COM } 13227342SAruna.Ramakrishna@Sun.COM 13237342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 13247342SAruna.Ramakrishna@Sun.COM } else { 13257342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 13265895Syz147064 } 13273448Sdh155122 return (DLADM_STATUS_OK); 13283448Sdh155122 } 13293448Sdh155122 13307663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 13317663SSowmini.Varadhan@Sun.COM 13325903Ssowmini /* ARGSUSED */ 13333448Sdh155122 static dladm_status_t 13345903Ssowmini do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid, 13355903Ssowmini char **prop_val, uint_t *val_cnt, uint_t id) 13363448Sdh155122 { 13375895Syz147064 wl_rates_t *wrp; 13385895Syz147064 uint_t i; 13395895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 13405895Syz147064 13417663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 13427663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 13437663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 13445895Syz147064 13457663SSowmini.Varadhan@Sun.COM status = i_dladm_wlan_param(linkid, wrp, id, WLDP_BUFSIZE, B_FALSE); 13465895Syz147064 if (status != DLADM_STATUS_OK) 13475895Syz147064 goto done; 13485895Syz147064 13495895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 13505895Syz147064 status = DLADM_STATUS_TOOSMALL; 13515895Syz147064 goto done; 13525895Syz147064 } 13535895Syz147064 13545895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 13555895Syz147064 prop_val[0][0] = '\0'; 13565895Syz147064 *val_cnt = 1; 13575895Syz147064 goto done; 13585895Syz147064 } 13595895Syz147064 13605895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 13615895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 13625895Syz147064 wrp->wl_rates_rates[i] % 2, 13635895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 13645895Syz147064 } 13655895Syz147064 *val_cnt = wrp->wl_rates_num; 13663448Sdh155122 13675895Syz147064 done: 13687663SSowmini.Varadhan@Sun.COM free(wrp); 13695895Syz147064 return (status); 13705895Syz147064 } 13715895Syz147064 13725895Syz147064 static dladm_status_t 13735903Ssowmini do_get_rate_prop(struct prop_desc *pd, datalink_id_t linkid, 1374*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1375*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 13765895Syz147064 { 1377*8118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 1378*8118SVasumathi.Sundaram@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 13797342SAruna.Ramakrishna@Sun.COM return (i_dladm_speed_get(pd, linkid, prop_val, 13807342SAruna.Ramakrishna@Sun.COM val_cnt, flags)); 1381*8118SVasumathi.Sundaram@Sun.COM } 13825960Ssowmini 1383*8118SVasumathi.Sundaram@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 13845903Ssowmini return (do_get_rate_common(pd, linkid, prop_val, val_cnt, 13857663SSowmini.Varadhan@Sun.COM MAC_PROP_WL_DESIRED_RATES)); 13865895Syz147064 } 13875895Syz147064 13886512Ssowmini /* ARGSUSED */ 13895895Syz147064 static dladm_status_t 13905903Ssowmini do_get_rate_mod(struct prop_desc *pd, datalink_id_t linkid, 1391*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1392*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 13935895Syz147064 { 1394*8118SVasumathi.Sundaram@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 1395*8118SVasumathi.Sundaram@Sun.COM 13965960Ssowmini switch (media) { 13975960Ssowmini case DL_ETHER: 13986512Ssowmini /* 13996512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 14006512Ssowmini * links can have a speed of 5.5 Gbps. 14016512Ssowmini */ 14026512Ssowmini return (DLADM_STATUS_NOTSUP); 14035960Ssowmini 14045960Ssowmini case DL_WIFI: 14055960Ssowmini return (do_get_rate_common(pd, linkid, prop_val, val_cnt, 14067663SSowmini.Varadhan@Sun.COM MAC_PROP_WL_SUPPORTED_RATES)); 14075960Ssowmini default: 14085960Ssowmini return (DLADM_STATUS_BADARG); 14095960Ssowmini } 14105895Syz147064 } 14115895Syz147064 14125895Syz147064 static dladm_status_t 14135895Syz147064 do_set_rate(datalink_id_t linkid, dladm_wlan_rates_t *rates) 14145895Syz147064 { 14155895Syz147064 int i; 14165895Syz147064 uint_t len; 14175895Syz147064 wl_rates_t *wrp; 14185895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 14195895Syz147064 14207663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 14217663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 14225895Syz147064 return (DLADM_STATUS_NOMEM); 14235895Syz147064 14247663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 14255895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 14265895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 14275895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 14285895Syz147064 14295895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 14305895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 14317663SSowmini.Varadhan@Sun.COM status = i_dladm_wlan_param(linkid, wrp, MAC_PROP_WL_DESIRED_RATES, 14327663SSowmini.Varadhan@Sun.COM len, B_TRUE); 14335895Syz147064 14347663SSowmini.Varadhan@Sun.COM free(wrp); 14355895Syz147064 return (status); 14365895Syz147064 } 14373448Sdh155122 14385903Ssowmini /* ARGSUSED */ 14395895Syz147064 static dladm_status_t 14405903Ssowmini do_set_rate_prop(prop_desc_t *pd, datalink_id_t linkid, 14415960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 14425895Syz147064 { 14435895Syz147064 dladm_wlan_rates_t rates; 14445895Syz147064 dladm_status_t status; 14455895Syz147064 14465960Ssowmini /* 14475960Ssowmini * can currently set rate on WIFI links only. 14485960Ssowmini */ 14495960Ssowmini if (media != DL_WIFI) 14505960Ssowmini return (DLADM_STATUS_PROPRDONLY); 14515960Ssowmini 14525895Syz147064 if (val_cnt != 1) 14535895Syz147064 return (DLADM_STATUS_BADVALCNT); 14545895Syz147064 14555895Syz147064 rates.wr_cnt = 1; 14565895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 14575895Syz147064 14585895Syz147064 status = do_set_rate(linkid, &rates); 14595895Syz147064 14605895Syz147064 done: 14615895Syz147064 return (status); 14625895Syz147064 } 14633448Sdh155122 14645895Syz147064 /* ARGSUSED */ 14655895Syz147064 static dladm_status_t 14665903Ssowmini do_check_rate(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, 14675960Ssowmini uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 14685895Syz147064 { 14695895Syz147064 int i; 14705895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 14715895Syz147064 char *buf, **modval; 14725895Syz147064 dladm_status_t status; 1473*8118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 14745895Syz147064 14755895Syz147064 if (val_cnt != 1) 14765895Syz147064 return (DLADM_STATUS_BADVALCNT); 14775895Syz147064 14785895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 14795895Syz147064 MAX_SUPPORT_RATES); 14805895Syz147064 if (buf == NULL) { 14815895Syz147064 status = DLADM_STATUS_NOMEM; 14825895Syz147064 goto done; 14835895Syz147064 } 14843448Sdh155122 14855895Syz147064 modval = (char **)(void *)buf; 14865895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 14875895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 14885895Syz147064 i * DLADM_STRSIZE; 14895895Syz147064 } 14905895Syz147064 1491*8118SVasumathi.Sundaram@Sun.COM status = do_get_rate_mod(NULL, linkid, modval, &modval_cnt, media, 1492*8118SVasumathi.Sundaram@Sun.COM 0, &perm_flags); 14935895Syz147064 if (status != DLADM_STATUS_OK) 14945895Syz147064 goto done; 14955895Syz147064 14965895Syz147064 for (i = 0; i < modval_cnt; i++) { 14975895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 14985903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 14995903Ssowmini (atof(*prop_val) * 2); 15005895Syz147064 status = DLADM_STATUS_OK; 15013448Sdh155122 break; 15023448Sdh155122 } 15035895Syz147064 } 15045895Syz147064 if (i == modval_cnt) 15055895Syz147064 status = DLADM_STATUS_BADVAL; 15065895Syz147064 done: 15075895Syz147064 free(buf); 15085895Syz147064 return (status); 15095895Syz147064 } 15105895Syz147064 15115895Syz147064 static dladm_status_t 15127663SSowmini.Varadhan@Sun.COM do_get_phyconf(datalink_id_t linkid, void *buf, int buflen) 15135895Syz147064 { 15147663SSowmini.Varadhan@Sun.COM return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG, 15157663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 15165895Syz147064 } 15175895Syz147064 15185903Ssowmini /* ARGSUSED */ 15195895Syz147064 static dladm_status_t 15205903Ssowmini do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid, 1521*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1522*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 15235895Syz147064 { 15245895Syz147064 uint32_t channel; 15257663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 15265895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 15277663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 15285895Syz147064 1529*8118SVasumathi.Sundaram@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 15307663SSowmini.Varadhan@Sun.COM if ((status = do_get_phyconf(linkid, buf, sizeof (buf))) 15317663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 15325895Syz147064 goto done; 15335895Syz147064 15347663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 15357663SSowmini.Varadhan@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 15365895Syz147064 status = DLADM_STATUS_NOTFOUND; 15375895Syz147064 goto done; 15385895Syz147064 } 15395895Syz147064 15405895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 15415895Syz147064 *val_cnt = 1; 15423448Sdh155122 15435895Syz147064 done: 15445895Syz147064 return (status); 15455895Syz147064 } 15465895Syz147064 15475895Syz147064 static dladm_status_t 15487663SSowmini.Varadhan@Sun.COM do_get_powermode(datalink_id_t linkid, void *buf, int buflen) 15495895Syz147064 { 15507663SSowmini.Varadhan@Sun.COM return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_POWER_MODE, 15517663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 15525895Syz147064 } 15535895Syz147064 15545903Ssowmini /* ARGSUSED */ 15555895Syz147064 static dladm_status_t 15565903Ssowmini do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid, 1557*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1558*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 15595895Syz147064 { 15607663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 15615895Syz147064 const char *s; 15627663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 15635895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 15645895Syz147064 15657663SSowmini.Varadhan@Sun.COM if ((status = do_get_powermode(linkid, buf, sizeof (buf))) 15667663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 15675895Syz147064 goto done; 15685895Syz147064 15697663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 15707663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 15715895Syz147064 case WL_PM_AM: 15725895Syz147064 s = "off"; 15735895Syz147064 break; 15745895Syz147064 case WL_PM_MPS: 15755895Syz147064 s = "max"; 15765895Syz147064 break; 15775895Syz147064 case WL_PM_FAST: 15785895Syz147064 s = "fast"; 15793448Sdh155122 break; 15803448Sdh155122 default: 15815895Syz147064 status = DLADM_STATUS_NOTFOUND; 15825895Syz147064 goto done; 15835895Syz147064 } 15845895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 15855895Syz147064 *val_cnt = 1; 15865895Syz147064 15875895Syz147064 done: 1588*8118SVasumathi.Sundaram@Sun.COM if (status == DLADM_STATUS_OK) 1589*8118SVasumathi.Sundaram@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 1590*8118SVasumathi.Sundaram@Sun.COM else 1591*8118SVasumathi.Sundaram@Sun.COM *perm_flags = 0; 15925895Syz147064 return (status); 15935895Syz147064 } 15945895Syz147064 15955895Syz147064 static dladm_status_t 15965895Syz147064 do_set_powermode(datalink_id_t linkid, dladm_wlan_powermode_t *pm) 15975895Syz147064 { 15985895Syz147064 wl_ps_mode_t ps_mode; 15995895Syz147064 16005895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 16015895Syz147064 16025895Syz147064 switch (*pm) { 16035895Syz147064 case DLADM_WLAN_PM_OFF: 16045895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 16053448Sdh155122 break; 16065895Syz147064 case DLADM_WLAN_PM_MAX: 16075895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 16085895Syz147064 break; 16095895Syz147064 case DLADM_WLAN_PM_FAST: 16105895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 16115895Syz147064 break; 16125895Syz147064 default: 16135895Syz147064 return (DLADM_STATUS_NOTSUP); 16143448Sdh155122 } 16157663SSowmini.Varadhan@Sun.COM return (i_dladm_wlan_param(linkid, &ps_mode, MAC_PROP_WL_POWER_MODE, 16167663SSowmini.Varadhan@Sun.COM sizeof (ps_mode), B_TRUE)); 16175895Syz147064 } 16185895Syz147064 16195895Syz147064 /* ARGSUSED */ 16205895Syz147064 static dladm_status_t 16215903Ssowmini do_set_powermode_prop(prop_desc_t *pd, datalink_id_t linkid, 16225960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16235895Syz147064 { 16245895Syz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 16255895Syz147064 dladm_status_t status; 16265895Syz147064 16275895Syz147064 if (val_cnt != 1) 16285895Syz147064 return (DLADM_STATUS_BADVALCNT); 16295895Syz147064 16305895Syz147064 status = do_set_powermode(linkid, &powermode); 16313448Sdh155122 16323448Sdh155122 return (status); 16333448Sdh155122 } 16343448Sdh155122 16353448Sdh155122 static dladm_status_t 16367663SSowmini.Varadhan@Sun.COM do_get_radio(datalink_id_t linkid, void *buf, int buflen) 16373448Sdh155122 { 16387663SSowmini.Varadhan@Sun.COM return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RADIO, buflen, 16397663SSowmini.Varadhan@Sun.COM B_FALSE)); 16405895Syz147064 } 16413448Sdh155122 16425903Ssowmini /* ARGSUSED */ 16435895Syz147064 static dladm_status_t 16445903Ssowmini do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid, 1645*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1646*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 16475895Syz147064 { 16485895Syz147064 wl_radio_t radio; 16495895Syz147064 const char *s; 16507663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 16515895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 16523448Sdh155122 16537663SSowmini.Varadhan@Sun.COM if ((status = do_get_radio(linkid, buf, sizeof (buf))) 16547663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 16555895Syz147064 goto done; 16563448Sdh155122 16577663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 16585895Syz147064 switch (radio) { 16595895Syz147064 case B_TRUE: 16605895Syz147064 s = "on"; 16615895Syz147064 break; 16625895Syz147064 case B_FALSE: 16635895Syz147064 s = "off"; 16645895Syz147064 break; 16655895Syz147064 default: 16665895Syz147064 status = DLADM_STATUS_NOTFOUND; 16675895Syz147064 goto done; 16685895Syz147064 } 16695895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 16705895Syz147064 *val_cnt = 1; 16713448Sdh155122 16725895Syz147064 done: 1673*8118SVasumathi.Sundaram@Sun.COM if (status == DLADM_STATUS_OK) 1674*8118SVasumathi.Sundaram@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 1675*8118SVasumathi.Sundaram@Sun.COM else 1676*8118SVasumathi.Sundaram@Sun.COM *perm_flags = 0; 16773448Sdh155122 return (status); 16783448Sdh155122 } 16793448Sdh155122 16803448Sdh155122 static dladm_status_t 16815895Syz147064 do_set_radio(datalink_id_t linkid, dladm_wlan_radio_t *radio) 16823448Sdh155122 { 16835895Syz147064 wl_radio_t r; 16843448Sdh155122 16855895Syz147064 switch (*radio) { 16865895Syz147064 case DLADM_WLAN_RADIO_ON: 16875895Syz147064 r = B_TRUE; 16885895Syz147064 break; 16895895Syz147064 case DLADM_WLAN_RADIO_OFF: 16905895Syz147064 r = B_FALSE; 16915895Syz147064 break; 16925895Syz147064 default: 16935895Syz147064 return (DLADM_STATUS_NOTSUP); 16945895Syz147064 } 16957663SSowmini.Varadhan@Sun.COM return (i_dladm_wlan_param(linkid, &r, MAC_PROP_WL_RADIO, 16967663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 16975895Syz147064 } 16983448Sdh155122 16995895Syz147064 /* ARGSUSED */ 17005895Syz147064 static dladm_status_t 17015903Ssowmini do_set_radio_prop(prop_desc_t *pd, datalink_id_t linkid, 17025960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t fags, datalink_media_t media) 17035895Syz147064 { 17045895Syz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 17055895Syz147064 dladm_status_t status; 17063448Sdh155122 17075895Syz147064 if (val_cnt != 1) 17085895Syz147064 return (DLADM_STATUS_BADVALCNT); 17095895Syz147064 17105895Syz147064 status = do_set_radio(linkid, &radio); 17113448Sdh155122 17123448Sdh155122 return (status); 17133448Sdh155122 } 17143448Sdh155122 17155895Syz147064 static dladm_status_t 17165895Syz147064 i_dladm_set_linkprop_db(datalink_id_t linkid, const char *prop_name, 17175895Syz147064 char **prop_val, uint_t val_cnt) 17183448Sdh155122 { 17195895Syz147064 char buf[MAXLINELEN]; 17205895Syz147064 int i; 17215895Syz147064 dladm_conf_t conf; 17225895Syz147064 dladm_status_t status; 17233448Sdh155122 17245895Syz147064 status = dladm_read_conf(linkid, &conf); 17255895Syz147064 if (status != DLADM_STATUS_OK) 17265895Syz147064 return (status); 17273448Sdh155122 17285895Syz147064 /* 17295895Syz147064 * reset case. 17305895Syz147064 */ 17315895Syz147064 if (val_cnt == 0) { 17325895Syz147064 status = dladm_unset_conf_field(conf, prop_name); 17335895Syz147064 if (status == DLADM_STATUS_OK) 17345895Syz147064 status = dladm_write_conf(conf); 17355895Syz147064 goto done; 17365895Syz147064 } 17373448Sdh155122 17385895Syz147064 buf[0] = '\0'; 17395895Syz147064 for (i = 0; i < val_cnt; i++) { 17405895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 17415895Syz147064 if (i != val_cnt - 1) 17425895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 17433448Sdh155122 } 17443448Sdh155122 17455895Syz147064 status = dladm_set_conf_field(conf, prop_name, DLADM_TYPE_STR, buf); 17465895Syz147064 if (status == DLADM_STATUS_OK) 17475895Syz147064 status = dladm_write_conf(conf); 17485895Syz147064 17495895Syz147064 done: 17505895Syz147064 dladm_destroy_conf(conf); 17515895Syz147064 return (status); 17523448Sdh155122 } 17535895Syz147064 17545895Syz147064 static dladm_status_t 17555895Syz147064 i_dladm_get_linkprop_db(datalink_id_t linkid, const char *prop_name, 17565895Syz147064 char **prop_val, uint_t *val_cntp) 17575895Syz147064 { 17585895Syz147064 char buf[MAXLINELEN], *str; 17595895Syz147064 uint_t cnt = 0; 17605895Syz147064 dladm_conf_t conf; 17615895Syz147064 dladm_status_t status; 17625895Syz147064 17635895Syz147064 status = dladm_read_conf(linkid, &conf); 17645895Syz147064 if (status != DLADM_STATUS_OK) 17655895Syz147064 return (status); 17665895Syz147064 17675895Syz147064 status = dladm_get_conf_field(conf, prop_name, buf, MAXLINELEN); 17685895Syz147064 if (status != DLADM_STATUS_OK) 17695895Syz147064 goto done; 17705895Syz147064 17715895Syz147064 str = strtok(buf, ","); 17725895Syz147064 while (str != NULL) { 17735895Syz147064 if (cnt == *val_cntp) { 17745895Syz147064 status = DLADM_STATUS_TOOSMALL; 17755895Syz147064 goto done; 17765895Syz147064 } 17775895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 17785895Syz147064 str = strtok(NULL, ","); 17795895Syz147064 } 17805895Syz147064 17815895Syz147064 *val_cntp = cnt; 17825895Syz147064 17835895Syz147064 done: 17845895Syz147064 dladm_destroy_conf(conf); 17855895Syz147064 return (status); 17865895Syz147064 } 17875903Ssowmini 17887663SSowmini.Varadhan@Sun.COM static link_attr_t * 17895903Ssowmini dladm_name2prop(const char *prop_name) 17905903Ssowmini { 17917663SSowmini.Varadhan@Sun.COM link_attr_t *p; 17925903Ssowmini 17937663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 17945903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 17955903Ssowmini break; 17965903Ssowmini } 17975903Ssowmini return (p); 17985903Ssowmini } 17995903Ssowmini 18007663SSowmini.Varadhan@Sun.COM static link_attr_t * 18017663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 18027663SSowmini.Varadhan@Sun.COM { 18037663SSowmini.Varadhan@Sun.COM link_attr_t *p; 18047663SSowmini.Varadhan@Sun.COM 18057663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 18067663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 18077663SSowmini.Varadhan@Sun.COM break; 18087663SSowmini.Varadhan@Sun.COM } 18097663SSowmini.Varadhan@Sun.COM return (p); 18107663SSowmini.Varadhan@Sun.COM } 18115903Ssowmini 18126789Sam223141 static dld_ioc_macprop_t * 18137663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 18147663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 18157663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 18165903Ssowmini { 18175903Ssowmini int dsize; 18186789Sam223141 dld_ioc_macprop_t *dip; 18195903Ssowmini 18205903Ssowmini *status = DLADM_STATUS_OK; 18216789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 18225903Ssowmini dip = malloc(dsize); 18235903Ssowmini if (dip == NULL) { 18245903Ssowmini *status = DLADM_STATUS_NOMEM; 18255903Ssowmini return (NULL); 18265903Ssowmini } 18275903Ssowmini bzero(dip, dsize); 18285903Ssowmini dip->pr_valsize = valsize; 18296512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 18306789Sam223141 dip->pr_version = MAC_PROP_VERSION; 18315960Ssowmini dip->pr_linkid = linkid; 18327663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 18336512Ssowmini dip->pr_flags = flags; 18345903Ssowmini return (dip); 18355903Ssowmini } 18365903Ssowmini 18377663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 18387663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 18397663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 18407663SSowmini.Varadhan@Sun.COM { 18417663SSowmini.Varadhan@Sun.COM link_attr_t *p; 18427663SSowmini.Varadhan@Sun.COM 18437663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 18447663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 18457663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 18467663SSowmini.Varadhan@Sun.COM flags, status)); 18477663SSowmini.Varadhan@Sun.COM } 18487663SSowmini.Varadhan@Sun.COM 18497663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 18507663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 18517663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 18527663SSowmini.Varadhan@Sun.COM { 18537663SSowmini.Varadhan@Sun.COM link_attr_t *p; 18547663SSowmini.Varadhan@Sun.COM 18557663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 18567663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 18577663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 18587663SSowmini.Varadhan@Sun.COM flags, status)); 18597663SSowmini.Varadhan@Sun.COM } 18607663SSowmini.Varadhan@Sun.COM 18615903Ssowmini /* ARGSUSED */ 18625903Ssowmini static dladm_status_t 18637342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid, 18645960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 18655903Ssowmini { 18666789Sam223141 dld_ioc_macprop_t *dip; 18675903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 18685903Ssowmini uint8_t u8; 18695903Ssowmini uint16_t u16; 18705903Ssowmini uint32_t u32; 18715903Ssowmini void *val; 18725903Ssowmini 18737663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, pd->pd_name, 0, &status); 18745903Ssowmini if (dip == NULL) 18755903Ssowmini return (status); 18765903Ssowmini 18775903Ssowmini if (pd->pd_flags & PD_CHECK_ALLOC) 18785903Ssowmini val = (void *)vdp->vd_val; 18795903Ssowmini else { 18805903Ssowmini /* 18815903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 18825903Ssowmini * No need (yet) to distinguish these from arrays of same size. 18835903Ssowmini */ 18845903Ssowmini switch (dip->pr_valsize) { 18855903Ssowmini case 1: 18865903Ssowmini u8 = vdp->vd_val; 18875903Ssowmini val = &u8; 18885903Ssowmini break; 18895903Ssowmini case 2: 18905903Ssowmini u16 = vdp->vd_val; 18915903Ssowmini val = &u16; 18925903Ssowmini break; 18935903Ssowmini case 4: 18945903Ssowmini u32 = vdp->vd_val; 18955903Ssowmini val = &u32; 18965903Ssowmini break; 18975903Ssowmini default: 18985903Ssowmini val = &vdp->vd_val; 18995903Ssowmini break; 19005903Ssowmini } 19015903Ssowmini } 19025903Ssowmini 19037342SAruna.Ramakrishna@Sun.COM if (val != NULL) 19047342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 19057342SAruna.Ramakrishna@Sun.COM else 19067342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 19077342SAruna.Ramakrishna@Sun.COM 19087663SSowmini.Varadhan@Sun.COM status = i_dladm_macprop(dip, B_TRUE); 19097663SSowmini.Varadhan@Sun.COM 19107663SSowmini.Varadhan@Sun.COM done: 19117663SSowmini.Varadhan@Sun.COM free(dip); 19127663SSowmini.Varadhan@Sun.COM return (status); 19137663SSowmini.Varadhan@Sun.COM } 19147663SSowmini.Varadhan@Sun.COM 19157663SSowmini.Varadhan@Sun.COM dladm_status_t 19167663SSowmini.Varadhan@Sun.COM i_dladm_macprop(void *dip, boolean_t set) 19177663SSowmini.Varadhan@Sun.COM { 19187663SSowmini.Varadhan@Sun.COM int fd; 19197663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 19207663SSowmini.Varadhan@Sun.COM 19215903Ssowmini if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 19225903Ssowmini status = dladm_errno2status(errno); 19237663SSowmini.Varadhan@Sun.COM return (status); 19245903Ssowmini } 19257663SSowmini.Varadhan@Sun.COM if (ioctl(fd, (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 19265903Ssowmini status = dladm_errno2status(errno); 19275903Ssowmini 19285903Ssowmini (void) close(fd); 19295903Ssowmini return (status); 19305903Ssowmini } 19315903Ssowmini 19326789Sam223141 static dld_ioc_macprop_t * 19337342SAruna.Ramakrishna@Sun.COM i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags, 19346512Ssowmini dladm_status_t *status) 19355903Ssowmini { 19366789Sam223141 dld_ioc_macprop_t *dip = NULL; 19376512Ssowmini 19387663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 19396512Ssowmini if (dip == NULL) 19406512Ssowmini return (NULL); 19415903Ssowmini 19427663SSowmini.Varadhan@Sun.COM *status = i_dladm_macprop(dip, B_FALSE); 19436512Ssowmini if (*status != DLADM_STATUS_OK) { 19446512Ssowmini free(dip); 19456512Ssowmini return (NULL); 19466512Ssowmini } 19476512Ssowmini return (dip); 19485903Ssowmini } 19495903Ssowmini 19505903Ssowmini /* ARGSUSED */ 19515903Ssowmini static dladm_status_t 19527342SAruna.Ramakrishna@Sun.COM i_dladm_defmtu_check(struct prop_desc *pd, datalink_id_t linkid, 19537342SAruna.Ramakrishna@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *v, datalink_media_t media) 19545903Ssowmini { 19555903Ssowmini if (val_cnt != 1) 19565903Ssowmini return (DLADM_STATUS_BADVAL); 19576512Ssowmini v->vd_val = atoi(prop_val[0]); 19585903Ssowmini return (DLADM_STATUS_OK); 19595903Ssowmini } 19605903Ssowmini 19615903Ssowmini /* ARGSUSED */ 19625903Ssowmini static dladm_status_t 19637342SAruna.Ramakrishna@Sun.COM i_dladm_duplex_get(struct prop_desc *pd, datalink_id_t linkid, 1964*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 1965*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 19665903Ssowmini { 19675903Ssowmini link_duplex_t link_duplex; 19685903Ssowmini dladm_status_t status; 19695903Ssowmini 19705903Ssowmini if ((status = dladm_get_single_mac_stat(linkid, "link_duplex", 19715903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 19725903Ssowmini return (status); 19735903Ssowmini 19745903Ssowmini switch (link_duplex) { 19755903Ssowmini case LINK_DUPLEX_FULL: 19765903Ssowmini (void) strcpy(*prop_val, "full"); 19775903Ssowmini break; 19785903Ssowmini case LINK_DUPLEX_HALF: 19795903Ssowmini (void) strcpy(*prop_val, "half"); 19805903Ssowmini break; 19815903Ssowmini default: 19825903Ssowmini (void) strcpy(*prop_val, "unknown"); 19835903Ssowmini break; 19845903Ssowmini } 19855903Ssowmini *val_cnt = 1; 19865903Ssowmini return (DLADM_STATUS_OK); 19875903Ssowmini } 19885903Ssowmini 19895903Ssowmini /* ARGSUSED */ 19905903Ssowmini static dladm_status_t 19917342SAruna.Ramakrishna@Sun.COM i_dladm_speed_get(struct prop_desc *pd, datalink_id_t linkid, 19926512Ssowmini char **prop_val, uint_t *val_cnt, uint_t flags) 19935903Ssowmini { 19945903Ssowmini uint64_t ifspeed = 0; 19955903Ssowmini dladm_status_t status; 19965903Ssowmini 19975903Ssowmini if ((status = dladm_get_single_mac_stat(linkid, "ifspeed", 19985903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 19995903Ssowmini return (status); 20006512Ssowmini 20015960Ssowmini if ((ifspeed % 1000000) != 0) { 20025960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 20035960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 20045960Ssowmini } else { 20055960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 20065960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 20075960Ssowmini } 20085903Ssowmini *val_cnt = 1; 20095903Ssowmini return (DLADM_STATUS_OK); 20105903Ssowmini } 20115903Ssowmini 20125903Ssowmini /* ARGSUSED */ 20135903Ssowmini static dladm_status_t 20147342SAruna.Ramakrishna@Sun.COM i_dladm_status_get(struct prop_desc *pd, datalink_id_t linkid, 2015*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 2016*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 20175903Ssowmini { 20186512Ssowmini link_state_t link_state; 20196512Ssowmini dladm_status_t status; 20206512Ssowmini uchar_t *cp; 20216789Sam223141 dld_ioc_macprop_t *dip; 20225903Ssowmini 20237342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 20246512Ssowmini if (status != DLADM_STATUS_OK) 20255903Ssowmini return (status); 20266512Ssowmini cp = (uchar_t *)dip->pr_val; 20276512Ssowmini (void) memcpy(&link_state, cp, sizeof (link_state)); 20285903Ssowmini 20295903Ssowmini switch (link_state) { 20305903Ssowmini case LINK_STATE_UP: 20315903Ssowmini (void) strcpy(*prop_val, "up"); 20325903Ssowmini break; 20335903Ssowmini case LINK_STATE_DOWN: 20345903Ssowmini (void) strcpy(*prop_val, "down"); 20355903Ssowmini break; 20365903Ssowmini default: 20375903Ssowmini (void) strcpy(*prop_val, "unknown"); 20385903Ssowmini break; 20395903Ssowmini } 20405903Ssowmini *val_cnt = 1; 2041*8118SVasumathi.Sundaram@Sun.COM *perm_flags = dip->pr_perm_flags; 20426512Ssowmini free(dip); 20435903Ssowmini return (DLADM_STATUS_OK); 20445903Ssowmini } 20455903Ssowmini 20465903Ssowmini /* ARGSUSED */ 20475903Ssowmini static dladm_status_t 20487342SAruna.Ramakrishna@Sun.COM i_dladm_binary_get(struct prop_desc *pd, datalink_id_t linkid, 2049*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 2050*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 20515903Ssowmini { 20526789Sam223141 dld_ioc_macprop_t *dip; 20535903Ssowmini dladm_status_t status; 20545903Ssowmini 20557342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 20566512Ssowmini if (dip == NULL) 20575903Ssowmini return (status); 20585903Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 2059*8118SVasumathi.Sundaram@Sun.COM *perm_flags = dip->pr_perm_flags; 20605903Ssowmini free(dip); 20615903Ssowmini *val_cnt = 1; 20625903Ssowmini return (DLADM_STATUS_OK); 20635903Ssowmini } 20645903Ssowmini 20655960Ssowmini /* ARGSUSED */ 20665903Ssowmini static dladm_status_t 20677342SAruna.Ramakrishna@Sun.COM i_dladm_uint32_get(struct prop_desc *pd, datalink_id_t linkid, 2068*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 2069*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 20705903Ssowmini { 20716789Sam223141 dld_ioc_macprop_t *dip; 20726512Ssowmini uint32_t v = 0; 20735903Ssowmini uchar_t *cp; 20745903Ssowmini dladm_status_t status; 20755903Ssowmini 20767342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 20776512Ssowmini if (dip == NULL) 20785903Ssowmini return (status); 20795903Ssowmini cp = (uchar_t *)dip->pr_val; 20805903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 20816512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 2082*8118SVasumathi.Sundaram@Sun.COM *perm_flags = dip->pr_perm_flags; 20835903Ssowmini free(dip); 20845903Ssowmini *val_cnt = 1; 20855903Ssowmini return (DLADM_STATUS_OK); 20865903Ssowmini } 20875903Ssowmini 20885960Ssowmini /* ARGSUSED */ 20895903Ssowmini static dladm_status_t 20907342SAruna.Ramakrishna@Sun.COM i_dladm_flowctl_get(struct prop_desc *pd, datalink_id_t linkid, 2091*8118SVasumathi.Sundaram@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 2092*8118SVasumathi.Sundaram@Sun.COM uint_t *perm_flags) 20935903Ssowmini { 20946789Sam223141 dld_ioc_macprop_t *dip; 20955903Ssowmini link_flowctrl_t v; 20965903Ssowmini dladm_status_t status; 20975903Ssowmini uchar_t *cp; 20985903Ssowmini 20997342SAruna.Ramakrishna@Sun.COM dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status); 21006512Ssowmini if (dip == NULL) 21015903Ssowmini return (status); 21025903Ssowmini cp = (uchar_t *)dip->pr_val; 21035903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 21045903Ssowmini switch (v) { 21055903Ssowmini case LINK_FLOWCTRL_NONE: 21065903Ssowmini (void) sprintf(*prop_val, "no"); 21075903Ssowmini break; 21085903Ssowmini case LINK_FLOWCTRL_RX: 21095903Ssowmini (void) sprintf(*prop_val, "rx"); 21105903Ssowmini break; 21115903Ssowmini case LINK_FLOWCTRL_TX: 21125903Ssowmini (void) sprintf(*prop_val, "tx"); 21135903Ssowmini break; 21145903Ssowmini case LINK_FLOWCTRL_BI: 21155903Ssowmini (void) sprintf(*prop_val, "bi"); 21165903Ssowmini break; 21175903Ssowmini } 2118*8118SVasumathi.Sundaram@Sun.COM *perm_flags = dip->pr_perm_flags; 21195903Ssowmini free(dip); 21205903Ssowmini *val_cnt = 1; 21215903Ssowmini return (DLADM_STATUS_OK); 21225903Ssowmini } 21235903Ssowmini 21245903Ssowmini 21255903Ssowmini /* ARGSUSED */ 21265903Ssowmini static dladm_status_t 21277342SAruna.Ramakrishna@Sun.COM i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, 21285903Ssowmini char **prop_val, uint_t val_cnt, uint_t flags) 21295903Ssowmini { 21307663SSowmini.Varadhan@Sun.COM int i, slen; 21317408SSebastien.Roy@Sun.COM int bufsize = 0; 21326789Sam223141 dld_ioc_macprop_t *dip = NULL; 21335903Ssowmini uchar_t *dp; 21347663SSowmini.Varadhan@Sun.COM link_attr_t *p; 21356512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 21365903Ssowmini 21375903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 21385903Ssowmini (prop_val != NULL && val_cnt == 0)) 21395903Ssowmini return (DLADM_STATUS_BADARG); 21405903Ssowmini p = dladm_name2prop(prop_name); 21416789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 21425903Ssowmini return (DLADM_STATUS_BADARG); 21435903Ssowmini 21445903Ssowmini /* 21455903Ssowmini * private properties: all parsing is done in the kernel. 21465903Ssowmini * allocate a enough space for each property + its separator (','). 21475903Ssowmini */ 21485903Ssowmini for (i = 0; i < val_cnt; i++) { 21495903Ssowmini bufsize += strlen(prop_val[i]) + 1; 21505903Ssowmini } 21516512Ssowmini 21526512Ssowmini if (prop_val == NULL) { 21536512Ssowmini /* 21546512Ssowmini * getting default value. so use more buffer space. 21556512Ssowmini */ 21567663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 21576512Ssowmini } 21586512Ssowmini 21597663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 21606789Sam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 21615903Ssowmini if (dip == NULL) 21625903Ssowmini return (status); 21635903Ssowmini 21645903Ssowmini dp = (uchar_t *)dip->pr_val; 21655903Ssowmini slen = 0; 21667663SSowmini.Varadhan@Sun.COM 21676512Ssowmini if (prop_val == NULL) { 21687663SSowmini.Varadhan@Sun.COM status = i_dladm_macprop(dip, B_FALSE); 21696512Ssowmini } else { 21706512Ssowmini for (i = 0; i < val_cnt; i++) { 21716512Ssowmini int plen = 0; 21725903Ssowmini 21736512Ssowmini plen = strlen(prop_val[i]); 21746512Ssowmini bcopy(prop_val[i], dp, plen); 21756512Ssowmini slen += plen; 21766512Ssowmini /* 21776512Ssowmini * add a "," separator and update dp. 21786512Ssowmini */ 21796512Ssowmini if (i != (val_cnt -1)) 21806512Ssowmini dp[slen++] = ','; 21816512Ssowmini dp += (plen + 1); 21826512Ssowmini } 21837663SSowmini.Varadhan@Sun.COM status = i_dladm_macprop(dip, B_TRUE); 21845903Ssowmini } 21856512Ssowmini 21865903Ssowmini free(dip); 21876512Ssowmini return (status); 21885903Ssowmini } 21895903Ssowmini 21905903Ssowmini static dladm_status_t 21917342SAruna.Ramakrishna@Sun.COM i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, 21926512Ssowmini char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags) 21935903Ssowmini { 21947663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 21956789Sam223141 dld_ioc_macprop_t *dip = NULL; 21967663SSowmini.Varadhan@Sun.COM link_attr_t *p; 21975903Ssowmini char tmp = '\0'; 21985903Ssowmini 21995903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 22005903Ssowmini (prop_val != NULL && val_cnt == 0)) 22015903Ssowmini return (DLADM_STATUS_BADARG); 22025903Ssowmini 22035903Ssowmini p = dladm_name2prop(prop_name); 22046789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 22055903Ssowmini return (DLADM_STATUS_BADARG); 22065903Ssowmini 22076512Ssowmini if (type == DLADM_PROP_VAL_MODIFIABLE) { 22085903Ssowmini *prop_val = &tmp; 22095903Ssowmini *val_cnt = 1; 22105903Ssowmini return (DLADM_STATUS_OK); 22115903Ssowmini } 22125903Ssowmini 22135903Ssowmini /* 22145903Ssowmini * private properties: all parsing is done in the kernel. 22155903Ssowmini */ 22167663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 22177663SSowmini.Varadhan@Sun.COM dld_flags, &status); 22185903Ssowmini if (dip == NULL) 22195903Ssowmini return (status); 22205903Ssowmini 22217663SSowmini.Varadhan@Sun.COM if ((status = i_dladm_macprop(dip, B_FALSE)) == DLADM_STATUS_OK) { 2222*8118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 2223*8118SVasumathi.Sundaram@Sun.COM switch (dip->pr_perm_flags) { 2224*8118SVasumathi.Sundaram@Sun.COM case MAC_PROP_PERM_READ: 2225*8118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, 2226*8118SVasumathi.Sundaram@Sun.COM PERM_READ_ONLY, DLADM_PROP_VAL_MAX); 2227*8118SVasumathi.Sundaram@Sun.COM break; 2228*8118SVasumathi.Sundaram@Sun.COM case MAC_PROP_PERM_RW: 2229*8118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, 2230*8118SVasumathi.Sundaram@Sun.COM PERM_READ_WRITE, 2231*8118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 2232*8118SVasumathi.Sundaram@Sun.COM break; 2233*8118SVasumathi.Sundaram@Sun.COM } 2234*8118SVasumathi.Sundaram@Sun.COM } else { 2235*8118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 2236*8118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 2237*8118SVasumathi.Sundaram@Sun.COM } 22385903Ssowmini *val_cnt = 1; 22395903Ssowmini } 22406512Ssowmini free(dip); 22415903Ssowmini return (status); 22425903Ssowmini } 22436512Ssowmini 22446512Ssowmini 22456512Ssowmini static dladm_status_t 22466512Ssowmini i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid, 22476512Ssowmini datalink_media_t media, uint_t flags) 22486512Ssowmini { 22496512Ssowmini dladm_status_t status; 22506512Ssowmini char **prop_vals = NULL, *buf; 22516512Ssowmini size_t bufsize; 22526512Ssowmini uint_t cnt; 22536512Ssowmini int i; 2254*8118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 22556512Ssowmini 22566512Ssowmini /* 22576512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 22586512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 22596512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 22606512Ssowmini */ 22616512Ssowmini bufsize = 22626512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 22636512Ssowmini buf = malloc(bufsize); 22646512Ssowmini prop_vals = (char **)(void *)buf; 22656512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 22666512Ssowmini prop_vals[i] = buf + 22676512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 22686512Ssowmini i * DLADM_PROP_VAL_MAX; 22696512Ssowmini } 22706768Sar224390 22716768Sar224390 /* 22727342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 22737342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 22747342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 22757342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 22767342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 22777342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 22787342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 22797342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 22806768Sar224390 */ 22816789Sam223141 status = pdp->pd_get(pdp, linkid, prop_vals, &cnt, media, 2282*8118SVasumathi.Sundaram@Sun.COM MAC_PROP_DEFAULT, &perm_flags); 22836512Ssowmini if (status == DLADM_STATUS_OK) { 2284*8118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 2285*8118SVasumathi.Sundaram@Sun.COM status = i_dladm_set_single_prop(linkid, pdp->pd_class, 2286*8118SVasumathi.Sundaram@Sun.COM media, pdp, prop_vals, cnt, flags); 2287*8118SVasumathi.Sundaram@Sun.COM } 2288*8118SVasumathi.Sundaram@Sun.COM else 2289*8118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 22906512Ssowmini } 22916512Ssowmini free(buf); 22926512Ssowmini return (status); 22936512Ssowmini } 22947663SSowmini.Varadhan@Sun.COM 22957663SSowmini.Varadhan@Sun.COM int 22967663SSowmini.Varadhan@Sun.COM macprop_to_wifi(mac_prop_id_t wl_prop) 22977663SSowmini.Varadhan@Sun.COM { 22987663SSowmini.Varadhan@Sun.COM switch (wl_prop) { 22997663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_ESSID: 23007663SSowmini.Varadhan@Sun.COM return (WL_ESSID); 23017663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_BSSID: 23027663SSowmini.Varadhan@Sun.COM return (WL_BSSID); 23037663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_BSSTYPE: 23047663SSowmini.Varadhan@Sun.COM return (WL_BSS_TYPE); 23057663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_LINKSTATUS: 23067663SSowmini.Varadhan@Sun.COM return (WL_LINKSTATUS); 23077663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_DESIRED_RATES: 23087663SSowmini.Varadhan@Sun.COM return (WL_DESIRED_RATES); 23097663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_SUPPORTED_RATES: 23107663SSowmini.Varadhan@Sun.COM return (WL_SUPPORTED_RATES); 23117663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_AUTH_MODE: 23127663SSowmini.Varadhan@Sun.COM return (WL_AUTH_MODE); 23137663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_ENCRYPTION: 23147663SSowmini.Varadhan@Sun.COM return (WL_ENCRYPTION); 23157663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_RSSI: 23167663SSowmini.Varadhan@Sun.COM return (WL_RSSI); 23177663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_PHY_CONFIG: 23187663SSowmini.Varadhan@Sun.COM return (WL_PHY_CONFIG); 23197663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_CAPABILITY: 23207663SSowmini.Varadhan@Sun.COM return (WL_CAPABILITY); 23217663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_WPA: 23227663SSowmini.Varadhan@Sun.COM return (WL_WPA); 23237663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_SCANRESULTS: 23247663SSowmini.Varadhan@Sun.COM return (WL_SCANRESULTS); 23257663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_POWER_MODE: 23267663SSowmini.Varadhan@Sun.COM return (WL_POWER_MODE); 23277663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_RADIO: 23287663SSowmini.Varadhan@Sun.COM return (WL_RADIO); 23297663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_ESS_LIST: 23307663SSowmini.Varadhan@Sun.COM return (WL_ESS_LIST); 23317663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_KEY_TAB: 23327663SSowmini.Varadhan@Sun.COM return (WL_WEP_KEY_TAB); 23337663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_CREATE_IBSS: 23347663SSowmini.Varadhan@Sun.COM return (WL_CREATE_IBSS); 23357663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_SETOPTIE: 23367663SSowmini.Varadhan@Sun.COM return (WL_SETOPTIE); 23377663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_DELKEY: 23387663SSowmini.Varadhan@Sun.COM return (WL_DELKEY); 23397663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_KEY: 23407663SSowmini.Varadhan@Sun.COM return (WL_KEY); 23417663SSowmini.Varadhan@Sun.COM case MAC_PROP_WL_MLME: 23427663SSowmini.Varadhan@Sun.COM return (WL_MLME); 23437663SSowmini.Varadhan@Sun.COM default: 23447663SSowmini.Varadhan@Sun.COM return (-1); 23457663SSowmini.Varadhan@Sun.COM } 23467663SSowmini.Varadhan@Sun.COM } 23477663SSowmini.Varadhan@Sun.COM 23487663SSowmini.Varadhan@Sun.COM dladm_status_t 23497663SSowmini.Varadhan@Sun.COM i_dladm_wlan_param(datalink_id_t linkid, void *buf, mac_prop_id_t cmd, 23507663SSowmini.Varadhan@Sun.COM size_t len, boolean_t set) 23517663SSowmini.Varadhan@Sun.COM { 23527663SSowmini.Varadhan@Sun.COM uint32_t flags; 23537663SSowmini.Varadhan@Sun.COM dladm_status_t status; 23547663SSowmini.Varadhan@Sun.COM uint32_t media; 23557663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 23567663SSowmini.Varadhan@Sun.COM void *dp; 23577663SSowmini.Varadhan@Sun.COM 23587663SSowmini.Varadhan@Sun.COM if ((status = dladm_datalink_id2info(linkid, &flags, NULL, &media, 23597663SSowmini.Varadhan@Sun.COM NULL, 0)) != DLADM_STATUS_OK) { 23607663SSowmini.Varadhan@Sun.COM return (status); 23617663SSowmini.Varadhan@Sun.COM } 23627663SSowmini.Varadhan@Sun.COM 23637663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 23647663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 23657663SSowmini.Varadhan@Sun.COM 23667663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 23677663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 23687663SSowmini.Varadhan@Sun.COM 23697663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 23707663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 23717663SSowmini.Varadhan@Sun.COM 23727663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 23737663SSowmini.Varadhan@Sun.COM if (dip == NULL) 23747663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 23757663SSowmini.Varadhan@Sun.COM 23767663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 23777663SSowmini.Varadhan@Sun.COM if (set) 23787663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 23797663SSowmini.Varadhan@Sun.COM 23807663SSowmini.Varadhan@Sun.COM status = i_dladm_macprop(dip, set); 23817663SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_NOTSUP) { 23827663SSowmini.Varadhan@Sun.COM if (set) { 23837663SSowmini.Varadhan@Sun.COM status = i_dladm_wlan_set_legacy_ioctl(linkid, 23847663SSowmini.Varadhan@Sun.COM buf, len, macprop_to_wifi(cmd)); 23857663SSowmini.Varadhan@Sun.COM } else { 23867663SSowmini.Varadhan@Sun.COM status = i_dladm_wlan_get_legacy_ioctl(linkid, 23877663SSowmini.Varadhan@Sun.COM buf, len, macprop_to_wifi(cmd)); 23887663SSowmini.Varadhan@Sun.COM } 23897663SSowmini.Varadhan@Sun.COM } else if (status == DLADM_STATUS_OK) { 23907663SSowmini.Varadhan@Sun.COM if (!set) 23917663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 23927663SSowmini.Varadhan@Sun.COM } 23937663SSowmini.Varadhan@Sun.COM 23947663SSowmini.Varadhan@Sun.COM free(dip); 23957663SSowmini.Varadhan@Sun.COM return (status); 23967663SSowmini.Varadhan@Sun.COM } 23977663SSowmini.Varadhan@Sun.COM 23987663SSowmini.Varadhan@Sun.COM static dladm_status_t 23997663SSowmini.Varadhan@Sun.COM i_dladm_wlan_get_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen, 24007663SSowmini.Varadhan@Sun.COM uint_t id) 24017663SSowmini.Varadhan@Sun.COM { 24027663SSowmini.Varadhan@Sun.COM wldp_t *gbuf; 24037663SSowmini.Varadhan@Sun.COM dladm_status_t status; 24047663SSowmini.Varadhan@Sun.COM 24057663SSowmini.Varadhan@Sun.COM if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 24067663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 24077663SSowmini.Varadhan@Sun.COM 24087663SSowmini.Varadhan@Sun.COM (void) memset(gbuf, 0, MAX_BUF_LEN); 24097663SSowmini.Varadhan@Sun.COM status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, MAX_BUF_LEN, 24107663SSowmini.Varadhan@Sun.COM WLAN_GET_PARAM, sizeof (wldp_t)); 24117663SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) 24127663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, gbuf->wldp_buf, buflen); 24137663SSowmini.Varadhan@Sun.COM 24147663SSowmini.Varadhan@Sun.COM free(gbuf); 24157663SSowmini.Varadhan@Sun.COM return (status); 24167663SSowmini.Varadhan@Sun.COM } 24177663SSowmini.Varadhan@Sun.COM 24187663SSowmini.Varadhan@Sun.COM static dladm_status_t 24197663SSowmini.Varadhan@Sun.COM i_dladm_wlan_set_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen, 24207663SSowmini.Varadhan@Sun.COM uint_t id) 24217663SSowmini.Varadhan@Sun.COM { 24227663SSowmini.Varadhan@Sun.COM wldp_t *gbuf; 24237663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 24247663SSowmini.Varadhan@Sun.COM 24257663SSowmini.Varadhan@Sun.COM if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) 24267663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 24277663SSowmini.Varadhan@Sun.COM 24287663SSowmini.Varadhan@Sun.COM (void) memset(gbuf, 0, MAX_BUF_LEN); 24297663SSowmini.Varadhan@Sun.COM (void) memcpy(gbuf->wldp_buf, buf, buflen); 24307663SSowmini.Varadhan@Sun.COM buflen += WIFI_BUF_OFFSET; 24317663SSowmini.Varadhan@Sun.COM status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, buflen, 24327663SSowmini.Varadhan@Sun.COM WLAN_SET_PARAM, buflen); 24337663SSowmini.Varadhan@Sun.COM 24347663SSowmini.Varadhan@Sun.COM free(gbuf); 24357663SSowmini.Varadhan@Sun.COM return (status); 24367663SSowmini.Varadhan@Sun.COM } 2437