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> 57*10616SSebastien.Roy@Sun.COM #include <inet/iptun.h> 587663SSowmini.Varadhan@Sun.COM #include <net/wpa.h> 597663SSowmini.Varadhan@Sun.COM #include <sys/sysmacros.h> 6010491SRishi.Srivatsavai@Sun.COM #include <sys/vlan.h> 6110491SRishi.Srivatsavai@Sun.COM #include <libdlbridge.h> 6210491SRishi.Srivatsavai@Sun.COM #include <stp_in.h> 633448Sdh155122 645895Syz147064 /* 655895Syz147064 * The linkprop get() callback. 668275SEric Cheng * - pd: pointer to the prop_desc_t 675895Syz147064 * - propstrp: a property string array to keep the returned property. 685895Syz147064 * Caller allocated. 695895Syz147064 * - cntp: number of returned properties. 705895Syz147064 * Caller also uses it to indicate how many it expects. 715895Syz147064 */ 725903Ssowmini struct prop_desc; 738275SEric Cheng typedef struct prop_desc prop_desc_t; 748275SEric Cheng 758453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 765960Ssowmini datalink_id_t, char **propstp, uint_t *cntp, 778118SVasumathi.Sundaram@Sun.COM datalink_media_t, uint_t, uint_t *); 785895Syz147064 795895Syz147064 /* 805895Syz147064 * The linkprop set() callback. 815895Syz147064 * - propval: a val_desc_t array which keeps the property values to be set. 825895Syz147064 * - cnt: number of properties to be set. 835903Ssowmini * - flags: additional flags passed down the system call. 845903Ssowmini * 855903Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 865903Ssowmini * a format suitable for kernel consumption. This may require allocation 875903Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 885903Ssowmini * by all other pd_sets) which invokes the ioctl. 895895Syz147064 */ 908453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 918275SEric Cheng val_desc_t *propval, uint_t cnt, uint_t flags, 928275SEric Cheng datalink_media_t); 933448Sdh155122 945895Syz147064 /* 955895Syz147064 * The linkprop check() callback. 965895Syz147064 * - propstrp: property string array which keeps the property to be checked. 975895Syz147064 * - cnt: number of properties. 985895Syz147064 * - propval: return value; the property values of the given property strings. 995903Ssowmini * 1005903Ssowmini * pd_check checks that the input values are valid. It does so by 1015903Ssowmini * iteraring through the pd_modval list for the property. If 1025903Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 1035903Ssowmini * specific to this property can be used. If the input values are 1045903Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 1055903Ssowmini * with either a val_desc_t found on the pd_modval list or something 1065903Ssowmini * generated on the fly. 1075895Syz147064 */ 1088453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 1098453SAnurag.Maskey@Sun.COM datalink_id_t, char **propstrp, uint_t cnt, 1108453SAnurag.Maskey@Sun.COM val_desc_t *propval, datalink_media_t); 1113448Sdh155122 1127663SSowmini.Varadhan@Sun.COM typedef struct link_attr_s { 1136789Sam223141 mac_prop_id_t pp_id; 1145903Ssowmini size_t pp_valsize; 1155903Ssowmini char *pp_name; 1167663SSowmini.Varadhan@Sun.COM } link_attr_t; 1175903Ssowmini 1187663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 1198275SEric Cheng const char *, uint_t, dladm_status_t *); 1207663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 1218275SEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 1228453SAnurag.Maskey@Sun.COM static dld_ioc_macprop_t *i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 1238453SAnurag.Maskey@Sun.COM char *, uint_t, dladm_status_t *, uint_t *); 1248453SAnurag.Maskey@Sun.COM 1259692SRishi.Srivatsavai@Sun.COM static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1268453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 1278460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1288453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *, dladm_prop_type_t, 1298453SAnurag.Maskey@Sun.COM uint_t); 1307663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_name2prop(const char *); 1317663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 1328275SEric Cheng 1335895Syz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 1345895Syz147064 do_get_rate_prop, do_get_channel_prop, 1355903Ssowmini do_get_powermode_prop, do_get_radio_prop, 1367342SAruna.Ramakrishna@Sun.COM i_dladm_duplex_get, i_dladm_status_get, 1377342SAruna.Ramakrishna@Sun.COM i_dladm_binary_get, i_dladm_uint32_get, 1388460SArtem.Kachitchkin@Sun.COM i_dladm_flowctl_get, i_dladm_maxbw_get, 1398874SSebastien.Roy@Sun.COM i_dladm_cpus_get, i_dladm_priority_get, 14010491SRishi.Srivatsavai@Sun.COM i_dladm_tagmode_get, i_dladm_range_get, 14110491SRishi.Srivatsavai@Sun.COM get_stp_prop, get_bridge_forward, 14210491SRishi.Srivatsavai@Sun.COM get_bridge_pvid; 1438275SEric Cheng 1447342SAruna.Ramakrishna@Sun.COM static pd_setf_t do_set_zone, do_set_rate_prop, 1455903Ssowmini do_set_powermode_prop, do_set_radio_prop, 14610491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, do_set_res, do_set_cpus, 14710491SRishi.Srivatsavai@Sun.COM set_stp_prop, set_bridge_forward, set_bridge_pvid; 1488275SEric Cheng 1495903Ssowmini static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 150*10616SSebastien.Roy@Sun.COM do_check_hoplimit, do_check_encaplim, 15110491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, do_check_maxbw, do_check_cpus, 15210491SRishi.Srivatsavai@Sun.COM do_check_priority, check_stp_prop, check_bridge_pvid; 1538275SEric Cheng 1548453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_speed_get(dladm_handle_t, prop_desc_t *, 1558453SAnurag.Maskey@Sun.COM datalink_id_t, char **, uint_t *, uint_t, uint_t *); 1568453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1578275SEric Cheng static const char *dladm_perm2str(uint_t, char *); 1588275SEric Cheng 1598275SEric Cheng struct prop_desc { 1605895Syz147064 /* 1615895Syz147064 * link property name 1625895Syz147064 */ 1635895Syz147064 char *pd_name; 1645895Syz147064 1655895Syz147064 /* 1665895Syz147064 * default property value, can be set to { "", NULL } 1675895Syz147064 */ 1685895Syz147064 val_desc_t pd_defval; 1695895Syz147064 1705895Syz147064 /* 1715895Syz147064 * list of optional property values, can be NULL. 1725895Syz147064 * 1735895Syz147064 * This is set to non-NULL if there is a list of possible property 1745895Syz147064 * values. pd_optval would point to the array of possible values. 1755895Syz147064 */ 1765895Syz147064 val_desc_t *pd_optval; 1775895Syz147064 1785895Syz147064 /* 1795895Syz147064 * count of the above optional property values. 0 if pd_optval is NULL. 1805895Syz147064 */ 1815895Syz147064 uint_t pd_noptval; 1825895Syz147064 1835895Syz147064 /* 18410491SRishi.Srivatsavai@Sun.COM * callback to set link property; set to NULL if this property is 18510491SRishi.Srivatsavai@Sun.COM * read-only and may be called before or after permanent update; see 18610491SRishi.Srivatsavai@Sun.COM * flags. 1875895Syz147064 */ 1885895Syz147064 pd_setf_t *pd_set; 1895895Syz147064 1905895Syz147064 /* 1915895Syz147064 * callback to get modifiable link property 1925895Syz147064 */ 1935895Syz147064 pd_getf_t *pd_getmod; 1945895Syz147064 1955895Syz147064 /* 1965895Syz147064 * callback to get current link property 1975895Syz147064 */ 1985895Syz147064 pd_getf_t *pd_get; 1995895Syz147064 2005895Syz147064 /* 2015895Syz147064 * callback to validate link property value, set to NULL if pd_optval 2025895Syz147064 * is not NULL. In that case, validate the value by comparing it with 2035895Syz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 2045895Syz147064 * valid. 2055895Syz147064 */ 2065895Syz147064 pd_checkf_t *pd_check; 2075895Syz147064 2085895Syz147064 uint_t pd_flags; 2095903Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 2105903Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 21110491SRishi.Srivatsavai@Sun.COM #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 2125895Syz147064 /* 2135895Syz147064 * indicate link classes this property applies to. 2145895Syz147064 */ 2155895Syz147064 datalink_class_t pd_class; 2165895Syz147064 2175895Syz147064 /* 2185895Syz147064 * indicate link media type this property applies to. 2195895Syz147064 */ 2205895Syz147064 datalink_media_t pd_dmedia; 2218275SEric Cheng }; 2223448Sdh155122 2236789Sam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 2245903Ssowmini 2257663SSowmini.Varadhan@Sun.COM /* 2267663SSowmini.Varadhan@Sun.COM * Supported link properties enumerated in the prop_table[] array are 2277663SSowmini.Varadhan@Sun.COM * computed using the callback functions in that array. To compute the 2287663SSowmini.Varadhan@Sun.COM * property value, multiple distinct system calls may be needed (e.g., 2297663SSowmini.Varadhan@Sun.COM * for wifi speed, we need to issue system calls to get desired/supported 2307663SSowmini.Varadhan@Sun.COM * rates). The link_attr[] table enumerates the interfaces to the kernel, 2317663SSowmini.Varadhan@Sun.COM * and the type/size of the data passed in the user-kernel interface. 2327663SSowmini.Varadhan@Sun.COM */ 2337663SSowmini.Varadhan@Sun.COM static link_attr_t link_attr[] = { 2347663SSowmini.Varadhan@Sun.COM { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 2355903Ssowmini 2367663SSowmini.Varadhan@Sun.COM { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 2377663SSowmini.Varadhan@Sun.COM 2387663SSowmini.Varadhan@Sun.COM { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 2397663SSowmini.Varadhan@Sun.COM 2407663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 2415903Ssowmini 2427663SSowmini.Varadhan@Sun.COM { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 2435903Ssowmini 2447663SSowmini.Varadhan@Sun.COM { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 2457663SSowmini.Varadhan@Sun.COM 2467663SSowmini.Varadhan@Sun.COM { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 2475903Ssowmini 2487663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2497663SSowmini.Varadhan@Sun.COM 2509449Sxiuyan.wang@Sun.COM { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 2519449Sxiuyan.wang@Sun.COM 2529449Sxiuyan.wang@Sun.COM { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 2539449Sxiuyan.wang@Sun.COM 2547663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2557663SSowmini.Varadhan@Sun.COM 2567663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 2575903Ssowmini 2587663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 2595903Ssowmini 2607663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 2617663SSowmini.Varadhan@Sun.COM 2627663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 2637342SAruna.Ramakrishna@Sun.COM 2647663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 2657663SSowmini.Varadhan@Sun.COM 2667663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 2677663SSowmini.Varadhan@Sun.COM 2687663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 2697342SAruna.Ramakrishna@Sun.COM 2707663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 2717663SSowmini.Varadhan@Sun.COM 2727663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 2735903Ssowmini 2747663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 2757663SSowmini.Varadhan@Sun.COM 2767663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 2775903Ssowmini 2787663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 2797663SSowmini.Varadhan@Sun.COM 2807663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 2815903Ssowmini 2827663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 2837663SSowmini.Varadhan@Sun.COM 2847663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 2857663SSowmini.Varadhan@Sun.COM 2867663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2877663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 2885903Ssowmini 2897663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2907663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 2917663SSowmini.Varadhan@Sun.COM 2927663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 2935903Ssowmini 2947663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 2957663SSowmini.Varadhan@Sun.COM 2967663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 2975903Ssowmini 2987663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 2997663SSowmini.Varadhan@Sun.COM 3007663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 3015903Ssowmini 3027663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 3037663SSowmini.Varadhan@Sun.COM 3047663SSowmini.Varadhan@Sun.COM /* wl_wpa_ess_t has variable length */ 3057663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 3065903Ssowmini 3077663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 3087663SSowmini.Varadhan@Sun.COM 3097663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 3105903Ssowmini 3117663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 3127663SSowmini.Varadhan@Sun.COM 3137663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 3145903Ssowmini 3157663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 3167663SSowmini.Varadhan@Sun.COM 3177663SSowmini.Varadhan@Sun.COM /* wl_wpa_ie_t has variable length */ 3187663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 3195903Ssowmini 3207663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 3217663SSowmini.Varadhan@Sun.COM 3227663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 3235903Ssowmini 3247663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 3257663SSowmini.Varadhan@Sun.COM 3268275SEric Cheng { MAC_PROP_MAXBW, sizeof (mac_resource_props_t), "maxbw"}, 3278275SEric Cheng 3288275SEric Cheng { MAC_PROP_PRIO, sizeof (mac_resource_props_t), "priority"}, 3298275SEric Cheng 3308275SEric Cheng { MAC_PROP_BIND_CPU, sizeof (mac_resource_props_t), "cpus"}, 3318275SEric Cheng 3328874SSebastien.Roy@Sun.COM { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 3338874SSebastien.Roy@Sun.COM 334*10616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 335*10616SSebastien.Roy@Sun.COM 336*10616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 337*10616SSebastien.Roy@Sun.COM 33810491SRishi.Srivatsavai@Sun.COM { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 33910491SRishi.Srivatsavai@Sun.COM 34010491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 34110491SRishi.Srivatsavai@Sun.COM 34210491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 34310491SRishi.Srivatsavai@Sun.COM 3447663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3458275SEric Cheng 3465903Ssowmini }; 3475903Ssowmini 34810491SRishi.Srivatsavai@Sun.COM typedef struct bridge_public_prop_s { 34910491SRishi.Srivatsavai@Sun.COM const char *bpp_name; 35010491SRishi.Srivatsavai@Sun.COM int bpp_code; 35110491SRishi.Srivatsavai@Sun.COM } bridge_public_prop_t; 35210491SRishi.Srivatsavai@Sun.COM 35310491SRishi.Srivatsavai@Sun.COM static const bridge_public_prop_t bridge_prop[] = { 35410491SRishi.Srivatsavai@Sun.COM { "stp", PT_CFG_NON_STP }, 35510491SRishi.Srivatsavai@Sun.COM { "stp_priority", PT_CFG_PRIO }, 35610491SRishi.Srivatsavai@Sun.COM { "stp_cost", PT_CFG_COST }, 35710491SRishi.Srivatsavai@Sun.COM { "stp_edge", PT_CFG_EDGE }, 35810491SRishi.Srivatsavai@Sun.COM { "stp_p2p", PT_CFG_P2P }, 35910491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", PT_CFG_MCHECK }, 36010491SRishi.Srivatsavai@Sun.COM { NULL, 0 } 36110491SRishi.Srivatsavai@Sun.COM }; 36210491SRishi.Srivatsavai@Sun.COM 3635903Ssowmini static val_desc_t link_duplex_vals[] = { 3645903Ssowmini { "half", LINK_DUPLEX_HALF }, 3655903Ssowmini { "full", LINK_DUPLEX_HALF } 3665903Ssowmini }; 3675903Ssowmini static val_desc_t link_status_vals[] = { 3685903Ssowmini { "up", LINK_STATE_UP }, 3695903Ssowmini { "down", LINK_STATE_DOWN } 3705903Ssowmini }; 3715903Ssowmini static val_desc_t link_01_vals[] = { 3725903Ssowmini { "1", 1 }, 3735903Ssowmini { "0", 0 } 3745903Ssowmini }; 3755903Ssowmini static val_desc_t link_flow_vals[] = { 3765903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3775903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3785903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 3795903Ssowmini { "bi", LINK_FLOWCTRL_BI } 3805903Ssowmini }; 3818275SEric Cheng static val_desc_t link_priority_vals[] = { 3828275SEric Cheng { "low", MPL_LOW }, 3838275SEric Cheng { "medium", MPL_MEDIUM }, 3848275SEric Cheng { "high", MPL_HIGH } 3858275SEric Cheng }; 3865903Ssowmini 3878874SSebastien.Roy@Sun.COM static val_desc_t link_tagmode_vals[] = { 3888874SSebastien.Roy@Sun.COM { "normal", LINK_TAGMODE_NORMAL }, 3898874SSebastien.Roy@Sun.COM { "vlanonly", LINK_TAGMODE_VLANONLY } 3908874SSebastien.Roy@Sun.COM }; 3918874SSebastien.Roy@Sun.COM 3925895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 3935895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 3945895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 3955895Syz147064 }; 3965895Syz147064 3975895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 3985895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 3995895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 4005895Syz147064 { "max", DLADM_WLAN_PM_MAX } 4015895Syz147064 }; 4025895Syz147064 40310491SRishi.Srivatsavai@Sun.COM static val_desc_t stp_p2p_vals[] = { 40410491SRishi.Srivatsavai@Sun.COM { "true", P2P_FORCE_TRUE }, 40510491SRishi.Srivatsavai@Sun.COM { "false", P2P_FORCE_FALSE }, 40610491SRishi.Srivatsavai@Sun.COM { "auto", P2P_AUTO } 40710491SRishi.Srivatsavai@Sun.COM }; 40810491SRishi.Srivatsavai@Sun.COM 4098275SEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 4108275SEric Cheng #define RESET_VAL ((uintptr_t)-1) 4118275SEric Cheng 4123448Sdh155122 static prop_desc_t prop_table[] = { 4135903Ssowmini { "channel", { NULL, 0 }, 4145903Ssowmini NULL, 0, NULL, NULL, 4155895Syz147064 do_get_channel_prop, NULL, 0, 4165903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4175895Syz147064 4185895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 4195895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 4205895Syz147064 do_set_powermode_prop, NULL, 4215895Syz147064 do_get_powermode_prop, NULL, 0, 4225903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4235895Syz147064 4245895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 4255895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 4265895Syz147064 do_set_radio_prop, NULL, 4275895Syz147064 do_get_radio_prop, NULL, 0, 4285903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4295895Syz147064 4305895Syz147064 { "speed", { "", 0 }, NULL, 0, 4315895Syz147064 do_set_rate_prop, do_get_rate_mod, 4325895Syz147064 do_get_rate_prop, do_check_rate, 0, 4335960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 4345895Syz147064 4356512Ssowmini { "autopush", { "", 0 }, NULL, 0, 4367342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, 4377342SAruna.Ramakrishna@Sun.COM do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 4385903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4395895Syz147064 4406512Ssowmini { "zone", { "", 0 }, NULL, 0, 4413448Sdh155122 do_set_zone, NULL, 4427342SAruna.Ramakrishna@Sun.COM do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 4435903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4445903Ssowmini 4458275SEric Cheng { "duplex", { "", 0 }, 4465903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 4477342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_duplex_get, NULL, 4485903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4495903Ssowmini 4508275SEric Cheng { "state", { "up", LINK_STATE_UP }, 4515903Ssowmini link_status_vals, VALCNT(link_status_vals), 4527342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_status_get, NULL, 4536512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4545903Ssowmini 45510191SSowmini.Varadhan@Sun.COM { "adv_autoneg_cap", { "", 0 }, 4565903Ssowmini link_01_vals, VALCNT(link_01_vals), 4577342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4585903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4595903Ssowmini 4606512Ssowmini { "mtu", { "", 0 }, NULL, 0, 4619514SGirish.Moodalbail@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, 46210491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_get, i_dladm_uint32_check, 0, DATALINK_CLASS_ALL, 4637342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 4645903Ssowmini 4656512Ssowmini { "flowctrl", { "", 0 }, 4665903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 4677342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 4685903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4695903Ssowmini 4709449Sxiuyan.wang@Sun.COM { "adv_10gfdx_cap", { "", 0 }, 4719449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 4729449Sxiuyan.wang@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4739449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4749449Sxiuyan.wang@Sun.COM 4759449Sxiuyan.wang@Sun.COM { "en_10gfdx_cap", { "", 0 }, 4769449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 4779449Sxiuyan.wang@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4789449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4799449Sxiuyan.wang@Sun.COM 4806512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 4816512Ssowmini link_01_vals, VALCNT(link_01_vals), 4827342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4835903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4845903Ssowmini 4856512Ssowmini { "en_1000fdx_cap", { "", 0 }, 4865903Ssowmini link_01_vals, VALCNT(link_01_vals), 4877342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4885903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4895903Ssowmini 4906512Ssowmini { "adv_1000hdx_cap", { "", 0 }, 4915903Ssowmini link_01_vals, VALCNT(link_01_vals), 4927342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4935903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4945903Ssowmini 4956512Ssowmini { "en_1000hdx_cap", { "", 0 }, 4965903Ssowmini link_01_vals, VALCNT(link_01_vals), 4977342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4985903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4995903Ssowmini 5006512Ssowmini { "adv_100fdx_cap", { "", 0 }, 5015903Ssowmini link_01_vals, VALCNT(link_01_vals), 5027342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5035903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5045903Ssowmini 5056512Ssowmini { "en_100fdx_cap", { "", 0 }, 5065903Ssowmini link_01_vals, VALCNT(link_01_vals), 5077342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5085903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5095903Ssowmini 5106512Ssowmini { "adv_100hdx_cap", { "", 0 }, 5115903Ssowmini link_01_vals, VALCNT(link_01_vals), 5127342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5135903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5145903Ssowmini 5156512Ssowmini { "en_100hdx_cap", { "", 0 }, 5165903Ssowmini link_01_vals, VALCNT(link_01_vals), 5177342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5185903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5195903Ssowmini 5206512Ssowmini { "adv_10fdx_cap", { "", 0 }, 5215903Ssowmini link_01_vals, VALCNT(link_01_vals), 5227342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5235903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5245903Ssowmini 5256512Ssowmini { "en_10fdx_cap", { "", 0 }, 5265903Ssowmini link_01_vals, VALCNT(link_01_vals), 5277342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5285903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5295903Ssowmini 5306512Ssowmini { "adv_10hdx_cap", { "", 0 }, 5315903Ssowmini link_01_vals, VALCNT(link_01_vals), 5327342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5335903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5345903Ssowmini 5356512Ssowmini { "en_10hdx_cap", { "", 0 }, 5365903Ssowmini link_01_vals, VALCNT(link_01_vals), 5377342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5388275SEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5398275SEric Cheng 5408275SEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 5418275SEric Cheng do_set_res, NULL, 5428460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get, do_check_maxbw, PD_CHECK_ALLOC, 5438275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5448275SEric Cheng 5458275SEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 5468275SEric Cheng do_set_cpus, NULL, 5478460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get, do_check_cpus, 0, 5488275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5498275SEric Cheng 5508275SEric Cheng { "priority", { "high", RESET_VAL }, 5518275SEric Cheng link_priority_vals, VALCNT(link_priority_vals), do_set_res, NULL, 5528460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get, do_check_priority, PD_CHECK_ALLOC, 5538275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5548874SSebastien.Roy@Sun.COM 5558874SSebastien.Roy@Sun.COM { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 5568874SSebastien.Roy@Sun.COM link_tagmode_vals, VALCNT(link_tagmode_vals), 5578874SSebastien.Roy@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_tagmode_get, 5588874SSebastien.Roy@Sun.COM NULL, 0, 5598874SSebastien.Roy@Sun.COM DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 56010491SRishi.Srivatsavai@Sun.COM DL_ETHER }, 56110491SRishi.Srivatsavai@Sun.COM 562*10616SSebastien.Roy@Sun.COM { "hoplimit", { "", 0 }, NULL, 0, 563*10616SSebastien.Roy@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, i_dladm_uint32_get, 564*10616SSebastien.Roy@Sun.COM do_check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 565*10616SSebastien.Roy@Sun.COM 566*10616SSebastien.Roy@Sun.COM { "encaplimit", { "", 0 }, NULL, 0, 567*10616SSebastien.Roy@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, i_dladm_uint32_get, 568*10616SSebastien.Roy@Sun.COM do_check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 569*10616SSebastien.Roy@Sun.COM 57010491SRishi.Srivatsavai@Sun.COM { "forward", { "1", 1 }, 57110491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 57210491SRishi.Srivatsavai@Sun.COM set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 57310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 57410491SRishi.Srivatsavai@Sun.COM 57510491SRishi.Srivatsavai@Sun.COM { "default_tag", { "1", 1 }, NULL, 0, 57610491SRishi.Srivatsavai@Sun.COM set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 57710491SRishi.Srivatsavai@Sun.COM 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 57810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 57910491SRishi.Srivatsavai@Sun.COM 58010491SRishi.Srivatsavai@Sun.COM { "learn_limit", { "1000", 1000 }, NULL, 0, 58110491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 58210491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, 0, 58310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 58410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 58510491SRishi.Srivatsavai@Sun.COM 58610491SRishi.Srivatsavai@Sun.COM { "learn_decay", { "200", 200 }, NULL, 0, 58710491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 58810491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, 0, 58910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 59010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 59110491SRishi.Srivatsavai@Sun.COM 59210491SRishi.Srivatsavai@Sun.COM { "stp", { "1", 1 }, 59310491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 59410491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 59510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 59610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 59710491SRishi.Srivatsavai@Sun.COM 59810491SRishi.Srivatsavai@Sun.COM { "stp_priority", { "128", 128 }, NULL, 0, 59910491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 60010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 60110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 60210491SRishi.Srivatsavai@Sun.COM 60310491SRishi.Srivatsavai@Sun.COM { "stp_cost", { "auto", 0 }, NULL, 0, 60410491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 60510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 60610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 60710491SRishi.Srivatsavai@Sun.COM 60810491SRishi.Srivatsavai@Sun.COM { "stp_edge", { "1", 1 }, 60910491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 61010491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 61110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 61210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 61310491SRishi.Srivatsavai@Sun.COM 61410491SRishi.Srivatsavai@Sun.COM { "stp_p2p", { "auto", P2P_AUTO }, 61510491SRishi.Srivatsavai@Sun.COM stp_p2p_vals, VALCNT(stp_p2p_vals), 61610491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 61710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 61810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 61910491SRishi.Srivatsavai@Sun.COM 62010491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", { "0", 0 }, 62110491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 62210491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 62310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 62410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6253448Sdh155122 }; 6263448Sdh155122 6275895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 6285895Syz147064 6298275SEric Cheng static resource_prop_t rsrc_prop_table[] = { 6308275SEric Cheng {"maxbw", do_extract_maxbw}, 6318275SEric Cheng {"priority", do_extract_priority}, 6328275SEric Cheng {"cpus", do_extract_cpus} 6338275SEric Cheng }; 6348275SEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 6358275SEric Cheng sizeof (resource_prop_t)) 6368275SEric Cheng 6377663SSowmini.Varadhan@Sun.COM /* 6387663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 6397663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 6407663SSowmini.Varadhan@Sun.COM */ 6417663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 6427663SSowmini.Varadhan@Sun.COM 6438453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 6448453SAnurag.Maskey@Sun.COM const char *, char **, uint_t); 6458453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 6468453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *); 6478460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 6488460SArtem.Kachitchkin@Sun.COM datalink_id_t, void *, int (*)(dladm_handle_t, 6498460SArtem.Kachitchkin@Sun.COM datalink_id_t, const char *, void *)); 6508453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 6518453SAnurag.Maskey@Sun.COM datalink_class_t, uint32_t, prop_desc_t *, char **, 6528453SAnurag.Maskey@Sun.COM uint_t, uint_t); 6538453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 6548453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 6558453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 6568453SAnurag.Maskey@Sun.COM datalink_id_t, datalink_media_t, uint_t); 6578275SEric Cheng 6585895Syz147064 /* 6595895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 6605895Syz147064 * rates to be retrieved. However, we cannot increase it at this 6615895Syz147064 * time because it will break binary compatibility with unbundled 6625895Syz147064 * WiFi drivers and utilities. So for now we define an additional 6635895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 6645895Syz147064 */ 6655895Syz147064 #define MAX_SUPPORT_RATES 64 6665895Syz147064 6675895Syz147064 #define AP_ANCHOR "[anchor]" 6685895Syz147064 #define AP_DELIMITER '.' 6695895Syz147064 6705895Syz147064 static dladm_status_t 6715895Syz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, 6725895Syz147064 val_desc_t *vdp) 6735895Syz147064 { 6745895Syz147064 int i, j; 6755895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 6763147Sxc151355 6775895Syz147064 for (j = 0; j < val_cnt; j++) { 6785895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 6795895Syz147064 if (strcasecmp(*prop_val, 6805895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 6815895Syz147064 break; 6825895Syz147064 } 6835895Syz147064 } 6845895Syz147064 if (i == pdp->pd_noptval) { 6855895Syz147064 status = DLADM_STATUS_BADVAL; 6865895Syz147064 goto done; 6875895Syz147064 } 6885895Syz147064 (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); 6895895Syz147064 } 6905895Syz147064 6915895Syz147064 done: 6925895Syz147064 return (status); 6935895Syz147064 } 6945895Syz147064 6955895Syz147064 static dladm_status_t 6968453SAnurag.Maskey@Sun.COM i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 6978453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 6988453SAnurag.Maskey@Sun.COM uint_t val_cnt, uint_t flags) 6993147Sxc151355 { 7005895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 7015895Syz147064 val_desc_t *vdp = NULL; 7025895Syz147064 boolean_t needfree = B_FALSE; 7035895Syz147064 uint_t cnt, i; 7043147Sxc151355 7055895Syz147064 if (!(pdp->pd_class & class)) 7065895Syz147064 return (DLADM_STATUS_BADARG); 7075895Syz147064 7085895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 7093147Sxc151355 return (DLADM_STATUS_BADARG); 7103147Sxc151355 7115895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 7125895Syz147064 return (DLADM_STATUS_TEMPONLY); 7135895Syz147064 7145895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 7155895Syz147064 return (DLADM_STATUS_OK); 7165895Syz147064 7175895Syz147064 if (pdp->pd_set == NULL) 7185895Syz147064 return (DLADM_STATUS_PROPRDONLY); 7193448Sdh155122 7205895Syz147064 if (prop_val != NULL) { 7215895Syz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 7225895Syz147064 if (vdp == NULL) 7235895Syz147064 return (DLADM_STATUS_NOMEM); 7245895Syz147064 7255895Syz147064 if (pdp->pd_check != NULL) { 7268275SEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 7278453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, prop_val, 7288453SAnurag.Maskey@Sun.COM val_cnt, vdp, media); 7295895Syz147064 } else if (pdp->pd_optval != NULL) { 7305895Syz147064 status = do_check_prop(pdp, prop_val, val_cnt, vdp); 7315895Syz147064 } else { 7323448Sdh155122 status = DLADM_STATUS_BADARG; 7333147Sxc151355 } 7345895Syz147064 7353147Sxc151355 if (status != DLADM_STATUS_OK) 7365895Syz147064 goto done; 7375895Syz147064 7385895Syz147064 cnt = val_cnt; 7395895Syz147064 } else { 7408275SEric Cheng boolean_t defval = B_FALSE; 7418275SEric Cheng 7425895Syz147064 if (pdp->pd_defval.vd_name == NULL) 7435895Syz147064 return (DLADM_STATUS_NOTSUP); 7445895Syz147064 7457342SAruna.Ramakrishna@Sun.COM cnt = 1; 7468275SEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 7478275SEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 7486512Ssowmini if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 7496512Ssowmini return (DLADM_STATUS_NOMEM); 7507342SAruna.Ramakrishna@Sun.COM 7518275SEric Cheng if (defval) { 7528275SEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 7538275SEric Cheng sizeof (val_desc_t)); 7548275SEric Cheng } else if (pdp->pd_check != NULL) { 7558453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 7568453SAnurag.Maskey@Sun.COM prop_val, cnt, vdp, media); 7577342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 7587342SAruna.Ramakrishna@Sun.COM goto done; 7597342SAruna.Ramakrishna@Sun.COM } 7606512Ssowmini } else { 7618453SAnurag.Maskey@Sun.COM status = i_dladm_getset_defval(handle, pdp, linkid, 7626512Ssowmini media, flags); 7636512Ssowmini return (status); 7646512Ssowmini } 7655895Syz147064 } 76610491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_AFTER_PERM) 76710491SRishi.Srivatsavai@Sun.COM status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 76810491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_PERMONLY; 76910491SRishi.Srivatsavai@Sun.COM else 77010491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 77110491SRishi.Srivatsavai@Sun.COM media); 7725895Syz147064 if (needfree) { 7735895Syz147064 for (i = 0; i < cnt; i++) 7745903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 7753147Sxc151355 } 7765895Syz147064 done: 7775895Syz147064 free(vdp); 7785895Syz147064 return (status); 7795895Syz147064 } 7805895Syz147064 7815895Syz147064 static dladm_status_t 7828453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 7838453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 7845895Syz147064 { 7855895Syz147064 int i; 7865895Syz147064 boolean_t found = B_FALSE; 7875895Syz147064 datalink_class_t class; 7885895Syz147064 uint32_t media; 7895895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 7905895Syz147064 7918453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 7928453SAnurag.Maskey@Sun.COM NULL, 0); 7935895Syz147064 if (status != DLADM_STATUS_OK) 7945895Syz147064 return (status); 7955895Syz147064 7965895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 7975895Syz147064 prop_desc_t *pdp = &prop_table[i]; 7985895Syz147064 dladm_status_t s; 7995895Syz147064 8005895Syz147064 if (prop_name != NULL && 8015895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 8025895Syz147064 continue; 8035895Syz147064 found = B_TRUE; 8048453SAnurag.Maskey@Sun.COM s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 8058453SAnurag.Maskey@Sun.COM prop_val, val_cnt, flags); 8063448Sdh155122 8075895Syz147064 if (prop_name != NULL) { 8085895Syz147064 status = s; 8095895Syz147064 break; 8105895Syz147064 } else { 8115895Syz147064 if (s != DLADM_STATUS_OK && 8125895Syz147064 s != DLADM_STATUS_NOTSUP) 8135895Syz147064 status = s; 8145895Syz147064 } 8155895Syz147064 } 8165903Ssowmini if (!found) { 8175903Ssowmini if (prop_name[0] == '_') { 8185903Ssowmini /* other private properties */ 8199692SRishi.Srivatsavai@Sun.COM status = i_dladm_set_private_prop(handle, linkid, 8209692SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cnt, flags); 8215903Ssowmini } else { 8225903Ssowmini status = DLADM_STATUS_NOTFOUND; 8235903Ssowmini } 8245903Ssowmini } 8255895Syz147064 8265895Syz147064 return (status); 8275895Syz147064 } 8285895Syz147064 8295895Syz147064 /* 8305895Syz147064 * Set/reset link property for specific link 8315895Syz147064 */ 8325895Syz147064 dladm_status_t 8338453SAnurag.Maskey@Sun.COM dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8348453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8355895Syz147064 { 8365895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8375895Syz147064 8385895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 8395895Syz147064 (prop_val == NULL && val_cnt > 0) || 8405895Syz147064 (prop_val != NULL && val_cnt == 0) || 8415895Syz147064 (prop_name == NULL && prop_val != NULL)) { 8425895Syz147064 return (DLADM_STATUS_BADARG); 8435895Syz147064 } 8445895Syz147064 8459692SRishi.Srivatsavai@Sun.COM /* 8469692SRishi.Srivatsavai@Sun.COM * Check for valid link property against the flags passed 8479692SRishi.Srivatsavai@Sun.COM * and set the link property when active flag is passed. 8489692SRishi.Srivatsavai@Sun.COM */ 8498453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 8505895Syz147064 val_cnt, flags); 8515895Syz147064 if (status != DLADM_STATUS_OK) 8525895Syz147064 return (status); 8535895Syz147064 8545895Syz147064 if (flags & DLADM_OPT_PERSIST) { 8558453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 8563147Sxc151355 prop_val, val_cnt); 85710491SRishi.Srivatsavai@Sun.COM 85810491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 85910491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp = prop_table; 86010491SRishi.Srivatsavai@Sun.COM int i; 86110491SRishi.Srivatsavai@Sun.COM 86210491SRishi.Srivatsavai@Sun.COM for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 86310491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_flags & PD_AFTER_PERM)) 86410491SRishi.Srivatsavai@Sun.COM continue; 86510491SRishi.Srivatsavai@Sun.COM if (prop_name != NULL && 86610491SRishi.Srivatsavai@Sun.COM strcasecmp(prop_name, pdp->pd_name) != 0) 86710491SRishi.Srivatsavai@Sun.COM continue; 86810491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, NULL, 86910491SRishi.Srivatsavai@Sun.COM 0, flags, 0); 87010491SRishi.Srivatsavai@Sun.COM } 87110491SRishi.Srivatsavai@Sun.COM } 8723147Sxc151355 } 8733147Sxc151355 return (status); 8743147Sxc151355 } 8753147Sxc151355 8765895Syz147064 /* 8778460SArtem.Kachitchkin@Sun.COM * Walk all link properties of the given specific link. 8788460SArtem.Kachitchkin@Sun.COM * 8798460SArtem.Kachitchkin@Sun.COM * Note: this function currently lacks the ability to walk _all_ private 8808460SArtem.Kachitchkin@Sun.COM * properties if the link, because there is no kernel interface to 8818460SArtem.Kachitchkin@Sun.COM * retrieve all known private property names. Once such an interface 8828460SArtem.Kachitchkin@Sun.COM * is added, this function should be fixed accordingly. 8835895Syz147064 */ 8843147Sxc151355 dladm_status_t 8858453SAnurag.Maskey@Sun.COM dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 8868453SAnurag.Maskey@Sun.COM int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 8873147Sxc151355 { 8885895Syz147064 dladm_status_t status; 8895895Syz147064 datalink_class_t class; 8905895Syz147064 uint_t media; 8915895Syz147064 int i; 8925895Syz147064 8935895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 8945895Syz147064 return (DLADM_STATUS_BADARG); 8955895Syz147064 8968453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 8978453SAnurag.Maskey@Sun.COM NULL, 0); 8985895Syz147064 if (status != DLADM_STATUS_OK) 8995895Syz147064 return (status); 9005895Syz147064 9018460SArtem.Kachitchkin@Sun.COM /* public */ 9025895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 9035895Syz147064 if (!(prop_table[i].pd_class & class)) 9045895Syz147064 continue; 9055895Syz147064 9065895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 9075895Syz147064 continue; 9085895Syz147064 9098453SAnurag.Maskey@Sun.COM if (func(handle, linkid, prop_table[i].pd_name, arg) == 9105895Syz147064 DLADM_WALK_TERMINATE) { 9115895Syz147064 break; 9125895Syz147064 } 9135895Syz147064 } 9145895Syz147064 9158460SArtem.Kachitchkin@Sun.COM /* private */ 9168460SArtem.Kachitchkin@Sun.COM status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 9178460SArtem.Kachitchkin@Sun.COM 9188460SArtem.Kachitchkin@Sun.COM return (status); 9195895Syz147064 } 9203448Sdh155122 9215895Syz147064 /* 9225895Syz147064 * Get linkprop of the given specific link. 9235895Syz147064 */ 9245895Syz147064 dladm_status_t 9258453SAnurag.Maskey@Sun.COM dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9268453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, const char *prop_name, char **prop_val, 9278453SAnurag.Maskey@Sun.COM uint_t *val_cntp) 9285895Syz147064 { 9295895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9305895Syz147064 datalink_class_t class; 9315895Syz147064 uint_t media; 9325895Syz147064 prop_desc_t *pdp; 9336512Ssowmini uint_t cnt, dld_flags = 0; 9345895Syz147064 int i; 9358118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 9365895Syz147064 9376512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 9389514SGirish.Moodalbail@Sun.COM dld_flags |= MAC_PROP_DEFAULT; 9399514SGirish.Moodalbail@Sun.COM else if (type == DLADM_PROP_VAL_MODIFIABLE) 9409514SGirish.Moodalbail@Sun.COM dld_flags |= MAC_PROP_POSSIBLE; 9416512Ssowmini 9425895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 9435895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 9445895Syz147064 return (DLADM_STATUS_BADARG); 9455895Syz147064 9465895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 9475895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 9485895Syz147064 break; 9495895Syz147064 9505903Ssowmini if (i == DLADM_MAX_PROPS) { 9515903Ssowmini if (prop_name[0] == '_') { 9525903Ssowmini /* 9535903Ssowmini * private property. 9545903Ssowmini */ 9558460SArtem.Kachitchkin@Sun.COM if (type == DLADM_PROP_VAL_PERSISTENT) 9568460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_linkprop_db(handle, linkid, 9578460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp)); 9588460SArtem.Kachitchkin@Sun.COM else 9598460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_priv_prop(handle, linkid, 9608460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp, type, 9618460SArtem.Kachitchkin@Sun.COM dld_flags)); 9625903Ssowmini } else { 9635903Ssowmini return (DLADM_STATUS_NOTFOUND); 9645903Ssowmini } 9655903Ssowmini } 9665895Syz147064 9675895Syz147064 pdp = &prop_table[i]; 9685895Syz147064 9698453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9708453SAnurag.Maskey@Sun.COM NULL, 0); 9715895Syz147064 if (status != DLADM_STATUS_OK) 9725895Syz147064 return (status); 9735895Syz147064 9745895Syz147064 if (!(pdp->pd_class & class)) 9755895Syz147064 return (DLADM_STATUS_BADARG); 9765895Syz147064 9775895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 9783147Sxc151355 return (DLADM_STATUS_BADARG); 9793147Sxc151355 9805895Syz147064 switch (type) { 9815895Syz147064 case DLADM_PROP_VAL_CURRENT: 9828453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 9838453SAnurag.Maskey@Sun.COM media, dld_flags, &perm_flags); 9848118SVasumathi.Sundaram@Sun.COM break; 9858118SVasumathi.Sundaram@Sun.COM 9868118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 9878118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 9888118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 9898118SVasumathi.Sundaram@Sun.COM } else { 9908453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 9918453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 9928118SVasumathi.Sundaram@Sun.COM } 9938118SVasumathi.Sundaram@Sun.COM 9948118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 9959055SMichael.Lim@Sun.COM *val_cntp = 1; 9968275SEric Cheng if (status == DLADM_STATUS_OK) 9978275SEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 9985895Syz147064 break; 9995895Syz147064 10005895Syz147064 case DLADM_PROP_VAL_DEFAULT: 10016768Sar224390 /* 10026768Sar224390 * If defaults are not defined for the property, 10036768Sar224390 * pd_defval.vd_name should be null. If the driver 10046768Sar224390 * has to be contacted for the value, vd_name should 10056768Sar224390 * be the empty string (""). Otherwise, dladm will 10066768Sar224390 * just print whatever is in the table. 10076768Sar224390 */ 10085895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 10095895Syz147064 status = DLADM_STATUS_NOTSUP; 10105895Syz147064 break; 10115895Syz147064 } 10126512Ssowmini 10136512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 10148453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 10158453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10166512Ssowmini } else { 10176512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 10186512Ssowmini } 10195895Syz147064 *val_cntp = 1; 10205895Syz147064 break; 10213448Sdh155122 10225895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 10235895Syz147064 if (pdp->pd_getmod != NULL) { 10248453SAnurag.Maskey@Sun.COM status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 10258118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10265895Syz147064 break; 10275895Syz147064 } 10285895Syz147064 cnt = pdp->pd_noptval; 10295895Syz147064 if (cnt == 0) { 10305895Syz147064 status = DLADM_STATUS_NOTSUP; 10315895Syz147064 } else if (cnt > *val_cntp) { 10325895Syz147064 status = DLADM_STATUS_TOOSMALL; 10335895Syz147064 } else { 10345895Syz147064 for (i = 0; i < cnt; i++) { 10355895Syz147064 (void) strcpy(prop_val[i], 10365895Syz147064 pdp->pd_optval[i].vd_name); 10375895Syz147064 } 10385895Syz147064 *val_cntp = cnt; 10395895Syz147064 } 10405895Syz147064 break; 10415895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 10425895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 10435895Syz147064 return (DLADM_STATUS_TEMPONLY); 10448453SAnurag.Maskey@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 10455895Syz147064 prop_val, val_cntp); 10465895Syz147064 break; 10475895Syz147064 default: 10485895Syz147064 status = DLADM_STATUS_BADARG; 10495895Syz147064 break; 10503147Sxc151355 } 10513448Sdh155122 10525895Syz147064 return (status); 10535895Syz147064 } 10545895Syz147064 105510491SRishi.Srivatsavai@Sun.COM /* 105610491SRishi.Srivatsavai@Sun.COM * Get linkprop of the given specific link and run any possible conversion 105710491SRishi.Srivatsavai@Sun.COM * of the values using the check function for the property. Fails if the 105810491SRishi.Srivatsavai@Sun.COM * check function doesn't succeed for the property value. 105910491SRishi.Srivatsavai@Sun.COM */ 106010491SRishi.Srivatsavai@Sun.COM dladm_status_t 106110491SRishi.Srivatsavai@Sun.COM dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 106210491SRishi.Srivatsavai@Sun.COM dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 106310491SRishi.Srivatsavai@Sun.COM uint_t *val_cntp) 106410491SRishi.Srivatsavai@Sun.COM { 106510491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 106610491SRishi.Srivatsavai@Sun.COM datalink_class_t class; 106710491SRishi.Srivatsavai@Sun.COM uint_t media; 106810491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp; 106910491SRishi.Srivatsavai@Sun.COM uint_t dld_flags; 107010491SRishi.Srivatsavai@Sun.COM int valc, i; 107110491SRishi.Srivatsavai@Sun.COM char **prop_val; 107210491SRishi.Srivatsavai@Sun.COM uint_t perm_flags; 107310491SRishi.Srivatsavai@Sun.COM 107410491SRishi.Srivatsavai@Sun.COM if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 107510491SRishi.Srivatsavai@Sun.COM ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 107610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 107710491SRishi.Srivatsavai@Sun.COM 107810491SRishi.Srivatsavai@Sun.COM for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 107910491SRishi.Srivatsavai@Sun.COM if (strcasecmp(prop_name, pdp->pd_name) == 0) 108010491SRishi.Srivatsavai@Sun.COM break; 108110491SRishi.Srivatsavai@Sun.COM 108210491SRishi.Srivatsavai@Sun.COM if (pdp == prop_table + DLADM_MAX_PROPS) 108310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTFOUND); 108410491SRishi.Srivatsavai@Sun.COM 108510491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_CHECK_ALLOC) 108610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 108710491SRishi.Srivatsavai@Sun.COM 108810491SRishi.Srivatsavai@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 108910491SRishi.Srivatsavai@Sun.COM NULL, 0); 109010491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 109110491SRishi.Srivatsavai@Sun.COM return (status); 109210491SRishi.Srivatsavai@Sun.COM 109310491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_class & class)) 109410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 109510491SRishi.Srivatsavai@Sun.COM 109610491SRishi.Srivatsavai@Sun.COM if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 109710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 109810491SRishi.Srivatsavai@Sun.COM 109910491SRishi.Srivatsavai@Sun.COM prop_val = malloc(*val_cntp * sizeof (*prop_val) + 110010491SRishi.Srivatsavai@Sun.COM *val_cntp * DLADM_PROP_VAL_MAX); 110110491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) 110210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOMEM); 110310491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 110410491SRishi.Srivatsavai@Sun.COM prop_val[valc] = (char *)(prop_val + *val_cntp) + 110510491SRishi.Srivatsavai@Sun.COM valc * DLADM_PROP_VAL_MAX; 110610491SRishi.Srivatsavai@Sun.COM 110710491SRishi.Srivatsavai@Sun.COM dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? MAC_PROP_DEFAULT : 0; 110810491SRishi.Srivatsavai@Sun.COM 110910491SRishi.Srivatsavai@Sun.COM switch (type) { 111010491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_CURRENT: 111110491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 111210491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 111310491SRishi.Srivatsavai@Sun.COM break; 111410491SRishi.Srivatsavai@Sun.COM 111510491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_DEFAULT: 111610491SRishi.Srivatsavai@Sun.COM /* 111710491SRishi.Srivatsavai@Sun.COM * If defaults are not defined for the property, 111810491SRishi.Srivatsavai@Sun.COM * pd_defval.vd_name should be null. If the driver 111910491SRishi.Srivatsavai@Sun.COM * has to be contacted for the value, vd_name should 112010491SRishi.Srivatsavai@Sun.COM * be the empty string (""). Otherwise, dladm will 112110491SRishi.Srivatsavai@Sun.COM * just print whatever is in the table. 112210491SRishi.Srivatsavai@Sun.COM */ 112310491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name == NULL) { 112410491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOTSUP; 112510491SRishi.Srivatsavai@Sun.COM break; 112610491SRishi.Srivatsavai@Sun.COM } 112710491SRishi.Srivatsavai@Sun.COM 112810491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name[0] != '\0') { 112910491SRishi.Srivatsavai@Sun.COM *val_cntp = 1; 113010491SRishi.Srivatsavai@Sun.COM *ret_val = pdp->pd_defval.vd_val; 113110491SRishi.Srivatsavai@Sun.COM free(prop_val); 113210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 113310491SRishi.Srivatsavai@Sun.COM } 113410491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 113510491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 113610491SRishi.Srivatsavai@Sun.COM break; 113710491SRishi.Srivatsavai@Sun.COM 113810491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_PERSISTENT: 113910491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_TEMPONLY) 114010491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_TEMPONLY; 114110491SRishi.Srivatsavai@Sun.COM else 114210491SRishi.Srivatsavai@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, 114310491SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cntp); 114410491SRishi.Srivatsavai@Sun.COM break; 114510491SRishi.Srivatsavai@Sun.COM 114610491SRishi.Srivatsavai@Sun.COM default: 114710491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_BADARG; 114810491SRishi.Srivatsavai@Sun.COM break; 114910491SRishi.Srivatsavai@Sun.COM } 115010491SRishi.Srivatsavai@Sun.COM 115110491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 115210491SRishi.Srivatsavai@Sun.COM if (pdp->pd_check != NULL) { 115310491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp; 115410491SRishi.Srivatsavai@Sun.COM 115510491SRishi.Srivatsavai@Sun.COM vdp = malloc(sizeof (val_desc_t) * *val_cntp); 115610491SRishi.Srivatsavai@Sun.COM if (vdp == NULL) 115710491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOMEM; 115810491SRishi.Srivatsavai@Sun.COM else 115910491SRishi.Srivatsavai@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 116010491SRishi.Srivatsavai@Sun.COM prop_val, *val_cntp, vdp, media); 116110491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 116210491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 116310491SRishi.Srivatsavai@Sun.COM ret_val[valc] = vdp[valc].vd_val; 116410491SRishi.Srivatsavai@Sun.COM } 116510491SRishi.Srivatsavai@Sun.COM free(vdp); 116610491SRishi.Srivatsavai@Sun.COM } else { 116710491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) { 116810491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pdp->pd_noptval; i++) { 116910491SRishi.Srivatsavai@Sun.COM if (strcmp(pdp->pd_optval[i].vd_name, 117010491SRishi.Srivatsavai@Sun.COM prop_val[valc]) == 0) { 117110491SRishi.Srivatsavai@Sun.COM ret_val[valc] = 117210491SRishi.Srivatsavai@Sun.COM pdp->pd_optval[i].vd_val; 117310491SRishi.Srivatsavai@Sun.COM break; 117410491SRishi.Srivatsavai@Sun.COM } 117510491SRishi.Srivatsavai@Sun.COM } 117610491SRishi.Srivatsavai@Sun.COM if (i == pdp->pd_noptval) { 117710491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_FAILED; 117810491SRishi.Srivatsavai@Sun.COM break; 117910491SRishi.Srivatsavai@Sun.COM } 118010491SRishi.Srivatsavai@Sun.COM } 118110491SRishi.Srivatsavai@Sun.COM } 118210491SRishi.Srivatsavai@Sun.COM } 118310491SRishi.Srivatsavai@Sun.COM 118410491SRishi.Srivatsavai@Sun.COM free(prop_val); 118510491SRishi.Srivatsavai@Sun.COM 118610491SRishi.Srivatsavai@Sun.COM return (status); 118710491SRishi.Srivatsavai@Sun.COM } 118810491SRishi.Srivatsavai@Sun.COM 11895895Syz147064 /*ARGSUSED*/ 11905895Syz147064 static int 11918453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 11928453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 11935895Syz147064 { 11945895Syz147064 char *buf, **propvals; 11955895Syz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 11965895Syz147064 11975895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 11985895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 11995895Syz147064 return (DLADM_WALK_CONTINUE); 12005895Syz147064 } 12015895Syz147064 12025895Syz147064 propvals = (char **)(void *)buf; 12035895Syz147064 for (i = 0; i < valcnt; i++) { 12045895Syz147064 propvals[i] = buf + 12055895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 12065895Syz147064 i * DLADM_PROP_VAL_MAX; 12075895Syz147064 } 12085895Syz147064 12098453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 12108453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 12115895Syz147064 goto done; 12125895Syz147064 } 12135895Syz147064 12148453SAnurag.Maskey@Sun.COM (void) dladm_set_linkprop(handle, linkid, prop_name, propvals, valcnt, 12155895Syz147064 DLADM_OPT_ACTIVE); 12165895Syz147064 12175895Syz147064 done: 12185895Syz147064 if (buf != NULL) 12195895Syz147064 free(buf); 12205895Syz147064 12215895Syz147064 return (DLADM_WALK_CONTINUE); 12225895Syz147064 } 12235895Syz147064 12245895Syz147064 /*ARGSUSED*/ 12255895Syz147064 static int 12268453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 12275895Syz147064 { 12288275SEric Cheng datalink_class_t class; 12298275SEric Cheng dladm_status_t status; 12308275SEric Cheng 12318453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 12328453SAnurag.Maskey@Sun.COM NULL, 0); 12338275SEric Cheng if (status != DLADM_STATUS_OK) 12348275SEric Cheng return (DLADM_WALK_TERMINATE); 12358275SEric Cheng 12368275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 12378453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 12388275SEric Cheng 12395895Syz147064 return (DLADM_WALK_CONTINUE); 12405895Syz147064 } 12415895Syz147064 12425895Syz147064 dladm_status_t 12438453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 12448453SAnurag.Maskey@Sun.COM boolean_t any_media) 12455895Syz147064 { 12466916Sartem datalink_media_t dmedia; 12476916Sartem uint32_t media; 12486916Sartem 12496916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 12506916Sartem 12515895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 12528453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 12538453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 12548453SAnurag.Maskey@Sun.COM } else if (any_media || 12558453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 12568453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 12576916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 12588453SAnurag.Maskey@Sun.COM (void) dladm_walk_linkprop(handle, linkid, NULL, 12598453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 12603448Sdh155122 } 12613448Sdh155122 return (DLADM_STATUS_OK); 12623147Sxc151355 } 12633147Sxc151355 12645903Ssowmini /* ARGSUSED */ 12655895Syz147064 static dladm_status_t 12668453SAnurag.Maskey@Sun.COM do_get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 12678275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 12688275SEric Cheng uint_t flags, uint_t *perm_flags) 12693147Sxc151355 { 12708275SEric Cheng char zone_name[ZONENAME_MAX]; 12718275SEric Cheng zoneid_t zid; 12728275SEric Cheng dladm_status_t status; 12738275SEric Cheng char *cp; 12747342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 12753147Sxc151355 12766512Ssowmini if (flags != 0) 12776512Ssowmini return (DLADM_STATUS_NOTSUP); 12786512Ssowmini 12798453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 12808275SEric Cheng &status, perm_flags); 12815895Syz147064 if (status != DLADM_STATUS_OK) 12823448Sdh155122 return (status); 12833448Sdh155122 12847342SAruna.Ramakrishna@Sun.COM cp = dip->pr_val; 12857342SAruna.Ramakrishna@Sun.COM (void) memcpy(&zid, cp, sizeof (zid)); 12867342SAruna.Ramakrishna@Sun.COM free(dip); 12877342SAruna.Ramakrishna@Sun.COM 12885895Syz147064 *val_cnt = 1; 12895895Syz147064 if (zid != GLOBAL_ZONEID) { 12908118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 12915895Syz147064 return (dladm_errno2status(errno)); 12928118SVasumathi.Sundaram@Sun.COM } 12933147Sxc151355 12945895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 12953147Sxc151355 } else { 12965895Syz147064 *prop_val[0] = '\0'; 12973147Sxc151355 } 12983147Sxc151355 12993448Sdh155122 return (DLADM_STATUS_OK); 13003448Sdh155122 } 13013448Sdh155122 13023448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 13033448Sdh155122 13043448Sdh155122 static int 13053448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 13063448Sdh155122 { 13073448Sdh155122 char root[MAXPATHLEN]; 13083448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 13093448Sdh155122 void *dlhandle; 13103448Sdh155122 void *sym; 13113448Sdh155122 int ret; 13123448Sdh155122 13133448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 13143448Sdh155122 return (-1); 13153448Sdh155122 13163448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 13173448Sdh155122 (void) dlclose(dlhandle); 13183448Sdh155122 return (-1); 13193448Sdh155122 } 13203448Sdh155122 13213448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 13223448Sdh155122 13233448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 13243448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 13253448Sdh155122 (void) dlclose(dlhandle); 13263448Sdh155122 return (ret); 13273448Sdh155122 } 13283448Sdh155122 13293448Sdh155122 static dladm_status_t 13308453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 13318453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 13323448Sdh155122 { 13333448Sdh155122 char path[MAXPATHLEN]; 13345895Syz147064 char name[MAXLINKNAMELEN]; 13353448Sdh155122 di_prof_t prof = NULL; 13363448Sdh155122 char zone_name[ZONENAME_MAX]; 13373448Sdh155122 dladm_status_t status; 13385895Syz147064 int ret; 13393448Sdh155122 13403448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 13413448Sdh155122 return (dladm_errno2status(errno)); 13423448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 13433448Sdh155122 return (dladm_errno2status(errno)); 13443448Sdh155122 if (di_prof_init(path, &prof) != 0) 13453448Sdh155122 return (dladm_errno2status(errno)); 13463448Sdh155122 13478453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 13485895Syz147064 if (status != DLADM_STATUS_OK) 13495895Syz147064 goto cleanup; 13505895Syz147064 13515895Syz147064 if (add) 13525895Syz147064 ret = di_prof_add_dev(prof, name); 13535895Syz147064 else 13545895Syz147064 ret = di_prof_add_exclude(prof, name); 13555895Syz147064 13565895Syz147064 if (ret != 0) { 13573448Sdh155122 status = dladm_errno2status(errno); 13583448Sdh155122 goto cleanup; 13593448Sdh155122 } 13603448Sdh155122 13613448Sdh155122 if (di_prof_commit(prof) != 0) 13623448Sdh155122 status = dladm_errno2status(errno); 13633448Sdh155122 cleanup: 13643448Sdh155122 if (prof) 13653448Sdh155122 di_prof_fini(prof); 13663448Sdh155122 13673448Sdh155122 return (status); 13683448Sdh155122 } 13693448Sdh155122 13705903Ssowmini /* ARGSUSED */ 13713448Sdh155122 static dladm_status_t 13728453SAnurag.Maskey@Sun.COM do_set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13738453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 13743448Sdh155122 { 13758275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 13768275SEric Cheng zoneid_t zid_old, zid_new; 13778275SEric Cheng char *cp; 13787342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 13797342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 13803448Sdh155122 13813448Sdh155122 if (val_cnt != 1) 13823448Sdh155122 return (DLADM_STATUS_BADVALCNT); 13833448Sdh155122 13847342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 13857342SAruna.Ramakrishna@Sun.COM 13868453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 13878275SEric Cheng &status, NULL); 13888275SEric Cheng if (status != DLADM_STATUS_OK) 13898275SEric Cheng return (status); 13908275SEric Cheng 13918275SEric Cheng cp = dip->pr_val; 13928275SEric Cheng (void) memcpy(&zid_old, cp, sizeof (zid_old)); 13938275SEric Cheng free(dip); 13947342SAruna.Ramakrishna@Sun.COM 13957342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 13963448Sdh155122 if (zid_new == zid_old) 1397*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 1398*10616SSebastien.Roy@Sun.COM 1399*10616SSebastien.Roy@Sun.COM if ((status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, val_cnt, 1400*10616SSebastien.Roy@Sun.COM flags, media)) != DLADM_STATUS_OK) 14015895Syz147064 return (status); 14025895Syz147064 1403*10616SSebastien.Roy@Sun.COM /* 1404*10616SSebastien.Roy@Sun.COM * It is okay to fail to update the /dev entry (some vanity-named 1405*10616SSebastien.Roy@Sun.COM * links do not have a /dev entry). 1406*10616SSebastien.Roy@Sun.COM */ 14073448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 14088453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 14098453SAnurag.Maskey@Sun.COM B_FALSE); 14105895Syz147064 } 1411*10616SSebastien.Roy@Sun.COM if (zid_new != GLOBAL_ZONEID) 14128453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 14133448Sdh155122 14143448Sdh155122 return (DLADM_STATUS_OK); 14153448Sdh155122 } 14163448Sdh155122 14173448Sdh155122 /* ARGSUSED */ 14183448Sdh155122 static dladm_status_t 14198453SAnurag.Maskey@Sun.COM do_check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14208453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 14213448Sdh155122 { 14227342SAruna.Ramakrishna@Sun.COM char *zone_name; 14237342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 14247342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 14257342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14263448Sdh155122 14273448Sdh155122 if (val_cnt != 1) 14283448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14293448Sdh155122 14307342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 14317342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 14327342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 14333448Sdh155122 14348275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 14357342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 14367342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14377342SAruna.Ramakrishna@Sun.COM goto done; 14387342SAruna.Ramakrishna@Sun.COM } 14397342SAruna.Ramakrishna@Sun.COM 14407342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 14413448Sdh155122 ushort_t flags; 14423448Sdh155122 14437342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 14443448Sdh155122 sizeof (flags)) < 0) { 14457342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 14467342SAruna.Ramakrishna@Sun.COM goto done; 14473448Sdh155122 } 14483448Sdh155122 14493448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 14507342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14517342SAruna.Ramakrishna@Sun.COM goto done; 14523448Sdh155122 } 14533448Sdh155122 } 14543448Sdh155122 14557342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 14567342SAruna.Ramakrishna@Sun.COM 14577342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 1458*10616SSebastien.Roy@Sun.COM dzp->diz_linkid = linkid; 14597342SAruna.Ramakrishna@Sun.COM 14607342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 14615895Syz147064 return (DLADM_STATUS_OK); 14627342SAruna.Ramakrishna@Sun.COM done: 14637342SAruna.Ramakrishna@Sun.COM free(dzp); 14647342SAruna.Ramakrishna@Sun.COM return (status); 14655895Syz147064 } 14665895Syz147064 14675903Ssowmini /* ARGSUSED */ 14685895Syz147064 static dladm_status_t 14698460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14708275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 14718275SEric Cheng uint_t flags, uint_t *perm_flags) 14728275SEric Cheng { 14738275SEric Cheng dld_ioc_macprop_t *dip; 14748275SEric Cheng mac_resource_props_t mrp; 14758275SEric Cheng dladm_status_t status; 14768275SEric Cheng 14778453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 14788275SEric Cheng &status, perm_flags); 14798275SEric Cheng if (dip == NULL) 14808275SEric Cheng return (status); 14818275SEric Cheng 14828275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 14838275SEric Cheng free(dip); 14848275SEric Cheng 14858275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 14868275SEric Cheng (*prop_val)[0] = '\0'; 14878275SEric Cheng } else { 14888275SEric Cheng (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 14898275SEric Cheng } 14908275SEric Cheng *val_cnt = 1; 14918275SEric Cheng return (DLADM_STATUS_OK); 14928275SEric Cheng } 14938275SEric Cheng 14948275SEric Cheng /* ARGSUSED */ 14958275SEric Cheng static dladm_status_t 14968453SAnurag.Maskey@Sun.COM do_check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14978453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 14988275SEric Cheng { 14998275SEric Cheng uint64_t *maxbw; 15008275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 15018275SEric Cheng 15028275SEric Cheng if (val_cnt != 1) 15038275SEric Cheng return (DLADM_STATUS_BADVALCNT); 15048275SEric Cheng 15058275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 15068275SEric Cheng if (maxbw == NULL) 15078275SEric Cheng return (DLADM_STATUS_NOMEM); 15088275SEric Cheng 15098275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 15108275SEric Cheng if (status != DLADM_STATUS_OK) { 15118275SEric Cheng free(maxbw); 15128275SEric Cheng return (status); 15138275SEric Cheng } 15148275SEric Cheng 15158275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 15168275SEric Cheng free(maxbw); 15178275SEric Cheng return (DLADM_STATUS_MINMAXBW); 15188275SEric Cheng } 15198275SEric Cheng 15208275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 15218275SEric Cheng return (DLADM_STATUS_OK); 15228275SEric Cheng } 15238275SEric Cheng 15248275SEric Cheng /* ARGSUSED */ 15258275SEric Cheng dladm_status_t 15268275SEric Cheng do_extract_maxbw(val_desc_t *vdp, void *arg, uint_t cnt) 15278275SEric Cheng { 15288275SEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 15298275SEric Cheng 15308275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 15318275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 15328275SEric Cheng 15338275SEric Cheng return (DLADM_STATUS_OK); 15348275SEric Cheng } 15358275SEric Cheng 15368275SEric Cheng /* ARGSUSED */ 15378275SEric Cheng static dladm_status_t 15388460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15398275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15408275SEric Cheng uint_t flags, uint_t *perm_flags) 15418275SEric Cheng { 15428275SEric Cheng dld_ioc_macprop_t *dip; 15438275SEric Cheng mac_resource_props_t mrp; 15448275SEric Cheng int i; 15458275SEric Cheng uint32_t ncpus; 15468275SEric Cheng uchar_t *cp; 15478275SEric Cheng dladm_status_t status; 15488275SEric Cheng 15498453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15508275SEric Cheng &status, perm_flags); 15518275SEric Cheng if (dip == NULL) 15528275SEric Cheng return (status); 15538275SEric Cheng 15548275SEric Cheng cp = (uchar_t *)dip->pr_val; 15558275SEric Cheng (void) memcpy(&mrp, cp, sizeof (mac_resource_props_t)); 15568275SEric Cheng free(dip); 15578275SEric Cheng 15588275SEric Cheng ncpus = mrp.mrp_ncpus; 15598275SEric Cheng 15608275SEric Cheng if (ncpus > *val_cnt) 15618275SEric Cheng return (DLADM_STATUS_TOOSMALL); 15628275SEric Cheng 15638275SEric Cheng if (ncpus == 0) { 15648275SEric Cheng (*prop_val)[0] = '\0'; 15658275SEric Cheng *val_cnt = 1; 15668275SEric Cheng return (DLADM_STATUS_OK); 15678275SEric Cheng } 15688275SEric Cheng 15698275SEric Cheng *val_cnt = ncpus; 15708275SEric Cheng for (i = 0; i < ncpus; i++) { 15718275SEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 15728275SEric Cheng "%u", mrp.mrp_cpu[i]); 15738275SEric Cheng } 15748275SEric Cheng return (DLADM_STATUS_OK); 15758275SEric Cheng } 15768275SEric Cheng 15778275SEric Cheng /* ARGSUSED */ 15788275SEric Cheng static dladm_status_t 15798453SAnurag.Maskey@Sun.COM do_set_res(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15808453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 15818275SEric Cheng { 15828275SEric Cheng mac_resource_props_t mrp; 15838275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 15848275SEric Cheng dld_ioc_macprop_t *dip; 15858275SEric Cheng 15868275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 15878275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 15888275SEric Cheng flags, &status); 15898275SEric Cheng 15908275SEric Cheng if (dip == NULL) 15918275SEric Cheng return (status); 15928275SEric Cheng 15938275SEric Cheng if (vdp->vd_val == RESET_VAL) { 15948275SEric Cheng switch (dip->pr_num) { 15958275SEric Cheng case MAC_PROP_MAXBW: 15968275SEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 15978275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 15988275SEric Cheng break; 15998275SEric Cheng case MAC_PROP_PRIO: 16008275SEric Cheng mrp.mrp_priority = MPL_RESET; 16018275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16028275SEric Cheng break; 16038275SEric Cheng default: 16048275SEric Cheng free(dip); 16058275SEric Cheng return (DLADM_STATUS_BADARG); 16068275SEric Cheng } 16078275SEric Cheng } else { 16088275SEric Cheng switch (dip->pr_num) { 16098275SEric Cheng case MAC_PROP_MAXBW: 16108275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_maxbw, 16118275SEric Cheng sizeof (uint64_t)); 16128275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16138275SEric Cheng break; 16148275SEric Cheng case MAC_PROP_PRIO: 16158275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_priority, 16168275SEric Cheng sizeof (mac_priority_level_t)); 16178275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16188275SEric Cheng break; 16198275SEric Cheng default: 16208275SEric Cheng free(dip); 16218275SEric Cheng return (DLADM_STATUS_BADARG); 16228275SEric Cheng } 16238275SEric Cheng } 16248275SEric Cheng 16258275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 16268453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 16278275SEric Cheng free(dip); 16288275SEric Cheng return (status); 16298275SEric Cheng } 16308275SEric Cheng 16318275SEric Cheng /* ARGSUSED */ 16328275SEric Cheng static dladm_status_t 16338453SAnurag.Maskey@Sun.COM do_set_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16348453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16358275SEric Cheng { 16368275SEric Cheng mac_resource_props_t mrp; 16378275SEric Cheng dladm_status_t status; 16388275SEric Cheng dld_ioc_macprop_t *dip; 16398275SEric Cheng datalink_class_t class; 16408275SEric Cheng 16418275SEric Cheng /* 16428275SEric Cheng * CPU bindings can be set on VNIC and regular physical links. 16438275SEric Cheng * However VNICs fails the dladm_phys_info test(). So apply 16448275SEric Cheng * the phys_info test only on physical links. 16458275SEric Cheng */ 16468453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, 16478275SEric Cheng NULL, NULL, 0)) != DLADM_STATUS_OK) { 16488275SEric Cheng return (status); 16498275SEric Cheng } 16508275SEric Cheng 16518275SEric Cheng /* 16528275SEric Cheng * We set intr_cpu to -1. The interrupt will be retargetted, 16538275SEric Cheng * if possible when the setup is complete in MAC. 16548275SEric Cheng */ 16558275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 16568275SEric Cheng mrp.mrp_mask = MRP_CPUS; 16578275SEric Cheng if (vdp != NULL && vdp->vd_val != RESET_VAL) { 16588275SEric Cheng mac_resource_props_t *vmrp; 16598275SEric Cheng 16608275SEric Cheng vmrp = (mac_resource_props_t *)vdp->vd_val; 16618275SEric Cheng if (vmrp->mrp_ncpus > 0) { 16628275SEric Cheng bcopy(vmrp, &mrp, sizeof (mac_resource_props_t)); 16638275SEric Cheng mrp.mrp_mask = MRP_CPUS; 16648275SEric Cheng } 16658275SEric Cheng mrp.mrp_mask |= MRP_CPUS_USERSPEC; 16668275SEric Cheng mrp.mrp_fanout_mode = MCM_CPUS; 16678275SEric Cheng mrp.mrp_intr_cpu = -1; 16688275SEric Cheng } 16698275SEric Cheng 16708275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 16718275SEric Cheng flags, &status); 16728275SEric Cheng if (dip == NULL) 16738275SEric Cheng return (status); 16748275SEric Cheng 16758275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 16768453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 16778275SEric Cheng free(dip); 16788275SEric Cheng return (status); 16798275SEric Cheng } 16808275SEric Cheng 16818275SEric Cheng /* ARGSUSED */ 16828275SEric Cheng static dladm_status_t 16838453SAnurag.Maskey@Sun.COM do_check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16848453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 16858275SEric Cheng { 16868275SEric Cheng uint32_t cpuid; 16878275SEric Cheng int i, j, rc; 16888275SEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 16898275SEric Cheng mac_resource_props_t *mrp; 16908275SEric Cheng 16918275SEric Cheng mrp = malloc(sizeof (mac_resource_props_t)); 16928275SEric Cheng if (mrp == NULL) 16938275SEric Cheng return (DLADM_STATUS_NOMEM); 16948275SEric Cheng 16958275SEric Cheng for (i = 0; i < val_cnt; i++) { 16968275SEric Cheng errno = 0; 16978275SEric Cheng cpuid = strtol(prop_val[i], (char **)NULL, 10); 16988275SEric Cheng if (errno != 0 || cpuid >= nproc) { 16998275SEric Cheng free(mrp); 17008275SEric Cheng return (DLADM_STATUS_CPUMAX); 17018275SEric Cheng } 17028275SEric Cheng rc = p_online(cpuid, P_STATUS); 17038275SEric Cheng if (rc < 1) { 17048275SEric Cheng free(mrp); 17058275SEric Cheng return (DLADM_STATUS_CPUERR); 17068275SEric Cheng } 17078275SEric Cheng if (rc != P_ONLINE) { 17088275SEric Cheng free(mrp); 17098275SEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 17108275SEric Cheng } 17118275SEric Cheng mrp->mrp_cpu[i] = cpuid; 17128275SEric Cheng } 17138275SEric Cheng mrp->mrp_ncpus = (uint32_t)val_cnt; 17148275SEric Cheng 17158275SEric Cheng /* Check for duplicates */ 17168275SEric Cheng for (i = 0; i < val_cnt; i++) { 17178275SEric Cheng for (j = 0; j < val_cnt; j++) { 17188275SEric Cheng if (i != j && mrp->mrp_cpu[i] == mrp->mrp_cpu[j]) { 17198275SEric Cheng free(mrp); 17208275SEric Cheng return (DLADM_STATUS_BADARG); 17218275SEric Cheng } 17228275SEric Cheng } 17238275SEric Cheng } 17248275SEric Cheng vdp->vd_val = (uintptr_t)mrp; 17258275SEric Cheng 17268275SEric Cheng return (DLADM_STATUS_OK); 17278275SEric Cheng } 17288275SEric Cheng 17298275SEric Cheng /* ARGSUSED */ 17308275SEric Cheng dladm_status_t 17318275SEric Cheng do_extract_cpus(val_desc_t *vdp, void *arg, uint_t cnt) 17328275SEric Cheng { 17338275SEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 17348275SEric Cheng mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; 17358275SEric Cheng int i; 17368275SEric Cheng 17378275SEric Cheng for (i = 0; i < vmrp->mrp_ncpus; i++) { 17388275SEric Cheng mrp->mrp_cpu[i] = vmrp->mrp_cpu[i]; 17398275SEric Cheng } 17408275SEric Cheng mrp->mrp_ncpus = vmrp->mrp_ncpus; 17418275SEric Cheng mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 17428275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 17439055SMichael.Lim@Sun.COM mrp->mrp_intr_cpu = -1; 17448275SEric Cheng 17458275SEric Cheng return (DLADM_STATUS_OK); 17468275SEric Cheng } 17478275SEric Cheng 17488275SEric Cheng /* ARGSUSED */ 17498275SEric Cheng static dladm_status_t 17508460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get(dladm_handle_t handle, prop_desc_t *pdp, 17518460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 17528460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 17538275SEric Cheng { 17548275SEric Cheng dld_ioc_macprop_t *dip; 17558275SEric Cheng mac_resource_props_t mrp; 17568275SEric Cheng mac_priority_level_t pri; 17578275SEric Cheng dladm_status_t status; 17588275SEric Cheng 17598453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 17608275SEric Cheng &status, perm_flags); 17618275SEric Cheng if (dip == NULL) 17628275SEric Cheng return (status); 17638275SEric Cheng 17648275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 17658275SEric Cheng free(dip); 17668275SEric Cheng 17678275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 17688275SEric Cheng mrp.mrp_priority; 17698275SEric Cheng 17708275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 17718275SEric Cheng *val_cnt = 1; 17728275SEric Cheng return (DLADM_STATUS_OK); 17738275SEric Cheng } 17748275SEric Cheng 17758275SEric Cheng /* ARGSUSED */ 17768275SEric Cheng static dladm_status_t 17778453SAnurag.Maskey@Sun.COM do_check_priority(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 17788453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 17798275SEric Cheng { 17808275SEric Cheng mac_priority_level_t *pri; 17818275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 17828275SEric Cheng 17838275SEric Cheng if (val_cnt != 1) 17848275SEric Cheng return (DLADM_STATUS_BADVALCNT); 17858275SEric Cheng 17868275SEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 17878275SEric Cheng if (pri == NULL) 17888275SEric Cheng return (DLADM_STATUS_NOMEM); 17898275SEric Cheng 17908275SEric Cheng status = dladm_str2pri(*prop_val, pri); 17918275SEric Cheng if (status != DLADM_STATUS_OK) { 17928275SEric Cheng free(pri); 17938275SEric Cheng return (status); 17948275SEric Cheng } 17958275SEric Cheng 17968275SEric Cheng if (*pri < MPL_LOW || *pri > MPL_HIGH) { 17978275SEric Cheng free(pri); 17988275SEric Cheng return (DLADM_STATUS_BADVAL); 17998275SEric Cheng } 18008275SEric Cheng 18018275SEric Cheng vdp->vd_val = (uintptr_t)pri; 18028275SEric Cheng return (DLADM_STATUS_OK); 18038275SEric Cheng } 18048275SEric Cheng 18058275SEric Cheng /* ARGSUSED */ 18068275SEric Cheng dladm_status_t 18078275SEric Cheng do_extract_priority(val_desc_t *vdp, void *arg, uint_t cnt) 18088275SEric Cheng { 18098275SEric Cheng mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 18108275SEric Cheng 18118275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_priority, 18128275SEric Cheng sizeof (mac_priority_level_t)); 18138275SEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 18148275SEric Cheng 18158275SEric Cheng return (DLADM_STATUS_OK); 18168275SEric Cheng } 18178275SEric Cheng 18188275SEric Cheng /* ARGSUSED */ 18198275SEric Cheng static dladm_status_t 18208453SAnurag.Maskey@Sun.COM do_get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18218275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 18228275SEric Cheng uint_t flags, uint_t *perm_flags) 18235895Syz147064 { 18247342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 18257342SAruna.Ramakrishna@Sun.COM int i, len; 18267342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 18277342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 18285895Syz147064 18296789Sam223141 if (flags & MAC_PROP_DEFAULT) 18307776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 18316512Ssowmini 18325895Syz147064 *val_cnt = 1; 18338453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 18348275SEric Cheng &status, perm_flags); 18357342SAruna.Ramakrishna@Sun.COM if (dip == NULL) { 18365895Syz147064 (*prop_val)[0] = '\0'; 18378275SEric Cheng return (DLADM_STATUS_OK); 18385895Syz147064 } 18397342SAruna.Ramakrishna@Sun.COM (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 18405895Syz147064 18417342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 18425895Syz147064 if (i != 0) { 18435895Syz147064 (void) snprintf(*prop_val + len, 18445895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 18455895Syz147064 len += 1; 18465895Syz147064 } 18475895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 18487342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 18497342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 18507342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 18515895Syz147064 (void) snprintf(*prop_val + len, 18525895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 18535895Syz147064 AP_ANCHOR); 18545895Syz147064 len += (strlen(AP_ANCHOR) + 1); 18555895Syz147064 } 18565895Syz147064 } 18577342SAruna.Ramakrishna@Sun.COM free(dip); 18585895Syz147064 done: 18595895Syz147064 return (DLADM_STATUS_OK); 18605895Syz147064 } 18615895Syz147064 18625895Syz147064 /* 18635895Syz147064 * Add the specified module to the dlautopush structure; returns a 18645895Syz147064 * DLADM_STATUS_* code. 18655895Syz147064 */ 18665895Syz147064 dladm_status_t 18675895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 18685895Syz147064 { 18695895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 18705895Syz147064 return (DLADM_STATUS_BADVAL); 18715895Syz147064 18725895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 18735895Syz147064 /* 18745895Syz147064 * We don't allow multiple anchors, and the anchor must 18755895Syz147064 * be after at least one module. 18765895Syz147064 */ 18775895Syz147064 if (dlap->dap_anchor != 0) 18785895Syz147064 return (DLADM_STATUS_BADVAL); 18795895Syz147064 if (dlap->dap_npush == 0) 18805895Syz147064 return (DLADM_STATUS_BADVAL); 18815895Syz147064 18825895Syz147064 dlap->dap_anchor = dlap->dap_npush; 18835895Syz147064 return (DLADM_STATUS_OK); 18845895Syz147064 } 18858957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 18865895Syz147064 return (DLADM_STATUS_BADVALCNT); 18875895Syz147064 18885895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 18895895Syz147064 FMNAMESZ + 1); 18905895Syz147064 18915895Syz147064 return (DLADM_STATUS_OK); 18925895Syz147064 } 18935895Syz147064 18945895Syz147064 /* 18955895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 18965895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 18975895Syz147064 * latter is used in the autopush(1M) file. 18985895Syz147064 */ 18995895Syz147064 /* ARGSUSED */ 19005895Syz147064 static dladm_status_t 19018453SAnurag.Maskey@Sun.COM do_check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19028453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 19035895Syz147064 { 19045895Syz147064 char *module; 19055895Syz147064 struct dlautopush *dlap; 19065895Syz147064 dladm_status_t status; 19075895Syz147064 char val[DLADM_PROP_VAL_MAX]; 19085895Syz147064 char delimiters[4]; 19095895Syz147064 19105895Syz147064 if (val_cnt != 1) 19115895Syz147064 return (DLADM_STATUS_BADVALCNT); 19125895Syz147064 19137342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 19147342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 19157342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 19167342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 19173448Sdh155122 19187342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 19197342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 19207342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 19217342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 19227342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 19237342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 19247342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 19257342SAruna.Ramakrishna@Sun.COM return (status); 19267342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 19277342SAruna.Ramakrishna@Sun.COM } 19287342SAruna.Ramakrishna@Sun.COM 19297342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 19307342SAruna.Ramakrishna@Sun.COM } else { 19317342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 19325895Syz147064 } 19333448Sdh155122 return (DLADM_STATUS_OK); 19343448Sdh155122 } 19353448Sdh155122 19367663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 19377663SSowmini.Varadhan@Sun.COM 19385903Ssowmini /* ARGSUSED */ 19393448Sdh155122 static dladm_status_t 19408453SAnurag.Maskey@Sun.COM do_get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 19418453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 19428453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 19433448Sdh155122 { 19445895Syz147064 wl_rates_t *wrp; 19455895Syz147064 uint_t i; 19465895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 19475895Syz147064 19487663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 19497663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 19507663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 19515895Syz147064 19528453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 19538453SAnurag.Maskey@Sun.COM B_FALSE); 19545895Syz147064 if (status != DLADM_STATUS_OK) 19555895Syz147064 goto done; 19565895Syz147064 19575895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 19585895Syz147064 status = DLADM_STATUS_TOOSMALL; 19595895Syz147064 goto done; 19605895Syz147064 } 19615895Syz147064 19625895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 19635895Syz147064 prop_val[0][0] = '\0'; 19645895Syz147064 *val_cnt = 1; 19655895Syz147064 goto done; 19665895Syz147064 } 19675895Syz147064 19685895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 19695895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 19705895Syz147064 wrp->wl_rates_rates[i] % 2, 19715895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 19725895Syz147064 } 19735895Syz147064 *val_cnt = wrp->wl_rates_num; 19748275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 19753448Sdh155122 19765895Syz147064 done: 19777663SSowmini.Varadhan@Sun.COM free(wrp); 19785895Syz147064 return (status); 19795895Syz147064 } 19805895Syz147064 19815895Syz147064 static dladm_status_t 19828453SAnurag.Maskey@Sun.COM do_get_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19838275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 19848275SEric Cheng uint_t flags, uint_t *perm_flags) 19855895Syz147064 { 19868118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 19878453SAnurag.Maskey@Sun.COM return (i_dladm_speed_get(handle, pdp, linkid, prop_val, 19888275SEric Cheng val_cnt, flags, perm_flags)); 19898118SVasumathi.Sundaram@Sun.COM } 19905960Ssowmini 19918453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 19928275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 19935895Syz147064 } 19945895Syz147064 19956512Ssowmini /* ARGSUSED */ 19965895Syz147064 static dladm_status_t 19978453SAnurag.Maskey@Sun.COM do_get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19988275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 19998275SEric Cheng uint_t flags, uint_t *perm_flags) 20005895Syz147064 { 20015960Ssowmini switch (media) { 20025960Ssowmini case DL_ETHER: 20036512Ssowmini /* 20046512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 20056512Ssowmini * links can have a speed of 5.5 Gbps. 20066512Ssowmini */ 20076512Ssowmini return (DLADM_STATUS_NOTSUP); 20085960Ssowmini 20095960Ssowmini case DL_WIFI: 20108453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, 20118453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 20125960Ssowmini default: 20135960Ssowmini return (DLADM_STATUS_BADARG); 20145960Ssowmini } 20155895Syz147064 } 20165895Syz147064 20175895Syz147064 static dladm_status_t 20188453SAnurag.Maskey@Sun.COM do_set_rate(dladm_handle_t handle, datalink_id_t linkid, 20198453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 20205895Syz147064 { 20215895Syz147064 int i; 20225895Syz147064 uint_t len; 20235895Syz147064 wl_rates_t *wrp; 20245895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 20255895Syz147064 20267663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 20277663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 20285895Syz147064 return (DLADM_STATUS_NOMEM); 20295895Syz147064 20307663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 20315895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 20325895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 20335895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 20345895Syz147064 20355895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 20365895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 20378453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 20388453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 20395895Syz147064 20407663SSowmini.Varadhan@Sun.COM free(wrp); 20415895Syz147064 return (status); 20425895Syz147064 } 20433448Sdh155122 20445903Ssowmini /* ARGSUSED */ 20455895Syz147064 static dladm_status_t 20468453SAnurag.Maskey@Sun.COM do_set_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20475960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 20485895Syz147064 { 20495895Syz147064 dladm_wlan_rates_t rates; 20505895Syz147064 dladm_status_t status; 20515895Syz147064 20525960Ssowmini /* 20535960Ssowmini * can currently set rate on WIFI links only. 20545960Ssowmini */ 20555960Ssowmini if (media != DL_WIFI) 20565960Ssowmini return (DLADM_STATUS_PROPRDONLY); 20575960Ssowmini 20585895Syz147064 if (val_cnt != 1) 20595895Syz147064 return (DLADM_STATUS_BADVALCNT); 20605895Syz147064 20615895Syz147064 rates.wr_cnt = 1; 20625895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 20635895Syz147064 20648453SAnurag.Maskey@Sun.COM status = do_set_rate(handle, linkid, &rates); 20655895Syz147064 20665895Syz147064 done: 20675895Syz147064 return (status); 20685895Syz147064 } 20693448Sdh155122 20705895Syz147064 /* ARGSUSED */ 20715895Syz147064 static dladm_status_t 20728453SAnurag.Maskey@Sun.COM do_check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20738453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 20745895Syz147064 { 20755895Syz147064 int i; 20765895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 20775895Syz147064 char *buf, **modval; 20785895Syz147064 dladm_status_t status; 20798118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 20805895Syz147064 20815895Syz147064 if (val_cnt != 1) 20825895Syz147064 return (DLADM_STATUS_BADVALCNT); 20835895Syz147064 20845895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 20855895Syz147064 MAX_SUPPORT_RATES); 20865895Syz147064 if (buf == NULL) { 20875895Syz147064 status = DLADM_STATUS_NOMEM; 20885895Syz147064 goto done; 20895895Syz147064 } 20903448Sdh155122 20915895Syz147064 modval = (char **)(void *)buf; 20925895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 20935895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 20945895Syz147064 i * DLADM_STRSIZE; 20955895Syz147064 } 20965895Syz147064 20978453SAnurag.Maskey@Sun.COM status = do_get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 20988453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 20995895Syz147064 if (status != DLADM_STATUS_OK) 21005895Syz147064 goto done; 21015895Syz147064 21025895Syz147064 for (i = 0; i < modval_cnt; i++) { 21035895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 21045903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 21055903Ssowmini (atof(*prop_val) * 2); 21065895Syz147064 status = DLADM_STATUS_OK; 21073448Sdh155122 break; 21083448Sdh155122 } 21095895Syz147064 } 21105895Syz147064 if (i == modval_cnt) 21115895Syz147064 status = DLADM_STATUS_BADVAL; 21125895Syz147064 done: 21135895Syz147064 free(buf); 21145895Syz147064 return (status); 21155895Syz147064 } 21165895Syz147064 21175895Syz147064 static dladm_status_t 21188453SAnurag.Maskey@Sun.COM do_get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 21198453SAnurag.Maskey@Sun.COM int buflen) 21205895Syz147064 { 21218453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 21227663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 21235895Syz147064 } 21245895Syz147064 21255903Ssowmini /* ARGSUSED */ 21265895Syz147064 static dladm_status_t 21278453SAnurag.Maskey@Sun.COM do_get_channel_prop(dladm_handle_t handle, prop_desc_t *pdp, 21288453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 21298453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 21305895Syz147064 { 21315895Syz147064 uint32_t channel; 21327663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 21335895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 21347663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 21355895Syz147064 21368453SAnurag.Maskey@Sun.COM if ((status = do_get_phyconf(handle, linkid, buf, sizeof (buf))) 21377663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 21385895Syz147064 goto done; 21395895Syz147064 21407663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 21417663SSowmini.Varadhan@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 21425895Syz147064 status = DLADM_STATUS_NOTFOUND; 21435895Syz147064 goto done; 21445895Syz147064 } 21455895Syz147064 21465895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 21475895Syz147064 *val_cnt = 1; 21488275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 21495895Syz147064 done: 21505895Syz147064 return (status); 21515895Syz147064 } 21525895Syz147064 21535895Syz147064 static dladm_status_t 21548453SAnurag.Maskey@Sun.COM do_get_powermode(dladm_handle_t handle, datalink_id_t linkid, void *buf, 21558453SAnurag.Maskey@Sun.COM int buflen) 21565895Syz147064 { 21578453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_POWER_MODE, 21587663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 21595895Syz147064 } 21605895Syz147064 21615903Ssowmini /* ARGSUSED */ 21625895Syz147064 static dladm_status_t 21638453SAnurag.Maskey@Sun.COM do_get_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 21648453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 21658453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 21665895Syz147064 { 21677663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 21685895Syz147064 const char *s; 21697663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 21705895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 21715895Syz147064 21728453SAnurag.Maskey@Sun.COM if ((status = do_get_powermode(handle, linkid, buf, sizeof (buf))) 21737663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 21745895Syz147064 goto done; 21755895Syz147064 21767663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 21777663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 21785895Syz147064 case WL_PM_AM: 21795895Syz147064 s = "off"; 21805895Syz147064 break; 21815895Syz147064 case WL_PM_MPS: 21825895Syz147064 s = "max"; 21835895Syz147064 break; 21845895Syz147064 case WL_PM_FAST: 21855895Syz147064 s = "fast"; 21863448Sdh155122 break; 21873448Sdh155122 default: 21885895Syz147064 status = DLADM_STATUS_NOTFOUND; 21895895Syz147064 goto done; 21905895Syz147064 } 21915895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 21925895Syz147064 *val_cnt = 1; 21938275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 21945895Syz147064 done: 21955895Syz147064 return (status); 21965895Syz147064 } 21975895Syz147064 21985895Syz147064 static dladm_status_t 21998453SAnurag.Maskey@Sun.COM do_set_powermode(dladm_handle_t handle, datalink_id_t linkid, 22008453SAnurag.Maskey@Sun.COM dladm_wlan_powermode_t *pm) 22015895Syz147064 { 22025895Syz147064 wl_ps_mode_t ps_mode; 22035895Syz147064 22045895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 22055895Syz147064 22065895Syz147064 switch (*pm) { 22075895Syz147064 case DLADM_WLAN_PM_OFF: 22085895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 22093448Sdh155122 break; 22105895Syz147064 case DLADM_WLAN_PM_MAX: 22115895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 22125895Syz147064 break; 22135895Syz147064 case DLADM_WLAN_PM_FAST: 22145895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 22155895Syz147064 break; 22165895Syz147064 default: 22175895Syz147064 return (DLADM_STATUS_NOTSUP); 22183448Sdh155122 } 22198453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 22208453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 22215895Syz147064 } 22225895Syz147064 22235895Syz147064 /* ARGSUSED */ 22245895Syz147064 static dladm_status_t 22258453SAnurag.Maskey@Sun.COM do_set_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 22268453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 22278453SAnurag.Maskey@Sun.COM datalink_media_t media) 22285895Syz147064 { 22295895Syz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 22305895Syz147064 dladm_status_t status; 22315895Syz147064 22325895Syz147064 if (val_cnt != 1) 22335895Syz147064 return (DLADM_STATUS_BADVALCNT); 22345895Syz147064 22358453SAnurag.Maskey@Sun.COM status = do_set_powermode(handle, linkid, &powermode); 22363448Sdh155122 22373448Sdh155122 return (status); 22383448Sdh155122 } 22393448Sdh155122 22403448Sdh155122 static dladm_status_t 22418453SAnurag.Maskey@Sun.COM do_get_radio(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen) 22423448Sdh155122 { 22438453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_RADIO, 22448453SAnurag.Maskey@Sun.COM buflen, B_FALSE)); 22455895Syz147064 } 22463448Sdh155122 22475903Ssowmini /* ARGSUSED */ 22485895Syz147064 static dladm_status_t 22498453SAnurag.Maskey@Sun.COM do_get_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22508275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 22518275SEric Cheng uint_t flags, uint_t *perm_flags) 22525895Syz147064 { 22535895Syz147064 wl_radio_t radio; 22545895Syz147064 const char *s; 22557663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 22565895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 22573448Sdh155122 22588453SAnurag.Maskey@Sun.COM if ((status = do_get_radio(handle, linkid, buf, sizeof (buf))) 22597663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 22605895Syz147064 goto done; 22613448Sdh155122 22627663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 22635895Syz147064 switch (radio) { 22645895Syz147064 case B_TRUE: 22655895Syz147064 s = "on"; 22665895Syz147064 break; 22675895Syz147064 case B_FALSE: 22685895Syz147064 s = "off"; 22695895Syz147064 break; 22705895Syz147064 default: 22715895Syz147064 status = DLADM_STATUS_NOTFOUND; 22725895Syz147064 goto done; 22735895Syz147064 } 22745895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 22755895Syz147064 *val_cnt = 1; 22768275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 22775895Syz147064 done: 22783448Sdh155122 return (status); 22793448Sdh155122 } 22803448Sdh155122 22813448Sdh155122 static dladm_status_t 22828453SAnurag.Maskey@Sun.COM do_set_radio(dladm_handle_t handle, datalink_id_t linkid, 22838453SAnurag.Maskey@Sun.COM dladm_wlan_radio_t *radio) 22843448Sdh155122 { 22855895Syz147064 wl_radio_t r; 22863448Sdh155122 22875895Syz147064 switch (*radio) { 22885895Syz147064 case DLADM_WLAN_RADIO_ON: 22895895Syz147064 r = B_TRUE; 22905895Syz147064 break; 22915895Syz147064 case DLADM_WLAN_RADIO_OFF: 22925895Syz147064 r = B_FALSE; 22935895Syz147064 break; 22945895Syz147064 default: 22955895Syz147064 return (DLADM_STATUS_NOTSUP); 22965895Syz147064 } 22978453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 22987663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 22995895Syz147064 } 23003448Sdh155122 23015895Syz147064 /* ARGSUSED */ 23025895Syz147064 static dladm_status_t 23038453SAnurag.Maskey@Sun.COM do_set_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2304*10616SSebastien.Roy@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 23055895Syz147064 { 23065895Syz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 23075895Syz147064 dladm_status_t status; 23083448Sdh155122 23095895Syz147064 if (val_cnt != 1) 23105895Syz147064 return (DLADM_STATUS_BADVALCNT); 23115895Syz147064 23128453SAnurag.Maskey@Sun.COM status = do_set_radio(handle, linkid, &radio); 23133448Sdh155122 23143448Sdh155122 return (status); 23153448Sdh155122 } 23163448Sdh155122 2317*10616SSebastien.Roy@Sun.COM /* ARGSUSED */ 2318*10616SSebastien.Roy@Sun.COM static dladm_status_t 2319*10616SSebastien.Roy@Sun.COM do_check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 2320*10616SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 2321*10616SSebastien.Roy@Sun.COM datalink_media_t media) 2322*10616SSebastien.Roy@Sun.COM { 2323*10616SSebastien.Roy@Sun.COM int32_t hlim; 2324*10616SSebastien.Roy@Sun.COM char *ep; 2325*10616SSebastien.Roy@Sun.COM 2326*10616SSebastien.Roy@Sun.COM if (val_cnt != 1) 2327*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 2328*10616SSebastien.Roy@Sun.COM 2329*10616SSebastien.Roy@Sun.COM errno = 0; 2330*10616SSebastien.Roy@Sun.COM hlim = strtol(*prop_val, &ep, 10); 2331*10616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || hlim < 1 || 2332*10616SSebastien.Roy@Sun.COM hlim > (int32_t)UINT8_MAX) 2333*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 2334*10616SSebastien.Roy@Sun.COM vdp->vd_val = hlim; 2335*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 2336*10616SSebastien.Roy@Sun.COM } 2337*10616SSebastien.Roy@Sun.COM 2338*10616SSebastien.Roy@Sun.COM /* ARGSUSED */ 2339*10616SSebastien.Roy@Sun.COM static dladm_status_t 2340*10616SSebastien.Roy@Sun.COM do_check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2341*10616SSebastien.Roy@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 2342*10616SSebastien.Roy@Sun.COM { 2343*10616SSebastien.Roy@Sun.COM int32_t elim; 2344*10616SSebastien.Roy@Sun.COM char *ep; 2345*10616SSebastien.Roy@Sun.COM 2346*10616SSebastien.Roy@Sun.COM if (media != DL_IPV6) 2347*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG); 2348*10616SSebastien.Roy@Sun.COM 2349*10616SSebastien.Roy@Sun.COM if (val_cnt != 1) 2350*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 2351*10616SSebastien.Roy@Sun.COM 2352*10616SSebastien.Roy@Sun.COM errno = 0; 2353*10616SSebastien.Roy@Sun.COM elim = strtol(*prop_val, &ep, 10); 2354*10616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || elim < 0 || 2355*10616SSebastien.Roy@Sun.COM elim > (int32_t)UINT8_MAX) 2356*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 2357*10616SSebastien.Roy@Sun.COM vdp->vd_val = elim; 2358*10616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 2359*10616SSebastien.Roy@Sun.COM } 2360*10616SSebastien.Roy@Sun.COM 23615895Syz147064 static dladm_status_t 23628453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 23638453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 23643448Sdh155122 { 23655895Syz147064 char buf[MAXLINELEN]; 23665895Syz147064 int i; 23675895Syz147064 dladm_conf_t conf; 23685895Syz147064 dladm_status_t status; 23693448Sdh155122 23708453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 23715895Syz147064 if (status != DLADM_STATUS_OK) 23725895Syz147064 return (status); 23733448Sdh155122 23745895Syz147064 /* 23755895Syz147064 * reset case. 23765895Syz147064 */ 23775895Syz147064 if (val_cnt == 0) { 23788453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 23795895Syz147064 if (status == DLADM_STATUS_OK) 23808453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 23815895Syz147064 goto done; 23825895Syz147064 } 23833448Sdh155122 23845895Syz147064 buf[0] = '\0'; 23855895Syz147064 for (i = 0; i < val_cnt; i++) { 23865895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 23875895Syz147064 if (i != val_cnt - 1) 23885895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 23893448Sdh155122 } 23903448Sdh155122 23918453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 23928453SAnurag.Maskey@Sun.COM buf); 23935895Syz147064 if (status == DLADM_STATUS_OK) 23948453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 23955895Syz147064 23965895Syz147064 done: 23978453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 23985895Syz147064 return (status); 23993448Sdh155122 } 24005895Syz147064 24015895Syz147064 static dladm_status_t 24028453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 24038453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 24045895Syz147064 { 24055895Syz147064 char buf[MAXLINELEN], *str; 24065895Syz147064 uint_t cnt = 0; 24075895Syz147064 dladm_conf_t conf; 24085895Syz147064 dladm_status_t status; 24095895Syz147064 24108453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 24115895Syz147064 if (status != DLADM_STATUS_OK) 24125895Syz147064 return (status); 24135895Syz147064 24148453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 24155895Syz147064 if (status != DLADM_STATUS_OK) 24165895Syz147064 goto done; 24175895Syz147064 24185895Syz147064 str = strtok(buf, ","); 24195895Syz147064 while (str != NULL) { 24205895Syz147064 if (cnt == *val_cntp) { 24215895Syz147064 status = DLADM_STATUS_TOOSMALL; 24225895Syz147064 goto done; 24235895Syz147064 } 24245895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 24255895Syz147064 str = strtok(NULL, ","); 24265895Syz147064 } 24275895Syz147064 24285895Syz147064 *val_cntp = cnt; 24295895Syz147064 24305895Syz147064 done: 24318453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 24325895Syz147064 return (status); 24335895Syz147064 } 24345903Ssowmini 24358460SArtem.Kachitchkin@Sun.COM /* 24368460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 24378460SArtem.Kachitchkin@Sun.COM */ 24388460SArtem.Kachitchkin@Sun.COM static dladm_status_t 24398460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 24408460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 24418460SArtem.Kachitchkin@Sun.COM { 24428460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 24438460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 24448460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 24458460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 24468460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 24478460SArtem.Kachitchkin@Sun.COM size_t attrsz; 24488460SArtem.Kachitchkin@Sun.COM 24498460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 24508460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 24518460SArtem.Kachitchkin@Sun.COM 24528460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 24538460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 24548460SArtem.Kachitchkin@Sun.COM return (status); 24558460SArtem.Kachitchkin@Sun.COM 24568460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 24578460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 24588460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 24598460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 24608460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 24618460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 24628460SArtem.Kachitchkin@Sun.COM break; 24638460SArtem.Kachitchkin@Sun.COM } 24648460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 24658460SArtem.Kachitchkin@Sun.COM } 24668460SArtem.Kachitchkin@Sun.COM 24678460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 24688460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 24698460SArtem.Kachitchkin@Sun.COM } 24708460SArtem.Kachitchkin@Sun.COM 24717663SSowmini.Varadhan@Sun.COM static link_attr_t * 24725903Ssowmini dladm_name2prop(const char *prop_name) 24735903Ssowmini { 24747663SSowmini.Varadhan@Sun.COM link_attr_t *p; 24755903Ssowmini 24767663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 24775903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 24785903Ssowmini break; 24795903Ssowmini } 24805903Ssowmini return (p); 24815903Ssowmini } 24825903Ssowmini 24837663SSowmini.Varadhan@Sun.COM static link_attr_t * 24847663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 24857663SSowmini.Varadhan@Sun.COM { 24867663SSowmini.Varadhan@Sun.COM link_attr_t *p; 24877663SSowmini.Varadhan@Sun.COM 24887663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 24897663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 24907663SSowmini.Varadhan@Sun.COM break; 24917663SSowmini.Varadhan@Sun.COM } 24927663SSowmini.Varadhan@Sun.COM return (p); 24937663SSowmini.Varadhan@Sun.COM } 24945903Ssowmini 24956789Sam223141 static dld_ioc_macprop_t * 24967663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 24977663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 24987663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 24995903Ssowmini { 25005903Ssowmini int dsize; 25016789Sam223141 dld_ioc_macprop_t *dip; 25025903Ssowmini 25035903Ssowmini *status = DLADM_STATUS_OK; 25046789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 25055903Ssowmini dip = malloc(dsize); 25065903Ssowmini if (dip == NULL) { 25075903Ssowmini *status = DLADM_STATUS_NOMEM; 25085903Ssowmini return (NULL); 25095903Ssowmini } 25105903Ssowmini bzero(dip, dsize); 25115903Ssowmini dip->pr_valsize = valsize; 25126512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 25136789Sam223141 dip->pr_version = MAC_PROP_VERSION; 25145960Ssowmini dip->pr_linkid = linkid; 25157663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 25166512Ssowmini dip->pr_flags = flags; 25175903Ssowmini return (dip); 25185903Ssowmini } 25195903Ssowmini 25207663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 25217663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 25227663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 25237663SSowmini.Varadhan@Sun.COM { 25247663SSowmini.Varadhan@Sun.COM link_attr_t *p; 25257663SSowmini.Varadhan@Sun.COM 25267663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 25277663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 25287663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 25297663SSowmini.Varadhan@Sun.COM flags, status)); 25307663SSowmini.Varadhan@Sun.COM } 25317663SSowmini.Varadhan@Sun.COM 25327663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 25337663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 25347663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 25357663SSowmini.Varadhan@Sun.COM { 25367663SSowmini.Varadhan@Sun.COM link_attr_t *p; 25377663SSowmini.Varadhan@Sun.COM 25387663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 25397663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 25407663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 25417663SSowmini.Varadhan@Sun.COM flags, status)); 25427663SSowmini.Varadhan@Sun.COM } 25437663SSowmini.Varadhan@Sun.COM 25445903Ssowmini /* ARGSUSED */ 25455903Ssowmini static dladm_status_t 25468453SAnurag.Maskey@Sun.COM i_dladm_set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 25478453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 25488453SAnurag.Maskey@Sun.COM datalink_media_t media) 25495903Ssowmini { 25506789Sam223141 dld_ioc_macprop_t *dip; 25515903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 25525903Ssowmini uint8_t u8; 25535903Ssowmini uint16_t u16; 25545903Ssowmini uint32_t u32; 25555903Ssowmini void *val; 25565903Ssowmini 25578275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 25585903Ssowmini if (dip == NULL) 25595903Ssowmini return (status); 25605903Ssowmini 25618275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 25625903Ssowmini val = (void *)vdp->vd_val; 25635903Ssowmini else { 25645903Ssowmini /* 25655903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 25665903Ssowmini * No need (yet) to distinguish these from arrays of same size. 25675903Ssowmini */ 25685903Ssowmini switch (dip->pr_valsize) { 25695903Ssowmini case 1: 25705903Ssowmini u8 = vdp->vd_val; 25715903Ssowmini val = &u8; 25725903Ssowmini break; 25735903Ssowmini case 2: 25745903Ssowmini u16 = vdp->vd_val; 25755903Ssowmini val = &u16; 25765903Ssowmini break; 25775903Ssowmini case 4: 25785903Ssowmini u32 = vdp->vd_val; 25795903Ssowmini val = &u32; 25805903Ssowmini break; 25815903Ssowmini default: 25825903Ssowmini val = &vdp->vd_val; 25835903Ssowmini break; 25845903Ssowmini } 25855903Ssowmini } 25865903Ssowmini 25877342SAruna.Ramakrishna@Sun.COM if (val != NULL) 25887342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 25897342SAruna.Ramakrishna@Sun.COM else 25907342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 25917342SAruna.Ramakrishna@Sun.COM 25928453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 25937663SSowmini.Varadhan@Sun.COM 25947663SSowmini.Varadhan@Sun.COM done: 25957663SSowmini.Varadhan@Sun.COM free(dip); 25967663SSowmini.Varadhan@Sun.COM return (status); 25977663SSowmini.Varadhan@Sun.COM } 25987663SSowmini.Varadhan@Sun.COM 25997663SSowmini.Varadhan@Sun.COM dladm_status_t 26008453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 26017663SSowmini.Varadhan@Sun.COM { 26027663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 26037663SSowmini.Varadhan@Sun.COM 26048453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 26058453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 26065903Ssowmini status = dladm_errno2status(errno); 26078453SAnurag.Maskey@Sun.COM 26085903Ssowmini return (status); 26095903Ssowmini } 26105903Ssowmini 26116789Sam223141 static dld_ioc_macprop_t * 26128453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 26138453SAnurag.Maskey@Sun.COM char *prop_name, uint_t flags, dladm_status_t *status, uint_t *perm_flags) 26145903Ssowmini { 26156789Sam223141 dld_ioc_macprop_t *dip = NULL; 26166512Ssowmini 26177663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 26186512Ssowmini if (dip == NULL) 26196512Ssowmini return (NULL); 26205903Ssowmini 26218453SAnurag.Maskey@Sun.COM *status = i_dladm_macprop(handle, dip, B_FALSE); 26226512Ssowmini if (*status != DLADM_STATUS_OK) { 26236512Ssowmini free(dip); 26246512Ssowmini return (NULL); 26256512Ssowmini } 26268275SEric Cheng if (perm_flags != NULL) 26278275SEric Cheng *perm_flags = dip->pr_perm_flags; 26288275SEric Cheng 26296512Ssowmini return (dip); 26305903Ssowmini } 26315903Ssowmini 26325903Ssowmini /* ARGSUSED */ 26335903Ssowmini static dladm_status_t 263410491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check(dladm_handle_t handle, prop_desc_t *pdp, 26358453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *v, 26368453SAnurag.Maskey@Sun.COM datalink_media_t media) 26375903Ssowmini { 26385903Ssowmini if (val_cnt != 1) 26395903Ssowmini return (DLADM_STATUS_BADVAL); 264010491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 26415903Ssowmini return (DLADM_STATUS_OK); 26425903Ssowmini } 26435903Ssowmini 26445903Ssowmini /* ARGSUSED */ 26455903Ssowmini static dladm_status_t 26468453SAnurag.Maskey@Sun.COM i_dladm_duplex_get(dladm_handle_t handle, prop_desc_t *pdp, 26478453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 26488453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 26495903Ssowmini { 26505903Ssowmini link_duplex_t link_duplex; 26515903Ssowmini dladm_status_t status; 26525903Ssowmini 26538453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 26545903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 26555903Ssowmini return (status); 26565903Ssowmini 26575903Ssowmini switch (link_duplex) { 26585903Ssowmini case LINK_DUPLEX_FULL: 26595903Ssowmini (void) strcpy(*prop_val, "full"); 26605903Ssowmini break; 26615903Ssowmini case LINK_DUPLEX_HALF: 26625903Ssowmini (void) strcpy(*prop_val, "half"); 26635903Ssowmini break; 26645903Ssowmini default: 26655903Ssowmini (void) strcpy(*prop_val, "unknown"); 26665903Ssowmini break; 26675903Ssowmini } 26685903Ssowmini *val_cnt = 1; 26695903Ssowmini return (DLADM_STATUS_OK); 26705903Ssowmini } 26715903Ssowmini 26725903Ssowmini /* ARGSUSED */ 26735903Ssowmini static dladm_status_t 26748453SAnurag.Maskey@Sun.COM i_dladm_speed_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 26758275SEric Cheng char **prop_val, uint_t *val_cnt, uint_t flags, uint_t *perm_flags) 26765903Ssowmini { 26775903Ssowmini uint64_t ifspeed = 0; 26785903Ssowmini dladm_status_t status; 26795903Ssowmini 26808453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 26815903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 26825903Ssowmini return (status); 26836512Ssowmini 26845960Ssowmini if ((ifspeed % 1000000) != 0) { 26855960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 26865960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 26875960Ssowmini } else { 26885960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 26895960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 26905960Ssowmini } 26915903Ssowmini *val_cnt = 1; 26928275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 26935903Ssowmini return (DLADM_STATUS_OK); 26945903Ssowmini } 26955903Ssowmini 26965903Ssowmini /* ARGSUSED */ 26975903Ssowmini static dladm_status_t 26988453SAnurag.Maskey@Sun.COM i_dladm_status_get(dladm_handle_t handle, prop_desc_t *pdp, 26998453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27008453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27015903Ssowmini { 27028275SEric Cheng link_state_t link_state; 27038275SEric Cheng dladm_status_t status; 27048306SSowmini.Varadhan@Sun.COM 27058453SAnurag.Maskey@Sun.COM status = i_dladm_get_state(handle, linkid, &link_state); 27066512Ssowmini if (status != DLADM_STATUS_OK) 27075903Ssowmini return (status); 27088275SEric Cheng 27095903Ssowmini switch (link_state) { 27105903Ssowmini case LINK_STATE_UP: 27115903Ssowmini (void) strcpy(*prop_val, "up"); 27125903Ssowmini break; 27135903Ssowmini case LINK_STATE_DOWN: 27145903Ssowmini (void) strcpy(*prop_val, "down"); 27155903Ssowmini break; 27165903Ssowmini default: 27175903Ssowmini (void) strcpy(*prop_val, "unknown"); 27185903Ssowmini break; 27195903Ssowmini } 27205903Ssowmini *val_cnt = 1; 27218306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 27225903Ssowmini return (DLADM_STATUS_OK); 27235903Ssowmini } 27245903Ssowmini 27255903Ssowmini /* ARGSUSED */ 27265903Ssowmini static dladm_status_t 27278453SAnurag.Maskey@Sun.COM i_dladm_binary_get(dladm_handle_t handle, prop_desc_t *pdp, 27288453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27298453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27305903Ssowmini { 27316789Sam223141 dld_ioc_macprop_t *dip; 27325903Ssowmini dladm_status_t status; 27335903Ssowmini 27348453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 27358275SEric Cheng &status, perm_flags); 27366512Ssowmini if (dip == NULL) 27375903Ssowmini return (status); 27388275SEric Cheng 27395903Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 27405903Ssowmini free(dip); 27415903Ssowmini *val_cnt = 1; 27425903Ssowmini return (DLADM_STATUS_OK); 27435903Ssowmini } 27445903Ssowmini 27455960Ssowmini /* ARGSUSED */ 27465903Ssowmini static dladm_status_t 27478453SAnurag.Maskey@Sun.COM i_dladm_uint32_get(dladm_handle_t handle, prop_desc_t *pdp, 27488453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27498453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27505903Ssowmini { 27516789Sam223141 dld_ioc_macprop_t *dip; 27528275SEric Cheng uint32_t v = 0; 27535903Ssowmini uchar_t *cp; 27545903Ssowmini dladm_status_t status; 27555903Ssowmini 27568453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 27578275SEric Cheng &status, perm_flags); 27586512Ssowmini if (dip == NULL) 27595903Ssowmini return (status); 27608275SEric Cheng 27615903Ssowmini cp = (uchar_t *)dip->pr_val; 27625903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 27636512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 27645903Ssowmini free(dip); 27655903Ssowmini *val_cnt = 1; 27665903Ssowmini return (DLADM_STATUS_OK); 27675903Ssowmini } 27685903Ssowmini 27699514SGirish.Moodalbail@Sun.COM /* 27709514SGirish.Moodalbail@Sun.COM * Determines the size of the structure that needs to be sent to drivers 27719514SGirish.Moodalbail@Sun.COM * for retrieving the property range values. 27729514SGirish.Moodalbail@Sun.COM */ 27739514SGirish.Moodalbail@Sun.COM static int 27749514SGirish.Moodalbail@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 27759514SGirish.Moodalbail@Sun.COM { 27769514SGirish.Moodalbail@Sun.COM uint_t count = r->mpr_count; 27779514SGirish.Moodalbail@Sun.COM 27789514SGirish.Moodalbail@Sun.COM *sz = sizeof (mac_propval_range_t); 27799514SGirish.Moodalbail@Sun.COM --count; 27809514SGirish.Moodalbail@Sun.COM 27819514SGirish.Moodalbail@Sun.COM switch (r->mpr_type) { 27829514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: 27839514SGirish.Moodalbail@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 27849514SGirish.Moodalbail@Sun.COM return (0); 27859514SGirish.Moodalbail@Sun.COM default: 27869514SGirish.Moodalbail@Sun.COM break; 27879514SGirish.Moodalbail@Sun.COM } 27889514SGirish.Moodalbail@Sun.COM *sz = 0; 27899514SGirish.Moodalbail@Sun.COM return (EINVAL); 27909514SGirish.Moodalbail@Sun.COM } 27919514SGirish.Moodalbail@Sun.COM 27929514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 27939514SGirish.Moodalbail@Sun.COM static dladm_status_t 27949514SGirish.Moodalbail@Sun.COM i_dladm_range_get(dladm_handle_t handle, prop_desc_t *pdp, 27959514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27969514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 27979514SGirish.Moodalbail@Sun.COM { 27989514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 27999514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 28009514SGirish.Moodalbail@Sun.COM size_t sz; 28019514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 28029514SGirish.Moodalbail@Sun.COM 28039514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 28049514SGirish.Moodalbail@Sun.COM 28059514SGirish.Moodalbail@Sun.COM /* 28069514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 28079514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 28089514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 28099514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 28109514SGirish.Moodalbail@Sun.COM */ 28119514SGirish.Moodalbail@Sun.COM retry: 28129514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 28139514SGirish.Moodalbail@Sun.COM &status)) == NULL) 28149514SGirish.Moodalbail@Sun.COM return (status); 28159514SGirish.Moodalbail@Sun.COM 28169514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 28179514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 28189514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 28199514SGirish.Moodalbail@Sun.COM int err; 28209514SGirish.Moodalbail@Sun.COM 28219514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 28229514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 28239514SGirish.Moodalbail@Sun.COM free(dip); 28249514SGirish.Moodalbail@Sun.COM goto retry; 28259514SGirish.Moodalbail@Sun.COM } else { 28269514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 28279514SGirish.Moodalbail@Sun.COM } 28289514SGirish.Moodalbail@Sun.COM } 28299514SGirish.Moodalbail@Sun.COM free(dip); 28309514SGirish.Moodalbail@Sun.COM return (status); 28319514SGirish.Moodalbail@Sun.COM } 28329514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 28339514SGirish.Moodalbail@Sun.COM 28349514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 28359514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 28369514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 28379514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 28389514SGirish.Moodalbail@Sun.COM 28399514SGirish.Moodalbail@Sun.COM ur = &rangep->range_uint32[0]; 28409514SGirish.Moodalbail@Sun.COM 28419514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 28429514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 28439514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 28449514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 28459514SGirish.Moodalbail@Sun.COM } else { 28469514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 28479514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 28489514SGirish.Moodalbail@Sun.COM } 28499514SGirish.Moodalbail@Sun.COM } 28509514SGirish.Moodalbail@Sun.COM *val_cnt = count; 28519514SGirish.Moodalbail@Sun.COM break; 28529514SGirish.Moodalbail@Sun.COM } 28539514SGirish.Moodalbail@Sun.COM default: 28549514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 28559514SGirish.Moodalbail@Sun.COM break; 28569514SGirish.Moodalbail@Sun.COM } 28579514SGirish.Moodalbail@Sun.COM free(dip); 28589514SGirish.Moodalbail@Sun.COM return (status); 28599514SGirish.Moodalbail@Sun.COM } 28609514SGirish.Moodalbail@Sun.COM 28615960Ssowmini /* ARGSUSED */ 28625903Ssowmini static dladm_status_t 28638874SSebastien.Roy@Sun.COM i_dladm_tagmode_get(dladm_handle_t handle, prop_desc_t *pdp, 28648874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28658874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28668874SSebastien.Roy@Sun.COM { 28678874SSebastien.Roy@Sun.COM dld_ioc_macprop_t *dip; 28688874SSebastien.Roy@Sun.COM link_tagmode_t mode; 28698874SSebastien.Roy@Sun.COM dladm_status_t status; 28708874SSebastien.Roy@Sun.COM 28718874SSebastien.Roy@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 28728874SSebastien.Roy@Sun.COM &status, perm_flags); 28738874SSebastien.Roy@Sun.COM if (dip == NULL) 28748874SSebastien.Roy@Sun.COM return (status); 28758874SSebastien.Roy@Sun.COM (void) memcpy(&mode, dip->pr_val, sizeof (mode)); 28768874SSebastien.Roy@Sun.COM free(dip); 28778874SSebastien.Roy@Sun.COM 28788874SSebastien.Roy@Sun.COM switch (mode) { 28798874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 28808874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 28818874SSebastien.Roy@Sun.COM break; 28828874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 28838874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 28848874SSebastien.Roy@Sun.COM break; 28858874SSebastien.Roy@Sun.COM default: 28868874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 28878874SSebastien.Roy@Sun.COM } 28888874SSebastien.Roy@Sun.COM *val_cnt = 1; 28898874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 28908874SSebastien.Roy@Sun.COM } 28918874SSebastien.Roy@Sun.COM 28928874SSebastien.Roy@Sun.COM /* ARGSUSED */ 28938874SSebastien.Roy@Sun.COM static dladm_status_t 28948453SAnurag.Maskey@Sun.COM i_dladm_flowctl_get(dladm_handle_t handle, prop_desc_t *pdp, 28958453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28968453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28975903Ssowmini { 28986789Sam223141 dld_ioc_macprop_t *dip; 28995903Ssowmini link_flowctrl_t v; 29005903Ssowmini dladm_status_t status; 29015903Ssowmini uchar_t *cp; 29025903Ssowmini 29038453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29048275SEric Cheng &status, perm_flags); 29056512Ssowmini if (dip == NULL) 29065903Ssowmini return (status); 29078275SEric Cheng 29085903Ssowmini cp = (uchar_t *)dip->pr_val; 29095903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 29105903Ssowmini switch (v) { 29115903Ssowmini case LINK_FLOWCTRL_NONE: 29125903Ssowmini (void) sprintf(*prop_val, "no"); 29135903Ssowmini break; 29145903Ssowmini case LINK_FLOWCTRL_RX: 29155903Ssowmini (void) sprintf(*prop_val, "rx"); 29165903Ssowmini break; 29175903Ssowmini case LINK_FLOWCTRL_TX: 29185903Ssowmini (void) sprintf(*prop_val, "tx"); 29195903Ssowmini break; 29205903Ssowmini case LINK_FLOWCTRL_BI: 29215903Ssowmini (void) sprintf(*prop_val, "bi"); 29225903Ssowmini break; 29235903Ssowmini } 29245903Ssowmini free(dip); 29255903Ssowmini *val_cnt = 1; 29265903Ssowmini return (DLADM_STATUS_OK); 29275903Ssowmini } 29285903Ssowmini 29295903Ssowmini 29305903Ssowmini /* ARGSUSED */ 29315903Ssowmini static dladm_status_t 29329692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 29338453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 29348453SAnurag.Maskey@Sun.COM 29355903Ssowmini { 29367663SSowmini.Varadhan@Sun.COM int i, slen; 29377408SSebastien.Roy@Sun.COM int bufsize = 0; 29386789Sam223141 dld_ioc_macprop_t *dip = NULL; 29395903Ssowmini uchar_t *dp; 29407663SSowmini.Varadhan@Sun.COM link_attr_t *p; 29416512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 29425903Ssowmini 29435903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 29445903Ssowmini (prop_val != NULL && val_cnt == 0)) 29455903Ssowmini return (DLADM_STATUS_BADARG); 29465903Ssowmini p = dladm_name2prop(prop_name); 29476789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 29485903Ssowmini return (DLADM_STATUS_BADARG); 29495903Ssowmini 29509692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 29519692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 29529692SRishi.Srivatsavai@Sun.COM 29535903Ssowmini /* 29545903Ssowmini * private properties: all parsing is done in the kernel. 29555903Ssowmini * allocate a enough space for each property + its separator (','). 29565903Ssowmini */ 29575903Ssowmini for (i = 0; i < val_cnt; i++) { 29585903Ssowmini bufsize += strlen(prop_val[i]) + 1; 29595903Ssowmini } 29606512Ssowmini 29616512Ssowmini if (prop_val == NULL) { 29626512Ssowmini /* 29636512Ssowmini * getting default value. so use more buffer space. 29646512Ssowmini */ 29657663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 29666512Ssowmini } 29676512Ssowmini 29687663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 29696789Sam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 29705903Ssowmini if (dip == NULL) 29715903Ssowmini return (status); 29725903Ssowmini 29735903Ssowmini dp = (uchar_t *)dip->pr_val; 29745903Ssowmini slen = 0; 29757663SSowmini.Varadhan@Sun.COM 29766512Ssowmini if (prop_val == NULL) { 29778453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 29788460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 29796512Ssowmini } else { 29806512Ssowmini for (i = 0; i < val_cnt; i++) { 29816512Ssowmini int plen = 0; 29825903Ssowmini 29836512Ssowmini plen = strlen(prop_val[i]); 29846512Ssowmini bcopy(prop_val[i], dp, plen); 29856512Ssowmini slen += plen; 29866512Ssowmini /* 29876512Ssowmini * add a "," separator and update dp. 29886512Ssowmini */ 29896512Ssowmini if (i != (val_cnt -1)) 29906512Ssowmini dp[slen++] = ','; 29916512Ssowmini dp += (plen + 1); 29926512Ssowmini } 29938460SArtem.Kachitchkin@Sun.COM } 29948460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 29958453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 29966512Ssowmini 29975903Ssowmini free(dip); 29986512Ssowmini return (status); 29995903Ssowmini } 30005903Ssowmini 30015903Ssowmini static dladm_status_t 30028460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 30038453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 30048453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 30055903Ssowmini { 30067663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 30076789Sam223141 dld_ioc_macprop_t *dip = NULL; 30087663SSowmini.Varadhan@Sun.COM link_attr_t *p; 30095903Ssowmini 30105903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 30115903Ssowmini (prop_val != NULL && val_cnt == 0)) 30125903Ssowmini return (DLADM_STATUS_BADARG); 30135903Ssowmini 30145903Ssowmini p = dladm_name2prop(prop_name); 30156789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 30165903Ssowmini return (DLADM_STATUS_BADARG); 30175903Ssowmini 30185903Ssowmini /* 30195903Ssowmini * private properties: all parsing is done in the kernel. 30205903Ssowmini */ 30217663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 30227663SSowmini.Varadhan@Sun.COM dld_flags, &status); 30235903Ssowmini if (dip == NULL) 30245903Ssowmini return (status); 30255903Ssowmini 30268453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 30278453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 30288118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 30298275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 30308460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 30318460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 30328118SVasumathi.Sundaram@Sun.COM } else { 30338118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 30348118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 30358118SVasumathi.Sundaram@Sun.COM } 30365903Ssowmini *val_cnt = 1; 30378460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 30388460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 30398460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 30405903Ssowmini } 30416512Ssowmini free(dip); 30425903Ssowmini return (status); 30435903Ssowmini } 30446512Ssowmini 30456512Ssowmini 30466512Ssowmini static dladm_status_t 30478453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 30488453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 30496512Ssowmini { 30506512Ssowmini dladm_status_t status; 30516512Ssowmini char **prop_vals = NULL, *buf; 30526512Ssowmini size_t bufsize; 30536512Ssowmini uint_t cnt; 30546512Ssowmini int i; 30558118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 30566512Ssowmini 30576512Ssowmini /* 30586512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 30596512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 30606512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 30616512Ssowmini */ 30626512Ssowmini bufsize = 30636512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 30646512Ssowmini buf = malloc(bufsize); 30656512Ssowmini prop_vals = (char **)(void *)buf; 30666512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 30676512Ssowmini prop_vals[i] = buf + 30686512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 30696512Ssowmini i * DLADM_PROP_VAL_MAX; 30706512Ssowmini } 30716768Sar224390 30726768Sar224390 /* 30737342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 30747342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 30757342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 30767342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 30777342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 30787342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 30797342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 30807342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 30816768Sar224390 */ 30828453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 30838118SVasumathi.Sundaram@Sun.COM MAC_PROP_DEFAULT, &perm_flags); 30846512Ssowmini if (status == DLADM_STATUS_OK) { 30858118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 30868453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 30878453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 30888118SVasumathi.Sundaram@Sun.COM } 30898118SVasumathi.Sundaram@Sun.COM else 30908118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 30916512Ssowmini } 30926512Ssowmini free(buf); 30936512Ssowmini return (status); 30946512Ssowmini } 30957663SSowmini.Varadhan@Sun.COM 309610491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 309710491SRishi.Srivatsavai@Sun.COM static dladm_status_t 309810491SRishi.Srivatsavai@Sun.COM get_stp_prop(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 309910491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 310010491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 310110491SRishi.Srivatsavai@Sun.COM { 310210491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 310310491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 310410491SRishi.Srivatsavai@Sun.COM int val, i; 310510491SRishi.Srivatsavai@Sun.COM 310610491SRishi.Srivatsavai@Sun.COM if (flags != 0) 310710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 310810491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 310910491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 311010491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 311110491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 311210491SRishi.Srivatsavai@Sun.COM break; 311310491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 311410491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 311510491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 311610491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 311710491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 311810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 311910491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 312010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 312110491SRishi.Srivatsavai@Sun.COM } 312210491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 312310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 312410491SRishi.Srivatsavai@Sun.COM return (retv); 312510491SRishi.Srivatsavai@Sun.COM } 312610491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 312710491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 312810491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 312910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 313010491SRishi.Srivatsavai@Sun.COM } 313110491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 313210491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 313310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 313410491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 313510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 313610491SRishi.Srivatsavai@Sun.COM } 313710491SRishi.Srivatsavai@Sun.COM } 313810491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 313910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 314010491SRishi.Srivatsavai@Sun.COM } 314110491SRishi.Srivatsavai@Sun.COM 314210491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 314310491SRishi.Srivatsavai@Sun.COM static dladm_status_t 314410491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 314510491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 314610491SRishi.Srivatsavai@Sun.COM { 314710491SRishi.Srivatsavai@Sun.COM /* 314810491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 314910491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 315010491SRishi.Srivatsavai@Sun.COM */ 315110491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 315210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 315310491SRishi.Srivatsavai@Sun.COM 315410491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 315510491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 315610491SRishi.Srivatsavai@Sun.COM } 315710491SRishi.Srivatsavai@Sun.COM 315810491SRishi.Srivatsavai@Sun.COM /* 315910491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 316010491SRishi.Srivatsavai@Sun.COM */ 316110491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 316210491SRishi.Srivatsavai@Sun.COM static dladm_status_t 316310491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 316410491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 316510491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 316610491SRishi.Srivatsavai@Sun.COM { 316710491SRishi.Srivatsavai@Sun.COM char *cp; 316810491SRishi.Srivatsavai@Sun.COM boolean_t iscost; 316910491SRishi.Srivatsavai@Sun.COM 317010491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 317110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 317210491SRishi.Srivatsavai@Sun.COM 317310491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 317410491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 317510491SRishi.Srivatsavai@Sun.COM } else { 317610491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 317710491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 317810491SRishi.Srivatsavai@Sun.COM 317910491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 318010491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 318110491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 318210491SRishi.Srivatsavai@Sun.COM } else { 318310491SRishi.Srivatsavai@Sun.COM errno = 0; 318410491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 318510491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 318610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 318710491SRishi.Srivatsavai@Sun.COM } 318810491SRishi.Srivatsavai@Sun.COM } 318910491SRishi.Srivatsavai@Sun.COM 319010491SRishi.Srivatsavai@Sun.COM if (iscost) { 319110491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 319210491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 319310491SRishi.Srivatsavai@Sun.COM } else { 319410491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 319510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 319610491SRishi.Srivatsavai@Sun.COM /* 319710491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 319810491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 319910491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 320010491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 320110491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 320210491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 320310491SRishi.Srivatsavai@Sun.COM * can't be used now. 320410491SRishi.Srivatsavai@Sun.COM */ 320510491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 320610491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 320710491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 320810491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 320910491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 321010491SRishi.Srivatsavai@Sun.COM 321110491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 321210491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 321310491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 321410491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 321510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 321610491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 321710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 321810491SRishi.Srivatsavai@Sun.COM } 321910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 322010491SRishi.Srivatsavai@Sun.COM } 322110491SRishi.Srivatsavai@Sun.COM } 322210491SRishi.Srivatsavai@Sun.COM 322310491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 322410491SRishi.Srivatsavai@Sun.COM static dladm_status_t 322510491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 322610491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 322710491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 322810491SRishi.Srivatsavai@Sun.COM { 322910491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 323010491SRishi.Srivatsavai@Sun.COM uint_t val; 323110491SRishi.Srivatsavai@Sun.COM 323210491SRishi.Srivatsavai@Sun.COM if (flags != 0) 323310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 323410491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 323510491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 323610491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 323710491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 323810491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 323910491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 324010491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 324110491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 324210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 324310491SRishi.Srivatsavai@Sun.COM } 324410491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 324510491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 324610491SRishi.Srivatsavai@Sun.COM else 324710491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 324810491SRishi.Srivatsavai@Sun.COM return (retv); 324910491SRishi.Srivatsavai@Sun.COM } 325010491SRishi.Srivatsavai@Sun.COM 325110491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 325210491SRishi.Srivatsavai@Sun.COM static dladm_status_t 325310491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 325410491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 325510491SRishi.Srivatsavai@Sun.COM { 325610491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 325710491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 325810491SRishi.Srivatsavai@Sun.COM } 325910491SRishi.Srivatsavai@Sun.COM 326010491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 326110491SRishi.Srivatsavai@Sun.COM static dladm_status_t 326210491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 326310491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 326410491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 326510491SRishi.Srivatsavai@Sun.COM { 326610491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 326710491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 326810491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 326910491SRishi.Srivatsavai@Sun.COM 327010491SRishi.Srivatsavai@Sun.COM if (flags != 0) 327110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 327210491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 327310491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 327410491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 327510491SRishi.Srivatsavai@Sun.COM 0, &status); 327610491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 327710491SRishi.Srivatsavai@Sun.COM return (status); 327810491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 327910491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 328010491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 328110491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 328210491SRishi.Srivatsavai@Sun.COM } else { 328310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 328410491SRishi.Srivatsavai@Sun.COM } 328510491SRishi.Srivatsavai@Sun.COM free(dip); 328610491SRishi.Srivatsavai@Sun.COM return (status); 328710491SRishi.Srivatsavai@Sun.COM } 328810491SRishi.Srivatsavai@Sun.COM 328910491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 329010491SRishi.Srivatsavai@Sun.COM static dladm_status_t 329110491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 329210491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 329310491SRishi.Srivatsavai@Sun.COM { 329410491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 329510491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 329610491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 329710491SRishi.Srivatsavai@Sun.COM 329810491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 329910491SRishi.Srivatsavai@Sun.COM 0, &status); 330010491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 330110491SRishi.Srivatsavai@Sun.COM return (status); 330210491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 330310491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 330410491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 330510491SRishi.Srivatsavai@Sun.COM free(dip); 330610491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 330710491SRishi.Srivatsavai@Sun.COM return (status); 330810491SRishi.Srivatsavai@Sun.COM 330910491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 331010491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 331110491SRishi.Srivatsavai@Sun.COM } 331210491SRishi.Srivatsavai@Sun.COM 331310491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 331410491SRishi.Srivatsavai@Sun.COM static dladm_status_t 331510491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 331610491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 331710491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 331810491SRishi.Srivatsavai@Sun.COM { 331910491SRishi.Srivatsavai@Sun.COM char *cp; 332010491SRishi.Srivatsavai@Sun.COM 332110491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 332210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 332310491SRishi.Srivatsavai@Sun.COM 332410491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 332510491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 332610491SRishi.Srivatsavai@Sun.COM } else { 332710491SRishi.Srivatsavai@Sun.COM errno = 0; 332810491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 332910491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 333010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 333110491SRishi.Srivatsavai@Sun.COM } 333210491SRishi.Srivatsavai@Sun.COM 333310491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 333410491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 333510491SRishi.Srivatsavai@Sun.COM } 333610491SRishi.Srivatsavai@Sun.COM 33377663SSowmini.Varadhan@Sun.COM dladm_status_t 33388453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 33398453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 33407663SSowmini.Varadhan@Sun.COM { 33417663SSowmini.Varadhan@Sun.COM uint32_t flags; 33427663SSowmini.Varadhan@Sun.COM dladm_status_t status; 33437663SSowmini.Varadhan@Sun.COM uint32_t media; 33447663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 33457663SSowmini.Varadhan@Sun.COM void *dp; 33467663SSowmini.Varadhan@Sun.COM 33478453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 33488453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 33497663SSowmini.Varadhan@Sun.COM return (status); 33507663SSowmini.Varadhan@Sun.COM } 33517663SSowmini.Varadhan@Sun.COM 33527663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 33537663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 33547663SSowmini.Varadhan@Sun.COM 33557663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 33567663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 33577663SSowmini.Varadhan@Sun.COM 33587663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 33597663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 33607663SSowmini.Varadhan@Sun.COM 33617663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 33627663SSowmini.Varadhan@Sun.COM if (dip == NULL) 33637663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 33647663SSowmini.Varadhan@Sun.COM 33657663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 33667663SSowmini.Varadhan@Sun.COM if (set) 33677663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 33687663SSowmini.Varadhan@Sun.COM 33698453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 337010191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 33717663SSowmini.Varadhan@Sun.COM if (!set) 33727663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 33737663SSowmini.Varadhan@Sun.COM } 33747663SSowmini.Varadhan@Sun.COM 33757663SSowmini.Varadhan@Sun.COM free(dip); 33767663SSowmini.Varadhan@Sun.COM return (status); 33777663SSowmini.Varadhan@Sun.COM } 33787663SSowmini.Varadhan@Sun.COM 33798275SEric Cheng dladm_status_t 33808275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 33818275SEric Cheng { 33828460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 33838275SEric Cheng } 33848275SEric Cheng 33858275SEric Cheng /* 33868275SEric Cheng * Retrieve the one link property from the database 33878275SEric Cheng */ 33888275SEric Cheng /*ARGSUSED*/ 33898275SEric Cheng static int 33908453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 33918453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 33928275SEric Cheng { 33938275SEric Cheng dladm_arg_list_t *proplist = arg; 33948275SEric Cheng dladm_arg_info_t *aip = NULL; 33958275SEric Cheng 33968275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 33978275SEric Cheng /* 33988275SEric Cheng * it is fine to point to prop_name since prop_name points to the 33998275SEric Cheng * prop_table[n].pd_name. 34008275SEric Cheng */ 34018275SEric Cheng aip->ai_name = prop_name; 34028275SEric Cheng 34038453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 34048453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 34058275SEric Cheng 34068275SEric Cheng if (aip->ai_count != 0) 34078275SEric Cheng proplist->al_count++; 34088275SEric Cheng 34098275SEric Cheng return (DLADM_WALK_CONTINUE); 34108275SEric Cheng } 34118275SEric Cheng 34128275SEric Cheng 34138275SEric Cheng /* 34148275SEric Cheng * Retrieve all link properties for a link from the database and 34158275SEric Cheng * return a property list. 34168275SEric Cheng */ 34178275SEric Cheng dladm_status_t 34188453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 34198453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 34208275SEric Cheng { 34218275SEric Cheng dladm_arg_list_t *list; 34228275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 34238275SEric Cheng 34248275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 34258275SEric Cheng if (list == NULL) 34268275SEric Cheng return (dladm_errno2status(errno)); 34278275SEric Cheng 34288453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 34298453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 34308275SEric Cheng 34318275SEric Cheng *listp = list; 34328275SEric Cheng return (status); 34338275SEric Cheng } 34348275SEric Cheng 34358275SEric Cheng /* 34368275SEric Cheng * Retrieve the named property from a proplist, check the value and 34378275SEric Cheng * convert to a kernel structure. 34388275SEric Cheng */ 34398275SEric Cheng static dladm_status_t 34408453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 34418453SAnurag.Maskey@Sun.COM dladm_arg_list_t *proplist, const char *name, void *val) 34428275SEric Cheng { 34438275SEric Cheng dladm_status_t status; 34448275SEric Cheng dladm_arg_info_t *aip = NULL; 34458275SEric Cheng int i, j; 34468275SEric Cheng 34478275SEric Cheng /* Find named property in proplist */ 34488275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 34498275SEric Cheng aip = &proplist->al_info[i]; 34508275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 34518275SEric Cheng break; 34528275SEric Cheng } 34538275SEric Cheng 34548275SEric Cheng /* Property not in list */ 34558275SEric Cheng if (i == proplist->al_count) 34568275SEric Cheng return (DLADM_STATUS_OK); 34578275SEric Cheng 34588275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 34598275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 34608275SEric Cheng val_desc_t *vdp; 34618275SEric Cheng 34628275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 34638275SEric Cheng if (vdp == NULL) 34648275SEric Cheng return (DLADM_STATUS_NOMEM); 34658275SEric Cheng 34668275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 34678275SEric Cheng continue; 34688275SEric Cheng 34698275SEric Cheng if (aip->ai_val == NULL) 34708275SEric Cheng return (DLADM_STATUS_BADARG); 34718275SEric Cheng 34728275SEric Cheng /* Check property value */ 34738275SEric Cheng if (pdp->pd_check != NULL) { 34748453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 34758275SEric Cheng aip->ai_count, vdp, 0); 34768275SEric Cheng } else { 34778275SEric Cheng status = DLADM_STATUS_BADARG; 34788275SEric Cheng } 34798275SEric Cheng 34808275SEric Cheng if (status != DLADM_STATUS_OK) 34818275SEric Cheng return (status); 34828275SEric Cheng 34838275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 34848275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 34858275SEric Cheng 34868275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 34878275SEric Cheng continue; 34888275SEric Cheng 34898275SEric Cheng /* Extract kernel structure */ 34908275SEric Cheng if (rpp->rp_extract != NULL) { 34918275SEric Cheng status = rpp->rp_extract(vdp, val, 34928275SEric Cheng aip->ai_count); 34938275SEric Cheng } else { 34948275SEric Cheng status = DLADM_STATUS_BADARG; 34958275SEric Cheng } 34968275SEric Cheng break; 34978275SEric Cheng } 34988275SEric Cheng 34998275SEric Cheng if (status != DLADM_STATUS_OK) 35008275SEric Cheng return (status); 35018275SEric Cheng 35028275SEric Cheng break; 35038275SEric Cheng } 35048275SEric Cheng return (status); 35058275SEric Cheng } 35068275SEric Cheng 35078275SEric Cheng /* 35088275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 35098275SEric Cheng */ 35108275SEric Cheng dladm_status_t 35118453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 35128275SEric Cheng mac_resource_props_t *mrp) 35138275SEric Cheng { 35148275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 35158275SEric Cheng 35168453SAnurag.Maskey@Sun.COM status = i_dladm_link_proplist_extract_one(handle, proplist, "maxbw", 35178453SAnurag.Maskey@Sun.COM mrp); 35188275SEric Cheng if (status != DLADM_STATUS_OK) 35198275SEric Cheng return (status); 35208453SAnurag.Maskey@Sun.COM status = i_dladm_link_proplist_extract_one(handle, proplist, "priority", 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, "cpus", 35258453SAnurag.Maskey@Sun.COM mrp); 35268275SEric Cheng if (status != DLADM_STATUS_OK) 35278275SEric Cheng return (status); 35288275SEric Cheng return (status); 35298275SEric Cheng } 35308275SEric Cheng 35318275SEric Cheng static const char * 35328275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 35338275SEric Cheng { 35348275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 35358275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 35368275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 35378275SEric Cheng return (buf); 35388275SEric Cheng } 35398306SSowmini.Varadhan@Sun.COM 35408306SSowmini.Varadhan@Sun.COM dladm_status_t 35418453SAnurag.Maskey@Sun.COM i_dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 35428453SAnurag.Maskey@Sun.COM link_state_t *state) 35438306SSowmini.Varadhan@Sun.COM { 35448306SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 35458306SSowmini.Varadhan@Sun.COM dladm_status_t status; 35468306SSowmini.Varadhan@Sun.COM uint_t perms; 35478306SSowmini.Varadhan@Sun.COM 35488453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, "state", 0, &status, 35498453SAnurag.Maskey@Sun.COM &perms); 35508306SSowmini.Varadhan@Sun.COM if (status != DLADM_STATUS_OK) 35518306SSowmini.Varadhan@Sun.COM return (status); 35528306SSowmini.Varadhan@Sun.COM (void) memcpy(state, dip->pr_val, sizeof (*state)); 35538306SSowmini.Varadhan@Sun.COM free(dip); 35548306SSowmini.Varadhan@Sun.COM return (status); 35558306SSowmini.Varadhan@Sun.COM } 35568460SArtem.Kachitchkin@Sun.COM 35578460SArtem.Kachitchkin@Sun.COM boolean_t 35588460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 35598460SArtem.Kachitchkin@Sun.COM { 35608460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 35618460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 35628460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 35638460SArtem.Kachitchkin@Sun.COM "name", 35648460SArtem.Kachitchkin@Sun.COM "class", 35658460SArtem.Kachitchkin@Sun.COM "media", 35668460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 35678460SArtem.Kachitchkin@Sun.COM FPHYINST, 35688460SArtem.Kachitchkin@Sun.COM FDEVNAME, 35698460SArtem.Kachitchkin@Sun.COM 35708460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 35718460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 35728460SArtem.Kachitchkin@Sun.COM }; 35738460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 35748460SArtem.Kachitchkin@Sun.COM int i; 35758460SArtem.Kachitchkin@Sun.COM 35768460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 35778460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 35788460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 35798460SArtem.Kachitchkin@Sun.COM break; 35808460SArtem.Kachitchkin@Sun.COM } 35818460SArtem.Kachitchkin@Sun.COM } 35828460SArtem.Kachitchkin@Sun.COM 35838460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 35848460SArtem.Kachitchkin@Sun.COM } 3585