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 /* 228874SSebastien.Roy@Sun.COM * Copyright 2009 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> 448275SEric Cheng #include <libdlvnic.h> 458275SEric Cheng #include <libintl.h> 463448Sdh155122 #include <dlfcn.h> 473448Sdh155122 #include <link.h> 485895Syz147064 #include <inet/wifi_ioctl.h> 495903Ssowmini #include <libdladm.h> 508275SEric Cheng #include <libdlstat.h> 515903Ssowmini #include <sys/param.h> 528275SEric Cheng #include <sys/debug.h> 538275SEric Cheng #include <sys/dld.h> 548275SEric Cheng #include <sys/mac_flow.h> 555903Ssowmini #include <inttypes.h> 565903Ssowmini #include <sys/ethernet.h> 577663SSowmini.Varadhan@Sun.COM #include <net/wpa.h> 587663SSowmini.Varadhan@Sun.COM #include <sys/sysmacros.h> 59*10491SRishi.Srivatsavai@Sun.COM #include <sys/vlan.h> 60*10491SRishi.Srivatsavai@Sun.COM #include <libdlbridge.h> 61*10491SRishi.Srivatsavai@Sun.COM #include <stp_in.h> 623448Sdh155122 635895Syz147064 /* 645895Syz147064 * The linkprop get() callback. 658275SEric Cheng * - pd: pointer to the prop_desc_t 665895Syz147064 * - propstrp: a property string array to keep the returned property. 675895Syz147064 * Caller allocated. 685895Syz147064 * - cntp: number of returned properties. 695895Syz147064 * Caller also uses it to indicate how many it expects. 705895Syz147064 */ 715903Ssowmini struct prop_desc; 728275SEric Cheng typedef struct prop_desc prop_desc_t; 738275SEric Cheng 748453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 755960Ssowmini datalink_id_t, char **propstp, uint_t *cntp, 768118SVasumathi.Sundaram@Sun.COM datalink_media_t, uint_t, uint_t *); 775895Syz147064 785895Syz147064 /* 795895Syz147064 * The linkprop set() callback. 805895Syz147064 * - propval: a val_desc_t array which keeps the property values to be set. 815895Syz147064 * - cnt: number of properties to be set. 825903Ssowmini * - flags: additional flags passed down the system call. 835903Ssowmini * 845903Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 855903Ssowmini * a format suitable for kernel consumption. This may require allocation 865903Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 875903Ssowmini * by all other pd_sets) which invokes the ioctl. 885895Syz147064 */ 898453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 908275SEric Cheng val_desc_t *propval, uint_t cnt, uint_t flags, 918275SEric Cheng datalink_media_t); 923448Sdh155122 935895Syz147064 /* 945895Syz147064 * The linkprop check() callback. 955895Syz147064 * - propstrp: property string array which keeps the property to be checked. 965895Syz147064 * - cnt: number of properties. 975895Syz147064 * - propval: return value; the property values of the given property strings. 985903Ssowmini * 995903Ssowmini * pd_check checks that the input values are valid. It does so by 1005903Ssowmini * iteraring through the pd_modval list for the property. If 1015903Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 1025903Ssowmini * specific to this property can be used. If the input values are 1035903Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 1045903Ssowmini * with either a val_desc_t found on the pd_modval list or something 1055903Ssowmini * generated on the fly. 1065895Syz147064 */ 1078453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 1088453SAnurag.Maskey@Sun.COM datalink_id_t, char **propstrp, uint_t cnt, 1098453SAnurag.Maskey@Sun.COM val_desc_t *propval, datalink_media_t); 1103448Sdh155122 1117663SSowmini.Varadhan@Sun.COM typedef struct link_attr_s { 1126789Sam223141 mac_prop_id_t pp_id; 1135903Ssowmini size_t pp_valsize; 1145903Ssowmini char *pp_name; 1157663SSowmini.Varadhan@Sun.COM } link_attr_t; 1165903Ssowmini 1177663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 1188275SEric Cheng const char *, uint_t, dladm_status_t *); 1197663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 1208275SEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 1218453SAnurag.Maskey@Sun.COM static dld_ioc_macprop_t *i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 1228453SAnurag.Maskey@Sun.COM char *, uint_t, dladm_status_t *, uint_t *); 1238453SAnurag.Maskey@Sun.COM 1249692SRishi.Srivatsavai@Sun.COM static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1258453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 1268460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1278453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *, dladm_prop_type_t, 1288453SAnurag.Maskey@Sun.COM uint_t); 1297663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_name2prop(const char *); 1307663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 1318275SEric Cheng 1325895Syz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 1335895Syz147064 do_get_rate_prop, do_get_channel_prop, 1345903Ssowmini do_get_powermode_prop, do_get_radio_prop, 1357342SAruna.Ramakrishna@Sun.COM i_dladm_duplex_get, i_dladm_status_get, 1367342SAruna.Ramakrishna@Sun.COM i_dladm_binary_get, i_dladm_uint32_get, 1378460SArtem.Kachitchkin@Sun.COM i_dladm_flowctl_get, i_dladm_maxbw_get, 1388874SSebastien.Roy@Sun.COM i_dladm_cpus_get, i_dladm_priority_get, 139*10491SRishi.Srivatsavai@Sun.COM i_dladm_tagmode_get, i_dladm_range_get, 140*10491SRishi.Srivatsavai@Sun.COM get_stp_prop, get_bridge_forward, 141*10491SRishi.Srivatsavai@Sun.COM get_bridge_pvid; 1428275SEric Cheng 1437342SAruna.Ramakrishna@Sun.COM static pd_setf_t do_set_zone, do_set_rate_prop, 1445903Ssowmini do_set_powermode_prop, do_set_radio_prop, 145*10491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, do_set_res, do_set_cpus, 146*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, set_bridge_forward, set_bridge_pvid; 1478275SEric Cheng 1485903Ssowmini static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 149*10491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, do_check_maxbw, do_check_cpus, 150*10491SRishi.Srivatsavai@Sun.COM do_check_priority, check_stp_prop, check_bridge_pvid; 1518275SEric Cheng 1528453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_speed_get(dladm_handle_t, prop_desc_t *, 1538453SAnurag.Maskey@Sun.COM datalink_id_t, char **, uint_t *, uint_t, uint_t *); 1548453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1558275SEric Cheng static const char *dladm_perm2str(uint_t, char *); 1568275SEric Cheng 1578275SEric Cheng struct prop_desc { 1585895Syz147064 /* 1595895Syz147064 * link property name 1605895Syz147064 */ 1615895Syz147064 char *pd_name; 1625895Syz147064 1635895Syz147064 /* 1645895Syz147064 * default property value, can be set to { "", NULL } 1655895Syz147064 */ 1665895Syz147064 val_desc_t pd_defval; 1675895Syz147064 1685895Syz147064 /* 1695895Syz147064 * list of optional property values, can be NULL. 1705895Syz147064 * 1715895Syz147064 * This is set to non-NULL if there is a list of possible property 1725895Syz147064 * values. pd_optval would point to the array of possible values. 1735895Syz147064 */ 1745895Syz147064 val_desc_t *pd_optval; 1755895Syz147064 1765895Syz147064 /* 1775895Syz147064 * count of the above optional property values. 0 if pd_optval is NULL. 1785895Syz147064 */ 1795895Syz147064 uint_t pd_noptval; 1805895Syz147064 1815895Syz147064 /* 182*10491SRishi.Srivatsavai@Sun.COM * callback to set link property; set to NULL if this property is 183*10491SRishi.Srivatsavai@Sun.COM * read-only and may be called before or after permanent update; see 184*10491SRishi.Srivatsavai@Sun.COM * flags. 1855895Syz147064 */ 1865895Syz147064 pd_setf_t *pd_set; 1875895Syz147064 1885895Syz147064 /* 1895895Syz147064 * callback to get modifiable link property 1905895Syz147064 */ 1915895Syz147064 pd_getf_t *pd_getmod; 1925895Syz147064 1935895Syz147064 /* 1945895Syz147064 * callback to get current link property 1955895Syz147064 */ 1965895Syz147064 pd_getf_t *pd_get; 1975895Syz147064 1985895Syz147064 /* 1995895Syz147064 * callback to validate link property value, set to NULL if pd_optval 2005895Syz147064 * is not NULL. In that case, validate the value by comparing it with 2015895Syz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 2025895Syz147064 * valid. 2035895Syz147064 */ 2045895Syz147064 pd_checkf_t *pd_check; 2055895Syz147064 2065895Syz147064 uint_t pd_flags; 2075903Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 2085903Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 209*10491SRishi.Srivatsavai@Sun.COM #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 2105895Syz147064 /* 2115895Syz147064 * indicate link classes this property applies to. 2125895Syz147064 */ 2135895Syz147064 datalink_class_t pd_class; 2145895Syz147064 2155895Syz147064 /* 2165895Syz147064 * indicate link media type this property applies to. 2175895Syz147064 */ 2185895Syz147064 datalink_media_t pd_dmedia; 2198275SEric Cheng }; 2203448Sdh155122 2216789Sam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 2225903Ssowmini 2237663SSowmini.Varadhan@Sun.COM /* 2247663SSowmini.Varadhan@Sun.COM * Supported link properties enumerated in the prop_table[] array are 2257663SSowmini.Varadhan@Sun.COM * computed using the callback functions in that array. To compute the 2267663SSowmini.Varadhan@Sun.COM * property value, multiple distinct system calls may be needed (e.g., 2277663SSowmini.Varadhan@Sun.COM * for wifi speed, we need to issue system calls to get desired/supported 2287663SSowmini.Varadhan@Sun.COM * rates). The link_attr[] table enumerates the interfaces to the kernel, 2297663SSowmini.Varadhan@Sun.COM * and the type/size of the data passed in the user-kernel interface. 2307663SSowmini.Varadhan@Sun.COM */ 2317663SSowmini.Varadhan@Sun.COM static link_attr_t link_attr[] = { 2327663SSowmini.Varadhan@Sun.COM { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 2335903Ssowmini 2347663SSowmini.Varadhan@Sun.COM { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 2357663SSowmini.Varadhan@Sun.COM 2367663SSowmini.Varadhan@Sun.COM { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 2377663SSowmini.Varadhan@Sun.COM 2387663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 2395903Ssowmini 2407663SSowmini.Varadhan@Sun.COM { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 2415903Ssowmini 2427663SSowmini.Varadhan@Sun.COM { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 2437663SSowmini.Varadhan@Sun.COM 2447663SSowmini.Varadhan@Sun.COM { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 2455903Ssowmini 2467663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2477663SSowmini.Varadhan@Sun.COM 2489449Sxiuyan.wang@Sun.COM { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 2499449Sxiuyan.wang@Sun.COM 2509449Sxiuyan.wang@Sun.COM { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 2519449Sxiuyan.wang@Sun.COM 2527663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2537663SSowmini.Varadhan@Sun.COM 2547663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 2555903Ssowmini 2567663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 2575903Ssowmini 2587663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 2597663SSowmini.Varadhan@Sun.COM 2607663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 2617342SAruna.Ramakrishna@Sun.COM 2627663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 2637663SSowmini.Varadhan@Sun.COM 2647663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 2657663SSowmini.Varadhan@Sun.COM 2667663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 2677342SAruna.Ramakrishna@Sun.COM 2687663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 2697663SSowmini.Varadhan@Sun.COM 2707663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 2715903Ssowmini 2727663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 2737663SSowmini.Varadhan@Sun.COM 2747663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 2755903Ssowmini 2767663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 2777663SSowmini.Varadhan@Sun.COM 2787663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 2795903Ssowmini 2807663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 2817663SSowmini.Varadhan@Sun.COM 2827663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 2837663SSowmini.Varadhan@Sun.COM 2847663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2857663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 2865903Ssowmini 2877663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2887663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 2897663SSowmini.Varadhan@Sun.COM 2907663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 2915903Ssowmini 2927663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 2937663SSowmini.Varadhan@Sun.COM 2947663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 2955903Ssowmini 2967663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 2977663SSowmini.Varadhan@Sun.COM 2987663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 2995903Ssowmini 3007663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 3017663SSowmini.Varadhan@Sun.COM 3027663SSowmini.Varadhan@Sun.COM /* wl_wpa_ess_t has variable length */ 3037663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 3045903Ssowmini 3057663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 3067663SSowmini.Varadhan@Sun.COM 3077663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 3085903Ssowmini 3097663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 3107663SSowmini.Varadhan@Sun.COM 3117663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 3125903Ssowmini 3137663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 3147663SSowmini.Varadhan@Sun.COM 3157663SSowmini.Varadhan@Sun.COM /* wl_wpa_ie_t has variable length */ 3167663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 3175903Ssowmini 3187663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 3197663SSowmini.Varadhan@Sun.COM 3207663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 3215903Ssowmini 3227663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 3237663SSowmini.Varadhan@Sun.COM 3248275SEric Cheng { MAC_PROP_MAXBW, sizeof (mac_resource_props_t), "maxbw"}, 3258275SEric Cheng 3268275SEric Cheng { MAC_PROP_PRIO, sizeof (mac_resource_props_t), "priority"}, 3278275SEric Cheng 3288275SEric Cheng { MAC_PROP_BIND_CPU, sizeof (mac_resource_props_t), "cpus"}, 3298275SEric Cheng 3308874SSebastien.Roy@Sun.COM { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 3318874SSebastien.Roy@Sun.COM 332*10491SRishi.Srivatsavai@Sun.COM { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 333*10491SRishi.Srivatsavai@Sun.COM 334*10491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 335*10491SRishi.Srivatsavai@Sun.COM 336*10491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 337*10491SRishi.Srivatsavai@Sun.COM 3387663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3398275SEric Cheng 3405903Ssowmini }; 3415903Ssowmini 342*10491SRishi.Srivatsavai@Sun.COM typedef struct bridge_public_prop_s { 343*10491SRishi.Srivatsavai@Sun.COM const char *bpp_name; 344*10491SRishi.Srivatsavai@Sun.COM int bpp_code; 345*10491SRishi.Srivatsavai@Sun.COM } bridge_public_prop_t; 346*10491SRishi.Srivatsavai@Sun.COM 347*10491SRishi.Srivatsavai@Sun.COM static const bridge_public_prop_t bridge_prop[] = { 348*10491SRishi.Srivatsavai@Sun.COM { "stp", PT_CFG_NON_STP }, 349*10491SRishi.Srivatsavai@Sun.COM { "stp_priority", PT_CFG_PRIO }, 350*10491SRishi.Srivatsavai@Sun.COM { "stp_cost", PT_CFG_COST }, 351*10491SRishi.Srivatsavai@Sun.COM { "stp_edge", PT_CFG_EDGE }, 352*10491SRishi.Srivatsavai@Sun.COM { "stp_p2p", PT_CFG_P2P }, 353*10491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", PT_CFG_MCHECK }, 354*10491SRishi.Srivatsavai@Sun.COM { NULL, 0 } 355*10491SRishi.Srivatsavai@Sun.COM }; 356*10491SRishi.Srivatsavai@Sun.COM 3575903Ssowmini static val_desc_t link_duplex_vals[] = { 3585903Ssowmini { "half", LINK_DUPLEX_HALF }, 3595903Ssowmini { "full", LINK_DUPLEX_HALF } 3605903Ssowmini }; 3615903Ssowmini static val_desc_t link_status_vals[] = { 3625903Ssowmini { "up", LINK_STATE_UP }, 3635903Ssowmini { "down", LINK_STATE_DOWN } 3645903Ssowmini }; 3655903Ssowmini static val_desc_t link_01_vals[] = { 3665903Ssowmini { "1", 1 }, 3675903Ssowmini { "0", 0 } 3685903Ssowmini }; 3695903Ssowmini static val_desc_t link_flow_vals[] = { 3705903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3715903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3725903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 3735903Ssowmini { "bi", LINK_FLOWCTRL_BI } 3745903Ssowmini }; 3758275SEric Cheng static val_desc_t link_priority_vals[] = { 3768275SEric Cheng { "low", MPL_LOW }, 3778275SEric Cheng { "medium", MPL_MEDIUM }, 3788275SEric Cheng { "high", MPL_HIGH } 3798275SEric Cheng }; 3805903Ssowmini 3818874SSebastien.Roy@Sun.COM static val_desc_t link_tagmode_vals[] = { 3828874SSebastien.Roy@Sun.COM { "normal", LINK_TAGMODE_NORMAL }, 3838874SSebastien.Roy@Sun.COM { "vlanonly", LINK_TAGMODE_VLANONLY } 3848874SSebastien.Roy@Sun.COM }; 3858874SSebastien.Roy@Sun.COM 3865895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 3875895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 3885895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 3895895Syz147064 }; 3905895Syz147064 3915895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 3925895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 3935895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 3945895Syz147064 { "max", DLADM_WLAN_PM_MAX } 3955895Syz147064 }; 3965895Syz147064 397*10491SRishi.Srivatsavai@Sun.COM static val_desc_t stp_p2p_vals[] = { 398*10491SRishi.Srivatsavai@Sun.COM { "true", P2P_FORCE_TRUE }, 399*10491SRishi.Srivatsavai@Sun.COM { "false", P2P_FORCE_FALSE }, 400*10491SRishi.Srivatsavai@Sun.COM { "auto", P2P_AUTO } 401*10491SRishi.Srivatsavai@Sun.COM }; 402*10491SRishi.Srivatsavai@Sun.COM 4038275SEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 4048275SEric Cheng #define RESET_VAL ((uintptr_t)-1) 4058275SEric Cheng 4063448Sdh155122 static prop_desc_t prop_table[] = { 4075903Ssowmini { "channel", { NULL, 0 }, 4085903Ssowmini NULL, 0, NULL, NULL, 4095895Syz147064 do_get_channel_prop, NULL, 0, 4105903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4115895Syz147064 4125895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 4135895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 4145895Syz147064 do_set_powermode_prop, NULL, 4155895Syz147064 do_get_powermode_prop, NULL, 0, 4165903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4175895Syz147064 4185895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 4195895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 4205895Syz147064 do_set_radio_prop, NULL, 4215895Syz147064 do_get_radio_prop, NULL, 0, 4225903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4235895Syz147064 4245895Syz147064 { "speed", { "", 0 }, NULL, 0, 4255895Syz147064 do_set_rate_prop, do_get_rate_mod, 4265895Syz147064 do_get_rate_prop, do_check_rate, 0, 4275960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 4285895Syz147064 4296512Ssowmini { "autopush", { "", 0 }, NULL, 0, 4307342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, 4317342SAruna.Ramakrishna@Sun.COM do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 4325903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4335895Syz147064 4346512Ssowmini { "zone", { "", 0 }, NULL, 0, 4353448Sdh155122 do_set_zone, NULL, 4367342SAruna.Ramakrishna@Sun.COM do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 4375903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4385903Ssowmini 4398275SEric Cheng { "duplex", { "", 0 }, 4405903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 4417342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_duplex_get, NULL, 4425903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4435903Ssowmini 4448275SEric Cheng { "state", { "up", LINK_STATE_UP }, 4455903Ssowmini link_status_vals, VALCNT(link_status_vals), 4467342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_status_get, NULL, 4476512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4485903Ssowmini 44910191SSowmini.Varadhan@Sun.COM { "adv_autoneg_cap", { "", 0 }, 4505903Ssowmini link_01_vals, VALCNT(link_01_vals), 4517342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4525903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4535903Ssowmini 4546512Ssowmini { "mtu", { "", 0 }, NULL, 0, 4559514SGirish.Moodalbail@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, 456*10491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_get, i_dladm_uint32_check, 0, DATALINK_CLASS_ALL, 4577342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 4585903Ssowmini 4596512Ssowmini { "flowctrl", { "", 0 }, 4605903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 4617342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 4625903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4635903Ssowmini 4649449Sxiuyan.wang@Sun.COM { "adv_10gfdx_cap", { "", 0 }, 4659449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 4669449Sxiuyan.wang@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4679449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4689449Sxiuyan.wang@Sun.COM 4699449Sxiuyan.wang@Sun.COM { "en_10gfdx_cap", { "", 0 }, 4709449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 4719449Sxiuyan.wang@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4729449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4739449Sxiuyan.wang@Sun.COM 4746512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 4756512Ssowmini link_01_vals, VALCNT(link_01_vals), 4767342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4775903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4785903Ssowmini 4796512Ssowmini { "en_1000fdx_cap", { "", 0 }, 4805903Ssowmini link_01_vals, VALCNT(link_01_vals), 4817342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4825903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4835903Ssowmini 4846512Ssowmini { "adv_1000hdx_cap", { "", 0 }, 4855903Ssowmini link_01_vals, VALCNT(link_01_vals), 4867342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4875903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4885903Ssowmini 4896512Ssowmini { "en_1000hdx_cap", { "", 0 }, 4905903Ssowmini link_01_vals, VALCNT(link_01_vals), 4917342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4925903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4935903Ssowmini 4946512Ssowmini { "adv_100fdx_cap", { "", 0 }, 4955903Ssowmini link_01_vals, VALCNT(link_01_vals), 4967342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4975903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4985903Ssowmini 4996512Ssowmini { "en_100fdx_cap", { "", 0 }, 5005903Ssowmini link_01_vals, VALCNT(link_01_vals), 5017342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5025903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5035903Ssowmini 5046512Ssowmini { "adv_100hdx_cap", { "", 0 }, 5055903Ssowmini link_01_vals, VALCNT(link_01_vals), 5067342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5075903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5085903Ssowmini 5096512Ssowmini { "en_100hdx_cap", { "", 0 }, 5105903Ssowmini link_01_vals, VALCNT(link_01_vals), 5117342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5125903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5135903Ssowmini 5146512Ssowmini { "adv_10fdx_cap", { "", 0 }, 5155903Ssowmini link_01_vals, VALCNT(link_01_vals), 5167342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5175903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5185903Ssowmini 5196512Ssowmini { "en_10fdx_cap", { "", 0 }, 5205903Ssowmini link_01_vals, VALCNT(link_01_vals), 5217342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5225903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5235903Ssowmini 5246512Ssowmini { "adv_10hdx_cap", { "", 0 }, 5255903Ssowmini link_01_vals, VALCNT(link_01_vals), 5267342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5275903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5285903Ssowmini 5296512Ssowmini { "en_10hdx_cap", { "", 0 }, 5305903Ssowmini link_01_vals, VALCNT(link_01_vals), 5317342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5328275SEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5338275SEric Cheng 5348275SEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 5358275SEric Cheng do_set_res, NULL, 5368460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get, do_check_maxbw, PD_CHECK_ALLOC, 5378275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5388275SEric Cheng 5398275SEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 5408275SEric Cheng do_set_cpus, NULL, 5418460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get, do_check_cpus, 0, 5428275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5438275SEric Cheng 5448275SEric Cheng { "priority", { "high", RESET_VAL }, 5458275SEric Cheng link_priority_vals, VALCNT(link_priority_vals), do_set_res, NULL, 5468460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get, do_check_priority, PD_CHECK_ALLOC, 5478275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5488874SSebastien.Roy@Sun.COM 5498874SSebastien.Roy@Sun.COM { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 5508874SSebastien.Roy@Sun.COM link_tagmode_vals, VALCNT(link_tagmode_vals), 5518874SSebastien.Roy@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_tagmode_get, 5528874SSebastien.Roy@Sun.COM NULL, 0, 5538874SSebastien.Roy@Sun.COM DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 554*10491SRishi.Srivatsavai@Sun.COM DL_ETHER }, 555*10491SRishi.Srivatsavai@Sun.COM 556*10491SRishi.Srivatsavai@Sun.COM { "forward", { "1", 1 }, 557*10491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 558*10491SRishi.Srivatsavai@Sun.COM set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 559*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 560*10491SRishi.Srivatsavai@Sun.COM 561*10491SRishi.Srivatsavai@Sun.COM { "default_tag", { "1", 1 }, NULL, 0, 562*10491SRishi.Srivatsavai@Sun.COM set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 563*10491SRishi.Srivatsavai@Sun.COM 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 564*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 565*10491SRishi.Srivatsavai@Sun.COM 566*10491SRishi.Srivatsavai@Sun.COM { "learn_limit", { "1000", 1000 }, NULL, 0, 567*10491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 568*10491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, 0, 569*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 570*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 571*10491SRishi.Srivatsavai@Sun.COM 572*10491SRishi.Srivatsavai@Sun.COM { "learn_decay", { "200", 200 }, NULL, 0, 573*10491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 574*10491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, 0, 575*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 576*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 577*10491SRishi.Srivatsavai@Sun.COM 578*10491SRishi.Srivatsavai@Sun.COM { "stp", { "1", 1 }, 579*10491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 580*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 581*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 582*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 583*10491SRishi.Srivatsavai@Sun.COM 584*10491SRishi.Srivatsavai@Sun.COM { "stp_priority", { "128", 128 }, NULL, 0, 585*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 586*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 587*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 588*10491SRishi.Srivatsavai@Sun.COM 589*10491SRishi.Srivatsavai@Sun.COM { "stp_cost", { "auto", 0 }, NULL, 0, 590*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 591*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 592*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 593*10491SRishi.Srivatsavai@Sun.COM 594*10491SRishi.Srivatsavai@Sun.COM { "stp_edge", { "1", 1 }, 595*10491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 596*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 597*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 598*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 599*10491SRishi.Srivatsavai@Sun.COM 600*10491SRishi.Srivatsavai@Sun.COM { "stp_p2p", { "auto", P2P_AUTO }, 601*10491SRishi.Srivatsavai@Sun.COM stp_p2p_vals, VALCNT(stp_p2p_vals), 602*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 603*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 604*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 605*10491SRishi.Srivatsavai@Sun.COM 606*10491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", { "0", 0 }, 607*10491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 608*10491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 609*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 610*10491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6113448Sdh155122 }; 6123448Sdh155122 6135895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 6145895Syz147064 6158275SEric Cheng static resource_prop_t rsrc_prop_table[] = { 6168275SEric Cheng {"maxbw", do_extract_maxbw}, 6178275SEric Cheng {"priority", do_extract_priority}, 6188275SEric Cheng {"cpus", do_extract_cpus} 6198275SEric Cheng }; 6208275SEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 6218275SEric Cheng sizeof (resource_prop_t)) 6228275SEric Cheng 6237663SSowmini.Varadhan@Sun.COM /* 6247663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 6257663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 6267663SSowmini.Varadhan@Sun.COM */ 6277663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 6287663SSowmini.Varadhan@Sun.COM 6298453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 6308453SAnurag.Maskey@Sun.COM const char *, char **, uint_t); 6318453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 6328453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *); 6338460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 6348460SArtem.Kachitchkin@Sun.COM datalink_id_t, void *, int (*)(dladm_handle_t, 6358460SArtem.Kachitchkin@Sun.COM datalink_id_t, const char *, void *)); 6368453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 6378453SAnurag.Maskey@Sun.COM datalink_class_t, uint32_t, prop_desc_t *, char **, 6388453SAnurag.Maskey@Sun.COM uint_t, uint_t); 6398453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 6408453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 6418453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 6428453SAnurag.Maskey@Sun.COM datalink_id_t, datalink_media_t, uint_t); 6438275SEric Cheng 6445895Syz147064 /* 6455895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 6465895Syz147064 * rates to be retrieved. However, we cannot increase it at this 6475895Syz147064 * time because it will break binary compatibility with unbundled 6485895Syz147064 * WiFi drivers and utilities. So for now we define an additional 6495895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 6505895Syz147064 */ 6515895Syz147064 #define MAX_SUPPORT_RATES 64 6525895Syz147064 6535895Syz147064 #define AP_ANCHOR "[anchor]" 6545895Syz147064 #define AP_DELIMITER '.' 6555895Syz147064 6565895Syz147064 static dladm_status_t 6575895Syz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 6585895Syz147064 val_desc_t *vdp) 6595895Syz147064 { 6605895Syz147064 int i, j; 6615895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 6623147Sxc151355 6635895Syz147064 for (j = 0; j < val_cnt; j++) { 6645895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 6655895Syz147064 if (strcasecmp(*prop_val, 6665895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 6675895Syz147064 break; 6685895Syz147064 } 6695895Syz147064 } 6705895Syz147064 if (i == pdp->pd_noptval) { 6715895Syz147064 status = DLADM_STATUS_BADVAL; 6725895Syz147064 goto done; 6735895Syz147064 } 6745895Syz147064 (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); 6755895Syz147064 } 6765895Syz147064 6775895Syz147064 done: 6785895Syz147064 return (status); 6795895Syz147064 } 6805895Syz147064 6815895Syz147064 static dladm_status_t 6828453SAnurag.Maskey@Sun.COM i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 6838453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 6848453SAnurag.Maskey@Sun.COM uint_t val_cnt, uint_t flags) 6853147Sxc151355 { 6865895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 6875895Syz147064 val_desc_t *vdp = NULL; 6885895Syz147064 boolean_t needfree = B_FALSE; 6895895Syz147064 uint_t cnt, i; 6903147Sxc151355 6915895Syz147064 if (!(pdp->pd_class & class)) 6925895Syz147064 return (DLADM_STATUS_BADARG); 6935895Syz147064 6945895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 6953147Sxc151355 return (DLADM_STATUS_BADARG); 6963147Sxc151355 6975895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 6985895Syz147064 return (DLADM_STATUS_TEMPONLY); 6995895Syz147064 7005895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 7015895Syz147064 return (DLADM_STATUS_OK); 7025895Syz147064 7035895Syz147064 if (pdp->pd_set == NULL) 7045895Syz147064 return (DLADM_STATUS_PROPRDONLY); 7053448Sdh155122 7065895Syz147064 if (prop_val != NULL) { 7075895Syz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 7085895Syz147064 if (vdp == NULL) 7095895Syz147064 return (DLADM_STATUS_NOMEM); 7105895Syz147064 7115895Syz147064 if (pdp->pd_check != NULL) { 7128275SEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 7138453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, prop_val, 7148453SAnurag.Maskey@Sun.COM val_cnt, vdp, media); 7155895Syz147064 } else if (pdp->pd_optval != NULL) { 7165895Syz147064 status = do_check_prop(pdp, prop_val, val_cnt, vdp); 7175895Syz147064 } else { 7183448Sdh155122 status = DLADM_STATUS_BADARG; 7193147Sxc151355 } 7205895Syz147064 7213147Sxc151355 if (status != DLADM_STATUS_OK) 7225895Syz147064 goto done; 7235895Syz147064 7245895Syz147064 cnt = val_cnt; 7255895Syz147064 } else { 7268275SEric Cheng boolean_t defval = B_FALSE; 7278275SEric Cheng 7285895Syz147064 if (pdp->pd_defval.vd_name == NULL) 7295895Syz147064 return (DLADM_STATUS_NOTSUP); 7305895Syz147064 7317342SAruna.Ramakrishna@Sun.COM cnt = 1; 7328275SEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 7338275SEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 7346512Ssowmini if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 7356512Ssowmini return (DLADM_STATUS_NOMEM); 7367342SAruna.Ramakrishna@Sun.COM 7378275SEric Cheng if (defval) { 7388275SEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 7398275SEric Cheng sizeof (val_desc_t)); 7408275SEric Cheng } else if (pdp->pd_check != NULL) { 7418453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 7428453SAnurag.Maskey@Sun.COM prop_val, cnt, vdp, media); 7437342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 7447342SAruna.Ramakrishna@Sun.COM goto done; 7457342SAruna.Ramakrishna@Sun.COM } 7466512Ssowmini } else { 7478453SAnurag.Maskey@Sun.COM status = i_dladm_getset_defval(handle, pdp, linkid, 7486512Ssowmini media, flags); 7496512Ssowmini return (status); 7506512Ssowmini } 7515895Syz147064 } 752*10491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_AFTER_PERM) 753*10491SRishi.Srivatsavai@Sun.COM status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 754*10491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_PERMONLY; 755*10491SRishi.Srivatsavai@Sun.COM else 756*10491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 757*10491SRishi.Srivatsavai@Sun.COM media); 7585895Syz147064 if (needfree) { 7595895Syz147064 for (i = 0; i < cnt; i++) 7605903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 7613147Sxc151355 } 7625895Syz147064 done: 7635895Syz147064 free(vdp); 7645895Syz147064 return (status); 7655895Syz147064 } 7665895Syz147064 7675895Syz147064 static dladm_status_t 7688453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 7698453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 7705895Syz147064 { 7715895Syz147064 int i; 7725895Syz147064 boolean_t found = B_FALSE; 7735895Syz147064 datalink_class_t class; 7745895Syz147064 uint32_t media; 7755895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 7765895Syz147064 7778453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 7788453SAnurag.Maskey@Sun.COM NULL, 0); 7795895Syz147064 if (status != DLADM_STATUS_OK) 7805895Syz147064 return (status); 7815895Syz147064 7825895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 7835895Syz147064 prop_desc_t *pdp = &prop_table[i]; 7845895Syz147064 dladm_status_t s; 7855895Syz147064 7865895Syz147064 if (prop_name != NULL && 7875895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 7885895Syz147064 continue; 7895895Syz147064 found = B_TRUE; 7908453SAnurag.Maskey@Sun.COM s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 7918453SAnurag.Maskey@Sun.COM prop_val, val_cnt, flags); 7923448Sdh155122 7935895Syz147064 if (prop_name != NULL) { 7945895Syz147064 status = s; 7955895Syz147064 break; 7965895Syz147064 } else { 7975895Syz147064 if (s != DLADM_STATUS_OK && 7985895Syz147064 s != DLADM_STATUS_NOTSUP) 7995895Syz147064 status = s; 8005895Syz147064 } 8015895Syz147064 } 8025903Ssowmini if (!found) { 8035903Ssowmini if (prop_name[0] == '_') { 8045903Ssowmini /* other private properties */ 8059692SRishi.Srivatsavai@Sun.COM status = i_dladm_set_private_prop(handle, linkid, 8069692SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cnt, flags); 8075903Ssowmini } else { 8085903Ssowmini status = DLADM_STATUS_NOTFOUND; 8095903Ssowmini } 8105903Ssowmini } 8115895Syz147064 8125895Syz147064 return (status); 8135895Syz147064 } 8145895Syz147064 8155895Syz147064 /* 8165895Syz147064 * Set/reset link property for specific link 8175895Syz147064 */ 8185895Syz147064 dladm_status_t 8198453SAnurag.Maskey@Sun.COM dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8208453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8215895Syz147064 { 8225895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8235895Syz147064 8245895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 8255895Syz147064 (prop_val == NULL && val_cnt > 0) || 8265895Syz147064 (prop_val != NULL && val_cnt == 0) || 8275895Syz147064 (prop_name == NULL && prop_val != NULL)) { 8285895Syz147064 return (DLADM_STATUS_BADARG); 8295895Syz147064 } 8305895Syz147064 8319692SRishi.Srivatsavai@Sun.COM /* 8329692SRishi.Srivatsavai@Sun.COM * Check for valid link property against the flags passed 8339692SRishi.Srivatsavai@Sun.COM * and set the link property when active flag is passed. 8349692SRishi.Srivatsavai@Sun.COM */ 8358453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 8365895Syz147064 val_cnt, flags); 8375895Syz147064 if (status != DLADM_STATUS_OK) 8385895Syz147064 return (status); 8395895Syz147064 8405895Syz147064 if (flags & DLADM_OPT_PERSIST) { 8418453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 8423147Sxc151355 prop_val, val_cnt); 843*10491SRishi.Srivatsavai@Sun.COM 844*10491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 845*10491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp = prop_table; 846*10491SRishi.Srivatsavai@Sun.COM int i; 847*10491SRishi.Srivatsavai@Sun.COM 848*10491SRishi.Srivatsavai@Sun.COM for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 849*10491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_flags & PD_AFTER_PERM)) 850*10491SRishi.Srivatsavai@Sun.COM continue; 851*10491SRishi.Srivatsavai@Sun.COM if (prop_name != NULL && 852*10491SRishi.Srivatsavai@Sun.COM strcasecmp(prop_name, pdp->pd_name) != 0) 853*10491SRishi.Srivatsavai@Sun.COM continue; 854*10491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, NULL, 855*10491SRishi.Srivatsavai@Sun.COM 0, flags, 0); 856*10491SRishi.Srivatsavai@Sun.COM } 857*10491SRishi.Srivatsavai@Sun.COM } 8583147Sxc151355 } 8593147Sxc151355 return (status); 8603147Sxc151355 } 8613147Sxc151355 8625895Syz147064 /* 8638460SArtem.Kachitchkin@Sun.COM * Walk all link properties of the given specific link. 8648460SArtem.Kachitchkin@Sun.COM * 8658460SArtem.Kachitchkin@Sun.COM * Note: this function currently lacks the ability to walk _all_ private 8668460SArtem.Kachitchkin@Sun.COM * properties if the link, because there is no kernel interface to 8678460SArtem.Kachitchkin@Sun.COM * retrieve all known private property names. Once such an interface 8688460SArtem.Kachitchkin@Sun.COM * is added, this function should be fixed accordingly. 8695895Syz147064 */ 8703147Sxc151355 dladm_status_t 8718453SAnurag.Maskey@Sun.COM dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 8728453SAnurag.Maskey@Sun.COM int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 8733147Sxc151355 { 8745895Syz147064 dladm_status_t status; 8755895Syz147064 datalink_class_t class; 8765895Syz147064 uint_t media; 8775895Syz147064 int i; 8785895Syz147064 8795895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 8805895Syz147064 return (DLADM_STATUS_BADARG); 8815895Syz147064 8828453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 8838453SAnurag.Maskey@Sun.COM NULL, 0); 8845895Syz147064 if (status != DLADM_STATUS_OK) 8855895Syz147064 return (status); 8865895Syz147064 8878460SArtem.Kachitchkin@Sun.COM /* public */ 8885895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 8895895Syz147064 if (!(prop_table[i].pd_class & class)) 8905895Syz147064 continue; 8915895Syz147064 8925895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 8935895Syz147064 continue; 8945895Syz147064 8958453SAnurag.Maskey@Sun.COM if (func(handle, linkid, prop_table[i].pd_name, arg) == 8965895Syz147064 DLADM_WALK_TERMINATE) { 8975895Syz147064 break; 8985895Syz147064 } 8995895Syz147064 } 9005895Syz147064 9018460SArtem.Kachitchkin@Sun.COM /* private */ 9028460SArtem.Kachitchkin@Sun.COM status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 9038460SArtem.Kachitchkin@Sun.COM 9048460SArtem.Kachitchkin@Sun.COM return (status); 9055895Syz147064 } 9063448Sdh155122 9075895Syz147064 /* 9085895Syz147064 * Get linkprop of the given specific link. 9095895Syz147064 */ 9105895Syz147064 dladm_status_t 9118453SAnurag.Maskey@Sun.COM dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9128453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, const char *prop_name, char **prop_val, 9138453SAnurag.Maskey@Sun.COM uint_t *val_cntp) 9145895Syz147064 { 9155895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9165895Syz147064 datalink_class_t class; 9175895Syz147064 uint_t media; 9185895Syz147064 prop_desc_t *pdp; 9196512Ssowmini uint_t cnt, dld_flags = 0; 9205895Syz147064 int i; 9218118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 9225895Syz147064 9236512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 9249514SGirish.Moodalbail@Sun.COM dld_flags |= MAC_PROP_DEFAULT; 9259514SGirish.Moodalbail@Sun.COM else if (type == DLADM_PROP_VAL_MODIFIABLE) 9269514SGirish.Moodalbail@Sun.COM dld_flags |= MAC_PROP_POSSIBLE; 9276512Ssowmini 9285895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 9295895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 9305895Syz147064 return (DLADM_STATUS_BADARG); 9315895Syz147064 9325895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 9335895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 9345895Syz147064 break; 9355895Syz147064 9365903Ssowmini if (i == DLADM_MAX_PROPS) { 9375903Ssowmini if (prop_name[0] == '_') { 9385903Ssowmini /* 9395903Ssowmini * private property. 9405903Ssowmini */ 9418460SArtem.Kachitchkin@Sun.COM if (type == DLADM_PROP_VAL_PERSISTENT) 9428460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_linkprop_db(handle, linkid, 9438460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp)); 9448460SArtem.Kachitchkin@Sun.COM else 9458460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_priv_prop(handle, linkid, 9468460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp, type, 9478460SArtem.Kachitchkin@Sun.COM dld_flags)); 9485903Ssowmini } else { 9495903Ssowmini return (DLADM_STATUS_NOTFOUND); 9505903Ssowmini } 9515903Ssowmini } 9525895Syz147064 9535895Syz147064 pdp = &prop_table[i]; 9545895Syz147064 9558453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9568453SAnurag.Maskey@Sun.COM NULL, 0); 9575895Syz147064 if (status != DLADM_STATUS_OK) 9585895Syz147064 return (status); 9595895Syz147064 9605895Syz147064 if (!(pdp->pd_class & class)) 9615895Syz147064 return (DLADM_STATUS_BADARG); 9625895Syz147064 9635895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 9643147Sxc151355 return (DLADM_STATUS_BADARG); 9653147Sxc151355 9665895Syz147064 switch (type) { 9675895Syz147064 case DLADM_PROP_VAL_CURRENT: 9688453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 9698453SAnurag.Maskey@Sun.COM media, dld_flags, &perm_flags); 9708118SVasumathi.Sundaram@Sun.COM break; 9718118SVasumathi.Sundaram@Sun.COM 9728118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 9738118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 9748118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 9758118SVasumathi.Sundaram@Sun.COM } else { 9768453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 9778453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 9788118SVasumathi.Sundaram@Sun.COM } 9798118SVasumathi.Sundaram@Sun.COM 9808118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 9819055SMichael.Lim@Sun.COM *val_cntp = 1; 9828275SEric Cheng if (status == DLADM_STATUS_OK) 9838275SEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 9845895Syz147064 break; 9855895Syz147064 9865895Syz147064 case DLADM_PROP_VAL_DEFAULT: 9876768Sar224390 /* 9886768Sar224390 * If defaults are not defined for the property, 9896768Sar224390 * pd_defval.vd_name should be null. If the driver 9906768Sar224390 * has to be contacted for the value, vd_name should 9916768Sar224390 * be the empty string (""). Otherwise, dladm will 9926768Sar224390 * just print whatever is in the table. 9936768Sar224390 */ 9945895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 9955895Syz147064 status = DLADM_STATUS_NOTSUP; 9965895Syz147064 break; 9975895Syz147064 } 9986512Ssowmini 9996512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 10008453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 10018453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10026512Ssowmini } else { 10036512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 10046512Ssowmini } 10055895Syz147064 *val_cntp = 1; 10065895Syz147064 break; 10073448Sdh155122 10085895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 10095895Syz147064 if (pdp->pd_getmod != NULL) { 10108453SAnurag.Maskey@Sun.COM status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 10118118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10125895Syz147064 break; 10135895Syz147064 } 10145895Syz147064 cnt = pdp->pd_noptval; 10155895Syz147064 if (cnt == 0) { 10165895Syz147064 status = DLADM_STATUS_NOTSUP; 10175895Syz147064 } else if (cnt > *val_cntp) { 10185895Syz147064 status = DLADM_STATUS_TOOSMALL; 10195895Syz147064 } else { 10205895Syz147064 for (i = 0; i < cnt; i++) { 10215895Syz147064 (void) strcpy(prop_val[i], 10225895Syz147064 pdp->pd_optval[i].vd_name); 10235895Syz147064 } 10245895Syz147064 *val_cntp = cnt; 10255895Syz147064 } 10265895Syz147064 break; 10275895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 10285895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 10295895Syz147064 return (DLADM_STATUS_TEMPONLY); 10308453SAnurag.Maskey@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 10315895Syz147064 prop_val, val_cntp); 10325895Syz147064 break; 10335895Syz147064 default: 10345895Syz147064 status = DLADM_STATUS_BADARG; 10355895Syz147064 break; 10363147Sxc151355 } 10373448Sdh155122 10385895Syz147064 return (status); 10395895Syz147064 } 10405895Syz147064 1041*10491SRishi.Srivatsavai@Sun.COM /* 1042*10491SRishi.Srivatsavai@Sun.COM * Get linkprop of the given specific link and run any possible conversion 1043*10491SRishi.Srivatsavai@Sun.COM * of the values using the check function for the property. Fails if the 1044*10491SRishi.Srivatsavai@Sun.COM * check function doesn't succeed for the property value. 1045*10491SRishi.Srivatsavai@Sun.COM */ 1046*10491SRishi.Srivatsavai@Sun.COM dladm_status_t 1047*10491SRishi.Srivatsavai@Sun.COM dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 1048*10491SRishi.Srivatsavai@Sun.COM dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 1049*10491SRishi.Srivatsavai@Sun.COM uint_t *val_cntp) 1050*10491SRishi.Srivatsavai@Sun.COM { 1051*10491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 1052*10491SRishi.Srivatsavai@Sun.COM datalink_class_t class; 1053*10491SRishi.Srivatsavai@Sun.COM uint_t media; 1054*10491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp; 1055*10491SRishi.Srivatsavai@Sun.COM uint_t dld_flags; 1056*10491SRishi.Srivatsavai@Sun.COM int valc, i; 1057*10491SRishi.Srivatsavai@Sun.COM char **prop_val; 1058*10491SRishi.Srivatsavai@Sun.COM uint_t perm_flags; 1059*10491SRishi.Srivatsavai@Sun.COM 1060*10491SRishi.Srivatsavai@Sun.COM if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 1061*10491SRishi.Srivatsavai@Sun.COM ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 1062*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 1063*10491SRishi.Srivatsavai@Sun.COM 1064*10491SRishi.Srivatsavai@Sun.COM for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 1065*10491SRishi.Srivatsavai@Sun.COM if (strcasecmp(prop_name, pdp->pd_name) == 0) 1066*10491SRishi.Srivatsavai@Sun.COM break; 1067*10491SRishi.Srivatsavai@Sun.COM 1068*10491SRishi.Srivatsavai@Sun.COM if (pdp == prop_table + DLADM_MAX_PROPS) 1069*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTFOUND); 1070*10491SRishi.Srivatsavai@Sun.COM 1071*10491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_CHECK_ALLOC) 1072*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 1073*10491SRishi.Srivatsavai@Sun.COM 1074*10491SRishi.Srivatsavai@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 1075*10491SRishi.Srivatsavai@Sun.COM NULL, 0); 1076*10491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 1077*10491SRishi.Srivatsavai@Sun.COM return (status); 1078*10491SRishi.Srivatsavai@Sun.COM 1079*10491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_class & class)) 1080*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 1081*10491SRishi.Srivatsavai@Sun.COM 1082*10491SRishi.Srivatsavai@Sun.COM if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 1083*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 1084*10491SRishi.Srivatsavai@Sun.COM 1085*10491SRishi.Srivatsavai@Sun.COM prop_val = malloc(*val_cntp * sizeof (*prop_val) + 1086*10491SRishi.Srivatsavai@Sun.COM *val_cntp * DLADM_PROP_VAL_MAX); 1087*10491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) 1088*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOMEM); 1089*10491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 1090*10491SRishi.Srivatsavai@Sun.COM prop_val[valc] = (char *)(prop_val + *val_cntp) + 1091*10491SRishi.Srivatsavai@Sun.COM valc * DLADM_PROP_VAL_MAX; 1092*10491SRishi.Srivatsavai@Sun.COM 1093*10491SRishi.Srivatsavai@Sun.COM dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? MAC_PROP_DEFAULT : 0; 1094*10491SRishi.Srivatsavai@Sun.COM 1095*10491SRishi.Srivatsavai@Sun.COM switch (type) { 1096*10491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_CURRENT: 1097*10491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 1098*10491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 1099*10491SRishi.Srivatsavai@Sun.COM break; 1100*10491SRishi.Srivatsavai@Sun.COM 1101*10491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_DEFAULT: 1102*10491SRishi.Srivatsavai@Sun.COM /* 1103*10491SRishi.Srivatsavai@Sun.COM * If defaults are not defined for the property, 1104*10491SRishi.Srivatsavai@Sun.COM * pd_defval.vd_name should be null. If the driver 1105*10491SRishi.Srivatsavai@Sun.COM * has to be contacted for the value, vd_name should 1106*10491SRishi.Srivatsavai@Sun.COM * be the empty string (""). Otherwise, dladm will 1107*10491SRishi.Srivatsavai@Sun.COM * just print whatever is in the table. 1108*10491SRishi.Srivatsavai@Sun.COM */ 1109*10491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name == NULL) { 1110*10491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOTSUP; 1111*10491SRishi.Srivatsavai@Sun.COM break; 1112*10491SRishi.Srivatsavai@Sun.COM } 1113*10491SRishi.Srivatsavai@Sun.COM 1114*10491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name[0] != '\0') { 1115*10491SRishi.Srivatsavai@Sun.COM *val_cntp = 1; 1116*10491SRishi.Srivatsavai@Sun.COM *ret_val = pdp->pd_defval.vd_val; 1117*10491SRishi.Srivatsavai@Sun.COM free(prop_val); 1118*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 1119*10491SRishi.Srivatsavai@Sun.COM } 1120*10491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 1121*10491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 1122*10491SRishi.Srivatsavai@Sun.COM break; 1123*10491SRishi.Srivatsavai@Sun.COM 1124*10491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_PERSISTENT: 1125*10491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_TEMPONLY) 1126*10491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_TEMPONLY; 1127*10491SRishi.Srivatsavai@Sun.COM else 1128*10491SRishi.Srivatsavai@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, 1129*10491SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cntp); 1130*10491SRishi.Srivatsavai@Sun.COM break; 1131*10491SRishi.Srivatsavai@Sun.COM 1132*10491SRishi.Srivatsavai@Sun.COM default: 1133*10491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_BADARG; 1134*10491SRishi.Srivatsavai@Sun.COM break; 1135*10491SRishi.Srivatsavai@Sun.COM } 1136*10491SRishi.Srivatsavai@Sun.COM 1137*10491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 1138*10491SRishi.Srivatsavai@Sun.COM if (pdp->pd_check != NULL) { 1139*10491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp; 1140*10491SRishi.Srivatsavai@Sun.COM 1141*10491SRishi.Srivatsavai@Sun.COM vdp = malloc(sizeof (val_desc_t) * *val_cntp); 1142*10491SRishi.Srivatsavai@Sun.COM if (vdp == NULL) 1143*10491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOMEM; 1144*10491SRishi.Srivatsavai@Sun.COM else 1145*10491SRishi.Srivatsavai@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 1146*10491SRishi.Srivatsavai@Sun.COM prop_val, *val_cntp, vdp, media); 1147*10491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 1148*10491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 1149*10491SRishi.Srivatsavai@Sun.COM ret_val[valc] = vdp[valc].vd_val; 1150*10491SRishi.Srivatsavai@Sun.COM } 1151*10491SRishi.Srivatsavai@Sun.COM free(vdp); 1152*10491SRishi.Srivatsavai@Sun.COM } else { 1153*10491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) { 1154*10491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pdp->pd_noptval; i++) { 1155*10491SRishi.Srivatsavai@Sun.COM if (strcmp(pdp->pd_optval[i].vd_name, 1156*10491SRishi.Srivatsavai@Sun.COM prop_val[valc]) == 0) { 1157*10491SRishi.Srivatsavai@Sun.COM ret_val[valc] = 1158*10491SRishi.Srivatsavai@Sun.COM pdp->pd_optval[i].vd_val; 1159*10491SRishi.Srivatsavai@Sun.COM break; 1160*10491SRishi.Srivatsavai@Sun.COM } 1161*10491SRishi.Srivatsavai@Sun.COM } 1162*10491SRishi.Srivatsavai@Sun.COM if (i == pdp->pd_noptval) { 1163*10491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_FAILED; 1164*10491SRishi.Srivatsavai@Sun.COM break; 1165*10491SRishi.Srivatsavai@Sun.COM } 1166*10491SRishi.Srivatsavai@Sun.COM } 1167*10491SRishi.Srivatsavai@Sun.COM } 1168*10491SRishi.Srivatsavai@Sun.COM } 1169*10491SRishi.Srivatsavai@Sun.COM 1170*10491SRishi.Srivatsavai@Sun.COM free(prop_val); 1171*10491SRishi.Srivatsavai@Sun.COM 1172*10491SRishi.Srivatsavai@Sun.COM return (status); 1173*10491SRishi.Srivatsavai@Sun.COM } 1174*10491SRishi.Srivatsavai@Sun.COM 11755895Syz147064 /*ARGSUSED*/ 11765895Syz147064 static int 11778453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 11788453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 11795895Syz147064 { 11805895Syz147064 char *buf, **propvals; 11815895Syz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 11825895Syz147064 11835895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 11845895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 11855895Syz147064 return (DLADM_WALK_CONTINUE); 11865895Syz147064 } 11875895Syz147064 11885895Syz147064 propvals = (char **)(void *)buf; 11895895Syz147064 for (i = 0; i < valcnt; i++) { 11905895Syz147064 propvals[i] = buf + 11915895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 11925895Syz147064 i * DLADM_PROP_VAL_MAX; 11935895Syz147064 } 11945895Syz147064 11958453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 11968453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 11975895Syz147064 goto done; 11985895Syz147064 } 11995895Syz147064 12008453SAnurag.Maskey@Sun.COM (void) dladm_set_linkprop(handle, linkid, prop_name, propvals, valcnt, 12015895Syz147064 DLADM_OPT_ACTIVE); 12025895Syz147064 12035895Syz147064 done: 12045895Syz147064 if (buf != NULL) 12055895Syz147064 free(buf); 12065895Syz147064 12075895Syz147064 return (DLADM_WALK_CONTINUE); 12085895Syz147064 } 12095895Syz147064 12105895Syz147064 /*ARGSUSED*/ 12115895Syz147064 static int 12128453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 12135895Syz147064 { 12148275SEric Cheng datalink_class_t class; 12158275SEric Cheng dladm_status_t status; 12168275SEric Cheng 12178453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 12188453SAnurag.Maskey@Sun.COM NULL, 0); 12198275SEric Cheng if (status != DLADM_STATUS_OK) 12208275SEric Cheng return (DLADM_WALK_TERMINATE); 12218275SEric Cheng 12228275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 12238453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 12248275SEric Cheng 12255895Syz147064 return (DLADM_WALK_CONTINUE); 12265895Syz147064 } 12275895Syz147064 12285895Syz147064 dladm_status_t 12298453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 12308453SAnurag.Maskey@Sun.COM boolean_t any_media) 12315895Syz147064 { 12326916Sartem datalink_media_t dmedia; 12336916Sartem uint32_t media; 12346916Sartem 12356916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 12366916Sartem 12375895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 12388453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 12398453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 12408453SAnurag.Maskey@Sun.COM } else if (any_media || 12418453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 12428453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 12436916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 12448453SAnurag.Maskey@Sun.COM (void) dladm_walk_linkprop(handle, linkid, NULL, 12458453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 12463448Sdh155122 } 12473448Sdh155122 return (DLADM_STATUS_OK); 12483147Sxc151355 } 12493147Sxc151355 12505903Ssowmini /* ARGSUSED */ 12515895Syz147064 static dladm_status_t 12528453SAnurag.Maskey@Sun.COM do_get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 12538275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 12548275SEric Cheng uint_t flags, uint_t *perm_flags) 12553147Sxc151355 { 12568275SEric Cheng char zone_name[ZONENAME_MAX]; 12578275SEric Cheng zoneid_t zid; 12588275SEric Cheng dladm_status_t status; 12598275SEric Cheng char *cp; 12607342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 12613147Sxc151355 12626512Ssowmini if (flags != 0) 12636512Ssowmini return (DLADM_STATUS_NOTSUP); 12646512Ssowmini 12658453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 12668275SEric Cheng &status, perm_flags); 12675895Syz147064 if (status != DLADM_STATUS_OK) 12683448Sdh155122 return (status); 12693448Sdh155122 12707342SAruna.Ramakrishna@Sun.COM cp = dip->pr_val; 12717342SAruna.Ramakrishna@Sun.COM (void) memcpy(&zid, cp, sizeof (zid)); 12727342SAruna.Ramakrishna@Sun.COM free(dip); 12737342SAruna.Ramakrishna@Sun.COM 12745895Syz147064 *val_cnt = 1; 12755895Syz147064 if (zid != GLOBAL_ZONEID) { 12768118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 12775895Syz147064 return (dladm_errno2status(errno)); 12788118SVasumathi.Sundaram@Sun.COM } 12793147Sxc151355 12805895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 12813147Sxc151355 } else { 12825895Syz147064 *prop_val[0] = '\0'; 12833147Sxc151355 } 12843147Sxc151355 12853448Sdh155122 return (DLADM_STATUS_OK); 12863448Sdh155122 } 12873448Sdh155122 12883448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 12893448Sdh155122 12903448Sdh155122 static int 12913448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 12923448Sdh155122 { 12933448Sdh155122 char root[MAXPATHLEN]; 12943448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 12953448Sdh155122 void *dlhandle; 12963448Sdh155122 void *sym; 12973448Sdh155122 int ret; 12983448Sdh155122 12993448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 13003448Sdh155122 return (-1); 13013448Sdh155122 13023448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 13033448Sdh155122 (void) dlclose(dlhandle); 13043448Sdh155122 return (-1); 13053448Sdh155122 } 13063448Sdh155122 13073448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 13083448Sdh155122 13093448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 13103448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 13113448Sdh155122 (void) dlclose(dlhandle); 13123448Sdh155122 return (ret); 13133448Sdh155122 } 13143448Sdh155122 13153448Sdh155122 static dladm_status_t 13168453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 13178453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 13183448Sdh155122 { 13193448Sdh155122 char path[MAXPATHLEN]; 13205895Syz147064 char name[MAXLINKNAMELEN]; 13213448Sdh155122 di_prof_t prof = NULL; 13223448Sdh155122 char zone_name[ZONENAME_MAX]; 13233448Sdh155122 dladm_status_t status; 13245895Syz147064 int ret; 13253448Sdh155122 13263448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 13273448Sdh155122 return (dladm_errno2status(errno)); 13283448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 13293448Sdh155122 return (dladm_errno2status(errno)); 13303448Sdh155122 if (di_prof_init(path, &prof) != 0) 13313448Sdh155122 return (dladm_errno2status(errno)); 13323448Sdh155122 13338453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 13345895Syz147064 if (status != DLADM_STATUS_OK) 13355895Syz147064 goto cleanup; 13365895Syz147064 13375895Syz147064 if (add) 13385895Syz147064 ret = di_prof_add_dev(prof, name); 13395895Syz147064 else 13405895Syz147064 ret = di_prof_add_exclude(prof, name); 13415895Syz147064 13425895Syz147064 if (ret != 0) { 13433448Sdh155122 status = dladm_errno2status(errno); 13443448Sdh155122 goto cleanup; 13453448Sdh155122 } 13463448Sdh155122 13473448Sdh155122 if (di_prof_commit(prof) != 0) 13483448Sdh155122 status = dladm_errno2status(errno); 13493448Sdh155122 cleanup: 13503448Sdh155122 if (prof) 13513448Sdh155122 di_prof_fini(prof); 13523448Sdh155122 13533448Sdh155122 return (status); 13543448Sdh155122 } 13553448Sdh155122 13565903Ssowmini /* ARGSUSED */ 13573448Sdh155122 static dladm_status_t 13588453SAnurag.Maskey@Sun.COM do_set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13598453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 13603448Sdh155122 { 13618275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 13628275SEric Cheng zoneid_t zid_old, zid_new; 13638275SEric Cheng char link[MAXLINKNAMELEN]; 13648275SEric Cheng char *cp; 13657342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 13667342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 13673448Sdh155122 13683448Sdh155122 if (val_cnt != 1) 13693448Sdh155122 return (DLADM_STATUS_BADVALCNT); 13703448Sdh155122 13717342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 13727342SAruna.Ramakrishna@Sun.COM 13738453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 13748275SEric Cheng &status, NULL); 13758275SEric Cheng if (status != DLADM_STATUS_OK) 13768275SEric Cheng return (status); 13778275SEric Cheng 13788275SEric Cheng cp = dip->pr_val; 13798275SEric Cheng (void) memcpy(&zid_old, cp, sizeof (zid_old)); 13808275SEric Cheng free(dip); 13817342SAruna.Ramakrishna@Sun.COM 13827342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 13837342SAruna.Ramakrishna@Sun.COM (void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN); 13843448Sdh155122 13853448Sdh155122 /* Do nothing if setting to current value */ 13863448Sdh155122 if (zid_new == zid_old) 13875895Syz147064 return (status); 13885895Syz147064 13895895Syz147064 if (zid_new != GLOBAL_ZONEID) { 13905895Syz147064 /* 13915895Syz147064 * If the new zoneid is the global zone, we could destroy 13925895Syz147064 * the link (in the case of an implicitly-created VLAN) as a 13937342SAruna.Ramakrishna@Sun.COM * result of setting the zoneid. In that case, we defer the 13947342SAruna.Ramakrishna@Sun.COM * operation to the end of this function to avoid recreating 13957342SAruna.Ramakrishna@Sun.COM * the VLAN and getting a different linkid during the rollback 13967342SAruna.Ramakrishna@Sun.COM * if other operation fails. 13975895Syz147064 * 13987342SAruna.Ramakrishna@Sun.COM * Otherwise, this operation will hold a reference to the 13995895Syz147064 * link and prevent a link renaming, so we need to do it 14005895Syz147064 * before other operations. 14015895Syz147064 */ 14028453SAnurag.Maskey@Sun.COM status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, 14038453SAnurag.Maskey@Sun.COM val_cnt, flags, media); 14045895Syz147064 if (status != DLADM_STATUS_OK) 14055895Syz147064 return (status); 14065895Syz147064 } 14075895Syz147064 14083448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 14095895Syz147064 if (zone_remove_datalink(zid_old, link) != 0 && 14103448Sdh155122 errno != ENXIO) { 14113448Sdh155122 status = dladm_errno2status(errno); 14123448Sdh155122 goto rollback1; 14133448Sdh155122 } 14143448Sdh155122 14155895Syz147064 /* 14165895Syz147064 * It is okay to fail to update the /dev entry (some 14175895Syz147064 * vanity-named links do not have a /dev entry). 14185895Syz147064 */ 14198453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 14208453SAnurag.Maskey@Sun.COM B_FALSE); 14215895Syz147064 } 14225895Syz147064 14235895Syz147064 if (zid_new != GLOBAL_ZONEID) { 14245895Syz147064 if (zone_add_datalink(zid_new, link) != 0) { 14255895Syz147064 status = dladm_errno2status(errno); 14265895Syz147064 goto rollback2; 14275895Syz147064 } 14285895Syz147064 14298453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 14305895Syz147064 } else { 14318453SAnurag.Maskey@Sun.COM status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, 14328453SAnurag.Maskey@Sun.COM val_cnt, flags, media); 14333448Sdh155122 if (status != DLADM_STATUS_OK) 14343448Sdh155122 goto rollback2; 14353448Sdh155122 } 14363448Sdh155122 14373448Sdh155122 return (DLADM_STATUS_OK); 14383448Sdh155122 14393448Sdh155122 rollback2: 14403448Sdh155122 if (zid_old != GLOBAL_ZONEID) 14418453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, B_TRUE); 14425895Syz147064 if (zid_old != GLOBAL_ZONEID) 14435895Syz147064 (void) zone_add_datalink(zid_old, link); 14443448Sdh155122 rollback1: 14457342SAruna.Ramakrishna@Sun.COM if (zid_new != GLOBAL_ZONEID) { 14467342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zid_old; 14478453SAnurag.Maskey@Sun.COM (void) i_dladm_set_public_prop(handle, pdp, linkid, vdp, 14488453SAnurag.Maskey@Sun.COM val_cnt, flags, media); 14497342SAruna.Ramakrishna@Sun.COM } 14507342SAruna.Ramakrishna@Sun.COM 14513448Sdh155122 return (status); 14523448Sdh155122 } 14533448Sdh155122 14543448Sdh155122 /* ARGSUSED */ 14553448Sdh155122 static dladm_status_t 14568453SAnurag.Maskey@Sun.COM do_check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14578453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 14583448Sdh155122 { 14597342SAruna.Ramakrishna@Sun.COM char *zone_name; 14607342SAruna.Ramakrishna@Sun.COM char linkname[MAXLINKNAMELEN]; 14617342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 14627342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 14637342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14643448Sdh155122 14653448Sdh155122 if (val_cnt != 1) 14663448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14673448Sdh155122 14687342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 14697342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 14707342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 14713448Sdh155122 14728453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL, 14738275SEric Cheng linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 14748275SEric Cheng goto done; 14757342SAruna.Ramakrishna@Sun.COM } 14767342SAruna.Ramakrishna@Sun.COM 14778275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 14787342SAruna.Ramakrishna@Sun.COM if (strlen(linkname) > MAXLINKNAMELEN) { 14797342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14807342SAruna.Ramakrishna@Sun.COM goto done; 14817342SAruna.Ramakrishna@Sun.COM } 14827342SAruna.Ramakrishna@Sun.COM 14837342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 14847342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14857342SAruna.Ramakrishna@Sun.COM goto done; 14867342SAruna.Ramakrishna@Sun.COM } 14877342SAruna.Ramakrishna@Sun.COM 14887342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 14893448Sdh155122 ushort_t flags; 14903448Sdh155122 14917342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 14923448Sdh155122 sizeof (flags)) < 0) { 14937342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 14947342SAruna.Ramakrishna@Sun.COM goto done; 14953448Sdh155122 } 14963448Sdh155122 14973448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 14987342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14997342SAruna.Ramakrishna@Sun.COM goto done; 15003448Sdh155122 } 15013448Sdh155122 } 15023448Sdh155122 15037342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15047342SAruna.Ramakrishna@Sun.COM 15057342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 15067342SAruna.Ramakrishna@Sun.COM (void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN); 15077342SAruna.Ramakrishna@Sun.COM 15087342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 15095895Syz147064 return (DLADM_STATUS_OK); 15107342SAruna.Ramakrishna@Sun.COM done: 15117342SAruna.Ramakrishna@Sun.COM free(dzp); 15127342SAruna.Ramakrishna@Sun.COM return (status); 15135895Syz147064 } 15145895Syz147064 15155903Ssowmini /* ARGSUSED */ 15165895Syz147064 static dladm_status_t 15178460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15188275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15198275SEric Cheng uint_t flags, uint_t *perm_flags) 15208275SEric Cheng { 15218275SEric Cheng dld_ioc_macprop_t *dip; 15228275SEric Cheng mac_resource_props_t mrp; 15238275SEric Cheng dladm_status_t status; 15248275SEric Cheng 15258453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15268275SEric Cheng &status, perm_flags); 15278275SEric Cheng if (dip == NULL) 15288275SEric Cheng return (status); 15298275SEric Cheng 15308275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 15318275SEric Cheng free(dip); 15328275SEric Cheng 15338275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 15348275SEric Cheng (*prop_val)[0] = '\0'; 15358275SEric Cheng } else { 15368275SEric Cheng (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 15378275SEric Cheng } 15388275SEric Cheng *val_cnt = 1; 15398275SEric Cheng return (DLADM_STATUS_OK); 15408275SEric Cheng } 15418275SEric Cheng 15428275SEric Cheng /* ARGSUSED */ 15438275SEric Cheng static dladm_status_t 15448453SAnurag.Maskey@Sun.COM do_check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15458453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 15468275SEric Cheng { 15478275SEric Cheng uint64_t *maxbw; 15488275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 15498275SEric Cheng 15508275SEric Cheng if (val_cnt != 1) 15518275SEric Cheng return (DLADM_STATUS_BADVALCNT); 15528275SEric Cheng 15538275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 15548275SEric Cheng if (maxbw == NULL) 15558275SEric Cheng return (DLADM_STATUS_NOMEM); 15568275SEric Cheng 15578275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 15588275SEric Cheng if (status != DLADM_STATUS_OK) { 15598275SEric Cheng free(maxbw); 15608275SEric Cheng return (status); 15618275SEric Cheng } 15628275SEric Cheng 15638275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 15648275SEric Cheng free(maxbw); 15658275SEric Cheng return (DLADM_STATUS_MINMAXBW); 15668275SEric Cheng } 15678275SEric Cheng 15688275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 15698275SEric Cheng return (DLADM_STATUS_OK); 15708275SEric Cheng } 15718275SEric Cheng 15728275SEric Cheng /* ARGSUSED */ 15738275SEric Cheng dladm_status_t 15748275SEric Cheng do_extract_maxbw(val_desc_t *vdp, void *arg, uint_t cnt) 15758275SEric Cheng { 15768275SEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 15778275SEric Cheng 15788275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 15798275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 15808275SEric Cheng 15818275SEric Cheng return (DLADM_STATUS_OK); 15828275SEric Cheng } 15838275SEric Cheng 15848275SEric Cheng /* ARGSUSED */ 15858275SEric Cheng static dladm_status_t 15868460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15878275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15888275SEric Cheng uint_t flags, uint_t *perm_flags) 15898275SEric Cheng { 15908275SEric Cheng dld_ioc_macprop_t *dip; 15918275SEric Cheng mac_resource_props_t mrp; 15928275SEric Cheng int i; 15938275SEric Cheng uint32_t ncpus; 15948275SEric Cheng uchar_t *cp; 15958275SEric Cheng dladm_status_t status; 15968275SEric Cheng 15978453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15988275SEric Cheng &status, perm_flags); 15998275SEric Cheng if (dip == NULL) 16008275SEric Cheng return (status); 16018275SEric Cheng 16028275SEric Cheng cp = (uchar_t *)dip->pr_val; 16038275SEric Cheng (void) memcpy(&mrp, cp, sizeof (mac_resource_props_t)); 16048275SEric Cheng free(dip); 16058275SEric Cheng 16068275SEric Cheng ncpus = mrp.mrp_ncpus; 16078275SEric Cheng 16088275SEric Cheng if (ncpus > *val_cnt) 16098275SEric Cheng return (DLADM_STATUS_TOOSMALL); 16108275SEric Cheng 16118275SEric Cheng if (ncpus == 0) { 16128275SEric Cheng (*prop_val)[0] = '\0'; 16138275SEric Cheng *val_cnt = 1; 16148275SEric Cheng return (DLADM_STATUS_OK); 16158275SEric Cheng } 16168275SEric Cheng 16178275SEric Cheng *val_cnt = ncpus; 16188275SEric Cheng for (i = 0; i < ncpus; i++) { 16198275SEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 16208275SEric Cheng "%u", mrp.mrp_cpu[i]); 16218275SEric Cheng } 16228275SEric Cheng return (DLADM_STATUS_OK); 16238275SEric Cheng } 16248275SEric Cheng 16258275SEric Cheng /* ARGSUSED */ 16268275SEric Cheng static dladm_status_t 16278453SAnurag.Maskey@Sun.COM do_set_res(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16288453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16298275SEric Cheng { 16308275SEric Cheng mac_resource_props_t mrp; 16318275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 16328275SEric Cheng dld_ioc_macprop_t *dip; 16338275SEric Cheng 16348275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 16358275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 16368275SEric Cheng flags, &status); 16378275SEric Cheng 16388275SEric Cheng if (dip == NULL) 16398275SEric Cheng return (status); 16408275SEric Cheng 16418275SEric Cheng if (vdp->vd_val == RESET_VAL) { 16428275SEric Cheng switch (dip->pr_num) { 16438275SEric Cheng case MAC_PROP_MAXBW: 16448275SEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 16458275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16468275SEric Cheng break; 16478275SEric Cheng case MAC_PROP_PRIO: 16488275SEric Cheng mrp.mrp_priority = MPL_RESET; 16498275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16508275SEric Cheng break; 16518275SEric Cheng default: 16528275SEric Cheng free(dip); 16538275SEric Cheng return (DLADM_STATUS_BADARG); 16548275SEric Cheng } 16558275SEric Cheng } else { 16568275SEric Cheng switch (dip->pr_num) { 16578275SEric Cheng case MAC_PROP_MAXBW: 16588275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_maxbw, 16598275SEric Cheng sizeof (uint64_t)); 16608275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16618275SEric Cheng break; 16628275SEric Cheng case MAC_PROP_PRIO: 16638275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_priority, 16648275SEric Cheng sizeof (mac_priority_level_t)); 16658275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16668275SEric Cheng break; 16678275SEric Cheng default: 16688275SEric Cheng free(dip); 16698275SEric Cheng return (DLADM_STATUS_BADARG); 16708275SEric Cheng } 16718275SEric Cheng } 16728275SEric Cheng 16738275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 16748453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 16758275SEric Cheng free(dip); 16768275SEric Cheng return (status); 16778275SEric Cheng } 16788275SEric Cheng 16798275SEric Cheng /* ARGSUSED */ 16808275SEric Cheng static dladm_status_t 16818453SAnurag.Maskey@Sun.COM do_set_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16828453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16838275SEric Cheng { 16848275SEric Cheng mac_resource_props_t mrp; 16858275SEric Cheng dladm_status_t status; 16868275SEric Cheng dld_ioc_macprop_t *dip; 16878275SEric Cheng datalink_class_t class; 16888275SEric Cheng 16898275SEric Cheng /* 16908275SEric Cheng * CPU bindings can be set on VNIC and regular physical links. 16918275SEric Cheng * However VNICs fails the dladm_phys_info test(). So apply 16928275SEric Cheng * the phys_info test only on physical links. 16938275SEric Cheng */ 16948453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, 16958275SEric Cheng NULL, NULL, 0)) != DLADM_STATUS_OK) { 16968275SEric Cheng return (status); 16978275SEric Cheng } 16988275SEric Cheng 16998275SEric Cheng /* 17008275SEric Cheng * We set intr_cpu to -1. The interrupt will be retargetted, 17018275SEric Cheng * if possible when the setup is complete in MAC. 17028275SEric Cheng */ 17038275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 17048275SEric Cheng mrp.mrp_mask = MRP_CPUS; 17058275SEric Cheng if (vdp != NULL && vdp->vd_val != RESET_VAL) { 17068275SEric Cheng mac_resource_props_t *vmrp; 17078275SEric Cheng 17088275SEric Cheng vmrp = (mac_resource_props_t *)vdp->vd_val; 17098275SEric Cheng if (vmrp->mrp_ncpus > 0) { 17108275SEric Cheng bcopy(vmrp, &mrp, sizeof (mac_resource_props_t)); 17118275SEric Cheng mrp.mrp_mask = MRP_CPUS; 17128275SEric Cheng } 17138275SEric Cheng mrp.mrp_mask |= MRP_CPUS_USERSPEC; 17148275SEric Cheng mrp.mrp_fanout_mode = MCM_CPUS; 17158275SEric Cheng mrp.mrp_intr_cpu = -1; 17168275SEric Cheng } 17178275SEric Cheng 17188275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 17198275SEric Cheng flags, &status); 17208275SEric Cheng if (dip == NULL) 17218275SEric Cheng return (status); 17228275SEric Cheng 17238275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 17248453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 17258275SEric Cheng free(dip); 17268275SEric Cheng return (status); 17278275SEric Cheng } 17288275SEric Cheng 17298275SEric Cheng /* ARGSUSED */ 17308275SEric Cheng static dladm_status_t 17318453SAnurag.Maskey@Sun.COM do_check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 17328453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 17338275SEric Cheng { 17348275SEric Cheng uint32_t cpuid; 17358275SEric Cheng int i, j, rc; 17368275SEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 17378275SEric Cheng mac_resource_props_t *mrp; 17388275SEric Cheng 17398275SEric Cheng mrp = malloc(sizeof (mac_resource_props_t)); 17408275SEric Cheng if (mrp == NULL) 17418275SEric Cheng return (DLADM_STATUS_NOMEM); 17428275SEric Cheng 17438275SEric Cheng for (i = 0; i < val_cnt; i++) { 17448275SEric Cheng errno = 0; 17458275SEric Cheng cpuid = strtol(prop_val[i], (char **)NULL, 10); 17468275SEric Cheng if (errno != 0 || cpuid >= nproc) { 17478275SEric Cheng free(mrp); 17488275SEric Cheng return (DLADM_STATUS_CPUMAX); 17498275SEric Cheng } 17508275SEric Cheng rc = p_online(cpuid, P_STATUS); 17518275SEric Cheng if (rc < 1) { 17528275SEric Cheng free(mrp); 17538275SEric Cheng return (DLADM_STATUS_CPUERR); 17548275SEric Cheng } 17558275SEric Cheng if (rc != P_ONLINE) { 17568275SEric Cheng free(mrp); 17578275SEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 17588275SEric Cheng } 17598275SEric Cheng mrp->mrp_cpu[i] = cpuid; 17608275SEric Cheng } 17618275SEric Cheng mrp->mrp_ncpus = (uint32_t)val_cnt; 17628275SEric Cheng 17638275SEric Cheng /* Check for duplicates */ 17648275SEric Cheng for (i = 0; i < val_cnt; i++) { 17658275SEric Cheng for (j = 0; j < val_cnt; j++) { 17668275SEric Cheng if (i != j && mrp->mrp_cpu[i] == mrp->mrp_cpu[j]) { 17678275SEric Cheng free(mrp); 17688275SEric Cheng return (DLADM_STATUS_BADARG); 17698275SEric Cheng } 17708275SEric Cheng } 17718275SEric Cheng } 17728275SEric Cheng vdp->vd_val = (uintptr_t)mrp; 17738275SEric Cheng 17748275SEric Cheng return (DLADM_STATUS_OK); 17758275SEric Cheng } 17768275SEric Cheng 17778275SEric Cheng /* ARGSUSED */ 17788275SEric Cheng dladm_status_t 17798275SEric Cheng do_extract_cpus(val_desc_t *vdp, void *arg, uint_t cnt) 17808275SEric Cheng { 17818275SEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 17828275SEric Cheng mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; 17838275SEric Cheng int i; 17848275SEric Cheng 17858275SEric Cheng for (i = 0; i < vmrp->mrp_ncpus; i++) { 17868275SEric Cheng mrp->mrp_cpu[i] = vmrp->mrp_cpu[i]; 17878275SEric Cheng } 17888275SEric Cheng mrp->mrp_ncpus = vmrp->mrp_ncpus; 17898275SEric Cheng mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 17908275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 17919055SMichael.Lim@Sun.COM mrp->mrp_intr_cpu = -1; 17928275SEric Cheng 17938275SEric Cheng return (DLADM_STATUS_OK); 17948275SEric Cheng } 17958275SEric Cheng 17968275SEric Cheng /* ARGSUSED */ 17978275SEric Cheng static dladm_status_t 17988460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get(dladm_handle_t handle, prop_desc_t *pdp, 17998460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 18008460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 18018275SEric Cheng { 18028275SEric Cheng dld_ioc_macprop_t *dip; 18038275SEric Cheng mac_resource_props_t mrp; 18048275SEric Cheng mac_priority_level_t pri; 18058275SEric Cheng dladm_status_t status; 18068275SEric Cheng 18078453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 18088275SEric Cheng &status, perm_flags); 18098275SEric Cheng if (dip == NULL) 18108275SEric Cheng return (status); 18118275SEric Cheng 18128275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 18138275SEric Cheng free(dip); 18148275SEric Cheng 18158275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 18168275SEric Cheng mrp.mrp_priority; 18178275SEric Cheng 18188275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 18198275SEric Cheng *val_cnt = 1; 18208275SEric Cheng return (DLADM_STATUS_OK); 18218275SEric Cheng } 18228275SEric Cheng 18238275SEric Cheng /* ARGSUSED */ 18248275SEric Cheng static dladm_status_t 18258453SAnurag.Maskey@Sun.COM do_check_priority(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18268453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 18278275SEric Cheng { 18288275SEric Cheng mac_priority_level_t *pri; 18298275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 18308275SEric Cheng 18318275SEric Cheng if (val_cnt != 1) 18328275SEric Cheng return (DLADM_STATUS_BADVALCNT); 18338275SEric Cheng 18348275SEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 18358275SEric Cheng if (pri == NULL) 18368275SEric Cheng return (DLADM_STATUS_NOMEM); 18378275SEric Cheng 18388275SEric Cheng status = dladm_str2pri(*prop_val, pri); 18398275SEric Cheng if (status != DLADM_STATUS_OK) { 18408275SEric Cheng free(pri); 18418275SEric Cheng return (status); 18428275SEric Cheng } 18438275SEric Cheng 18448275SEric Cheng if (*pri < MPL_LOW || *pri > MPL_HIGH) { 18458275SEric Cheng free(pri); 18468275SEric Cheng return (DLADM_STATUS_BADVAL); 18478275SEric Cheng } 18488275SEric Cheng 18498275SEric Cheng vdp->vd_val = (uintptr_t)pri; 18508275SEric Cheng return (DLADM_STATUS_OK); 18518275SEric Cheng } 18528275SEric Cheng 18538275SEric Cheng /* ARGSUSED */ 18548275SEric Cheng dladm_status_t 18558275SEric Cheng do_extract_priority(val_desc_t *vdp, void *arg, uint_t cnt) 18568275SEric Cheng { 18578275SEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 18588275SEric Cheng 18598275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_priority, 18608275SEric Cheng sizeof (mac_priority_level_t)); 18618275SEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 18628275SEric Cheng 18638275SEric Cheng return (DLADM_STATUS_OK); 18648275SEric Cheng } 18658275SEric Cheng 18668275SEric Cheng /* ARGSUSED */ 18678275SEric Cheng static dladm_status_t 18688453SAnurag.Maskey@Sun.COM do_get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18698275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 18708275SEric Cheng uint_t flags, uint_t *perm_flags) 18715895Syz147064 { 18727342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 18737342SAruna.Ramakrishna@Sun.COM int i, len; 18747342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 18757342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 18765895Syz147064 18776789Sam223141 if (flags & MAC_PROP_DEFAULT) 18787776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 18796512Ssowmini 18805895Syz147064 *val_cnt = 1; 18818453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 18828275SEric Cheng &status, perm_flags); 18837342SAruna.Ramakrishna@Sun.COM if (dip == NULL) { 18845895Syz147064 (*prop_val)[0] = '\0'; 18858275SEric Cheng return (DLADM_STATUS_OK); 18865895Syz147064 } 18877342SAruna.Ramakrishna@Sun.COM (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 18885895Syz147064 18897342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 18905895Syz147064 if (i != 0) { 18915895Syz147064 (void) snprintf(*prop_val + len, 18925895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 18935895Syz147064 len += 1; 18945895Syz147064 } 18955895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 18967342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 18977342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 18987342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 18995895Syz147064 (void) snprintf(*prop_val + len, 19005895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 19015895Syz147064 AP_ANCHOR); 19025895Syz147064 len += (strlen(AP_ANCHOR) + 1); 19035895Syz147064 } 19045895Syz147064 } 19057342SAruna.Ramakrishna@Sun.COM free(dip); 19065895Syz147064 done: 19075895Syz147064 return (DLADM_STATUS_OK); 19085895Syz147064 } 19095895Syz147064 19105895Syz147064 /* 19115895Syz147064 * Add the specified module to the dlautopush structure; returns a 19125895Syz147064 * DLADM_STATUS_* code. 19135895Syz147064 */ 19145895Syz147064 dladm_status_t 19155895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 19165895Syz147064 { 19175895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 19185895Syz147064 return (DLADM_STATUS_BADVAL); 19195895Syz147064 19205895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 19215895Syz147064 /* 19225895Syz147064 * We don't allow multiple anchors, and the anchor must 19235895Syz147064 * be after at least one module. 19245895Syz147064 */ 19255895Syz147064 if (dlap->dap_anchor != 0) 19265895Syz147064 return (DLADM_STATUS_BADVAL); 19275895Syz147064 if (dlap->dap_npush == 0) 19285895Syz147064 return (DLADM_STATUS_BADVAL); 19295895Syz147064 19305895Syz147064 dlap->dap_anchor = dlap->dap_npush; 19315895Syz147064 return (DLADM_STATUS_OK); 19325895Syz147064 } 19338957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 19345895Syz147064 return (DLADM_STATUS_BADVALCNT); 19355895Syz147064 19365895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 19375895Syz147064 FMNAMESZ + 1); 19385895Syz147064 19395895Syz147064 return (DLADM_STATUS_OK); 19405895Syz147064 } 19415895Syz147064 19425895Syz147064 /* 19435895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 19445895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 19455895Syz147064 * latter is used in the autopush(1M) file. 19465895Syz147064 */ 19475895Syz147064 /* ARGSUSED */ 19485895Syz147064 static dladm_status_t 19498453SAnurag.Maskey@Sun.COM do_check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19508453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 19515895Syz147064 { 19525895Syz147064 char *module; 19535895Syz147064 struct dlautopush *dlap; 19545895Syz147064 dladm_status_t status; 19555895Syz147064 char val[DLADM_PROP_VAL_MAX]; 19565895Syz147064 char delimiters[4]; 19575895Syz147064 19585895Syz147064 if (val_cnt != 1) 19595895Syz147064 return (DLADM_STATUS_BADVALCNT); 19605895Syz147064 19617342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 19627342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 19637342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 19647342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 19653448Sdh155122 19667342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 19677342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 19687342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 19697342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 19707342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 19717342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 19727342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 19737342SAruna.Ramakrishna@Sun.COM return (status); 19747342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 19757342SAruna.Ramakrishna@Sun.COM } 19767342SAruna.Ramakrishna@Sun.COM 19777342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 19787342SAruna.Ramakrishna@Sun.COM } else { 19797342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 19805895Syz147064 } 19813448Sdh155122 return (DLADM_STATUS_OK); 19823448Sdh155122 } 19833448Sdh155122 19847663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 19857663SSowmini.Varadhan@Sun.COM 19865903Ssowmini /* ARGSUSED */ 19873448Sdh155122 static dladm_status_t 19888453SAnurag.Maskey@Sun.COM do_get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 19898453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 19908453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 19913448Sdh155122 { 19925895Syz147064 wl_rates_t *wrp; 19935895Syz147064 uint_t i; 19945895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 19955895Syz147064 19967663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 19977663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 19987663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 19995895Syz147064 20008453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 20018453SAnurag.Maskey@Sun.COM B_FALSE); 20025895Syz147064 if (status != DLADM_STATUS_OK) 20035895Syz147064 goto done; 20045895Syz147064 20055895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 20065895Syz147064 status = DLADM_STATUS_TOOSMALL; 20075895Syz147064 goto done; 20085895Syz147064 } 20095895Syz147064 20105895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 20115895Syz147064 prop_val[0][0] = '\0'; 20125895Syz147064 *val_cnt = 1; 20135895Syz147064 goto done; 20145895Syz147064 } 20155895Syz147064 20165895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 20175895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 20185895Syz147064 wrp->wl_rates_rates[i] % 2, 20195895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 20205895Syz147064 } 20215895Syz147064 *val_cnt = wrp->wl_rates_num; 20228275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 20233448Sdh155122 20245895Syz147064 done: 20257663SSowmini.Varadhan@Sun.COM free(wrp); 20265895Syz147064 return (status); 20275895Syz147064 } 20285895Syz147064 20295895Syz147064 static dladm_status_t 20308453SAnurag.Maskey@Sun.COM do_get_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20318275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 20328275SEric Cheng uint_t flags, uint_t *perm_flags) 20335895Syz147064 { 20348118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 20358453SAnurag.Maskey@Sun.COM return (i_dladm_speed_get(handle, pdp, linkid, prop_val, 20368275SEric Cheng val_cnt, flags, perm_flags)); 20378118SVasumathi.Sundaram@Sun.COM } 20385960Ssowmini 20398453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 20408275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 20415895Syz147064 } 20425895Syz147064 20436512Ssowmini /* ARGSUSED */ 20445895Syz147064 static dladm_status_t 20458453SAnurag.Maskey@Sun.COM do_get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20468275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 20478275SEric Cheng uint_t flags, uint_t *perm_flags) 20485895Syz147064 { 20495960Ssowmini switch (media) { 20505960Ssowmini case DL_ETHER: 20516512Ssowmini /* 20526512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 20536512Ssowmini * links can have a speed of 5.5 Gbps. 20546512Ssowmini */ 20556512Ssowmini return (DLADM_STATUS_NOTSUP); 20565960Ssowmini 20575960Ssowmini case DL_WIFI: 20588453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, 20598453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 20605960Ssowmini default: 20615960Ssowmini return (DLADM_STATUS_BADARG); 20625960Ssowmini } 20635895Syz147064 } 20645895Syz147064 20655895Syz147064 static dladm_status_t 20668453SAnurag.Maskey@Sun.COM do_set_rate(dladm_handle_t handle, datalink_id_t linkid, 20678453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 20685895Syz147064 { 20695895Syz147064 int i; 20705895Syz147064 uint_t len; 20715895Syz147064 wl_rates_t *wrp; 20725895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 20735895Syz147064 20747663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 20757663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 20765895Syz147064 return (DLADM_STATUS_NOMEM); 20775895Syz147064 20787663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 20795895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 20805895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 20815895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 20825895Syz147064 20835895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 20845895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 20858453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 20868453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 20875895Syz147064 20887663SSowmini.Varadhan@Sun.COM free(wrp); 20895895Syz147064 return (status); 20905895Syz147064 } 20913448Sdh155122 20925903Ssowmini /* ARGSUSED */ 20935895Syz147064 static dladm_status_t 20948453SAnurag.Maskey@Sun.COM do_set_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20955960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 20965895Syz147064 { 20975895Syz147064 dladm_wlan_rates_t rates; 20985895Syz147064 dladm_status_t status; 20995895Syz147064 21005960Ssowmini /* 21015960Ssowmini * can currently set rate on WIFI links only. 21025960Ssowmini */ 21035960Ssowmini if (media != DL_WIFI) 21045960Ssowmini return (DLADM_STATUS_PROPRDONLY); 21055960Ssowmini 21065895Syz147064 if (val_cnt != 1) 21075895Syz147064 return (DLADM_STATUS_BADVALCNT); 21085895Syz147064 21095895Syz147064 rates.wr_cnt = 1; 21105895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 21115895Syz147064 21128453SAnurag.Maskey@Sun.COM status = do_set_rate(handle, linkid, &rates); 21135895Syz147064 21145895Syz147064 done: 21155895Syz147064 return (status); 21165895Syz147064 } 21173448Sdh155122 21185895Syz147064 /* ARGSUSED */ 21195895Syz147064 static dladm_status_t 21208453SAnurag.Maskey@Sun.COM do_check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21218453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 21225895Syz147064 { 21235895Syz147064 int i; 21245895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 21255895Syz147064 char *buf, **modval; 21265895Syz147064 dladm_status_t status; 21278118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 21285895Syz147064 21295895Syz147064 if (val_cnt != 1) 21305895Syz147064 return (DLADM_STATUS_BADVALCNT); 21315895Syz147064 21325895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 21335895Syz147064 MAX_SUPPORT_RATES); 21345895Syz147064 if (buf == NULL) { 21355895Syz147064 status = DLADM_STATUS_NOMEM; 21365895Syz147064 goto done; 21375895Syz147064 } 21383448Sdh155122 21395895Syz147064 modval = (char **)(void *)buf; 21405895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 21415895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 21425895Syz147064 i * DLADM_STRSIZE; 21435895Syz147064 } 21445895Syz147064 21458453SAnurag.Maskey@Sun.COM status = do_get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 21468453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 21475895Syz147064 if (status != DLADM_STATUS_OK) 21485895Syz147064 goto done; 21495895Syz147064 21505895Syz147064 for (i = 0; i < modval_cnt; i++) { 21515895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 21525903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 21535903Ssowmini (atof(*prop_val) * 2); 21545895Syz147064 status = DLADM_STATUS_OK; 21553448Sdh155122 break; 21563448Sdh155122 } 21575895Syz147064 } 21585895Syz147064 if (i == modval_cnt) 21595895Syz147064 status = DLADM_STATUS_BADVAL; 21605895Syz147064 done: 21615895Syz147064 free(buf); 21625895Syz147064 return (status); 21635895Syz147064 } 21645895Syz147064 21655895Syz147064 static dladm_status_t 21668453SAnurag.Maskey@Sun.COM do_get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 21678453SAnurag.Maskey@Sun.COM int buflen) 21685895Syz147064 { 21698453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 21707663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 21715895Syz147064 } 21725895Syz147064 21735903Ssowmini /* ARGSUSED */ 21745895Syz147064 static dladm_status_t 21758453SAnurag.Maskey@Sun.COM do_get_channel_prop(dladm_handle_t handle, prop_desc_t *pdp, 21768453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 21778453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 21785895Syz147064 { 21795895Syz147064 uint32_t channel; 21807663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 21815895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 21827663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 21835895Syz147064 21848453SAnurag.Maskey@Sun.COM if ((status = do_get_phyconf(handle, linkid, buf, sizeof (buf))) 21857663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 21865895Syz147064 goto done; 21875895Syz147064 21887663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 21897663SSowmini.Varadhan@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 21905895Syz147064 status = DLADM_STATUS_NOTFOUND; 21915895Syz147064 goto done; 21925895Syz147064 } 21935895Syz147064 21945895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 21955895Syz147064 *val_cnt = 1; 21968275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 21975895Syz147064 done: 21985895Syz147064 return (status); 21995895Syz147064 } 22005895Syz147064 22015895Syz147064 static dladm_status_t 22028453SAnurag.Maskey@Sun.COM do_get_powermode(dladm_handle_t handle, datalink_id_t linkid, void *buf, 22038453SAnurag.Maskey@Sun.COM int buflen) 22045895Syz147064 { 22058453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_POWER_MODE, 22067663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 22075895Syz147064 } 22085895Syz147064 22095903Ssowmini /* ARGSUSED */ 22105895Syz147064 static dladm_status_t 22118453SAnurag.Maskey@Sun.COM do_get_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 22128453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 22138453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 22145895Syz147064 { 22157663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 22165895Syz147064 const char *s; 22177663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 22185895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 22195895Syz147064 22208453SAnurag.Maskey@Sun.COM if ((status = do_get_powermode(handle, linkid, buf, sizeof (buf))) 22217663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 22225895Syz147064 goto done; 22235895Syz147064 22247663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 22257663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 22265895Syz147064 case WL_PM_AM: 22275895Syz147064 s = "off"; 22285895Syz147064 break; 22295895Syz147064 case WL_PM_MPS: 22305895Syz147064 s = "max"; 22315895Syz147064 break; 22325895Syz147064 case WL_PM_FAST: 22335895Syz147064 s = "fast"; 22343448Sdh155122 break; 22353448Sdh155122 default: 22365895Syz147064 status = DLADM_STATUS_NOTFOUND; 22375895Syz147064 goto done; 22385895Syz147064 } 22395895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 22405895Syz147064 *val_cnt = 1; 22418275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 22425895Syz147064 done: 22435895Syz147064 return (status); 22445895Syz147064 } 22455895Syz147064 22465895Syz147064 static dladm_status_t 22478453SAnurag.Maskey@Sun.COM do_set_powermode(dladm_handle_t handle, datalink_id_t linkid, 22488453SAnurag.Maskey@Sun.COM dladm_wlan_powermode_t *pm) 22495895Syz147064 { 22505895Syz147064 wl_ps_mode_t ps_mode; 22515895Syz147064 22525895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 22535895Syz147064 22545895Syz147064 switch (*pm) { 22555895Syz147064 case DLADM_WLAN_PM_OFF: 22565895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 22573448Sdh155122 break; 22585895Syz147064 case DLADM_WLAN_PM_MAX: 22595895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 22605895Syz147064 break; 22615895Syz147064 case DLADM_WLAN_PM_FAST: 22625895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 22635895Syz147064 break; 22645895Syz147064 default: 22655895Syz147064 return (DLADM_STATUS_NOTSUP); 22663448Sdh155122 } 22678453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 22688453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 22695895Syz147064 } 22705895Syz147064 22715895Syz147064 /* ARGSUSED */ 22725895Syz147064 static dladm_status_t 22738453SAnurag.Maskey@Sun.COM do_set_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 22748453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 22758453SAnurag.Maskey@Sun.COM datalink_media_t media) 22765895Syz147064 { 22775895Syz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 22785895Syz147064 dladm_status_t status; 22795895Syz147064 22805895Syz147064 if (val_cnt != 1) 22815895Syz147064 return (DLADM_STATUS_BADVALCNT); 22825895Syz147064 22838453SAnurag.Maskey@Sun.COM status = do_set_powermode(handle, linkid, &powermode); 22843448Sdh155122 22853448Sdh155122 return (status); 22863448Sdh155122 } 22873448Sdh155122 22883448Sdh155122 static dladm_status_t 22898453SAnurag.Maskey@Sun.COM do_get_radio(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen) 22903448Sdh155122 { 22918453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_RADIO, 22928453SAnurag.Maskey@Sun.COM buflen, B_FALSE)); 22935895Syz147064 } 22943448Sdh155122 22955903Ssowmini /* ARGSUSED */ 22965895Syz147064 static dladm_status_t 22978453SAnurag.Maskey@Sun.COM do_get_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22988275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 22998275SEric Cheng uint_t flags, uint_t *perm_flags) 23005895Syz147064 { 23015895Syz147064 wl_radio_t radio; 23025895Syz147064 const char *s; 23037663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 23045895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 23053448Sdh155122 23068453SAnurag.Maskey@Sun.COM if ((status = do_get_radio(handle, linkid, buf, sizeof (buf))) 23077663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 23085895Syz147064 goto done; 23093448Sdh155122 23107663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 23115895Syz147064 switch (radio) { 23125895Syz147064 case B_TRUE: 23135895Syz147064 s = "on"; 23145895Syz147064 break; 23155895Syz147064 case B_FALSE: 23165895Syz147064 s = "off"; 23175895Syz147064 break; 23185895Syz147064 default: 23195895Syz147064 status = DLADM_STATUS_NOTFOUND; 23205895Syz147064 goto done; 23215895Syz147064 } 23225895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 23235895Syz147064 *val_cnt = 1; 23248275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 23255895Syz147064 done: 23263448Sdh155122 return (status); 23273448Sdh155122 } 23283448Sdh155122 23293448Sdh155122 static dladm_status_t 23308453SAnurag.Maskey@Sun.COM do_set_radio(dladm_handle_t handle, datalink_id_t linkid, 23318453SAnurag.Maskey@Sun.COM dladm_wlan_radio_t *radio) 23323448Sdh155122 { 23335895Syz147064 wl_radio_t r; 23343448Sdh155122 23355895Syz147064 switch (*radio) { 23365895Syz147064 case DLADM_WLAN_RADIO_ON: 23375895Syz147064 r = B_TRUE; 23385895Syz147064 break; 23395895Syz147064 case DLADM_WLAN_RADIO_OFF: 23405895Syz147064 r = B_FALSE; 23415895Syz147064 break; 23425895Syz147064 default: 23435895Syz147064 return (DLADM_STATUS_NOTSUP); 23445895Syz147064 } 23458453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 23467663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 23475895Syz147064 } 23483448Sdh155122 23495895Syz147064 /* ARGSUSED */ 23505895Syz147064 static dladm_status_t 23518453SAnurag.Maskey@Sun.COM do_set_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 23525960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t fags, datalink_media_t media) 23535895Syz147064 { 23545895Syz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 23555895Syz147064 dladm_status_t status; 23563448Sdh155122 23575895Syz147064 if (val_cnt != 1) 23585895Syz147064 return (DLADM_STATUS_BADVALCNT); 23595895Syz147064 23608453SAnurag.Maskey@Sun.COM status = do_set_radio(handle, linkid, &radio); 23613448Sdh155122 23623448Sdh155122 return (status); 23633448Sdh155122 } 23643448Sdh155122 23655895Syz147064 static dladm_status_t 23668453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 23678453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 23683448Sdh155122 { 23695895Syz147064 char buf[MAXLINELEN]; 23705895Syz147064 int i; 23715895Syz147064 dladm_conf_t conf; 23725895Syz147064 dladm_status_t status; 23733448Sdh155122 23748453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 23755895Syz147064 if (status != DLADM_STATUS_OK) 23765895Syz147064 return (status); 23773448Sdh155122 23785895Syz147064 /* 23795895Syz147064 * reset case. 23805895Syz147064 */ 23815895Syz147064 if (val_cnt == 0) { 23828453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 23835895Syz147064 if (status == DLADM_STATUS_OK) 23848453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 23855895Syz147064 goto done; 23865895Syz147064 } 23873448Sdh155122 23885895Syz147064 buf[0] = '\0'; 23895895Syz147064 for (i = 0; i < val_cnt; i++) { 23905895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 23915895Syz147064 if (i != val_cnt - 1) 23925895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 23933448Sdh155122 } 23943448Sdh155122 23958453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 23968453SAnurag.Maskey@Sun.COM buf); 23975895Syz147064 if (status == DLADM_STATUS_OK) 23988453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 23995895Syz147064 24005895Syz147064 done: 24018453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 24025895Syz147064 return (status); 24033448Sdh155122 } 24045895Syz147064 24055895Syz147064 static dladm_status_t 24068453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 24078453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 24085895Syz147064 { 24095895Syz147064 char buf[MAXLINELEN], *str; 24105895Syz147064 uint_t cnt = 0; 24115895Syz147064 dladm_conf_t conf; 24125895Syz147064 dladm_status_t status; 24135895Syz147064 24148453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 24155895Syz147064 if (status != DLADM_STATUS_OK) 24165895Syz147064 return (status); 24175895Syz147064 24188453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 24195895Syz147064 if (status != DLADM_STATUS_OK) 24205895Syz147064 goto done; 24215895Syz147064 24225895Syz147064 str = strtok(buf, ","); 24235895Syz147064 while (str != NULL) { 24245895Syz147064 if (cnt == *val_cntp) { 24255895Syz147064 status = DLADM_STATUS_TOOSMALL; 24265895Syz147064 goto done; 24275895Syz147064 } 24285895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 24295895Syz147064 str = strtok(NULL, ","); 24305895Syz147064 } 24315895Syz147064 24325895Syz147064 *val_cntp = cnt; 24335895Syz147064 24345895Syz147064 done: 24358453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 24365895Syz147064 return (status); 24375895Syz147064 } 24385903Ssowmini 24398460SArtem.Kachitchkin@Sun.COM /* 24408460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 24418460SArtem.Kachitchkin@Sun.COM */ 24428460SArtem.Kachitchkin@Sun.COM static dladm_status_t 24438460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 24448460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 24458460SArtem.Kachitchkin@Sun.COM { 24468460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 24478460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 24488460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 24498460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 24508460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 24518460SArtem.Kachitchkin@Sun.COM size_t attrsz; 24528460SArtem.Kachitchkin@Sun.COM 24538460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 24548460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 24558460SArtem.Kachitchkin@Sun.COM 24568460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 24578460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 24588460SArtem.Kachitchkin@Sun.COM return (status); 24598460SArtem.Kachitchkin@Sun.COM 24608460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 24618460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 24628460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 24638460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 24648460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 24658460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 24668460SArtem.Kachitchkin@Sun.COM break; 24678460SArtem.Kachitchkin@Sun.COM } 24688460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 24698460SArtem.Kachitchkin@Sun.COM } 24708460SArtem.Kachitchkin@Sun.COM 24718460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 24728460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 24738460SArtem.Kachitchkin@Sun.COM } 24748460SArtem.Kachitchkin@Sun.COM 24757663SSowmini.Varadhan@Sun.COM static link_attr_t * 24765903Ssowmini dladm_name2prop(const char *prop_name) 24775903Ssowmini { 24787663SSowmini.Varadhan@Sun.COM link_attr_t *p; 24795903Ssowmini 24807663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 24815903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 24825903Ssowmini break; 24835903Ssowmini } 24845903Ssowmini return (p); 24855903Ssowmini } 24865903Ssowmini 24877663SSowmini.Varadhan@Sun.COM static link_attr_t * 24887663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 24897663SSowmini.Varadhan@Sun.COM { 24907663SSowmini.Varadhan@Sun.COM link_attr_t *p; 24917663SSowmini.Varadhan@Sun.COM 24927663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 24937663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 24947663SSowmini.Varadhan@Sun.COM break; 24957663SSowmini.Varadhan@Sun.COM } 24967663SSowmini.Varadhan@Sun.COM return (p); 24977663SSowmini.Varadhan@Sun.COM } 24985903Ssowmini 24996789Sam223141 static dld_ioc_macprop_t * 25007663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 25017663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 25027663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 25035903Ssowmini { 25045903Ssowmini int dsize; 25056789Sam223141 dld_ioc_macprop_t *dip; 25065903Ssowmini 25075903Ssowmini *status = DLADM_STATUS_OK; 25086789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 25095903Ssowmini dip = malloc(dsize); 25105903Ssowmini if (dip == NULL) { 25115903Ssowmini *status = DLADM_STATUS_NOMEM; 25125903Ssowmini return (NULL); 25135903Ssowmini } 25145903Ssowmini bzero(dip, dsize); 25155903Ssowmini dip->pr_valsize = valsize; 25166512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 25176789Sam223141 dip->pr_version = MAC_PROP_VERSION; 25185960Ssowmini dip->pr_linkid = linkid; 25197663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 25206512Ssowmini dip->pr_flags = flags; 25215903Ssowmini return (dip); 25225903Ssowmini } 25235903Ssowmini 25247663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 25257663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 25267663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 25277663SSowmini.Varadhan@Sun.COM { 25287663SSowmini.Varadhan@Sun.COM link_attr_t *p; 25297663SSowmini.Varadhan@Sun.COM 25307663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 25317663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 25327663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 25337663SSowmini.Varadhan@Sun.COM flags, status)); 25347663SSowmini.Varadhan@Sun.COM } 25357663SSowmini.Varadhan@Sun.COM 25367663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 25377663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 25387663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 25397663SSowmini.Varadhan@Sun.COM { 25407663SSowmini.Varadhan@Sun.COM link_attr_t *p; 25417663SSowmini.Varadhan@Sun.COM 25427663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 25437663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 25447663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 25457663SSowmini.Varadhan@Sun.COM flags, status)); 25467663SSowmini.Varadhan@Sun.COM } 25477663SSowmini.Varadhan@Sun.COM 25485903Ssowmini /* ARGSUSED */ 25495903Ssowmini static dladm_status_t 25508453SAnurag.Maskey@Sun.COM i_dladm_set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 25518453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 25528453SAnurag.Maskey@Sun.COM datalink_media_t media) 25535903Ssowmini { 25546789Sam223141 dld_ioc_macprop_t *dip; 25555903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 25565903Ssowmini uint8_t u8; 25575903Ssowmini uint16_t u16; 25585903Ssowmini uint32_t u32; 25595903Ssowmini void *val; 25605903Ssowmini 25618275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 25625903Ssowmini if (dip == NULL) 25635903Ssowmini return (status); 25645903Ssowmini 25658275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 25665903Ssowmini val = (void *)vdp->vd_val; 25675903Ssowmini else { 25685903Ssowmini /* 25695903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 25705903Ssowmini * No need (yet) to distinguish these from arrays of same size. 25715903Ssowmini */ 25725903Ssowmini switch (dip->pr_valsize) { 25735903Ssowmini case 1: 25745903Ssowmini u8 = vdp->vd_val; 25755903Ssowmini val = &u8; 25765903Ssowmini break; 25775903Ssowmini case 2: 25785903Ssowmini u16 = vdp->vd_val; 25795903Ssowmini val = &u16; 25805903Ssowmini break; 25815903Ssowmini case 4: 25825903Ssowmini u32 = vdp->vd_val; 25835903Ssowmini val = &u32; 25845903Ssowmini break; 25855903Ssowmini default: 25865903Ssowmini val = &vdp->vd_val; 25875903Ssowmini break; 25885903Ssowmini } 25895903Ssowmini } 25905903Ssowmini 25917342SAruna.Ramakrishna@Sun.COM if (val != NULL) 25927342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 25937342SAruna.Ramakrishna@Sun.COM else 25947342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 25957342SAruna.Ramakrishna@Sun.COM 25968453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 25977663SSowmini.Varadhan@Sun.COM 25987663SSowmini.Varadhan@Sun.COM done: 25997663SSowmini.Varadhan@Sun.COM free(dip); 26007663SSowmini.Varadhan@Sun.COM return (status); 26017663SSowmini.Varadhan@Sun.COM } 26027663SSowmini.Varadhan@Sun.COM 26037663SSowmini.Varadhan@Sun.COM dladm_status_t 26048453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 26057663SSowmini.Varadhan@Sun.COM { 26067663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 26077663SSowmini.Varadhan@Sun.COM 26088453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 26098453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 26105903Ssowmini status = dladm_errno2status(errno); 26118453SAnurag.Maskey@Sun.COM 26125903Ssowmini return (status); 26135903Ssowmini } 26145903Ssowmini 26156789Sam223141 static dld_ioc_macprop_t * 26168453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 26178453SAnurag.Maskey@Sun.COM char *prop_name, uint_t flags, dladm_status_t *status, uint_t *perm_flags) 26185903Ssowmini { 26196789Sam223141 dld_ioc_macprop_t *dip = NULL; 26206512Ssowmini 26217663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 26226512Ssowmini if (dip == NULL) 26236512Ssowmini return (NULL); 26245903Ssowmini 26258453SAnurag.Maskey@Sun.COM *status = i_dladm_macprop(handle, dip, B_FALSE); 26266512Ssowmini if (*status != DLADM_STATUS_OK) { 26276512Ssowmini free(dip); 26286512Ssowmini return (NULL); 26296512Ssowmini } 26308275SEric Cheng if (perm_flags != NULL) 26318275SEric Cheng *perm_flags = dip->pr_perm_flags; 26328275SEric Cheng 26336512Ssowmini return (dip); 26345903Ssowmini } 26355903Ssowmini 26365903Ssowmini /* ARGSUSED */ 26375903Ssowmini static dladm_status_t 2638*10491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check(dladm_handle_t handle, prop_desc_t *pdp, 26398453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *v, 26408453SAnurag.Maskey@Sun.COM datalink_media_t media) 26415903Ssowmini { 26425903Ssowmini if (val_cnt != 1) 26435903Ssowmini return (DLADM_STATUS_BADVAL); 2644*10491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 26455903Ssowmini return (DLADM_STATUS_OK); 26465903Ssowmini } 26475903Ssowmini 26485903Ssowmini /* ARGSUSED */ 26495903Ssowmini static dladm_status_t 26508453SAnurag.Maskey@Sun.COM i_dladm_duplex_get(dladm_handle_t handle, prop_desc_t *pdp, 26518453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 26528453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 26535903Ssowmini { 26545903Ssowmini link_duplex_t link_duplex; 26555903Ssowmini dladm_status_t status; 26565903Ssowmini 26578453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 26585903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 26595903Ssowmini return (status); 26605903Ssowmini 26615903Ssowmini switch (link_duplex) { 26625903Ssowmini case LINK_DUPLEX_FULL: 26635903Ssowmini (void) strcpy(*prop_val, "full"); 26645903Ssowmini break; 26655903Ssowmini case LINK_DUPLEX_HALF: 26665903Ssowmini (void) strcpy(*prop_val, "half"); 26675903Ssowmini break; 26685903Ssowmini default: 26695903Ssowmini (void) strcpy(*prop_val, "unknown"); 26705903Ssowmini break; 26715903Ssowmini } 26725903Ssowmini *val_cnt = 1; 26735903Ssowmini return (DLADM_STATUS_OK); 26745903Ssowmini } 26755903Ssowmini 26765903Ssowmini /* ARGSUSED */ 26775903Ssowmini static dladm_status_t 26788453SAnurag.Maskey@Sun.COM i_dladm_speed_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 26798275SEric Cheng char **prop_val, uint_t *val_cnt, uint_t flags, uint_t *perm_flags) 26805903Ssowmini { 26815903Ssowmini uint64_t ifspeed = 0; 26825903Ssowmini dladm_status_t status; 26835903Ssowmini 26848453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 26855903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 26865903Ssowmini return (status); 26876512Ssowmini 26885960Ssowmini if ((ifspeed % 1000000) != 0) { 26895960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 26905960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 26915960Ssowmini } else { 26925960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 26935960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 26945960Ssowmini } 26955903Ssowmini *val_cnt = 1; 26968275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 26975903Ssowmini return (DLADM_STATUS_OK); 26985903Ssowmini } 26995903Ssowmini 27005903Ssowmini /* ARGSUSED */ 27015903Ssowmini static dladm_status_t 27028453SAnurag.Maskey@Sun.COM i_dladm_status_get(dladm_handle_t handle, prop_desc_t *pdp, 27038453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27048453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27055903Ssowmini { 27068275SEric Cheng link_state_t link_state; 27078275SEric Cheng dladm_status_t status; 27088306SSowmini.Varadhan@Sun.COM 27098453SAnurag.Maskey@Sun.COM status = i_dladm_get_state(handle, linkid, &link_state); 27106512Ssowmini if (status != DLADM_STATUS_OK) 27115903Ssowmini return (status); 27128275SEric Cheng 27135903Ssowmini switch (link_state) { 27145903Ssowmini case LINK_STATE_UP: 27155903Ssowmini (void) strcpy(*prop_val, "up"); 27165903Ssowmini break; 27175903Ssowmini case LINK_STATE_DOWN: 27185903Ssowmini (void) strcpy(*prop_val, "down"); 27195903Ssowmini break; 27205903Ssowmini default: 27215903Ssowmini (void) strcpy(*prop_val, "unknown"); 27225903Ssowmini break; 27235903Ssowmini } 27245903Ssowmini *val_cnt = 1; 27258306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 27265903Ssowmini return (DLADM_STATUS_OK); 27275903Ssowmini } 27285903Ssowmini 27295903Ssowmini /* ARGSUSED */ 27305903Ssowmini static dladm_status_t 27318453SAnurag.Maskey@Sun.COM i_dladm_binary_get(dladm_handle_t handle, prop_desc_t *pdp, 27328453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27338453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27345903Ssowmini { 27356789Sam223141 dld_ioc_macprop_t *dip; 27365903Ssowmini dladm_status_t status; 27375903Ssowmini 27388453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 27398275SEric Cheng &status, perm_flags); 27406512Ssowmini if (dip == NULL) 27415903Ssowmini return (status); 27428275SEric Cheng 27435903Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 27445903Ssowmini free(dip); 27455903Ssowmini *val_cnt = 1; 27465903Ssowmini return (DLADM_STATUS_OK); 27475903Ssowmini } 27485903Ssowmini 27495960Ssowmini /* ARGSUSED */ 27505903Ssowmini static dladm_status_t 27518453SAnurag.Maskey@Sun.COM i_dladm_uint32_get(dladm_handle_t handle, prop_desc_t *pdp, 27528453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27538453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27545903Ssowmini { 27556789Sam223141 dld_ioc_macprop_t *dip; 27568275SEric Cheng uint32_t v = 0; 27575903Ssowmini uchar_t *cp; 27585903Ssowmini dladm_status_t status; 27595903Ssowmini 27608453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 27618275SEric Cheng &status, perm_flags); 27626512Ssowmini if (dip == NULL) 27635903Ssowmini return (status); 27648275SEric Cheng 27655903Ssowmini cp = (uchar_t *)dip->pr_val; 27665903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 27676512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 27685903Ssowmini free(dip); 27695903Ssowmini *val_cnt = 1; 27705903Ssowmini return (DLADM_STATUS_OK); 27715903Ssowmini } 27725903Ssowmini 27739514SGirish.Moodalbail@Sun.COM /* 27749514SGirish.Moodalbail@Sun.COM * Determines the size of the structure that needs to be sent to drivers 27759514SGirish.Moodalbail@Sun.COM * for retrieving the property range values. 27769514SGirish.Moodalbail@Sun.COM */ 27779514SGirish.Moodalbail@Sun.COM static int 27789514SGirish.Moodalbail@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 27799514SGirish.Moodalbail@Sun.COM { 27809514SGirish.Moodalbail@Sun.COM uint_t count = r->mpr_count; 27819514SGirish.Moodalbail@Sun.COM 27829514SGirish.Moodalbail@Sun.COM *sz = sizeof (mac_propval_range_t); 27839514SGirish.Moodalbail@Sun.COM --count; 27849514SGirish.Moodalbail@Sun.COM 27859514SGirish.Moodalbail@Sun.COM switch (r->mpr_type) { 27869514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: 27879514SGirish.Moodalbail@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 27889514SGirish.Moodalbail@Sun.COM return (0); 27899514SGirish.Moodalbail@Sun.COM default: 27909514SGirish.Moodalbail@Sun.COM break; 27919514SGirish.Moodalbail@Sun.COM } 27929514SGirish.Moodalbail@Sun.COM *sz = 0; 27939514SGirish.Moodalbail@Sun.COM return (EINVAL); 27949514SGirish.Moodalbail@Sun.COM } 27959514SGirish.Moodalbail@Sun.COM 27969514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 27979514SGirish.Moodalbail@Sun.COM static dladm_status_t 27989514SGirish.Moodalbail@Sun.COM i_dladm_range_get(dladm_handle_t handle, prop_desc_t *pdp, 27999514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28009514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28019514SGirish.Moodalbail@Sun.COM { 28029514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 28039514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 28049514SGirish.Moodalbail@Sun.COM size_t sz; 28059514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 28069514SGirish.Moodalbail@Sun.COM 28079514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 28089514SGirish.Moodalbail@Sun.COM 28099514SGirish.Moodalbail@Sun.COM /* 28109514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 28119514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 28129514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 28139514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 28149514SGirish.Moodalbail@Sun.COM */ 28159514SGirish.Moodalbail@Sun.COM retry: 28169514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 28179514SGirish.Moodalbail@Sun.COM &status)) == NULL) 28189514SGirish.Moodalbail@Sun.COM return (status); 28199514SGirish.Moodalbail@Sun.COM 28209514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 28219514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 28229514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 28239514SGirish.Moodalbail@Sun.COM int err; 28249514SGirish.Moodalbail@Sun.COM 28259514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 28269514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 28279514SGirish.Moodalbail@Sun.COM free(dip); 28289514SGirish.Moodalbail@Sun.COM goto retry; 28299514SGirish.Moodalbail@Sun.COM } else { 28309514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 28319514SGirish.Moodalbail@Sun.COM } 28329514SGirish.Moodalbail@Sun.COM } 28339514SGirish.Moodalbail@Sun.COM free(dip); 28349514SGirish.Moodalbail@Sun.COM return (status); 28359514SGirish.Moodalbail@Sun.COM } 28369514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 28379514SGirish.Moodalbail@Sun.COM 28389514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 28399514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 28409514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 28419514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 28429514SGirish.Moodalbail@Sun.COM 28439514SGirish.Moodalbail@Sun.COM ur = &rangep->range_uint32[0]; 28449514SGirish.Moodalbail@Sun.COM 28459514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 28469514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 28479514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 28489514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 28499514SGirish.Moodalbail@Sun.COM } else { 28509514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 28519514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 28529514SGirish.Moodalbail@Sun.COM } 28539514SGirish.Moodalbail@Sun.COM } 28549514SGirish.Moodalbail@Sun.COM *val_cnt = count; 28559514SGirish.Moodalbail@Sun.COM break; 28569514SGirish.Moodalbail@Sun.COM } 28579514SGirish.Moodalbail@Sun.COM default: 28589514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 28599514SGirish.Moodalbail@Sun.COM break; 28609514SGirish.Moodalbail@Sun.COM } 28619514SGirish.Moodalbail@Sun.COM free(dip); 28629514SGirish.Moodalbail@Sun.COM return (status); 28639514SGirish.Moodalbail@Sun.COM } 28649514SGirish.Moodalbail@Sun.COM 28655960Ssowmini /* ARGSUSED */ 28665903Ssowmini static dladm_status_t 28678874SSebastien.Roy@Sun.COM i_dladm_tagmode_get(dladm_handle_t handle, prop_desc_t *pdp, 28688874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28698874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28708874SSebastien.Roy@Sun.COM { 28718874SSebastien.Roy@Sun.COM dld_ioc_macprop_t *dip; 28728874SSebastien.Roy@Sun.COM link_tagmode_t mode; 28738874SSebastien.Roy@Sun.COM dladm_status_t status; 28748874SSebastien.Roy@Sun.COM 28758874SSebastien.Roy@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 28768874SSebastien.Roy@Sun.COM &status, perm_flags); 28778874SSebastien.Roy@Sun.COM if (dip == NULL) 28788874SSebastien.Roy@Sun.COM return (status); 28798874SSebastien.Roy@Sun.COM (void) memcpy(&mode, dip->pr_val, sizeof (mode)); 28808874SSebastien.Roy@Sun.COM free(dip); 28818874SSebastien.Roy@Sun.COM 28828874SSebastien.Roy@Sun.COM switch (mode) { 28838874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 28848874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 28858874SSebastien.Roy@Sun.COM break; 28868874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 28878874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 28888874SSebastien.Roy@Sun.COM break; 28898874SSebastien.Roy@Sun.COM default: 28908874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 28918874SSebastien.Roy@Sun.COM } 28928874SSebastien.Roy@Sun.COM *val_cnt = 1; 28938874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 28948874SSebastien.Roy@Sun.COM } 28958874SSebastien.Roy@Sun.COM 28968874SSebastien.Roy@Sun.COM /* ARGSUSED */ 28978874SSebastien.Roy@Sun.COM static dladm_status_t 28988453SAnurag.Maskey@Sun.COM i_dladm_flowctl_get(dladm_handle_t handle, prop_desc_t *pdp, 28998453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29008453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29015903Ssowmini { 29026789Sam223141 dld_ioc_macprop_t *dip; 29035903Ssowmini link_flowctrl_t v; 29045903Ssowmini dladm_status_t status; 29055903Ssowmini uchar_t *cp; 29065903Ssowmini 29078453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29088275SEric Cheng &status, perm_flags); 29096512Ssowmini if (dip == NULL) 29105903Ssowmini return (status); 29118275SEric Cheng 29125903Ssowmini cp = (uchar_t *)dip->pr_val; 29135903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 29145903Ssowmini switch (v) { 29155903Ssowmini case LINK_FLOWCTRL_NONE: 29165903Ssowmini (void) sprintf(*prop_val, "no"); 29175903Ssowmini break; 29185903Ssowmini case LINK_FLOWCTRL_RX: 29195903Ssowmini (void) sprintf(*prop_val, "rx"); 29205903Ssowmini break; 29215903Ssowmini case LINK_FLOWCTRL_TX: 29225903Ssowmini (void) sprintf(*prop_val, "tx"); 29235903Ssowmini break; 29245903Ssowmini case LINK_FLOWCTRL_BI: 29255903Ssowmini (void) sprintf(*prop_val, "bi"); 29265903Ssowmini break; 29275903Ssowmini } 29285903Ssowmini free(dip); 29295903Ssowmini *val_cnt = 1; 29305903Ssowmini return (DLADM_STATUS_OK); 29315903Ssowmini } 29325903Ssowmini 29335903Ssowmini 29345903Ssowmini /* ARGSUSED */ 29355903Ssowmini static dladm_status_t 29369692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 29378453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 29388453SAnurag.Maskey@Sun.COM 29395903Ssowmini { 29407663SSowmini.Varadhan@Sun.COM int i, slen; 29417408SSebastien.Roy@Sun.COM int bufsize = 0; 29426789Sam223141 dld_ioc_macprop_t *dip = NULL; 29435903Ssowmini uchar_t *dp; 29447663SSowmini.Varadhan@Sun.COM link_attr_t *p; 29456512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 29465903Ssowmini 29475903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 29485903Ssowmini (prop_val != NULL && val_cnt == 0)) 29495903Ssowmini return (DLADM_STATUS_BADARG); 29505903Ssowmini p = dladm_name2prop(prop_name); 29516789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 29525903Ssowmini return (DLADM_STATUS_BADARG); 29535903Ssowmini 29549692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 29559692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 29569692SRishi.Srivatsavai@Sun.COM 29575903Ssowmini /* 29585903Ssowmini * private properties: all parsing is done in the kernel. 29595903Ssowmini * allocate a enough space for each property + its separator (','). 29605903Ssowmini */ 29615903Ssowmini for (i = 0; i < val_cnt; i++) { 29625903Ssowmini bufsize += strlen(prop_val[i]) + 1; 29635903Ssowmini } 29646512Ssowmini 29656512Ssowmini if (prop_val == NULL) { 29666512Ssowmini /* 29676512Ssowmini * getting default value. so use more buffer space. 29686512Ssowmini */ 29697663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 29706512Ssowmini } 29716512Ssowmini 29727663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 29736789Sam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 29745903Ssowmini if (dip == NULL) 29755903Ssowmini return (status); 29765903Ssowmini 29775903Ssowmini dp = (uchar_t *)dip->pr_val; 29785903Ssowmini slen = 0; 29797663SSowmini.Varadhan@Sun.COM 29806512Ssowmini if (prop_val == NULL) { 29818453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 29828460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 29836512Ssowmini } else { 29846512Ssowmini for (i = 0; i < val_cnt; i++) { 29856512Ssowmini int plen = 0; 29865903Ssowmini 29876512Ssowmini plen = strlen(prop_val[i]); 29886512Ssowmini bcopy(prop_val[i], dp, plen); 29896512Ssowmini slen += plen; 29906512Ssowmini /* 29916512Ssowmini * add a "," separator and update dp. 29926512Ssowmini */ 29936512Ssowmini if (i != (val_cnt -1)) 29946512Ssowmini dp[slen++] = ','; 29956512Ssowmini dp += (plen + 1); 29966512Ssowmini } 29978460SArtem.Kachitchkin@Sun.COM } 29988460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 29998453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 30006512Ssowmini 30015903Ssowmini free(dip); 30026512Ssowmini return (status); 30035903Ssowmini } 30045903Ssowmini 30055903Ssowmini static dladm_status_t 30068460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 30078453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 30088453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 30095903Ssowmini { 30107663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 30116789Sam223141 dld_ioc_macprop_t *dip = NULL; 30127663SSowmini.Varadhan@Sun.COM link_attr_t *p; 30135903Ssowmini 30145903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 30155903Ssowmini (prop_val != NULL && val_cnt == 0)) 30165903Ssowmini return (DLADM_STATUS_BADARG); 30175903Ssowmini 30185903Ssowmini p = dladm_name2prop(prop_name); 30196789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 30205903Ssowmini return (DLADM_STATUS_BADARG); 30215903Ssowmini 30225903Ssowmini /* 30235903Ssowmini * private properties: all parsing is done in the kernel. 30245903Ssowmini */ 30257663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 30267663SSowmini.Varadhan@Sun.COM dld_flags, &status); 30275903Ssowmini if (dip == NULL) 30285903Ssowmini return (status); 30295903Ssowmini 30308453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 30318453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 30328118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 30338275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 30348460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 30358460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 30368118SVasumathi.Sundaram@Sun.COM } else { 30378118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 30388118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 30398118SVasumathi.Sundaram@Sun.COM } 30405903Ssowmini *val_cnt = 1; 30418460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 30428460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 30438460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 30445903Ssowmini } 30456512Ssowmini free(dip); 30465903Ssowmini return (status); 30475903Ssowmini } 30486512Ssowmini 30496512Ssowmini 30506512Ssowmini static dladm_status_t 30518453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 30528453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 30536512Ssowmini { 30546512Ssowmini dladm_status_t status; 30556512Ssowmini char **prop_vals = NULL, *buf; 30566512Ssowmini size_t bufsize; 30576512Ssowmini uint_t cnt; 30586512Ssowmini int i; 30598118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 30606512Ssowmini 30616512Ssowmini /* 30626512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 30636512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 30646512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 30656512Ssowmini */ 30666512Ssowmini bufsize = 30676512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 30686512Ssowmini buf = malloc(bufsize); 30696512Ssowmini prop_vals = (char **)(void *)buf; 30706512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 30716512Ssowmini prop_vals[i] = buf + 30726512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 30736512Ssowmini i * DLADM_PROP_VAL_MAX; 30746512Ssowmini } 30756768Sar224390 30766768Sar224390 /* 30777342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 30787342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 30797342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 30807342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 30817342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 30827342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 30837342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 30847342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 30856768Sar224390 */ 30868453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 30878118SVasumathi.Sundaram@Sun.COM MAC_PROP_DEFAULT, &perm_flags); 30886512Ssowmini if (status == DLADM_STATUS_OK) { 30898118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 30908453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 30918453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 30928118SVasumathi.Sundaram@Sun.COM } 30938118SVasumathi.Sundaram@Sun.COM else 30948118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 30956512Ssowmini } 30966512Ssowmini free(buf); 30976512Ssowmini return (status); 30986512Ssowmini } 30997663SSowmini.Varadhan@Sun.COM 3100*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3101*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3102*10491SRishi.Srivatsavai@Sun.COM get_stp_prop(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 3103*10491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 3104*10491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 3105*10491SRishi.Srivatsavai@Sun.COM { 3106*10491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 3107*10491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 3108*10491SRishi.Srivatsavai@Sun.COM int val, i; 3109*10491SRishi.Srivatsavai@Sun.COM 3110*10491SRishi.Srivatsavai@Sun.COM if (flags != 0) 3111*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 3112*10491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 3113*10491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 3114*10491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 3115*10491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 3116*10491SRishi.Srivatsavai@Sun.COM break; 3117*10491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 3118*10491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 3119*10491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 3120*10491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 3121*10491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 3122*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 3123*10491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 3124*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3125*10491SRishi.Srivatsavai@Sun.COM } 3126*10491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 3127*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 3128*10491SRishi.Srivatsavai@Sun.COM return (retv); 3129*10491SRishi.Srivatsavai@Sun.COM } 3130*10491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 3131*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 3132*10491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 3133*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3134*10491SRishi.Srivatsavai@Sun.COM } 3135*10491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 3136*10491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 3137*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 3138*10491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 3139*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3140*10491SRishi.Srivatsavai@Sun.COM } 3141*10491SRishi.Srivatsavai@Sun.COM } 3142*10491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 3143*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3144*10491SRishi.Srivatsavai@Sun.COM } 3145*10491SRishi.Srivatsavai@Sun.COM 3146*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 3147*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3148*10491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 3149*10491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3150*10491SRishi.Srivatsavai@Sun.COM { 3151*10491SRishi.Srivatsavai@Sun.COM /* 3152*10491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 3153*10491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 3154*10491SRishi.Srivatsavai@Sun.COM */ 3155*10491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 3156*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3157*10491SRishi.Srivatsavai@Sun.COM 3158*10491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 3159*10491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 3160*10491SRishi.Srivatsavai@Sun.COM } 3161*10491SRishi.Srivatsavai@Sun.COM 3162*10491SRishi.Srivatsavai@Sun.COM /* 3163*10491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 3164*10491SRishi.Srivatsavai@Sun.COM */ 3165*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3166*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3167*10491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 3168*10491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 3169*10491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 3170*10491SRishi.Srivatsavai@Sun.COM { 3171*10491SRishi.Srivatsavai@Sun.COM char *cp; 3172*10491SRishi.Srivatsavai@Sun.COM boolean_t iscost; 3173*10491SRishi.Srivatsavai@Sun.COM 3174*10491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 3175*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 3176*10491SRishi.Srivatsavai@Sun.COM 3177*10491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 3178*10491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 3179*10491SRishi.Srivatsavai@Sun.COM } else { 3180*10491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 3181*10491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 3182*10491SRishi.Srivatsavai@Sun.COM 3183*10491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 3184*10491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 3185*10491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 3186*10491SRishi.Srivatsavai@Sun.COM } else { 3187*10491SRishi.Srivatsavai@Sun.COM errno = 0; 3188*10491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 3189*10491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 3190*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 3191*10491SRishi.Srivatsavai@Sun.COM } 3192*10491SRishi.Srivatsavai@Sun.COM } 3193*10491SRishi.Srivatsavai@Sun.COM 3194*10491SRishi.Srivatsavai@Sun.COM if (iscost) { 3195*10491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 3196*10491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 3197*10491SRishi.Srivatsavai@Sun.COM } else { 3198*10491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 3199*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 3200*10491SRishi.Srivatsavai@Sun.COM /* 3201*10491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 3202*10491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 3203*10491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 3204*10491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 3205*10491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 3206*10491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 3207*10491SRishi.Srivatsavai@Sun.COM * can't be used now. 3208*10491SRishi.Srivatsavai@Sun.COM */ 3209*10491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 3210*10491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 3211*10491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 3212*10491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 3213*10491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 3214*10491SRishi.Srivatsavai@Sun.COM 3215*10491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 3216*10491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 3217*10491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 3218*10491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 3219*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 3220*10491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 3221*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 3222*10491SRishi.Srivatsavai@Sun.COM } 3223*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3224*10491SRishi.Srivatsavai@Sun.COM } 3225*10491SRishi.Srivatsavai@Sun.COM } 3226*10491SRishi.Srivatsavai@Sun.COM 3227*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3228*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3229*10491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 3230*10491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3231*10491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 3232*10491SRishi.Srivatsavai@Sun.COM { 3233*10491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 3234*10491SRishi.Srivatsavai@Sun.COM uint_t val; 3235*10491SRishi.Srivatsavai@Sun.COM 3236*10491SRishi.Srivatsavai@Sun.COM if (flags != 0) 3237*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 3238*10491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 3239*10491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 3240*10491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 3241*10491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 3242*10491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 3243*10491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 3244*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 3245*10491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 3246*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 3247*10491SRishi.Srivatsavai@Sun.COM } 3248*10491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 3249*10491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 3250*10491SRishi.Srivatsavai@Sun.COM else 3251*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 3252*10491SRishi.Srivatsavai@Sun.COM return (retv); 3253*10491SRishi.Srivatsavai@Sun.COM } 3254*10491SRishi.Srivatsavai@Sun.COM 3255*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3256*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3257*10491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 3258*10491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3259*10491SRishi.Srivatsavai@Sun.COM { 3260*10491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 3261*10491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 3262*10491SRishi.Srivatsavai@Sun.COM } 3263*10491SRishi.Srivatsavai@Sun.COM 3264*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3265*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3266*10491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 3267*10491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3268*10491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 3269*10491SRishi.Srivatsavai@Sun.COM { 3270*10491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 3271*10491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 3272*10491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 3273*10491SRishi.Srivatsavai@Sun.COM 3274*10491SRishi.Srivatsavai@Sun.COM if (flags != 0) 3275*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 3276*10491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 3277*10491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 3278*10491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 3279*10491SRishi.Srivatsavai@Sun.COM 0, &status); 3280*10491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 3281*10491SRishi.Srivatsavai@Sun.COM return (status); 3282*10491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 3283*10491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 3284*10491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 3285*10491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 3286*10491SRishi.Srivatsavai@Sun.COM } else { 3287*10491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 3288*10491SRishi.Srivatsavai@Sun.COM } 3289*10491SRishi.Srivatsavai@Sun.COM free(dip); 3290*10491SRishi.Srivatsavai@Sun.COM return (status); 3291*10491SRishi.Srivatsavai@Sun.COM } 3292*10491SRishi.Srivatsavai@Sun.COM 3293*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3294*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3295*10491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 3296*10491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3297*10491SRishi.Srivatsavai@Sun.COM { 3298*10491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 3299*10491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 3300*10491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 3301*10491SRishi.Srivatsavai@Sun.COM 3302*10491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 3303*10491SRishi.Srivatsavai@Sun.COM 0, &status); 3304*10491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 3305*10491SRishi.Srivatsavai@Sun.COM return (status); 3306*10491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 3307*10491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 3308*10491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 3309*10491SRishi.Srivatsavai@Sun.COM free(dip); 3310*10491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 3311*10491SRishi.Srivatsavai@Sun.COM return (status); 3312*10491SRishi.Srivatsavai@Sun.COM 3313*10491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 3314*10491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 3315*10491SRishi.Srivatsavai@Sun.COM } 3316*10491SRishi.Srivatsavai@Sun.COM 3317*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 3318*10491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3319*10491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 3320*10491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 3321*10491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 3322*10491SRishi.Srivatsavai@Sun.COM { 3323*10491SRishi.Srivatsavai@Sun.COM char *cp; 3324*10491SRishi.Srivatsavai@Sun.COM 3325*10491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 3326*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 3327*10491SRishi.Srivatsavai@Sun.COM 3328*10491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 3329*10491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 3330*10491SRishi.Srivatsavai@Sun.COM } else { 3331*10491SRishi.Srivatsavai@Sun.COM errno = 0; 3332*10491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 3333*10491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 3334*10491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 3335*10491SRishi.Srivatsavai@Sun.COM } 3336*10491SRishi.Srivatsavai@Sun.COM 3337*10491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 3338*10491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 3339*10491SRishi.Srivatsavai@Sun.COM } 3340*10491SRishi.Srivatsavai@Sun.COM 33417663SSowmini.Varadhan@Sun.COM dladm_status_t 33428453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 33438453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 33447663SSowmini.Varadhan@Sun.COM { 33457663SSowmini.Varadhan@Sun.COM uint32_t flags; 33467663SSowmini.Varadhan@Sun.COM dladm_status_t status; 33477663SSowmini.Varadhan@Sun.COM uint32_t media; 33487663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 33497663SSowmini.Varadhan@Sun.COM void *dp; 33507663SSowmini.Varadhan@Sun.COM 33518453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 33528453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 33537663SSowmini.Varadhan@Sun.COM return (status); 33547663SSowmini.Varadhan@Sun.COM } 33557663SSowmini.Varadhan@Sun.COM 33567663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 33577663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 33587663SSowmini.Varadhan@Sun.COM 33597663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 33607663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 33617663SSowmini.Varadhan@Sun.COM 33627663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 33637663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 33647663SSowmini.Varadhan@Sun.COM 33657663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 33667663SSowmini.Varadhan@Sun.COM if (dip == NULL) 33677663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 33687663SSowmini.Varadhan@Sun.COM 33697663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 33707663SSowmini.Varadhan@Sun.COM if (set) 33717663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 33727663SSowmini.Varadhan@Sun.COM 33738453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 337410191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 33757663SSowmini.Varadhan@Sun.COM if (!set) 33767663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 33777663SSowmini.Varadhan@Sun.COM } 33787663SSowmini.Varadhan@Sun.COM 33797663SSowmini.Varadhan@Sun.COM free(dip); 33807663SSowmini.Varadhan@Sun.COM return (status); 33817663SSowmini.Varadhan@Sun.COM } 33827663SSowmini.Varadhan@Sun.COM 33838275SEric Cheng dladm_status_t 33848275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 33858275SEric Cheng { 33868460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 33878275SEric Cheng } 33888275SEric Cheng 33898275SEric Cheng /* 33908275SEric Cheng * Retrieve the one link property from the database 33918275SEric Cheng */ 33928275SEric Cheng /*ARGSUSED*/ 33938275SEric Cheng static int 33948453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 33958453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 33968275SEric Cheng { 33978275SEric Cheng dladm_arg_list_t *proplist = arg; 33988275SEric Cheng dladm_arg_info_t *aip = NULL; 33998275SEric Cheng 34008275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 34018275SEric Cheng /* 34028275SEric Cheng * it is fine to point to prop_name since prop_name points to the 34038275SEric Cheng * prop_table[n].pd_name. 34048275SEric Cheng */ 34058275SEric Cheng aip->ai_name = prop_name; 34068275SEric Cheng 34078453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 34088453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 34098275SEric Cheng 34108275SEric Cheng if (aip->ai_count != 0) 34118275SEric Cheng proplist->al_count++; 34128275SEric Cheng 34138275SEric Cheng return (DLADM_WALK_CONTINUE); 34148275SEric Cheng } 34158275SEric Cheng 34168275SEric Cheng 34178275SEric Cheng /* 34188275SEric Cheng * Retrieve all link properties for a link from the database and 34198275SEric Cheng * return a property list. 34208275SEric Cheng */ 34218275SEric Cheng dladm_status_t 34228453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 34238453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 34248275SEric Cheng { 34258275SEric Cheng dladm_arg_list_t *list; 34268275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 34278275SEric Cheng 34288275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 34298275SEric Cheng if (list == NULL) 34308275SEric Cheng return (dladm_errno2status(errno)); 34318275SEric Cheng 34328453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 34338453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 34348275SEric Cheng 34358275SEric Cheng *listp = list; 34368275SEric Cheng return (status); 34378275SEric Cheng } 34388275SEric Cheng 34398275SEric Cheng /* 34408275SEric Cheng * Retrieve the named property from a proplist, check the value and 34418275SEric Cheng * convert to a kernel structure. 34428275SEric Cheng */ 34438275SEric Cheng static dladm_status_t 34448453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 34458453SAnurag.Maskey@Sun.COM dladm_arg_list_t *proplist, const char *name, void *val) 34468275SEric Cheng { 34478275SEric Cheng dladm_status_t status; 34488275SEric Cheng dladm_arg_info_t *aip = NULL; 34498275SEric Cheng int i, j; 34508275SEric Cheng 34518275SEric Cheng /* Find named property in proplist */ 34528275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 34538275SEric Cheng aip = &proplist->al_info[i]; 34548275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 34558275SEric Cheng break; 34568275SEric Cheng } 34578275SEric Cheng 34588275SEric Cheng /* Property not in list */ 34598275SEric Cheng if (i == proplist->al_count) 34608275SEric Cheng return (DLADM_STATUS_OK); 34618275SEric Cheng 34628275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 34638275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 34648275SEric Cheng val_desc_t *vdp; 34658275SEric Cheng 34668275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 34678275SEric Cheng if (vdp == NULL) 34688275SEric Cheng return (DLADM_STATUS_NOMEM); 34698275SEric Cheng 34708275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 34718275SEric Cheng continue; 34728275SEric Cheng 34738275SEric Cheng if (aip->ai_val == NULL) 34748275SEric Cheng return (DLADM_STATUS_BADARG); 34758275SEric Cheng 34768275SEric Cheng /* Check property value */ 34778275SEric Cheng if (pdp->pd_check != NULL) { 34788453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 34798275SEric Cheng aip->ai_count, vdp, 0); 34808275SEric Cheng } else { 34818275SEric Cheng status = DLADM_STATUS_BADARG; 34828275SEric Cheng } 34838275SEric Cheng 34848275SEric Cheng if (status != DLADM_STATUS_OK) 34858275SEric Cheng return (status); 34868275SEric Cheng 34878275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 34888275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 34898275SEric Cheng 34908275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 34918275SEric Cheng continue; 34928275SEric Cheng 34938275SEric Cheng /* Extract kernel structure */ 34948275SEric Cheng if (rpp->rp_extract != NULL) { 34958275SEric Cheng status = rpp->rp_extract(vdp, val, 34968275SEric Cheng aip->ai_count); 34978275SEric Cheng } else { 34988275SEric Cheng status = DLADM_STATUS_BADARG; 34998275SEric Cheng } 35008275SEric Cheng break; 35018275SEric Cheng } 35028275SEric Cheng 35038275SEric Cheng if (status != DLADM_STATUS_OK) 35048275SEric Cheng return (status); 35058275SEric Cheng 35068275SEric Cheng break; 35078275SEric Cheng } 35088275SEric Cheng return (status); 35098275SEric Cheng } 35108275SEric Cheng 35118275SEric Cheng /* 35128275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 35138275SEric Cheng */ 35148275SEric Cheng dladm_status_t 35158453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 35168275SEric Cheng mac_resource_props_t *mrp) 35178275SEric Cheng { 35188275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 35198275SEric Cheng 35208453SAnurag.Maskey@Sun.COM status = i_dladm_link_proplist_extract_one(handle, proplist, "maxbw", 35218453SAnurag.Maskey@Sun.COM mrp); 35228275SEric Cheng if (status != DLADM_STATUS_OK) 35238275SEric Cheng return (status); 35248453SAnurag.Maskey@Sun.COM status = i_dladm_link_proplist_extract_one(handle, proplist, "priority", 35258453SAnurag.Maskey@Sun.COM mrp); 35268275SEric Cheng if (status != DLADM_STATUS_OK) 35278275SEric Cheng return (status); 35288453SAnurag.Maskey@Sun.COM status = i_dladm_link_proplist_extract_one(handle, proplist, "cpus", 35298453SAnurag.Maskey@Sun.COM mrp); 35308275SEric Cheng if (status != DLADM_STATUS_OK) 35318275SEric Cheng return (status); 35328275SEric Cheng return (status); 35338275SEric Cheng } 35348275SEric Cheng 35358275SEric Cheng static const char * 35368275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 35378275SEric Cheng { 35388275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 35398275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 35408275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 35418275SEric Cheng return (buf); 35428275SEric Cheng } 35438306SSowmini.Varadhan@Sun.COM 35448306SSowmini.Varadhan@Sun.COM dladm_status_t 35458453SAnurag.Maskey@Sun.COM i_dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 35468453SAnurag.Maskey@Sun.COM link_state_t *state) 35478306SSowmini.Varadhan@Sun.COM { 35488306SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 35498306SSowmini.Varadhan@Sun.COM dladm_status_t status; 35508306SSowmini.Varadhan@Sun.COM uint_t perms; 35518306SSowmini.Varadhan@Sun.COM 35528453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, "state", 0, &status, 35538453SAnurag.Maskey@Sun.COM &perms); 35548306SSowmini.Varadhan@Sun.COM if (status != DLADM_STATUS_OK) 35558306SSowmini.Varadhan@Sun.COM return (status); 35568306SSowmini.Varadhan@Sun.COM (void) memcpy(state, dip->pr_val, sizeof (*state)); 35578306SSowmini.Varadhan@Sun.COM free(dip); 35588306SSowmini.Varadhan@Sun.COM return (status); 35598306SSowmini.Varadhan@Sun.COM } 35608460SArtem.Kachitchkin@Sun.COM 35618460SArtem.Kachitchkin@Sun.COM boolean_t 35628460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 35638460SArtem.Kachitchkin@Sun.COM { 35648460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 35658460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 35668460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 35678460SArtem.Kachitchkin@Sun.COM "name", 35688460SArtem.Kachitchkin@Sun.COM "class", 35698460SArtem.Kachitchkin@Sun.COM "media", 35708460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 35718460SArtem.Kachitchkin@Sun.COM FPHYINST, 35728460SArtem.Kachitchkin@Sun.COM FDEVNAME, 35738460SArtem.Kachitchkin@Sun.COM 35748460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 35758460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 35768460SArtem.Kachitchkin@Sun.COM }; 35778460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 35788460SArtem.Kachitchkin@Sun.COM int i; 35798460SArtem.Kachitchkin@Sun.COM 35808460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 35818460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 35828460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 35838460SArtem.Kachitchkin@Sun.COM break; 35848460SArtem.Kachitchkin@Sun.COM } 35858460SArtem.Kachitchkin@Sun.COM } 35868460SArtem.Kachitchkin@Sun.COM 35878460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 35888460SArtem.Kachitchkin@Sun.COM } 3589