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> 545903Ssowmini #include <inttypes.h> 555903Ssowmini #include <sys/ethernet.h> 5610616SSebastien.Roy@Sun.COM #include <inet/iptun.h> 577663SSowmini.Varadhan@Sun.COM #include <net/wpa.h> 587663SSowmini.Varadhan@Sun.COM #include <sys/sysmacros.h> 5910491SRishi.Srivatsavai@Sun.COM #include <sys/vlan.h> 6010491SRishi.Srivatsavai@Sun.COM #include <libdlbridge.h> 6110491SRishi.Srivatsavai@Sun.COM #include <stp_in.h> 623448Sdh155122 635895Syz147064 /* 645895Syz147064 * The linkprop get() callback. 658275SEric Cheng * - pd: pointer to the prop_desc_t 665895Syz147064 * - propstrp: a property string array to keep the returned property. 675895Syz147064 * Caller allocated. 685895Syz147064 * - cntp: number of returned properties. 695895Syz147064 * Caller also uses it to indicate how many it expects. 705895Syz147064 */ 715903Ssowmini struct prop_desc; 728275SEric Cheng typedef struct prop_desc prop_desc_t; 738275SEric Cheng 748453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 755960Ssowmini datalink_id_t, char **propstp, uint_t *cntp, 768118SVasumathi.Sundaram@Sun.COM datalink_media_t, uint_t, uint_t *); 775895Syz147064 785895Syz147064 /* 795895Syz147064 * The linkprop set() callback. 805895Syz147064 * - propval: a val_desc_t array which keeps the property values to be set. 815895Syz147064 * - cnt: number of properties to be set. 825903Ssowmini * - flags: additional flags passed down the system call. 835903Ssowmini * 845903Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 855903Ssowmini * a format suitable for kernel consumption. This may require allocation 865903Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 875903Ssowmini * by all other pd_sets) which invokes the ioctl. 885895Syz147064 */ 898453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 908275SEric Cheng val_desc_t *propval, uint_t cnt, uint_t flags, 918275SEric Cheng datalink_media_t); 923448Sdh155122 935895Syz147064 /* 945895Syz147064 * The linkprop check() callback. 955895Syz147064 * - propstrp: property string array which keeps the property to be checked. 965895Syz147064 * - cnt: number of properties. 975895Syz147064 * - propval: return value; the property values of the given property strings. 985903Ssowmini * 995903Ssowmini * pd_check checks that the input values are valid. It does so by 1005903Ssowmini * iteraring through the pd_modval list for the property. If 1015903Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 1025903Ssowmini * specific to this property can be used. If the input values are 1035903Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 1045903Ssowmini * with either a val_desc_t found on the pd_modval list or something 1055903Ssowmini * generated on the fly. 1065895Syz147064 */ 1078453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 1088453SAnurag.Maskey@Sun.COM datalink_id_t, char **propstrp, uint_t cnt, 1098453SAnurag.Maskey@Sun.COM val_desc_t *propval, datalink_media_t); 1103448Sdh155122 1117663SSowmini.Varadhan@Sun.COM typedef struct link_attr_s { 1126789Sam223141 mac_prop_id_t pp_id; 1135903Ssowmini size_t pp_valsize; 1145903Ssowmini char *pp_name; 1157663SSowmini.Varadhan@Sun.COM } link_attr_t; 1165903Ssowmini 1177663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 1188275SEric Cheng const char *, uint_t, dladm_status_t *); 1197663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 1208275SEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 1218453SAnurag.Maskey@Sun.COM static dld_ioc_macprop_t *i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 1228453SAnurag.Maskey@Sun.COM char *, uint_t, dladm_status_t *, uint_t *); 1238453SAnurag.Maskey@Sun.COM 1249692SRishi.Srivatsavai@Sun.COM static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1258453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 1268460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1278453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *, dladm_prop_type_t, 1288453SAnurag.Maskey@Sun.COM uint_t); 1297663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_name2prop(const char *); 1307663SSowmini.Varadhan@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 1318275SEric Cheng 1325895Syz147064 static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, 1335895Syz147064 do_get_rate_prop, do_get_channel_prop, 1345903Ssowmini do_get_powermode_prop, do_get_radio_prop, 1357342SAruna.Ramakrishna@Sun.COM i_dladm_duplex_get, i_dladm_status_get, 1367342SAruna.Ramakrishna@Sun.COM i_dladm_binary_get, i_dladm_uint32_get, 1378460SArtem.Kachitchkin@Sun.COM i_dladm_flowctl_get, i_dladm_maxbw_get, 1388874SSebastien.Roy@Sun.COM i_dladm_cpus_get, i_dladm_priority_get, 13910491SRishi.Srivatsavai@Sun.COM i_dladm_tagmode_get, i_dladm_range_get, 14010491SRishi.Srivatsavai@Sun.COM get_stp_prop, get_bridge_forward, 141*10734SEric Cheng get_bridge_pvid, 142*10734SEric Cheng /* the above need to be renamed to "do_get_xxx" */ 143*10734SEric Cheng do_get_protection; 1448275SEric Cheng 1457342SAruna.Ramakrishna@Sun.COM static pd_setf_t do_set_zone, do_set_rate_prop, 1465903Ssowmini do_set_powermode_prop, do_set_radio_prop, 14710491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, do_set_res, do_set_cpus, 148*10734SEric Cheng set_stp_prop, set_bridge_forward, set_bridge_pvid, 149*10734SEric Cheng do_set_protection; 1508275SEric Cheng 1515903Ssowmini static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, 15210616SSebastien.Roy@Sun.COM do_check_hoplimit, do_check_encaplim, 15310491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, do_check_maxbw, do_check_cpus, 154*10734SEric Cheng do_check_priority, check_stp_prop, check_bridge_pvid, 155*10734SEric Cheng do_check_allowedips, do_check_prop; 1568275SEric Cheng 1578453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_speed_get(dladm_handle_t, prop_desc_t *, 1588453SAnurag.Maskey@Sun.COM datalink_id_t, char **, uint_t *, uint_t, uint_t *); 1598453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1608275SEric Cheng static const char *dladm_perm2str(uint_t, char *); 1618275SEric Cheng 1628275SEric Cheng struct prop_desc { 1635895Syz147064 /* 1645895Syz147064 * link property name 1655895Syz147064 */ 1665895Syz147064 char *pd_name; 1675895Syz147064 1685895Syz147064 /* 1695895Syz147064 * default property value, can be set to { "", NULL } 1705895Syz147064 */ 1715895Syz147064 val_desc_t pd_defval; 1725895Syz147064 1735895Syz147064 /* 1745895Syz147064 * list of optional property values, can be NULL. 1755895Syz147064 * 1765895Syz147064 * This is set to non-NULL if there is a list of possible property 1775895Syz147064 * values. pd_optval would point to the array of possible values. 1785895Syz147064 */ 1795895Syz147064 val_desc_t *pd_optval; 1805895Syz147064 1815895Syz147064 /* 1825895Syz147064 * count of the above optional property values. 0 if pd_optval is NULL. 1835895Syz147064 */ 1845895Syz147064 uint_t pd_noptval; 1855895Syz147064 1865895Syz147064 /* 18710491SRishi.Srivatsavai@Sun.COM * callback to set link property; set to NULL if this property is 18810491SRishi.Srivatsavai@Sun.COM * read-only and may be called before or after permanent update; see 18910491SRishi.Srivatsavai@Sun.COM * flags. 1905895Syz147064 */ 1915895Syz147064 pd_setf_t *pd_set; 1925895Syz147064 1935895Syz147064 /* 1945895Syz147064 * callback to get modifiable link property 1955895Syz147064 */ 1965895Syz147064 pd_getf_t *pd_getmod; 1975895Syz147064 1985895Syz147064 /* 1995895Syz147064 * callback to get current link property 2005895Syz147064 */ 2015895Syz147064 pd_getf_t *pd_get; 2025895Syz147064 2035895Syz147064 /* 2045895Syz147064 * callback to validate link property value, set to NULL if pd_optval 2055895Syz147064 * is not NULL. In that case, validate the value by comparing it with 2065895Syz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 2075895Syz147064 * valid. 2085895Syz147064 */ 2095895Syz147064 pd_checkf_t *pd_check; 2105895Syz147064 2115895Syz147064 uint_t pd_flags; 2125903Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 2135903Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 21410491SRishi.Srivatsavai@Sun.COM #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 2155895Syz147064 /* 2165895Syz147064 * indicate link classes this property applies to. 2175895Syz147064 */ 2185895Syz147064 datalink_class_t pd_class; 2195895Syz147064 2205895Syz147064 /* 2215895Syz147064 * indicate link media type this property applies to. 2225895Syz147064 */ 2235895Syz147064 datalink_media_t pd_dmedia; 2248275SEric Cheng }; 2253448Sdh155122 2266789Sam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 2275903Ssowmini 2287663SSowmini.Varadhan@Sun.COM /* 2297663SSowmini.Varadhan@Sun.COM * Supported link properties enumerated in the prop_table[] array are 2307663SSowmini.Varadhan@Sun.COM * computed using the callback functions in that array. To compute the 2317663SSowmini.Varadhan@Sun.COM * property value, multiple distinct system calls may be needed (e.g., 2327663SSowmini.Varadhan@Sun.COM * for wifi speed, we need to issue system calls to get desired/supported 2337663SSowmini.Varadhan@Sun.COM * rates). The link_attr[] table enumerates the interfaces to the kernel, 2347663SSowmini.Varadhan@Sun.COM * and the type/size of the data passed in the user-kernel interface. 2357663SSowmini.Varadhan@Sun.COM */ 2367663SSowmini.Varadhan@Sun.COM static link_attr_t link_attr[] = { 2377663SSowmini.Varadhan@Sun.COM { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 2385903Ssowmini 2397663SSowmini.Varadhan@Sun.COM { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 2407663SSowmini.Varadhan@Sun.COM 2417663SSowmini.Varadhan@Sun.COM { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 2427663SSowmini.Varadhan@Sun.COM 2437663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 2445903Ssowmini 2457663SSowmini.Varadhan@Sun.COM { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 2465903Ssowmini 2477663SSowmini.Varadhan@Sun.COM { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 2487663SSowmini.Varadhan@Sun.COM 2497663SSowmini.Varadhan@Sun.COM { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 2505903Ssowmini 2517663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2527663SSowmini.Varadhan@Sun.COM 2539449Sxiuyan.wang@Sun.COM { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 2549449Sxiuyan.wang@Sun.COM 2559449Sxiuyan.wang@Sun.COM { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 2569449Sxiuyan.wang@Sun.COM 2577663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2587663SSowmini.Varadhan@Sun.COM 2597663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 2605903Ssowmini 2617663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 2625903Ssowmini 2637663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 2647663SSowmini.Varadhan@Sun.COM 2657663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 2667342SAruna.Ramakrishna@Sun.COM 2677663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 2687663SSowmini.Varadhan@Sun.COM 2697663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 2707663SSowmini.Varadhan@Sun.COM 2717663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 2727342SAruna.Ramakrishna@Sun.COM 2737663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 2747663SSowmini.Varadhan@Sun.COM 2757663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 2765903Ssowmini 2777663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 2787663SSowmini.Varadhan@Sun.COM 2797663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 2805903Ssowmini 2817663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 2827663SSowmini.Varadhan@Sun.COM 2837663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 2845903Ssowmini 2857663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 2867663SSowmini.Varadhan@Sun.COM 2877663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 2887663SSowmini.Varadhan@Sun.COM 2897663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2907663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 2915903Ssowmini 2927663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2937663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 2947663SSowmini.Varadhan@Sun.COM 2957663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 2965903Ssowmini 2977663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 2987663SSowmini.Varadhan@Sun.COM 2997663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 3005903Ssowmini 3017663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 3027663SSowmini.Varadhan@Sun.COM 3037663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 3045903Ssowmini 3057663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 3067663SSowmini.Varadhan@Sun.COM 3077663SSowmini.Varadhan@Sun.COM /* wl_wpa_ess_t has variable length */ 3087663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 3095903Ssowmini 3107663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 3117663SSowmini.Varadhan@Sun.COM 3127663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 3135903Ssowmini 3147663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 3157663SSowmini.Varadhan@Sun.COM 3167663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 3175903Ssowmini 3187663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 3197663SSowmini.Varadhan@Sun.COM 3207663SSowmini.Varadhan@Sun.COM /* wl_wpa_ie_t has variable length */ 3217663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 3225903Ssowmini 3237663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 3247663SSowmini.Varadhan@Sun.COM 3257663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 3265903Ssowmini 3277663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 3287663SSowmini.Varadhan@Sun.COM 3298275SEric Cheng { MAC_PROP_MAXBW, sizeof (mac_resource_props_t), "maxbw"}, 3308275SEric Cheng 3318275SEric Cheng { MAC_PROP_PRIO, sizeof (mac_resource_props_t), "priority"}, 3328275SEric Cheng 3338275SEric Cheng { MAC_PROP_BIND_CPU, sizeof (mac_resource_props_t), "cpus"}, 3348275SEric Cheng 3358874SSebastien.Roy@Sun.COM { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 3368874SSebastien.Roy@Sun.COM 33710616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 33810616SSebastien.Roy@Sun.COM 33910616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 34010616SSebastien.Roy@Sun.COM 34110491SRishi.Srivatsavai@Sun.COM { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 34210491SRishi.Srivatsavai@Sun.COM 34310491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 34410491SRishi.Srivatsavai@Sun.COM 34510491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 34610491SRishi.Srivatsavai@Sun.COM 347*10734SEric Cheng { MAC_PROP_PROTECT, sizeof (mac_resource_props_t), "protection"}, 348*10734SEric Cheng 3497663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3505903Ssowmini }; 3515903Ssowmini 35210491SRishi.Srivatsavai@Sun.COM typedef struct bridge_public_prop_s { 35310491SRishi.Srivatsavai@Sun.COM const char *bpp_name; 35410491SRishi.Srivatsavai@Sun.COM int bpp_code; 35510491SRishi.Srivatsavai@Sun.COM } bridge_public_prop_t; 35610491SRishi.Srivatsavai@Sun.COM 35710491SRishi.Srivatsavai@Sun.COM static const bridge_public_prop_t bridge_prop[] = { 35810491SRishi.Srivatsavai@Sun.COM { "stp", PT_CFG_NON_STP }, 35910491SRishi.Srivatsavai@Sun.COM { "stp_priority", PT_CFG_PRIO }, 36010491SRishi.Srivatsavai@Sun.COM { "stp_cost", PT_CFG_COST }, 36110491SRishi.Srivatsavai@Sun.COM { "stp_edge", PT_CFG_EDGE }, 36210491SRishi.Srivatsavai@Sun.COM { "stp_p2p", PT_CFG_P2P }, 36310491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", PT_CFG_MCHECK }, 36410491SRishi.Srivatsavai@Sun.COM { NULL, 0 } 36510491SRishi.Srivatsavai@Sun.COM }; 36610491SRishi.Srivatsavai@Sun.COM 3675903Ssowmini static val_desc_t link_duplex_vals[] = { 3685903Ssowmini { "half", LINK_DUPLEX_HALF }, 3695903Ssowmini { "full", LINK_DUPLEX_HALF } 3705903Ssowmini }; 3715903Ssowmini static val_desc_t link_status_vals[] = { 3725903Ssowmini { "up", LINK_STATE_UP }, 3735903Ssowmini { "down", LINK_STATE_DOWN } 3745903Ssowmini }; 3755903Ssowmini static val_desc_t link_01_vals[] = { 3765903Ssowmini { "1", 1 }, 3775903Ssowmini { "0", 0 } 3785903Ssowmini }; 3795903Ssowmini static val_desc_t link_flow_vals[] = { 3805903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3815903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3825903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 3835903Ssowmini { "bi", LINK_FLOWCTRL_BI } 3845903Ssowmini }; 3858275SEric Cheng static val_desc_t link_priority_vals[] = { 3868275SEric Cheng { "low", MPL_LOW }, 3878275SEric Cheng { "medium", MPL_MEDIUM }, 3888275SEric Cheng { "high", MPL_HIGH } 3898275SEric Cheng }; 3905903Ssowmini 3918874SSebastien.Roy@Sun.COM static val_desc_t link_tagmode_vals[] = { 3928874SSebastien.Roy@Sun.COM { "normal", LINK_TAGMODE_NORMAL }, 3938874SSebastien.Roy@Sun.COM { "vlanonly", LINK_TAGMODE_VLANONLY } 3948874SSebastien.Roy@Sun.COM }; 3958874SSebastien.Roy@Sun.COM 396*10734SEric Cheng static val_desc_t link_protect_vals[] = { 397*10734SEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 398*10734SEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 399*10734SEric Cheng { "restricted", MPT_RESTRICTED } 400*10734SEric Cheng }; 401*10734SEric Cheng 4025895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 4035895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 4045895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 4055895Syz147064 }; 4065895Syz147064 4075895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 4085895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 4095895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 4105895Syz147064 { "max", DLADM_WLAN_PM_MAX } 4115895Syz147064 }; 4125895Syz147064 41310491SRishi.Srivatsavai@Sun.COM static val_desc_t stp_p2p_vals[] = { 41410491SRishi.Srivatsavai@Sun.COM { "true", P2P_FORCE_TRUE }, 41510491SRishi.Srivatsavai@Sun.COM { "false", P2P_FORCE_FALSE }, 41610491SRishi.Srivatsavai@Sun.COM { "auto", P2P_AUTO } 41710491SRishi.Srivatsavai@Sun.COM }; 41810491SRishi.Srivatsavai@Sun.COM 4198275SEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 4208275SEric Cheng #define RESET_VAL ((uintptr_t)-1) 4218275SEric Cheng 4223448Sdh155122 static prop_desc_t prop_table[] = { 4235903Ssowmini { "channel", { NULL, 0 }, 4245903Ssowmini NULL, 0, NULL, NULL, 4255895Syz147064 do_get_channel_prop, NULL, 0, 4265903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4275895Syz147064 4285895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 4295895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 4305895Syz147064 do_set_powermode_prop, NULL, 4315895Syz147064 do_get_powermode_prop, NULL, 0, 4325903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4335895Syz147064 4345895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 4355895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 4365895Syz147064 do_set_radio_prop, NULL, 4375895Syz147064 do_get_radio_prop, NULL, 0, 4385903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4395895Syz147064 4405895Syz147064 { "speed", { "", 0 }, NULL, 0, 4415895Syz147064 do_set_rate_prop, do_get_rate_mod, 4425895Syz147064 do_get_rate_prop, do_check_rate, 0, 4435960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 4445895Syz147064 4456512Ssowmini { "autopush", { "", 0 }, NULL, 0, 4467342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, 4477342SAruna.Ramakrishna@Sun.COM do_get_autopush, do_check_autopush, PD_CHECK_ALLOC, 4485903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4495895Syz147064 4506512Ssowmini { "zone", { "", 0 }, NULL, 0, 4513448Sdh155122 do_set_zone, NULL, 4527342SAruna.Ramakrishna@Sun.COM do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 4535903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4545903Ssowmini 4558275SEric Cheng { "duplex", { "", 0 }, 4565903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 4577342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_duplex_get, NULL, 4585903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4595903Ssowmini 4608275SEric Cheng { "state", { "up", LINK_STATE_UP }, 4615903Ssowmini link_status_vals, VALCNT(link_status_vals), 4627342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_status_get, NULL, 4636512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4645903Ssowmini 46510191SSowmini.Varadhan@Sun.COM { "adv_autoneg_cap", { "", 0 }, 4665903Ssowmini link_01_vals, VALCNT(link_01_vals), 4677342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4685903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4695903Ssowmini 4706512Ssowmini { "mtu", { "", 0 }, NULL, 0, 4719514SGirish.Moodalbail@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, 47210491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_get, i_dladm_uint32_check, 0, DATALINK_CLASS_ALL, 4737342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 4745903Ssowmini 4756512Ssowmini { "flowctrl", { "", 0 }, 4765903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 4777342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL, 4785903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4795903Ssowmini 4809449Sxiuyan.wang@Sun.COM { "adv_10gfdx_cap", { "", 0 }, 4819449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 4829449Sxiuyan.wang@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 4839449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4849449Sxiuyan.wang@Sun.COM 4859449Sxiuyan.wang@Sun.COM { "en_10gfdx_cap", { "", 0 }, 4869449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 4879449Sxiuyan.wang@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 4889449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4899449Sxiuyan.wang@Sun.COM 4906512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 4916512Ssowmini 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_1000fdx_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_1000hdx_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_1000hdx_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_100fdx_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_100fdx_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_100hdx_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_100hdx_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_10fdx_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_10fdx_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, 5385903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5395903Ssowmini 5406512Ssowmini { "adv_10hdx_cap", { "", 0 }, 5415903Ssowmini link_01_vals, VALCNT(link_01_vals), 5427342SAruna.Ramakrishna@Sun.COM NULL, NULL, i_dladm_binary_get, NULL, 5435903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5445903Ssowmini 5456512Ssowmini { "en_10hdx_cap", { "", 0 }, 5465903Ssowmini link_01_vals, VALCNT(link_01_vals), 5477342SAruna.Ramakrishna@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL, 5488275SEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5498275SEric Cheng 5508275SEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 5518275SEric Cheng do_set_res, NULL, 5528460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get, do_check_maxbw, PD_CHECK_ALLOC, 5538275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5548275SEric Cheng 5558275SEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 5568275SEric Cheng do_set_cpus, NULL, 5578460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get, do_check_cpus, 0, 5588275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5598275SEric Cheng 5608275SEric Cheng { "priority", { "high", RESET_VAL }, 5618275SEric Cheng link_priority_vals, VALCNT(link_priority_vals), do_set_res, NULL, 5628460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get, do_check_priority, PD_CHECK_ALLOC, 5638275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5648874SSebastien.Roy@Sun.COM 5658874SSebastien.Roy@Sun.COM { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 5668874SSebastien.Roy@Sun.COM link_tagmode_vals, VALCNT(link_tagmode_vals), 5678874SSebastien.Roy@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_tagmode_get, 5688874SSebastien.Roy@Sun.COM NULL, 0, 5698874SSebastien.Roy@Sun.COM DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 57010491SRishi.Srivatsavai@Sun.COM DL_ETHER }, 57110491SRishi.Srivatsavai@Sun.COM 57210616SSebastien.Roy@Sun.COM { "hoplimit", { "", 0 }, NULL, 0, 57310616SSebastien.Roy@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, i_dladm_uint32_get, 57410616SSebastien.Roy@Sun.COM do_check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 57510616SSebastien.Roy@Sun.COM 57610616SSebastien.Roy@Sun.COM { "encaplimit", { "", 0 }, NULL, 0, 57710616SSebastien.Roy@Sun.COM i_dladm_set_public_prop, i_dladm_range_get, i_dladm_uint32_get, 57810616SSebastien.Roy@Sun.COM do_check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 57910616SSebastien.Roy@Sun.COM 58010491SRishi.Srivatsavai@Sun.COM { "forward", { "1", 1 }, 58110491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 58210491SRishi.Srivatsavai@Sun.COM set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 58310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 58410491SRishi.Srivatsavai@Sun.COM 58510491SRishi.Srivatsavai@Sun.COM { "default_tag", { "1", 1 }, NULL, 0, 58610491SRishi.Srivatsavai@Sun.COM set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 58710491SRishi.Srivatsavai@Sun.COM 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 58810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 58910491SRishi.Srivatsavai@Sun.COM 59010491SRishi.Srivatsavai@Sun.COM { "learn_limit", { "1000", 1000 }, NULL, 0, 59110491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 59210491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, 0, 59310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 59410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 59510491SRishi.Srivatsavai@Sun.COM 59610491SRishi.Srivatsavai@Sun.COM { "learn_decay", { "200", 200 }, NULL, 0, 59710491SRishi.Srivatsavai@Sun.COM i_dladm_set_public_prop, NULL, i_dladm_uint32_get, 59810491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check, 0, 59910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 60010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 60110491SRishi.Srivatsavai@Sun.COM 60210491SRishi.Srivatsavai@Sun.COM { "stp", { "1", 1 }, 60310491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 60410491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, 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_priority", { "128", 128 }, NULL, 0, 60910491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 61010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 61110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 61210491SRishi.Srivatsavai@Sun.COM 61310491SRishi.Srivatsavai@Sun.COM { "stp_cost", { "auto", 0 }, NULL, 0, 61410491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 61510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 61610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 61710491SRishi.Srivatsavai@Sun.COM 61810491SRishi.Srivatsavai@Sun.COM { "stp_edge", { "1", 1 }, 61910491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 62010491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 62110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 62210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 62310491SRishi.Srivatsavai@Sun.COM 62410491SRishi.Srivatsavai@Sun.COM { "stp_p2p", { "auto", P2P_AUTO }, 62510491SRishi.Srivatsavai@Sun.COM stp_p2p_vals, VALCNT(stp_p2p_vals), 62610491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, NULL, PD_AFTER_PERM, 62710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 62810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 62910491SRishi.Srivatsavai@Sun.COM 63010491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", { "0", 0 }, 63110491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 63210491SRishi.Srivatsavai@Sun.COM set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, 63310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 63410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 635*10734SEric Cheng 636*10734SEric Cheng { "protection", { "--", RESET_VAL }, 637*10734SEric Cheng link_protect_vals, VALCNT(link_protect_vals), 638*10734SEric Cheng do_set_protection, NULL, do_get_protection, do_check_prop, 0, 639*10734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 640*10734SEric Cheng 641*10734SEric Cheng { "allowed-ips", { "--", 0 }, 642*10734SEric Cheng NULL, 0, do_set_protection, NULL, 643*10734SEric Cheng do_get_protection, do_check_allowedips, 0, 644*10734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6453448Sdh155122 }; 6463448Sdh155122 6475895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 6485895Syz147064 6498275SEric Cheng static resource_prop_t rsrc_prop_table[] = { 6508275SEric Cheng {"maxbw", do_extract_maxbw}, 6518275SEric Cheng {"priority", do_extract_priority}, 652*10734SEric Cheng {"cpus", do_extract_cpus}, 653*10734SEric Cheng {"protection", do_extract_protection}, 654*10734SEric Cheng {"allowed-ips", do_extract_allowedips} 6558275SEric Cheng }; 6568275SEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 6578275SEric Cheng sizeof (resource_prop_t)) 6588275SEric Cheng 6597663SSowmini.Varadhan@Sun.COM /* 6607663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 6617663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 6627663SSowmini.Varadhan@Sun.COM */ 6637663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 6647663SSowmini.Varadhan@Sun.COM 6658453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 6668453SAnurag.Maskey@Sun.COM const char *, char **, uint_t); 6678453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 6688453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *); 6698460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 6708460SArtem.Kachitchkin@Sun.COM datalink_id_t, void *, int (*)(dladm_handle_t, 6718460SArtem.Kachitchkin@Sun.COM datalink_id_t, const char *, void *)); 6728453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 6738453SAnurag.Maskey@Sun.COM datalink_class_t, uint32_t, prop_desc_t *, char **, 6748453SAnurag.Maskey@Sun.COM uint_t, uint_t); 6758453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 6768453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 6778453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 6788453SAnurag.Maskey@Sun.COM datalink_id_t, datalink_media_t, uint_t); 6798275SEric Cheng 6805895Syz147064 /* 6815895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 6825895Syz147064 * rates to be retrieved. However, we cannot increase it at this 6835895Syz147064 * time because it will break binary compatibility with unbundled 6845895Syz147064 * WiFi drivers and utilities. So for now we define an additional 6855895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 6865895Syz147064 */ 6875895Syz147064 #define MAX_SUPPORT_RATES 64 6885895Syz147064 6895895Syz147064 #define AP_ANCHOR "[anchor]" 6905895Syz147064 #define AP_DELIMITER '.' 6915895Syz147064 692*10734SEric Cheng /* ARGSUSED */ 6935895Syz147064 static dladm_status_t 694*10734SEric Cheng do_check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 695*10734SEric Cheng char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 6965895Syz147064 { 6975895Syz147064 int i, j; 6983147Sxc151355 6995895Syz147064 for (j = 0; j < val_cnt; j++) { 7005895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 701*10734SEric Cheng if (strcasecmp(prop_val[j], 7025895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 7035895Syz147064 break; 7045895Syz147064 } 7055895Syz147064 } 706*10734SEric Cheng if (i == pdp->pd_noptval) 707*10734SEric Cheng return (DLADM_STATUS_BADVAL); 708*10734SEric Cheng 709*10734SEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 7105895Syz147064 } 711*10734SEric Cheng return (DLADM_STATUS_OK); 7125895Syz147064 } 7135895Syz147064 7145895Syz147064 static dladm_status_t 7158453SAnurag.Maskey@Sun.COM i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 7168453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 7178453SAnurag.Maskey@Sun.COM uint_t val_cnt, uint_t flags) 7183147Sxc151355 { 7195895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 7205895Syz147064 val_desc_t *vdp = NULL; 7215895Syz147064 boolean_t needfree = B_FALSE; 7225895Syz147064 uint_t cnt, i; 7233147Sxc151355 7245895Syz147064 if (!(pdp->pd_class & class)) 7255895Syz147064 return (DLADM_STATUS_BADARG); 7265895Syz147064 7275895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 7283147Sxc151355 return (DLADM_STATUS_BADARG); 7293147Sxc151355 7305895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 7315895Syz147064 return (DLADM_STATUS_TEMPONLY); 7325895Syz147064 7335895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 7345895Syz147064 return (DLADM_STATUS_OK); 7355895Syz147064 7365895Syz147064 if (pdp->pd_set == NULL) 7375895Syz147064 return (DLADM_STATUS_PROPRDONLY); 7383448Sdh155122 7395895Syz147064 if (prop_val != NULL) { 7405895Syz147064 vdp = malloc(sizeof (val_desc_t) * val_cnt); 7415895Syz147064 if (vdp == NULL) 7425895Syz147064 return (DLADM_STATUS_NOMEM); 7435895Syz147064 7445895Syz147064 if (pdp->pd_check != NULL) { 7458275SEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 7468453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, prop_val, 7478453SAnurag.Maskey@Sun.COM val_cnt, vdp, media); 7485895Syz147064 } else if (pdp->pd_optval != NULL) { 749*10734SEric Cheng status = do_check_prop(handle, pdp, linkid, prop_val, 750*10734SEric Cheng val_cnt, vdp, media); 7515895Syz147064 } else { 7523448Sdh155122 status = DLADM_STATUS_BADARG; 7533147Sxc151355 } 7545895Syz147064 7553147Sxc151355 if (status != DLADM_STATUS_OK) 7565895Syz147064 goto done; 7575895Syz147064 7585895Syz147064 cnt = val_cnt; 7595895Syz147064 } else { 7608275SEric Cheng boolean_t defval = B_FALSE; 7618275SEric Cheng 7625895Syz147064 if (pdp->pd_defval.vd_name == NULL) 7635895Syz147064 return (DLADM_STATUS_NOTSUP); 7645895Syz147064 7657342SAruna.Ramakrishna@Sun.COM cnt = 1; 7668275SEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 7678275SEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 7686512Ssowmini if ((vdp = malloc(sizeof (val_desc_t))) == NULL) 7696512Ssowmini return (DLADM_STATUS_NOMEM); 7707342SAruna.Ramakrishna@Sun.COM 7718275SEric Cheng if (defval) { 7728275SEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 7738275SEric Cheng sizeof (val_desc_t)); 7748275SEric Cheng } else if (pdp->pd_check != NULL) { 7758453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 7768453SAnurag.Maskey@Sun.COM prop_val, cnt, vdp, media); 7777342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 7787342SAruna.Ramakrishna@Sun.COM goto done; 7797342SAruna.Ramakrishna@Sun.COM } 7806512Ssowmini } else { 7818453SAnurag.Maskey@Sun.COM status = i_dladm_getset_defval(handle, pdp, linkid, 7826512Ssowmini media, flags); 7836512Ssowmini return (status); 7846512Ssowmini } 7855895Syz147064 } 78610491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_AFTER_PERM) 78710491SRishi.Srivatsavai@Sun.COM status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 78810491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_PERMONLY; 78910491SRishi.Srivatsavai@Sun.COM else 79010491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 79110491SRishi.Srivatsavai@Sun.COM media); 7925895Syz147064 if (needfree) { 7935895Syz147064 for (i = 0; i < cnt; i++) 7945903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 7953147Sxc151355 } 7965895Syz147064 done: 7975895Syz147064 free(vdp); 7985895Syz147064 return (status); 7995895Syz147064 } 8005895Syz147064 8015895Syz147064 static dladm_status_t 8028453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8038453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8045895Syz147064 { 8055895Syz147064 int i; 8065895Syz147064 boolean_t found = B_FALSE; 8075895Syz147064 datalink_class_t class; 8085895Syz147064 uint32_t media; 8095895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8105895Syz147064 8118453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 8128453SAnurag.Maskey@Sun.COM NULL, 0); 8135895Syz147064 if (status != DLADM_STATUS_OK) 8145895Syz147064 return (status); 8155895Syz147064 8165895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 8175895Syz147064 prop_desc_t *pdp = &prop_table[i]; 8185895Syz147064 dladm_status_t s; 8195895Syz147064 8205895Syz147064 if (prop_name != NULL && 8215895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 8225895Syz147064 continue; 8235895Syz147064 found = B_TRUE; 8248453SAnurag.Maskey@Sun.COM s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 8258453SAnurag.Maskey@Sun.COM prop_val, val_cnt, flags); 8263448Sdh155122 8275895Syz147064 if (prop_name != NULL) { 8285895Syz147064 status = s; 8295895Syz147064 break; 8305895Syz147064 } else { 8315895Syz147064 if (s != DLADM_STATUS_OK && 8325895Syz147064 s != DLADM_STATUS_NOTSUP) 8335895Syz147064 status = s; 8345895Syz147064 } 8355895Syz147064 } 8365903Ssowmini if (!found) { 8375903Ssowmini if (prop_name[0] == '_') { 8385903Ssowmini /* other private properties */ 8399692SRishi.Srivatsavai@Sun.COM status = i_dladm_set_private_prop(handle, linkid, 8409692SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cnt, flags); 8415903Ssowmini } else { 8425903Ssowmini status = DLADM_STATUS_NOTFOUND; 8435903Ssowmini } 8445903Ssowmini } 8455895Syz147064 8465895Syz147064 return (status); 8475895Syz147064 } 8485895Syz147064 8495895Syz147064 /* 8505895Syz147064 * Set/reset link property for specific link 8515895Syz147064 */ 8525895Syz147064 dladm_status_t 8538453SAnurag.Maskey@Sun.COM dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8548453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8555895Syz147064 { 8565895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8575895Syz147064 8585895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 8595895Syz147064 (prop_val == NULL && val_cnt > 0) || 8605895Syz147064 (prop_val != NULL && val_cnt == 0) || 8615895Syz147064 (prop_name == NULL && prop_val != NULL)) { 8625895Syz147064 return (DLADM_STATUS_BADARG); 8635895Syz147064 } 8645895Syz147064 8659692SRishi.Srivatsavai@Sun.COM /* 8669692SRishi.Srivatsavai@Sun.COM * Check for valid link property against the flags passed 8679692SRishi.Srivatsavai@Sun.COM * and set the link property when active flag is passed. 8689692SRishi.Srivatsavai@Sun.COM */ 8698453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 8705895Syz147064 val_cnt, flags); 8715895Syz147064 if (status != DLADM_STATUS_OK) 8725895Syz147064 return (status); 8735895Syz147064 8745895Syz147064 if (flags & DLADM_OPT_PERSIST) { 8758453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 8763147Sxc151355 prop_val, val_cnt); 87710491SRishi.Srivatsavai@Sun.COM 87810491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 87910491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp = prop_table; 88010491SRishi.Srivatsavai@Sun.COM int i; 88110491SRishi.Srivatsavai@Sun.COM 88210491SRishi.Srivatsavai@Sun.COM for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 88310491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_flags & PD_AFTER_PERM)) 88410491SRishi.Srivatsavai@Sun.COM continue; 88510491SRishi.Srivatsavai@Sun.COM if (prop_name != NULL && 88610491SRishi.Srivatsavai@Sun.COM strcasecmp(prop_name, pdp->pd_name) != 0) 88710491SRishi.Srivatsavai@Sun.COM continue; 88810491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, NULL, 88910491SRishi.Srivatsavai@Sun.COM 0, flags, 0); 89010491SRishi.Srivatsavai@Sun.COM } 89110491SRishi.Srivatsavai@Sun.COM } 8923147Sxc151355 } 8933147Sxc151355 return (status); 8943147Sxc151355 } 8953147Sxc151355 8965895Syz147064 /* 8978460SArtem.Kachitchkin@Sun.COM * Walk all link properties of the given specific link. 8988460SArtem.Kachitchkin@Sun.COM * 8998460SArtem.Kachitchkin@Sun.COM * Note: this function currently lacks the ability to walk _all_ private 9008460SArtem.Kachitchkin@Sun.COM * properties if the link, because there is no kernel interface to 9018460SArtem.Kachitchkin@Sun.COM * retrieve all known private property names. Once such an interface 9028460SArtem.Kachitchkin@Sun.COM * is added, this function should be fixed accordingly. 9035895Syz147064 */ 9043147Sxc151355 dladm_status_t 9058453SAnurag.Maskey@Sun.COM dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 9068453SAnurag.Maskey@Sun.COM int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 9073147Sxc151355 { 9085895Syz147064 dladm_status_t status; 9095895Syz147064 datalink_class_t class; 9105895Syz147064 uint_t media; 9115895Syz147064 int i; 9125895Syz147064 9135895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 9145895Syz147064 return (DLADM_STATUS_BADARG); 9155895Syz147064 9168453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9178453SAnurag.Maskey@Sun.COM NULL, 0); 9185895Syz147064 if (status != DLADM_STATUS_OK) 9195895Syz147064 return (status); 9205895Syz147064 9218460SArtem.Kachitchkin@Sun.COM /* public */ 9225895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 9235895Syz147064 if (!(prop_table[i].pd_class & class)) 9245895Syz147064 continue; 9255895Syz147064 9265895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 9275895Syz147064 continue; 9285895Syz147064 9298453SAnurag.Maskey@Sun.COM if (func(handle, linkid, prop_table[i].pd_name, arg) == 9305895Syz147064 DLADM_WALK_TERMINATE) { 9315895Syz147064 break; 9325895Syz147064 } 9335895Syz147064 } 9345895Syz147064 9358460SArtem.Kachitchkin@Sun.COM /* private */ 9368460SArtem.Kachitchkin@Sun.COM status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 9378460SArtem.Kachitchkin@Sun.COM 9388460SArtem.Kachitchkin@Sun.COM return (status); 9395895Syz147064 } 9403448Sdh155122 9415895Syz147064 /* 9425895Syz147064 * Get linkprop of the given specific link. 9435895Syz147064 */ 9445895Syz147064 dladm_status_t 9458453SAnurag.Maskey@Sun.COM dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9468453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, const char *prop_name, char **prop_val, 9478453SAnurag.Maskey@Sun.COM uint_t *val_cntp) 9485895Syz147064 { 9495895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9505895Syz147064 datalink_class_t class; 9515895Syz147064 uint_t media; 9525895Syz147064 prop_desc_t *pdp; 9536512Ssowmini uint_t cnt, dld_flags = 0; 9545895Syz147064 int i; 9558118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 9565895Syz147064 9576512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 9589514SGirish.Moodalbail@Sun.COM dld_flags |= MAC_PROP_DEFAULT; 9599514SGirish.Moodalbail@Sun.COM else if (type == DLADM_PROP_VAL_MODIFIABLE) 9609514SGirish.Moodalbail@Sun.COM dld_flags |= MAC_PROP_POSSIBLE; 9616512Ssowmini 9625895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 9635895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 9645895Syz147064 return (DLADM_STATUS_BADARG); 9655895Syz147064 9665895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 9675895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 9685895Syz147064 break; 9695895Syz147064 9705903Ssowmini if (i == DLADM_MAX_PROPS) { 9715903Ssowmini if (prop_name[0] == '_') { 9725903Ssowmini /* 9735903Ssowmini * private property. 9745903Ssowmini */ 9758460SArtem.Kachitchkin@Sun.COM if (type == DLADM_PROP_VAL_PERSISTENT) 9768460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_linkprop_db(handle, linkid, 9778460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp)); 9788460SArtem.Kachitchkin@Sun.COM else 9798460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_priv_prop(handle, linkid, 9808460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp, type, 9818460SArtem.Kachitchkin@Sun.COM dld_flags)); 9825903Ssowmini } else { 9835903Ssowmini return (DLADM_STATUS_NOTFOUND); 9845903Ssowmini } 9855903Ssowmini } 9865895Syz147064 9875895Syz147064 pdp = &prop_table[i]; 9885895Syz147064 9898453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9908453SAnurag.Maskey@Sun.COM NULL, 0); 9915895Syz147064 if (status != DLADM_STATUS_OK) 9925895Syz147064 return (status); 9935895Syz147064 9945895Syz147064 if (!(pdp->pd_class & class)) 9955895Syz147064 return (DLADM_STATUS_BADARG); 9965895Syz147064 9975895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 9983147Sxc151355 return (DLADM_STATUS_BADARG); 9993147Sxc151355 10005895Syz147064 switch (type) { 10015895Syz147064 case DLADM_PROP_VAL_CURRENT: 10028453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 10038453SAnurag.Maskey@Sun.COM media, dld_flags, &perm_flags); 10048118SVasumathi.Sundaram@Sun.COM break; 10058118SVasumathi.Sundaram@Sun.COM 10068118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 10078118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 10088118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 10098118SVasumathi.Sundaram@Sun.COM } else { 10108453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 10118453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10128118SVasumathi.Sundaram@Sun.COM } 10138118SVasumathi.Sundaram@Sun.COM 10148118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 10159055SMichael.Lim@Sun.COM *val_cntp = 1; 10168275SEric Cheng if (status == DLADM_STATUS_OK) 10178275SEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 10185895Syz147064 break; 10195895Syz147064 10205895Syz147064 case DLADM_PROP_VAL_DEFAULT: 10216768Sar224390 /* 10226768Sar224390 * If defaults are not defined for the property, 10236768Sar224390 * pd_defval.vd_name should be null. If the driver 10246768Sar224390 * has to be contacted for the value, vd_name should 10256768Sar224390 * be the empty string (""). Otherwise, dladm will 10266768Sar224390 * just print whatever is in the table. 10276768Sar224390 */ 10285895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 10295895Syz147064 status = DLADM_STATUS_NOTSUP; 10305895Syz147064 break; 10315895Syz147064 } 10326512Ssowmini 10336512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 10348453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 10358453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10366512Ssowmini } else { 10376512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 10386512Ssowmini } 10395895Syz147064 *val_cntp = 1; 10405895Syz147064 break; 10413448Sdh155122 10425895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 10435895Syz147064 if (pdp->pd_getmod != NULL) { 10448453SAnurag.Maskey@Sun.COM status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 10458118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10465895Syz147064 break; 10475895Syz147064 } 10485895Syz147064 cnt = pdp->pd_noptval; 10495895Syz147064 if (cnt == 0) { 10505895Syz147064 status = DLADM_STATUS_NOTSUP; 10515895Syz147064 } else if (cnt > *val_cntp) { 10525895Syz147064 status = DLADM_STATUS_TOOSMALL; 10535895Syz147064 } else { 10545895Syz147064 for (i = 0; i < cnt; i++) { 10555895Syz147064 (void) strcpy(prop_val[i], 10565895Syz147064 pdp->pd_optval[i].vd_name); 10575895Syz147064 } 10585895Syz147064 *val_cntp = cnt; 10595895Syz147064 } 10605895Syz147064 break; 10615895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 10625895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 10635895Syz147064 return (DLADM_STATUS_TEMPONLY); 10648453SAnurag.Maskey@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 10655895Syz147064 prop_val, val_cntp); 10665895Syz147064 break; 10675895Syz147064 default: 10685895Syz147064 status = DLADM_STATUS_BADARG; 10695895Syz147064 break; 10703147Sxc151355 } 10713448Sdh155122 10725895Syz147064 return (status); 10735895Syz147064 } 10745895Syz147064 107510491SRishi.Srivatsavai@Sun.COM /* 107610491SRishi.Srivatsavai@Sun.COM * Get linkprop of the given specific link and run any possible conversion 107710491SRishi.Srivatsavai@Sun.COM * of the values using the check function for the property. Fails if the 107810491SRishi.Srivatsavai@Sun.COM * check function doesn't succeed for the property value. 107910491SRishi.Srivatsavai@Sun.COM */ 108010491SRishi.Srivatsavai@Sun.COM dladm_status_t 108110491SRishi.Srivatsavai@Sun.COM dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 108210491SRishi.Srivatsavai@Sun.COM dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 108310491SRishi.Srivatsavai@Sun.COM uint_t *val_cntp) 108410491SRishi.Srivatsavai@Sun.COM { 108510491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 108610491SRishi.Srivatsavai@Sun.COM datalink_class_t class; 108710491SRishi.Srivatsavai@Sun.COM uint_t media; 108810491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp; 108910491SRishi.Srivatsavai@Sun.COM uint_t dld_flags; 109010491SRishi.Srivatsavai@Sun.COM int valc, i; 109110491SRishi.Srivatsavai@Sun.COM char **prop_val; 109210491SRishi.Srivatsavai@Sun.COM uint_t perm_flags; 109310491SRishi.Srivatsavai@Sun.COM 109410491SRishi.Srivatsavai@Sun.COM if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 109510491SRishi.Srivatsavai@Sun.COM ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 109610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 109710491SRishi.Srivatsavai@Sun.COM 109810491SRishi.Srivatsavai@Sun.COM for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 109910491SRishi.Srivatsavai@Sun.COM if (strcasecmp(prop_name, pdp->pd_name) == 0) 110010491SRishi.Srivatsavai@Sun.COM break; 110110491SRishi.Srivatsavai@Sun.COM 110210491SRishi.Srivatsavai@Sun.COM if (pdp == prop_table + DLADM_MAX_PROPS) 110310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTFOUND); 110410491SRishi.Srivatsavai@Sun.COM 110510491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_CHECK_ALLOC) 110610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 110710491SRishi.Srivatsavai@Sun.COM 110810491SRishi.Srivatsavai@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 110910491SRishi.Srivatsavai@Sun.COM NULL, 0); 111010491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 111110491SRishi.Srivatsavai@Sun.COM return (status); 111210491SRishi.Srivatsavai@Sun.COM 111310491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_class & class)) 111410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 111510491SRishi.Srivatsavai@Sun.COM 111610491SRishi.Srivatsavai@Sun.COM if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 111710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 111810491SRishi.Srivatsavai@Sun.COM 111910491SRishi.Srivatsavai@Sun.COM prop_val = malloc(*val_cntp * sizeof (*prop_val) + 112010491SRishi.Srivatsavai@Sun.COM *val_cntp * DLADM_PROP_VAL_MAX); 112110491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) 112210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOMEM); 112310491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 112410491SRishi.Srivatsavai@Sun.COM prop_val[valc] = (char *)(prop_val + *val_cntp) + 112510491SRishi.Srivatsavai@Sun.COM valc * DLADM_PROP_VAL_MAX; 112610491SRishi.Srivatsavai@Sun.COM 112710491SRishi.Srivatsavai@Sun.COM dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? MAC_PROP_DEFAULT : 0; 112810491SRishi.Srivatsavai@Sun.COM 112910491SRishi.Srivatsavai@Sun.COM switch (type) { 113010491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_CURRENT: 113110491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 113210491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 113310491SRishi.Srivatsavai@Sun.COM break; 113410491SRishi.Srivatsavai@Sun.COM 113510491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_DEFAULT: 113610491SRishi.Srivatsavai@Sun.COM /* 113710491SRishi.Srivatsavai@Sun.COM * If defaults are not defined for the property, 113810491SRishi.Srivatsavai@Sun.COM * pd_defval.vd_name should be null. If the driver 113910491SRishi.Srivatsavai@Sun.COM * has to be contacted for the value, vd_name should 114010491SRishi.Srivatsavai@Sun.COM * be the empty string (""). Otherwise, dladm will 114110491SRishi.Srivatsavai@Sun.COM * just print whatever is in the table. 114210491SRishi.Srivatsavai@Sun.COM */ 114310491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name == NULL) { 114410491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOTSUP; 114510491SRishi.Srivatsavai@Sun.COM break; 114610491SRishi.Srivatsavai@Sun.COM } 114710491SRishi.Srivatsavai@Sun.COM 114810491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name[0] != '\0') { 114910491SRishi.Srivatsavai@Sun.COM *val_cntp = 1; 115010491SRishi.Srivatsavai@Sun.COM *ret_val = pdp->pd_defval.vd_val; 115110491SRishi.Srivatsavai@Sun.COM free(prop_val); 115210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 115310491SRishi.Srivatsavai@Sun.COM } 115410491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 115510491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 115610491SRishi.Srivatsavai@Sun.COM break; 115710491SRishi.Srivatsavai@Sun.COM 115810491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_PERSISTENT: 115910491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_TEMPONLY) 116010491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_TEMPONLY; 116110491SRishi.Srivatsavai@Sun.COM else 116210491SRishi.Srivatsavai@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, 116310491SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cntp); 116410491SRishi.Srivatsavai@Sun.COM break; 116510491SRishi.Srivatsavai@Sun.COM 116610491SRishi.Srivatsavai@Sun.COM default: 116710491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_BADARG; 116810491SRishi.Srivatsavai@Sun.COM break; 116910491SRishi.Srivatsavai@Sun.COM } 117010491SRishi.Srivatsavai@Sun.COM 117110491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 117210491SRishi.Srivatsavai@Sun.COM if (pdp->pd_check != NULL) { 117310491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp; 117410491SRishi.Srivatsavai@Sun.COM 117510491SRishi.Srivatsavai@Sun.COM vdp = malloc(sizeof (val_desc_t) * *val_cntp); 117610491SRishi.Srivatsavai@Sun.COM if (vdp == NULL) 117710491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOMEM; 117810491SRishi.Srivatsavai@Sun.COM else 117910491SRishi.Srivatsavai@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 118010491SRishi.Srivatsavai@Sun.COM prop_val, *val_cntp, vdp, media); 118110491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 118210491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 118310491SRishi.Srivatsavai@Sun.COM ret_val[valc] = vdp[valc].vd_val; 118410491SRishi.Srivatsavai@Sun.COM } 118510491SRishi.Srivatsavai@Sun.COM free(vdp); 118610491SRishi.Srivatsavai@Sun.COM } else { 118710491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) { 118810491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pdp->pd_noptval; i++) { 118910491SRishi.Srivatsavai@Sun.COM if (strcmp(pdp->pd_optval[i].vd_name, 119010491SRishi.Srivatsavai@Sun.COM prop_val[valc]) == 0) { 119110491SRishi.Srivatsavai@Sun.COM ret_val[valc] = 119210491SRishi.Srivatsavai@Sun.COM pdp->pd_optval[i].vd_val; 119310491SRishi.Srivatsavai@Sun.COM break; 119410491SRishi.Srivatsavai@Sun.COM } 119510491SRishi.Srivatsavai@Sun.COM } 119610491SRishi.Srivatsavai@Sun.COM if (i == pdp->pd_noptval) { 119710491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_FAILED; 119810491SRishi.Srivatsavai@Sun.COM break; 119910491SRishi.Srivatsavai@Sun.COM } 120010491SRishi.Srivatsavai@Sun.COM } 120110491SRishi.Srivatsavai@Sun.COM } 120210491SRishi.Srivatsavai@Sun.COM } 120310491SRishi.Srivatsavai@Sun.COM 120410491SRishi.Srivatsavai@Sun.COM free(prop_val); 120510491SRishi.Srivatsavai@Sun.COM 120610491SRishi.Srivatsavai@Sun.COM return (status); 120710491SRishi.Srivatsavai@Sun.COM } 120810491SRishi.Srivatsavai@Sun.COM 12095895Syz147064 /*ARGSUSED*/ 12105895Syz147064 static int 12118453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 12128453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 12135895Syz147064 { 12145895Syz147064 char *buf, **propvals; 12155895Syz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 12165895Syz147064 12175895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 12185895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 12195895Syz147064 return (DLADM_WALK_CONTINUE); 12205895Syz147064 } 12215895Syz147064 12225895Syz147064 propvals = (char **)(void *)buf; 12235895Syz147064 for (i = 0; i < valcnt; i++) { 12245895Syz147064 propvals[i] = buf + 12255895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 12265895Syz147064 i * DLADM_PROP_VAL_MAX; 12275895Syz147064 } 12285895Syz147064 12298453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 12308453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 12315895Syz147064 goto done; 12325895Syz147064 } 12335895Syz147064 12348453SAnurag.Maskey@Sun.COM (void) dladm_set_linkprop(handle, linkid, prop_name, propvals, valcnt, 12355895Syz147064 DLADM_OPT_ACTIVE); 12365895Syz147064 12375895Syz147064 done: 12385895Syz147064 if (buf != NULL) 12395895Syz147064 free(buf); 12405895Syz147064 12415895Syz147064 return (DLADM_WALK_CONTINUE); 12425895Syz147064 } 12435895Syz147064 12445895Syz147064 /*ARGSUSED*/ 12455895Syz147064 static int 12468453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 12475895Syz147064 { 12488275SEric Cheng datalink_class_t class; 12498275SEric Cheng dladm_status_t status; 12508275SEric Cheng 12518453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 12528453SAnurag.Maskey@Sun.COM NULL, 0); 12538275SEric Cheng if (status != DLADM_STATUS_OK) 12548275SEric Cheng return (DLADM_WALK_TERMINATE); 12558275SEric Cheng 12568275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 12578453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 12588275SEric Cheng 12595895Syz147064 return (DLADM_WALK_CONTINUE); 12605895Syz147064 } 12615895Syz147064 12625895Syz147064 dladm_status_t 12638453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 12648453SAnurag.Maskey@Sun.COM boolean_t any_media) 12655895Syz147064 { 12666916Sartem datalink_media_t dmedia; 12676916Sartem uint32_t media; 12686916Sartem 12696916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 12706916Sartem 12715895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 12728453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 12738453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 12748453SAnurag.Maskey@Sun.COM } else if (any_media || 12758453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 12768453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 12776916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 12788453SAnurag.Maskey@Sun.COM (void) dladm_walk_linkprop(handle, linkid, NULL, 12798453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 12803448Sdh155122 } 12813448Sdh155122 return (DLADM_STATUS_OK); 12823147Sxc151355 } 12833147Sxc151355 12845903Ssowmini /* ARGSUSED */ 12855895Syz147064 static dladm_status_t 12868453SAnurag.Maskey@Sun.COM do_get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 12878275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 12888275SEric Cheng uint_t flags, uint_t *perm_flags) 12893147Sxc151355 { 12908275SEric Cheng char zone_name[ZONENAME_MAX]; 12918275SEric Cheng zoneid_t zid; 12928275SEric Cheng dladm_status_t status; 12938275SEric Cheng char *cp; 12947342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 12953147Sxc151355 12966512Ssowmini if (flags != 0) 12976512Ssowmini return (DLADM_STATUS_NOTSUP); 12986512Ssowmini 12998453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 13008275SEric Cheng &status, perm_flags); 13015895Syz147064 if (status != DLADM_STATUS_OK) 13023448Sdh155122 return (status); 13033448Sdh155122 13047342SAruna.Ramakrishna@Sun.COM cp = dip->pr_val; 13057342SAruna.Ramakrishna@Sun.COM (void) memcpy(&zid, cp, sizeof (zid)); 13067342SAruna.Ramakrishna@Sun.COM free(dip); 13077342SAruna.Ramakrishna@Sun.COM 13085895Syz147064 *val_cnt = 1; 13095895Syz147064 if (zid != GLOBAL_ZONEID) { 13108118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 13115895Syz147064 return (dladm_errno2status(errno)); 13128118SVasumathi.Sundaram@Sun.COM } 13133147Sxc151355 13145895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 13153147Sxc151355 } else { 13165895Syz147064 *prop_val[0] = '\0'; 13173147Sxc151355 } 13183147Sxc151355 13193448Sdh155122 return (DLADM_STATUS_OK); 13203448Sdh155122 } 13213448Sdh155122 13223448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 13233448Sdh155122 13243448Sdh155122 static int 13253448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 13263448Sdh155122 { 13273448Sdh155122 char root[MAXPATHLEN]; 13283448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 13293448Sdh155122 void *dlhandle; 13303448Sdh155122 void *sym; 13313448Sdh155122 int ret; 13323448Sdh155122 13333448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 13343448Sdh155122 return (-1); 13353448Sdh155122 13363448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 13373448Sdh155122 (void) dlclose(dlhandle); 13383448Sdh155122 return (-1); 13393448Sdh155122 } 13403448Sdh155122 13413448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 13423448Sdh155122 13433448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 13443448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 13453448Sdh155122 (void) dlclose(dlhandle); 13463448Sdh155122 return (ret); 13473448Sdh155122 } 13483448Sdh155122 13493448Sdh155122 static dladm_status_t 13508453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 13518453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 13523448Sdh155122 { 13533448Sdh155122 char path[MAXPATHLEN]; 13545895Syz147064 char name[MAXLINKNAMELEN]; 13553448Sdh155122 di_prof_t prof = NULL; 13563448Sdh155122 char zone_name[ZONENAME_MAX]; 13573448Sdh155122 dladm_status_t status; 13585895Syz147064 int ret; 13593448Sdh155122 13603448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 13613448Sdh155122 return (dladm_errno2status(errno)); 13623448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 13633448Sdh155122 return (dladm_errno2status(errno)); 13643448Sdh155122 if (di_prof_init(path, &prof) != 0) 13653448Sdh155122 return (dladm_errno2status(errno)); 13663448Sdh155122 13678453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 13685895Syz147064 if (status != DLADM_STATUS_OK) 13695895Syz147064 goto cleanup; 13705895Syz147064 13715895Syz147064 if (add) 13725895Syz147064 ret = di_prof_add_dev(prof, name); 13735895Syz147064 else 13745895Syz147064 ret = di_prof_add_exclude(prof, name); 13755895Syz147064 13765895Syz147064 if (ret != 0) { 13773448Sdh155122 status = dladm_errno2status(errno); 13783448Sdh155122 goto cleanup; 13793448Sdh155122 } 13803448Sdh155122 13813448Sdh155122 if (di_prof_commit(prof) != 0) 13823448Sdh155122 status = dladm_errno2status(errno); 13833448Sdh155122 cleanup: 13843448Sdh155122 if (prof) 13853448Sdh155122 di_prof_fini(prof); 13863448Sdh155122 13873448Sdh155122 return (status); 13883448Sdh155122 } 13893448Sdh155122 13905903Ssowmini /* ARGSUSED */ 13913448Sdh155122 static dladm_status_t 13928453SAnurag.Maskey@Sun.COM do_set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13938453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 13943448Sdh155122 { 13958275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 13968275SEric Cheng zoneid_t zid_old, zid_new; 13978275SEric Cheng char *cp; 13987342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 13997342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14003448Sdh155122 14013448Sdh155122 if (val_cnt != 1) 14023448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14033448Sdh155122 14047342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 14057342SAruna.Ramakrishna@Sun.COM 14068453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 14078275SEric Cheng &status, NULL); 14088275SEric Cheng if (status != DLADM_STATUS_OK) 14098275SEric Cheng return (status); 14108275SEric Cheng 14118275SEric Cheng cp = dip->pr_val; 14128275SEric Cheng (void) memcpy(&zid_old, cp, sizeof (zid_old)); 14138275SEric Cheng free(dip); 14147342SAruna.Ramakrishna@Sun.COM 14157342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 14163448Sdh155122 if (zid_new == zid_old) 141710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 141810616SSebastien.Roy@Sun.COM 141910616SSebastien.Roy@Sun.COM if ((status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, val_cnt, 142010616SSebastien.Roy@Sun.COM flags, media)) != DLADM_STATUS_OK) 14215895Syz147064 return (status); 14225895Syz147064 142310616SSebastien.Roy@Sun.COM /* 142410616SSebastien.Roy@Sun.COM * It is okay to fail to update the /dev entry (some vanity-named 142510616SSebastien.Roy@Sun.COM * links do not have a /dev entry). 142610616SSebastien.Roy@Sun.COM */ 14273448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 14288453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 14298453SAnurag.Maskey@Sun.COM B_FALSE); 14305895Syz147064 } 143110616SSebastien.Roy@Sun.COM if (zid_new != GLOBAL_ZONEID) 14328453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 14333448Sdh155122 14343448Sdh155122 return (DLADM_STATUS_OK); 14353448Sdh155122 } 14363448Sdh155122 14373448Sdh155122 /* ARGSUSED */ 14383448Sdh155122 static dladm_status_t 14398453SAnurag.Maskey@Sun.COM do_check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14408453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 14413448Sdh155122 { 14427342SAruna.Ramakrishna@Sun.COM char *zone_name; 14437342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 14447342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 14457342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14463448Sdh155122 14473448Sdh155122 if (val_cnt != 1) 14483448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14493448Sdh155122 14507342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 14517342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 14527342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 14533448Sdh155122 14548275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 14557342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 14567342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14577342SAruna.Ramakrishna@Sun.COM goto done; 14587342SAruna.Ramakrishna@Sun.COM } 14597342SAruna.Ramakrishna@Sun.COM 14607342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 14613448Sdh155122 ushort_t flags; 14623448Sdh155122 14637342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 14643448Sdh155122 sizeof (flags)) < 0) { 14657342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 14667342SAruna.Ramakrishna@Sun.COM goto done; 14673448Sdh155122 } 14683448Sdh155122 14693448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 14707342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14717342SAruna.Ramakrishna@Sun.COM goto done; 14723448Sdh155122 } 14733448Sdh155122 } 14743448Sdh155122 14757342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 14767342SAruna.Ramakrishna@Sun.COM 14777342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 147810616SSebastien.Roy@Sun.COM dzp->diz_linkid = linkid; 14797342SAruna.Ramakrishna@Sun.COM 14807342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 14815895Syz147064 return (DLADM_STATUS_OK); 14827342SAruna.Ramakrishna@Sun.COM done: 14837342SAruna.Ramakrishna@Sun.COM free(dzp); 14847342SAruna.Ramakrishna@Sun.COM return (status); 14855895Syz147064 } 14865895Syz147064 14875903Ssowmini /* ARGSUSED */ 14885895Syz147064 static dladm_status_t 14898460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14908275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 14918275SEric Cheng uint_t flags, uint_t *perm_flags) 14928275SEric Cheng { 14938275SEric Cheng dld_ioc_macprop_t *dip; 14948275SEric Cheng mac_resource_props_t mrp; 14958275SEric Cheng dladm_status_t status; 14968275SEric Cheng 14978453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 14988275SEric Cheng &status, perm_flags); 14998275SEric Cheng if (dip == NULL) 15008275SEric Cheng return (status); 15018275SEric Cheng 15028275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 15038275SEric Cheng free(dip); 15048275SEric Cheng 15058275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 15068275SEric Cheng (*prop_val)[0] = '\0'; 15078275SEric Cheng } else { 15088275SEric Cheng (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 15098275SEric Cheng } 15108275SEric Cheng *val_cnt = 1; 15118275SEric Cheng return (DLADM_STATUS_OK); 15128275SEric Cheng } 15138275SEric Cheng 15148275SEric Cheng /* ARGSUSED */ 15158275SEric Cheng static dladm_status_t 15168453SAnurag.Maskey@Sun.COM do_check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15178453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 15188275SEric Cheng { 15198275SEric Cheng uint64_t *maxbw; 15208275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 15218275SEric Cheng 15228275SEric Cheng if (val_cnt != 1) 15238275SEric Cheng return (DLADM_STATUS_BADVALCNT); 15248275SEric Cheng 15258275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 15268275SEric Cheng if (maxbw == NULL) 15278275SEric Cheng return (DLADM_STATUS_NOMEM); 15288275SEric Cheng 15298275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 15308275SEric Cheng if (status != DLADM_STATUS_OK) { 15318275SEric Cheng free(maxbw); 15328275SEric Cheng return (status); 15338275SEric Cheng } 15348275SEric Cheng 15358275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 15368275SEric Cheng free(maxbw); 15378275SEric Cheng return (DLADM_STATUS_MINMAXBW); 15388275SEric Cheng } 15398275SEric Cheng 15408275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 15418275SEric Cheng return (DLADM_STATUS_OK); 15428275SEric Cheng } 15438275SEric Cheng 15448275SEric Cheng /* ARGSUSED */ 15458275SEric Cheng dladm_status_t 1546*10734SEric Cheng do_extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 15478275SEric Cheng { 1548*10734SEric Cheng mac_resource_props_t *mrp = arg; 15498275SEric Cheng 15508275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 15518275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 15528275SEric Cheng 15538275SEric Cheng return (DLADM_STATUS_OK); 15548275SEric Cheng } 15558275SEric Cheng 15568275SEric Cheng /* ARGSUSED */ 15578275SEric Cheng static dladm_status_t 15588460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15598275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15608275SEric Cheng uint_t flags, uint_t *perm_flags) 15618275SEric Cheng { 15628275SEric Cheng dld_ioc_macprop_t *dip; 15638275SEric Cheng mac_resource_props_t mrp; 15648275SEric Cheng int i; 15658275SEric Cheng uint32_t ncpus; 15668275SEric Cheng uchar_t *cp; 15678275SEric Cheng dladm_status_t status; 15688275SEric Cheng 15698453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15708275SEric Cheng &status, perm_flags); 15718275SEric Cheng if (dip == NULL) 15728275SEric Cheng return (status); 15738275SEric Cheng 15748275SEric Cheng cp = (uchar_t *)dip->pr_val; 15758275SEric Cheng (void) memcpy(&mrp, cp, sizeof (mac_resource_props_t)); 15768275SEric Cheng free(dip); 15778275SEric Cheng 15788275SEric Cheng ncpus = mrp.mrp_ncpus; 15798275SEric Cheng 15808275SEric Cheng if (ncpus > *val_cnt) 15818275SEric Cheng return (DLADM_STATUS_TOOSMALL); 15828275SEric Cheng 15838275SEric Cheng if (ncpus == 0) { 15848275SEric Cheng (*prop_val)[0] = '\0'; 15858275SEric Cheng *val_cnt = 1; 15868275SEric Cheng return (DLADM_STATUS_OK); 15878275SEric Cheng } 15888275SEric Cheng 15898275SEric Cheng *val_cnt = ncpus; 15908275SEric Cheng for (i = 0; i < ncpus; i++) { 15918275SEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 15928275SEric Cheng "%u", mrp.mrp_cpu[i]); 15938275SEric Cheng } 15948275SEric Cheng return (DLADM_STATUS_OK); 15958275SEric Cheng } 15968275SEric Cheng 15978275SEric Cheng /* ARGSUSED */ 15988275SEric Cheng static dladm_status_t 15998453SAnurag.Maskey@Sun.COM do_set_res(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16008453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16018275SEric Cheng { 16028275SEric Cheng mac_resource_props_t mrp; 16038275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 16048275SEric Cheng dld_ioc_macprop_t *dip; 16058275SEric Cheng 16068275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 16078275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 16088275SEric Cheng flags, &status); 16098275SEric Cheng 16108275SEric Cheng if (dip == NULL) 16118275SEric Cheng return (status); 16128275SEric Cheng 16138275SEric Cheng if (vdp->vd_val == RESET_VAL) { 16148275SEric Cheng switch (dip->pr_num) { 16158275SEric Cheng case MAC_PROP_MAXBW: 16168275SEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 16178275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16188275SEric Cheng break; 16198275SEric Cheng case MAC_PROP_PRIO: 16208275SEric Cheng mrp.mrp_priority = MPL_RESET; 16218275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16228275SEric Cheng break; 16238275SEric Cheng default: 16248275SEric Cheng free(dip); 16258275SEric Cheng return (DLADM_STATUS_BADARG); 16268275SEric Cheng } 16278275SEric Cheng } else { 16288275SEric Cheng switch (dip->pr_num) { 16298275SEric Cheng case MAC_PROP_MAXBW: 16308275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_maxbw, 16318275SEric Cheng sizeof (uint64_t)); 16328275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16338275SEric Cheng break; 16348275SEric Cheng case MAC_PROP_PRIO: 16358275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_priority, 16368275SEric Cheng sizeof (mac_priority_level_t)); 16378275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16388275SEric Cheng break; 16398275SEric Cheng default: 16408275SEric Cheng free(dip); 16418275SEric Cheng return (DLADM_STATUS_BADARG); 16428275SEric Cheng } 16438275SEric Cheng } 16448275SEric Cheng 16458275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 16468453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 16478275SEric Cheng free(dip); 16488275SEric Cheng return (status); 16498275SEric Cheng } 16508275SEric Cheng 16518275SEric Cheng /* ARGSUSED */ 16528275SEric Cheng static dladm_status_t 16538453SAnurag.Maskey@Sun.COM do_set_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16548453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16558275SEric Cheng { 16568275SEric Cheng mac_resource_props_t mrp; 16578275SEric Cheng dladm_status_t status; 16588275SEric Cheng dld_ioc_macprop_t *dip; 16598275SEric Cheng datalink_class_t class; 16608275SEric Cheng 16618275SEric Cheng /* 16628275SEric Cheng * CPU bindings can be set on VNIC and regular physical links. 16638275SEric Cheng * However VNICs fails the dladm_phys_info test(). So apply 16648275SEric Cheng * the phys_info test only on physical links. 16658275SEric Cheng */ 16668453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, 16678275SEric Cheng NULL, NULL, 0)) != DLADM_STATUS_OK) { 16688275SEric Cheng return (status); 16698275SEric Cheng } 16708275SEric Cheng 16718275SEric Cheng /* 16728275SEric Cheng * We set intr_cpu to -1. The interrupt will be retargetted, 16738275SEric Cheng * if possible when the setup is complete in MAC. 16748275SEric Cheng */ 16758275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 16768275SEric Cheng mrp.mrp_mask = MRP_CPUS; 16778275SEric Cheng if (vdp != NULL && vdp->vd_val != RESET_VAL) { 16788275SEric Cheng mac_resource_props_t *vmrp; 16798275SEric Cheng 16808275SEric Cheng vmrp = (mac_resource_props_t *)vdp->vd_val; 16818275SEric Cheng if (vmrp->mrp_ncpus > 0) { 16828275SEric Cheng bcopy(vmrp, &mrp, sizeof (mac_resource_props_t)); 16838275SEric Cheng mrp.mrp_mask = MRP_CPUS; 16848275SEric Cheng } 16858275SEric Cheng mrp.mrp_mask |= MRP_CPUS_USERSPEC; 16868275SEric Cheng mrp.mrp_fanout_mode = MCM_CPUS; 16878275SEric Cheng mrp.mrp_intr_cpu = -1; 16888275SEric Cheng } 16898275SEric Cheng 16908275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 16918275SEric Cheng flags, &status); 16928275SEric Cheng if (dip == NULL) 16938275SEric Cheng return (status); 16948275SEric Cheng 16958275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 16968453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 16978275SEric Cheng free(dip); 16988275SEric Cheng return (status); 16998275SEric Cheng } 17008275SEric Cheng 17018275SEric Cheng /* ARGSUSED */ 17028275SEric Cheng static dladm_status_t 17038453SAnurag.Maskey@Sun.COM do_check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 17048453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 17058275SEric Cheng { 17068275SEric Cheng uint32_t cpuid; 17078275SEric Cheng int i, j, rc; 17088275SEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 17098275SEric Cheng mac_resource_props_t *mrp; 17108275SEric Cheng 17118275SEric Cheng mrp = malloc(sizeof (mac_resource_props_t)); 17128275SEric Cheng if (mrp == NULL) 17138275SEric Cheng return (DLADM_STATUS_NOMEM); 17148275SEric Cheng 17158275SEric Cheng for (i = 0; i < val_cnt; i++) { 17168275SEric Cheng errno = 0; 17178275SEric Cheng cpuid = strtol(prop_val[i], (char **)NULL, 10); 17188275SEric Cheng if (errno != 0 || cpuid >= nproc) { 17198275SEric Cheng free(mrp); 17208275SEric Cheng return (DLADM_STATUS_CPUMAX); 17218275SEric Cheng } 17228275SEric Cheng rc = p_online(cpuid, P_STATUS); 17238275SEric Cheng if (rc < 1) { 17248275SEric Cheng free(mrp); 17258275SEric Cheng return (DLADM_STATUS_CPUERR); 17268275SEric Cheng } 17278275SEric Cheng if (rc != P_ONLINE) { 17288275SEric Cheng free(mrp); 17298275SEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 17308275SEric Cheng } 17318275SEric Cheng mrp->mrp_cpu[i] = cpuid; 17328275SEric Cheng } 17338275SEric Cheng mrp->mrp_ncpus = (uint32_t)val_cnt; 17348275SEric Cheng 17358275SEric Cheng /* Check for duplicates */ 17368275SEric Cheng for (i = 0; i < val_cnt; i++) { 17378275SEric Cheng for (j = 0; j < val_cnt; j++) { 17388275SEric Cheng if (i != j && mrp->mrp_cpu[i] == mrp->mrp_cpu[j]) { 17398275SEric Cheng free(mrp); 17408275SEric Cheng return (DLADM_STATUS_BADARG); 17418275SEric Cheng } 17428275SEric Cheng } 17438275SEric Cheng } 17448275SEric Cheng vdp->vd_val = (uintptr_t)mrp; 17458275SEric Cheng 17468275SEric Cheng return (DLADM_STATUS_OK); 17478275SEric Cheng } 17488275SEric Cheng 17498275SEric Cheng /* ARGSUSED */ 17508275SEric Cheng dladm_status_t 1751*10734SEric Cheng do_extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 17528275SEric Cheng { 1753*10734SEric Cheng mac_resource_props_t *mrp = arg; 17548275SEric Cheng mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; 17558275SEric Cheng int i; 17568275SEric Cheng 17578275SEric Cheng for (i = 0; i < vmrp->mrp_ncpus; i++) { 17588275SEric Cheng mrp->mrp_cpu[i] = vmrp->mrp_cpu[i]; 17598275SEric Cheng } 17608275SEric Cheng mrp->mrp_ncpus = vmrp->mrp_ncpus; 17618275SEric Cheng mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 17628275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 17639055SMichael.Lim@Sun.COM mrp->mrp_intr_cpu = -1; 17648275SEric Cheng 17658275SEric Cheng return (DLADM_STATUS_OK); 17668275SEric Cheng } 17678275SEric Cheng 17688275SEric Cheng /* ARGSUSED */ 17698275SEric Cheng static dladm_status_t 17708460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get(dladm_handle_t handle, prop_desc_t *pdp, 17718460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 17728460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 17738275SEric Cheng { 17748275SEric Cheng dld_ioc_macprop_t *dip; 17758275SEric Cheng mac_resource_props_t mrp; 17768275SEric Cheng mac_priority_level_t pri; 17778275SEric Cheng dladm_status_t status; 17788275SEric Cheng 17798453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 17808275SEric Cheng &status, perm_flags); 17818275SEric Cheng if (dip == NULL) 17828275SEric Cheng return (status); 17838275SEric Cheng 17848275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 17858275SEric Cheng free(dip); 17868275SEric Cheng 17878275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 17888275SEric Cheng mrp.mrp_priority; 17898275SEric Cheng 17908275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 17918275SEric Cheng *val_cnt = 1; 17928275SEric Cheng return (DLADM_STATUS_OK); 17938275SEric Cheng } 17948275SEric Cheng 17958275SEric Cheng /* ARGSUSED */ 17968275SEric Cheng static dladm_status_t 17978453SAnurag.Maskey@Sun.COM do_check_priority(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 17988453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 17998275SEric Cheng { 18008275SEric Cheng mac_priority_level_t *pri; 18018275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 18028275SEric Cheng 18038275SEric Cheng if (val_cnt != 1) 18048275SEric Cheng return (DLADM_STATUS_BADVALCNT); 18058275SEric Cheng 18068275SEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 18078275SEric Cheng if (pri == NULL) 18088275SEric Cheng return (DLADM_STATUS_NOMEM); 18098275SEric Cheng 18108275SEric Cheng status = dladm_str2pri(*prop_val, pri); 18118275SEric Cheng if (status != DLADM_STATUS_OK) { 18128275SEric Cheng free(pri); 18138275SEric Cheng return (status); 18148275SEric Cheng } 18158275SEric Cheng 18168275SEric Cheng if (*pri < MPL_LOW || *pri > MPL_HIGH) { 18178275SEric Cheng free(pri); 18188275SEric Cheng return (DLADM_STATUS_BADVAL); 18198275SEric Cheng } 18208275SEric Cheng 18218275SEric Cheng vdp->vd_val = (uintptr_t)pri; 18228275SEric Cheng return (DLADM_STATUS_OK); 18238275SEric Cheng } 18248275SEric Cheng 18258275SEric Cheng /* ARGSUSED */ 18268275SEric Cheng dladm_status_t 1827*10734SEric Cheng do_extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 18288275SEric Cheng { 1829*10734SEric Cheng mac_resource_props_t *mrp = arg; 18308275SEric Cheng 18318275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_priority, 18328275SEric Cheng sizeof (mac_priority_level_t)); 18338275SEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 18348275SEric Cheng 18358275SEric Cheng return (DLADM_STATUS_OK); 18368275SEric Cheng } 18378275SEric Cheng 18388275SEric Cheng /* ARGSUSED */ 18398275SEric Cheng static dladm_status_t 1840*10734SEric Cheng do_set_protection(dladm_handle_t handle, prop_desc_t *pdp, 1841*10734SEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 1842*10734SEric Cheng uint_t flags, datalink_media_t media) 1843*10734SEric Cheng { 1844*10734SEric Cheng mac_resource_props_t mrp; 1845*10734SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1846*10734SEric Cheng dld_ioc_macprop_t *dip; 1847*10734SEric Cheng 1848*10734SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 1849*10734SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, "protection", 1850*10734SEric Cheng flags, &status); 1851*10734SEric Cheng 1852*10734SEric Cheng if (dip == NULL) 1853*10734SEric Cheng return (status); 1854*10734SEric Cheng 1855*10734SEric Cheng if (strcmp(pdp->pd_name, "protection") == 0) { 1856*10734SEric Cheng status = do_extract_protection(vdp, val_cnt, &mrp); 1857*10734SEric Cheng if (status != DLADM_STATUS_OK) 1858*10734SEric Cheng goto done; 1859*10734SEric Cheng 1860*10734SEric Cheng } else if (strcmp(pdp->pd_name, "allowed-ips") == 0) { 1861*10734SEric Cheng status = do_extract_allowedips(vdp, val_cnt, &mrp); 1862*10734SEric Cheng if (status != DLADM_STATUS_OK) 1863*10734SEric Cheng goto done; 1864*10734SEric Cheng } else { 1865*10734SEric Cheng status = DLADM_STATUS_BADARG; 1866*10734SEric Cheng goto done; 1867*10734SEric Cheng } 1868*10734SEric Cheng 1869*10734SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 1870*10734SEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 1871*10734SEric Cheng 1872*10734SEric Cheng done: 1873*10734SEric Cheng free(dip); 1874*10734SEric Cheng return (status); 1875*10734SEric Cheng } 1876*10734SEric Cheng 1877*10734SEric Cheng /* ARGSUSED */ 1878*10734SEric Cheng static dladm_status_t 1879*10734SEric Cheng do_get_protection(dladm_handle_t handle, prop_desc_t *pdp, 1880*10734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 1881*10734SEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 1882*10734SEric Cheng { 1883*10734SEric Cheng dld_ioc_macprop_t *dip; 1884*10734SEric Cheng mac_resource_props_t mrp; 1885*10734SEric Cheng mac_protect_t *p; 1886*10734SEric Cheng dladm_status_t status; 1887*10734SEric Cheng int i; 1888*10734SEric Cheng 1889*10734SEric Cheng dip = i_dladm_get_public_prop(handle, linkid, "protection", flags, 1890*10734SEric Cheng &status, perm_flags); 1891*10734SEric Cheng if (dip == NULL) 1892*10734SEric Cheng return (status); 1893*10734SEric Cheng 1894*10734SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 1895*10734SEric Cheng free(dip); 1896*10734SEric Cheng 1897*10734SEric Cheng p = &mrp.mrp_protect; 1898*10734SEric Cheng if ((mrp.mrp_mask & MRP_PROTECT) != 0 && 1899*10734SEric Cheng strcmp(pdp->pd_name, "protection") == 0) { 1900*10734SEric Cheng uint32_t cnt = 0, setbits[32]; 1901*10734SEric Cheng 1902*10734SEric Cheng dladm_find_setbits32(p->mp_types, setbits, &cnt); 1903*10734SEric Cheng if (cnt > *val_cnt) 1904*10734SEric Cheng return (DLADM_STATUS_BADVALCNT); 1905*10734SEric Cheng 1906*10734SEric Cheng for (i = 0; i < cnt; i++) 1907*10734SEric Cheng (void) dladm_protect2str(setbits[i], prop_val[i]); 1908*10734SEric Cheng 1909*10734SEric Cheng *val_cnt = cnt; 1910*10734SEric Cheng return (DLADM_STATUS_OK); 1911*10734SEric Cheng } 1912*10734SEric Cheng 1913*10734SEric Cheng if (p->mp_ipaddrcnt > 0 && 1914*10734SEric Cheng strcmp(pdp->pd_name, "allowed-ips") == 0) { 1915*10734SEric Cheng if (p->mp_ipaddrcnt > *val_cnt) 1916*10734SEric Cheng return (DLADM_STATUS_BADVALCNT); 1917*10734SEric Cheng 1918*10734SEric Cheng for (i = 0; i < p->mp_ipaddrcnt; i++) { 1919*10734SEric Cheng (void) dladm_ipv4addr2str(&p->mp_ipaddrs[i], 1920*10734SEric Cheng prop_val[i]); 1921*10734SEric Cheng } 1922*10734SEric Cheng *val_cnt = p->mp_ipaddrcnt; 1923*10734SEric Cheng return (DLADM_STATUS_OK); 1924*10734SEric Cheng } 1925*10734SEric Cheng 1926*10734SEric Cheng *val_cnt = 0; 1927*10734SEric Cheng return (DLADM_STATUS_OK); 1928*10734SEric Cheng } 1929*10734SEric Cheng 1930*10734SEric Cheng dladm_status_t 1931*10734SEric Cheng do_extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 1932*10734SEric Cheng { 1933*10734SEric Cheng mac_resource_props_t *mrp = arg; 1934*10734SEric Cheng uint32_t types = 0; 1935*10734SEric Cheng int i; 1936*10734SEric Cheng 1937*10734SEric Cheng for (i = 0; i < cnt; i++) 1938*10734SEric Cheng types |= (uint32_t)vdp[i].vd_val; 1939*10734SEric Cheng 1940*10734SEric Cheng mrp->mrp_protect.mp_types = types; 1941*10734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 1942*10734SEric Cheng return (DLADM_STATUS_OK); 1943*10734SEric Cheng } 1944*10734SEric Cheng 1945*10734SEric Cheng dladm_status_t 1946*10734SEric Cheng do_extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 1947*10734SEric Cheng { 1948*10734SEric Cheng mac_resource_props_t *mrp = arg; 1949*10734SEric Cheng mac_protect_t *p = &mrp->mrp_protect; 1950*10734SEric Cheng int i; 1951*10734SEric Cheng 1952*10734SEric Cheng if (vdp->vd_val == 0) { 1953*10734SEric Cheng cnt = (uint_t)-1; 1954*10734SEric Cheng } else { 1955*10734SEric Cheng for (i = 0; i < cnt; i++) 1956*10734SEric Cheng p->mp_ipaddrs[i] = (ipaddr_t)vdp[i].vd_val; 1957*10734SEric Cheng } 1958*10734SEric Cheng p->mp_ipaddrcnt = cnt; 1959*10734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 1960*10734SEric Cheng return (DLADM_STATUS_OK); 1961*10734SEric Cheng } 1962*10734SEric Cheng 1963*10734SEric Cheng /* ARGSUSED */ 1964*10734SEric Cheng static dladm_status_t 1965*10734SEric Cheng do_check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 1966*10734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t val_cnt, 1967*10734SEric Cheng val_desc_t *vdp, datalink_media_t media) 1968*10734SEric Cheng { 1969*10734SEric Cheng dladm_status_t status; 1970*10734SEric Cheng ipaddr_t addr; 1971*10734SEric Cheng int i; 1972*10734SEric Cheng 1973*10734SEric Cheng if (val_cnt > MPT_MAXIPADDR) 1974*10734SEric Cheng return (DLADM_STATUS_BADVALCNT); 1975*10734SEric Cheng 1976*10734SEric Cheng for (i = 0; i < val_cnt; i++) { 1977*10734SEric Cheng status = dladm_str2ipv4addr(prop_val[i], &addr); 1978*10734SEric Cheng if (status != DLADM_STATUS_OK) 1979*10734SEric Cheng return (status); 1980*10734SEric Cheng 1981*10734SEric Cheng if (addr == 0) 1982*10734SEric Cheng return (DLADM_STATUS_BADVAL); 1983*10734SEric Cheng 1984*10734SEric Cheng vdp[i].vd_val = (uintptr_t)addr; 1985*10734SEric Cheng } 1986*10734SEric Cheng return (DLADM_STATUS_OK); 1987*10734SEric Cheng } 1988*10734SEric Cheng 1989*10734SEric Cheng /* ARGSUSED */ 1990*10734SEric Cheng static dladm_status_t 19918453SAnurag.Maskey@Sun.COM do_get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19928275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 19938275SEric Cheng uint_t flags, uint_t *perm_flags) 19945895Syz147064 { 19957342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 19967342SAruna.Ramakrishna@Sun.COM int i, len; 19977342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 19987342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 19995895Syz147064 20006789Sam223141 if (flags & MAC_PROP_DEFAULT) 20017776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 20026512Ssowmini 20035895Syz147064 *val_cnt = 1; 20048453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 20058275SEric Cheng &status, perm_flags); 20067342SAruna.Ramakrishna@Sun.COM if (dip == NULL) { 20075895Syz147064 (*prop_val)[0] = '\0'; 20088275SEric Cheng return (DLADM_STATUS_OK); 20095895Syz147064 } 20107342SAruna.Ramakrishna@Sun.COM (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 20115895Syz147064 20127342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 20135895Syz147064 if (i != 0) { 20145895Syz147064 (void) snprintf(*prop_val + len, 20155895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 20165895Syz147064 len += 1; 20175895Syz147064 } 20185895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 20197342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 20207342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 20217342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 20225895Syz147064 (void) snprintf(*prop_val + len, 20235895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 20245895Syz147064 AP_ANCHOR); 20255895Syz147064 len += (strlen(AP_ANCHOR) + 1); 20265895Syz147064 } 20275895Syz147064 } 20287342SAruna.Ramakrishna@Sun.COM free(dip); 20295895Syz147064 done: 20305895Syz147064 return (DLADM_STATUS_OK); 20315895Syz147064 } 20325895Syz147064 20335895Syz147064 /* 20345895Syz147064 * Add the specified module to the dlautopush structure; returns a 20355895Syz147064 * DLADM_STATUS_* code. 20365895Syz147064 */ 20375895Syz147064 dladm_status_t 20385895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 20395895Syz147064 { 20405895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 20415895Syz147064 return (DLADM_STATUS_BADVAL); 20425895Syz147064 20435895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 20445895Syz147064 /* 20455895Syz147064 * We don't allow multiple anchors, and the anchor must 20465895Syz147064 * be after at least one module. 20475895Syz147064 */ 20485895Syz147064 if (dlap->dap_anchor != 0) 20495895Syz147064 return (DLADM_STATUS_BADVAL); 20505895Syz147064 if (dlap->dap_npush == 0) 20515895Syz147064 return (DLADM_STATUS_BADVAL); 20525895Syz147064 20535895Syz147064 dlap->dap_anchor = dlap->dap_npush; 20545895Syz147064 return (DLADM_STATUS_OK); 20555895Syz147064 } 20568957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 20575895Syz147064 return (DLADM_STATUS_BADVALCNT); 20585895Syz147064 20595895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 20605895Syz147064 FMNAMESZ + 1); 20615895Syz147064 20625895Syz147064 return (DLADM_STATUS_OK); 20635895Syz147064 } 20645895Syz147064 20655895Syz147064 /* 20665895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 20675895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 20685895Syz147064 * latter is used in the autopush(1M) file. 20695895Syz147064 */ 20705895Syz147064 /* ARGSUSED */ 20715895Syz147064 static dladm_status_t 20728453SAnurag.Maskey@Sun.COM do_check_autopush(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 char *module; 20765895Syz147064 struct dlautopush *dlap; 20775895Syz147064 dladm_status_t status; 20785895Syz147064 char val[DLADM_PROP_VAL_MAX]; 20795895Syz147064 char delimiters[4]; 20805895Syz147064 20815895Syz147064 if (val_cnt != 1) 20825895Syz147064 return (DLADM_STATUS_BADVALCNT); 20835895Syz147064 20847342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 20857342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 20867342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 20877342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 20883448Sdh155122 20897342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 20907342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 20917342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 20927342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 20937342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 20947342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 20957342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 20967342SAruna.Ramakrishna@Sun.COM return (status); 20977342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 20987342SAruna.Ramakrishna@Sun.COM } 20997342SAruna.Ramakrishna@Sun.COM 21007342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 21017342SAruna.Ramakrishna@Sun.COM } else { 21027342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 21035895Syz147064 } 21043448Sdh155122 return (DLADM_STATUS_OK); 21053448Sdh155122 } 21063448Sdh155122 21077663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 21087663SSowmini.Varadhan@Sun.COM 21095903Ssowmini /* ARGSUSED */ 21103448Sdh155122 static dladm_status_t 21118453SAnurag.Maskey@Sun.COM do_get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 21128453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 21138453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 21143448Sdh155122 { 21155895Syz147064 wl_rates_t *wrp; 21165895Syz147064 uint_t i; 21175895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 21185895Syz147064 21197663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 21207663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 21217663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 21225895Syz147064 21238453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 21248453SAnurag.Maskey@Sun.COM B_FALSE); 21255895Syz147064 if (status != DLADM_STATUS_OK) 21265895Syz147064 goto done; 21275895Syz147064 21285895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 21295895Syz147064 status = DLADM_STATUS_TOOSMALL; 21305895Syz147064 goto done; 21315895Syz147064 } 21325895Syz147064 21335895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 21345895Syz147064 prop_val[0][0] = '\0'; 21355895Syz147064 *val_cnt = 1; 21365895Syz147064 goto done; 21375895Syz147064 } 21385895Syz147064 21395895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 21405895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 21415895Syz147064 wrp->wl_rates_rates[i] % 2, 21425895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 21435895Syz147064 } 21445895Syz147064 *val_cnt = wrp->wl_rates_num; 21458275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 21463448Sdh155122 21475895Syz147064 done: 21487663SSowmini.Varadhan@Sun.COM free(wrp); 21495895Syz147064 return (status); 21505895Syz147064 } 21515895Syz147064 21525895Syz147064 static dladm_status_t 21538453SAnurag.Maskey@Sun.COM do_get_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21548275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 21558275SEric Cheng uint_t flags, uint_t *perm_flags) 21565895Syz147064 { 21578118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 21588453SAnurag.Maskey@Sun.COM return (i_dladm_speed_get(handle, pdp, linkid, prop_val, 21598275SEric Cheng val_cnt, flags, perm_flags)); 21608118SVasumathi.Sundaram@Sun.COM } 21615960Ssowmini 21628453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 21638275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 21645895Syz147064 } 21655895Syz147064 21666512Ssowmini /* ARGSUSED */ 21675895Syz147064 static dladm_status_t 21688453SAnurag.Maskey@Sun.COM do_get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21698275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 21708275SEric Cheng uint_t flags, uint_t *perm_flags) 21715895Syz147064 { 21725960Ssowmini switch (media) { 21735960Ssowmini case DL_ETHER: 21746512Ssowmini /* 21756512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 21766512Ssowmini * links can have a speed of 5.5 Gbps. 21776512Ssowmini */ 21786512Ssowmini return (DLADM_STATUS_NOTSUP); 21795960Ssowmini 21805960Ssowmini case DL_WIFI: 21818453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, 21828453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 21835960Ssowmini default: 21845960Ssowmini return (DLADM_STATUS_BADARG); 21855960Ssowmini } 21865895Syz147064 } 21875895Syz147064 21885895Syz147064 static dladm_status_t 21898453SAnurag.Maskey@Sun.COM do_set_rate(dladm_handle_t handle, datalink_id_t linkid, 21908453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 21915895Syz147064 { 21925895Syz147064 int i; 21935895Syz147064 uint_t len; 21945895Syz147064 wl_rates_t *wrp; 21955895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 21965895Syz147064 21977663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 21987663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 21995895Syz147064 return (DLADM_STATUS_NOMEM); 22005895Syz147064 22017663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 22025895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 22035895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 22045895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 22055895Syz147064 22065895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 22075895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 22088453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 22098453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 22105895Syz147064 22117663SSowmini.Varadhan@Sun.COM free(wrp); 22125895Syz147064 return (status); 22135895Syz147064 } 22143448Sdh155122 22155903Ssowmini /* ARGSUSED */ 22165895Syz147064 static dladm_status_t 22178453SAnurag.Maskey@Sun.COM do_set_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22185960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 22195895Syz147064 { 22205895Syz147064 dladm_wlan_rates_t rates; 22215895Syz147064 dladm_status_t status; 22225895Syz147064 22235960Ssowmini /* 22245960Ssowmini * can currently set rate on WIFI links only. 22255960Ssowmini */ 22265960Ssowmini if (media != DL_WIFI) 22275960Ssowmini return (DLADM_STATUS_PROPRDONLY); 22285960Ssowmini 22295895Syz147064 if (val_cnt != 1) 22305895Syz147064 return (DLADM_STATUS_BADVALCNT); 22315895Syz147064 22325895Syz147064 rates.wr_cnt = 1; 22335895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 22345895Syz147064 22358453SAnurag.Maskey@Sun.COM status = do_set_rate(handle, linkid, &rates); 22365895Syz147064 22375895Syz147064 done: 22385895Syz147064 return (status); 22395895Syz147064 } 22403448Sdh155122 22415895Syz147064 /* ARGSUSED */ 22425895Syz147064 static dladm_status_t 22438453SAnurag.Maskey@Sun.COM do_check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22448453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 22455895Syz147064 { 22465895Syz147064 int i; 22475895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 22485895Syz147064 char *buf, **modval; 22495895Syz147064 dladm_status_t status; 22508118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 22515895Syz147064 22525895Syz147064 if (val_cnt != 1) 22535895Syz147064 return (DLADM_STATUS_BADVALCNT); 22545895Syz147064 22555895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 22565895Syz147064 MAX_SUPPORT_RATES); 22575895Syz147064 if (buf == NULL) { 22585895Syz147064 status = DLADM_STATUS_NOMEM; 22595895Syz147064 goto done; 22605895Syz147064 } 22613448Sdh155122 22625895Syz147064 modval = (char **)(void *)buf; 22635895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 22645895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 22655895Syz147064 i * DLADM_STRSIZE; 22665895Syz147064 } 22675895Syz147064 22688453SAnurag.Maskey@Sun.COM status = do_get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 22698453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 22705895Syz147064 if (status != DLADM_STATUS_OK) 22715895Syz147064 goto done; 22725895Syz147064 22735895Syz147064 for (i = 0; i < modval_cnt; i++) { 22745895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 22755903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 22765903Ssowmini (atof(*prop_val) * 2); 22775895Syz147064 status = DLADM_STATUS_OK; 22783448Sdh155122 break; 22793448Sdh155122 } 22805895Syz147064 } 22815895Syz147064 if (i == modval_cnt) 22825895Syz147064 status = DLADM_STATUS_BADVAL; 22835895Syz147064 done: 22845895Syz147064 free(buf); 22855895Syz147064 return (status); 22865895Syz147064 } 22875895Syz147064 22885895Syz147064 static dladm_status_t 22898453SAnurag.Maskey@Sun.COM do_get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 22908453SAnurag.Maskey@Sun.COM int buflen) 22915895Syz147064 { 22928453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 22937663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 22945895Syz147064 } 22955895Syz147064 22965903Ssowmini /* ARGSUSED */ 22975895Syz147064 static dladm_status_t 22988453SAnurag.Maskey@Sun.COM do_get_channel_prop(dladm_handle_t handle, prop_desc_t *pdp, 22998453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 23008453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 23015895Syz147064 { 23025895Syz147064 uint32_t channel; 23037663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 23045895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 23057663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 23065895Syz147064 23078453SAnurag.Maskey@Sun.COM if ((status = do_get_phyconf(handle, linkid, buf, sizeof (buf))) 23087663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 23095895Syz147064 goto done; 23105895Syz147064 23117663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 23127663SSowmini.Varadhan@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 23135895Syz147064 status = DLADM_STATUS_NOTFOUND; 23145895Syz147064 goto done; 23155895Syz147064 } 23165895Syz147064 23175895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 23185895Syz147064 *val_cnt = 1; 23198275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 23205895Syz147064 done: 23215895Syz147064 return (status); 23225895Syz147064 } 23235895Syz147064 23245895Syz147064 static dladm_status_t 23258453SAnurag.Maskey@Sun.COM do_get_powermode(dladm_handle_t handle, datalink_id_t linkid, void *buf, 23268453SAnurag.Maskey@Sun.COM int buflen) 23275895Syz147064 { 23288453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_POWER_MODE, 23297663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 23305895Syz147064 } 23315895Syz147064 23325903Ssowmini /* ARGSUSED */ 23335895Syz147064 static dladm_status_t 23348453SAnurag.Maskey@Sun.COM do_get_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 23358453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 23368453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 23375895Syz147064 { 23387663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 23395895Syz147064 const char *s; 23407663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 23415895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 23425895Syz147064 23438453SAnurag.Maskey@Sun.COM if ((status = do_get_powermode(handle, linkid, buf, sizeof (buf))) 23447663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 23455895Syz147064 goto done; 23465895Syz147064 23477663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 23487663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 23495895Syz147064 case WL_PM_AM: 23505895Syz147064 s = "off"; 23515895Syz147064 break; 23525895Syz147064 case WL_PM_MPS: 23535895Syz147064 s = "max"; 23545895Syz147064 break; 23555895Syz147064 case WL_PM_FAST: 23565895Syz147064 s = "fast"; 23573448Sdh155122 break; 23583448Sdh155122 default: 23595895Syz147064 status = DLADM_STATUS_NOTFOUND; 23605895Syz147064 goto done; 23615895Syz147064 } 23625895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 23635895Syz147064 *val_cnt = 1; 23648275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 23655895Syz147064 done: 23665895Syz147064 return (status); 23675895Syz147064 } 23685895Syz147064 23695895Syz147064 static dladm_status_t 23708453SAnurag.Maskey@Sun.COM do_set_powermode(dladm_handle_t handle, datalink_id_t linkid, 23718453SAnurag.Maskey@Sun.COM dladm_wlan_powermode_t *pm) 23725895Syz147064 { 23735895Syz147064 wl_ps_mode_t ps_mode; 23745895Syz147064 23755895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 23765895Syz147064 23775895Syz147064 switch (*pm) { 23785895Syz147064 case DLADM_WLAN_PM_OFF: 23795895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 23803448Sdh155122 break; 23815895Syz147064 case DLADM_WLAN_PM_MAX: 23825895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 23835895Syz147064 break; 23845895Syz147064 case DLADM_WLAN_PM_FAST: 23855895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 23865895Syz147064 break; 23875895Syz147064 default: 23885895Syz147064 return (DLADM_STATUS_NOTSUP); 23893448Sdh155122 } 23908453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 23918453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 23925895Syz147064 } 23935895Syz147064 23945895Syz147064 /* ARGSUSED */ 23955895Syz147064 static dladm_status_t 23968453SAnurag.Maskey@Sun.COM do_set_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 23978453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 23988453SAnurag.Maskey@Sun.COM datalink_media_t media) 23995895Syz147064 { 24005895Syz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 24015895Syz147064 dladm_status_t status; 24025895Syz147064 24035895Syz147064 if (val_cnt != 1) 24045895Syz147064 return (DLADM_STATUS_BADVALCNT); 24055895Syz147064 24068453SAnurag.Maskey@Sun.COM status = do_set_powermode(handle, linkid, &powermode); 24073448Sdh155122 24083448Sdh155122 return (status); 24093448Sdh155122 } 24103448Sdh155122 24113448Sdh155122 static dladm_status_t 24128453SAnurag.Maskey@Sun.COM do_get_radio(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen) 24133448Sdh155122 { 24148453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_RADIO, 24158453SAnurag.Maskey@Sun.COM buflen, B_FALSE)); 24165895Syz147064 } 24173448Sdh155122 24185903Ssowmini /* ARGSUSED */ 24195895Syz147064 static dladm_status_t 24208453SAnurag.Maskey@Sun.COM do_get_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 24218275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 24228275SEric Cheng uint_t flags, uint_t *perm_flags) 24235895Syz147064 { 24245895Syz147064 wl_radio_t radio; 24255895Syz147064 const char *s; 24267663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 24275895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 24283448Sdh155122 24298453SAnurag.Maskey@Sun.COM if ((status = do_get_radio(handle, linkid, buf, sizeof (buf))) 24307663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 24315895Syz147064 goto done; 24323448Sdh155122 24337663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 24345895Syz147064 switch (radio) { 24355895Syz147064 case B_TRUE: 24365895Syz147064 s = "on"; 24375895Syz147064 break; 24385895Syz147064 case B_FALSE: 24395895Syz147064 s = "off"; 24405895Syz147064 break; 24415895Syz147064 default: 24425895Syz147064 status = DLADM_STATUS_NOTFOUND; 24435895Syz147064 goto done; 24445895Syz147064 } 24455895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 24465895Syz147064 *val_cnt = 1; 24478275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 24485895Syz147064 done: 24493448Sdh155122 return (status); 24503448Sdh155122 } 24513448Sdh155122 24523448Sdh155122 static dladm_status_t 24538453SAnurag.Maskey@Sun.COM do_set_radio(dladm_handle_t handle, datalink_id_t linkid, 24548453SAnurag.Maskey@Sun.COM dladm_wlan_radio_t *radio) 24553448Sdh155122 { 24565895Syz147064 wl_radio_t r; 24573448Sdh155122 24585895Syz147064 switch (*radio) { 24595895Syz147064 case DLADM_WLAN_RADIO_ON: 24605895Syz147064 r = B_TRUE; 24615895Syz147064 break; 24625895Syz147064 case DLADM_WLAN_RADIO_OFF: 24635895Syz147064 r = B_FALSE; 24645895Syz147064 break; 24655895Syz147064 default: 24665895Syz147064 return (DLADM_STATUS_NOTSUP); 24675895Syz147064 } 24688453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 24697663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 24705895Syz147064 } 24713448Sdh155122 24725895Syz147064 /* ARGSUSED */ 24735895Syz147064 static dladm_status_t 24748453SAnurag.Maskey@Sun.COM do_set_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 247510616SSebastien.Roy@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 24765895Syz147064 { 24775895Syz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 24785895Syz147064 dladm_status_t status; 24793448Sdh155122 24805895Syz147064 if (val_cnt != 1) 24815895Syz147064 return (DLADM_STATUS_BADVALCNT); 24825895Syz147064 24838453SAnurag.Maskey@Sun.COM status = do_set_radio(handle, linkid, &radio); 24843448Sdh155122 24853448Sdh155122 return (status); 24863448Sdh155122 } 24873448Sdh155122 248810616SSebastien.Roy@Sun.COM /* ARGSUSED */ 248910616SSebastien.Roy@Sun.COM static dladm_status_t 249010616SSebastien.Roy@Sun.COM do_check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 249110616SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 249210616SSebastien.Roy@Sun.COM datalink_media_t media) 249310616SSebastien.Roy@Sun.COM { 249410616SSebastien.Roy@Sun.COM int32_t hlim; 249510616SSebastien.Roy@Sun.COM char *ep; 249610616SSebastien.Roy@Sun.COM 249710616SSebastien.Roy@Sun.COM if (val_cnt != 1) 249810616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 249910616SSebastien.Roy@Sun.COM 250010616SSebastien.Roy@Sun.COM errno = 0; 250110616SSebastien.Roy@Sun.COM hlim = strtol(*prop_val, &ep, 10); 250210616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || hlim < 1 || 250310616SSebastien.Roy@Sun.COM hlim > (int32_t)UINT8_MAX) 250410616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 250510616SSebastien.Roy@Sun.COM vdp->vd_val = hlim; 250610616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 250710616SSebastien.Roy@Sun.COM } 250810616SSebastien.Roy@Sun.COM 250910616SSebastien.Roy@Sun.COM /* ARGSUSED */ 251010616SSebastien.Roy@Sun.COM static dladm_status_t 251110616SSebastien.Roy@Sun.COM do_check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 251210616SSebastien.Roy@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 251310616SSebastien.Roy@Sun.COM { 251410616SSebastien.Roy@Sun.COM int32_t elim; 251510616SSebastien.Roy@Sun.COM char *ep; 251610616SSebastien.Roy@Sun.COM 251710616SSebastien.Roy@Sun.COM if (media != DL_IPV6) 251810616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG); 251910616SSebastien.Roy@Sun.COM 252010616SSebastien.Roy@Sun.COM if (val_cnt != 1) 252110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 252210616SSebastien.Roy@Sun.COM 252310616SSebastien.Roy@Sun.COM errno = 0; 252410616SSebastien.Roy@Sun.COM elim = strtol(*prop_val, &ep, 10); 252510616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || elim < 0 || 252610616SSebastien.Roy@Sun.COM elim > (int32_t)UINT8_MAX) 252710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 252810616SSebastien.Roy@Sun.COM vdp->vd_val = elim; 252910616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 253010616SSebastien.Roy@Sun.COM } 253110616SSebastien.Roy@Sun.COM 25325895Syz147064 static dladm_status_t 25338453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 25348453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 25353448Sdh155122 { 25365895Syz147064 char buf[MAXLINELEN]; 25375895Syz147064 int i; 25385895Syz147064 dladm_conf_t conf; 25395895Syz147064 dladm_status_t status; 25403448Sdh155122 25418453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 25425895Syz147064 if (status != DLADM_STATUS_OK) 25435895Syz147064 return (status); 25443448Sdh155122 25455895Syz147064 /* 25465895Syz147064 * reset case. 25475895Syz147064 */ 25485895Syz147064 if (val_cnt == 0) { 25498453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 25505895Syz147064 if (status == DLADM_STATUS_OK) 25518453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 25525895Syz147064 goto done; 25535895Syz147064 } 25543448Sdh155122 25555895Syz147064 buf[0] = '\0'; 25565895Syz147064 for (i = 0; i < val_cnt; i++) { 25575895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 25585895Syz147064 if (i != val_cnt - 1) 25595895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 25603448Sdh155122 } 25613448Sdh155122 25628453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 25638453SAnurag.Maskey@Sun.COM buf); 25645895Syz147064 if (status == DLADM_STATUS_OK) 25658453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 25665895Syz147064 25675895Syz147064 done: 25688453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 25695895Syz147064 return (status); 25703448Sdh155122 } 25715895Syz147064 25725895Syz147064 static dladm_status_t 25738453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 25748453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 25755895Syz147064 { 25765895Syz147064 char buf[MAXLINELEN], *str; 25775895Syz147064 uint_t cnt = 0; 25785895Syz147064 dladm_conf_t conf; 25795895Syz147064 dladm_status_t status; 25805895Syz147064 25818453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 25825895Syz147064 if (status != DLADM_STATUS_OK) 25835895Syz147064 return (status); 25845895Syz147064 25858453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 25865895Syz147064 if (status != DLADM_STATUS_OK) 25875895Syz147064 goto done; 25885895Syz147064 25895895Syz147064 str = strtok(buf, ","); 25905895Syz147064 while (str != NULL) { 25915895Syz147064 if (cnt == *val_cntp) { 25925895Syz147064 status = DLADM_STATUS_TOOSMALL; 25935895Syz147064 goto done; 25945895Syz147064 } 25955895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 25965895Syz147064 str = strtok(NULL, ","); 25975895Syz147064 } 25985895Syz147064 25995895Syz147064 *val_cntp = cnt; 26005895Syz147064 26015895Syz147064 done: 26028453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 26035895Syz147064 return (status); 26045895Syz147064 } 26055903Ssowmini 26068460SArtem.Kachitchkin@Sun.COM /* 26078460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 26088460SArtem.Kachitchkin@Sun.COM */ 26098460SArtem.Kachitchkin@Sun.COM static dladm_status_t 26108460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 26118460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 26128460SArtem.Kachitchkin@Sun.COM { 26138460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 26148460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 26158460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 26168460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 26178460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 26188460SArtem.Kachitchkin@Sun.COM size_t attrsz; 26198460SArtem.Kachitchkin@Sun.COM 26208460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 26218460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 26228460SArtem.Kachitchkin@Sun.COM 26238460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 26248460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 26258460SArtem.Kachitchkin@Sun.COM return (status); 26268460SArtem.Kachitchkin@Sun.COM 26278460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 26288460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 26298460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 26308460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 26318460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 26328460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 26338460SArtem.Kachitchkin@Sun.COM break; 26348460SArtem.Kachitchkin@Sun.COM } 26358460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 26368460SArtem.Kachitchkin@Sun.COM } 26378460SArtem.Kachitchkin@Sun.COM 26388460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 26398460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 26408460SArtem.Kachitchkin@Sun.COM } 26418460SArtem.Kachitchkin@Sun.COM 26427663SSowmini.Varadhan@Sun.COM static link_attr_t * 26435903Ssowmini dladm_name2prop(const char *prop_name) 26445903Ssowmini { 26457663SSowmini.Varadhan@Sun.COM link_attr_t *p; 26465903Ssowmini 26477663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 26485903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 26495903Ssowmini break; 26505903Ssowmini } 26515903Ssowmini return (p); 26525903Ssowmini } 26535903Ssowmini 26547663SSowmini.Varadhan@Sun.COM static link_attr_t * 26557663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 26567663SSowmini.Varadhan@Sun.COM { 26577663SSowmini.Varadhan@Sun.COM link_attr_t *p; 26587663SSowmini.Varadhan@Sun.COM 26597663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 26607663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 26617663SSowmini.Varadhan@Sun.COM break; 26627663SSowmini.Varadhan@Sun.COM } 26637663SSowmini.Varadhan@Sun.COM return (p); 26647663SSowmini.Varadhan@Sun.COM } 26655903Ssowmini 26666789Sam223141 static dld_ioc_macprop_t * 26677663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 26687663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 26697663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 26705903Ssowmini { 26715903Ssowmini int dsize; 26726789Sam223141 dld_ioc_macprop_t *dip; 26735903Ssowmini 26745903Ssowmini *status = DLADM_STATUS_OK; 26756789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 26765903Ssowmini dip = malloc(dsize); 26775903Ssowmini if (dip == NULL) { 26785903Ssowmini *status = DLADM_STATUS_NOMEM; 26795903Ssowmini return (NULL); 26805903Ssowmini } 26815903Ssowmini bzero(dip, dsize); 26825903Ssowmini dip->pr_valsize = valsize; 26836512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 26846789Sam223141 dip->pr_version = MAC_PROP_VERSION; 26855960Ssowmini dip->pr_linkid = linkid; 26867663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 26876512Ssowmini dip->pr_flags = flags; 26885903Ssowmini return (dip); 26895903Ssowmini } 26905903Ssowmini 26917663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 26927663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 26937663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 26947663SSowmini.Varadhan@Sun.COM { 26957663SSowmini.Varadhan@Sun.COM link_attr_t *p; 26967663SSowmini.Varadhan@Sun.COM 26977663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 26987663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 26997663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 27007663SSowmini.Varadhan@Sun.COM flags, status)); 27017663SSowmini.Varadhan@Sun.COM } 27027663SSowmini.Varadhan@Sun.COM 27037663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 27047663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 27057663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 27067663SSowmini.Varadhan@Sun.COM { 27077663SSowmini.Varadhan@Sun.COM link_attr_t *p; 27087663SSowmini.Varadhan@Sun.COM 27097663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 27107663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 27117663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 27127663SSowmini.Varadhan@Sun.COM flags, status)); 27137663SSowmini.Varadhan@Sun.COM } 27147663SSowmini.Varadhan@Sun.COM 27155903Ssowmini /* ARGSUSED */ 27165903Ssowmini static dladm_status_t 27178453SAnurag.Maskey@Sun.COM i_dladm_set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 27188453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 27198453SAnurag.Maskey@Sun.COM datalink_media_t media) 27205903Ssowmini { 27216789Sam223141 dld_ioc_macprop_t *dip; 27225903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 27235903Ssowmini uint8_t u8; 27245903Ssowmini uint16_t u16; 27255903Ssowmini uint32_t u32; 27265903Ssowmini void *val; 27275903Ssowmini 27288275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 27295903Ssowmini if (dip == NULL) 27305903Ssowmini return (status); 27315903Ssowmini 27328275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 27335903Ssowmini val = (void *)vdp->vd_val; 27345903Ssowmini else { 27355903Ssowmini /* 27365903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 27375903Ssowmini * No need (yet) to distinguish these from arrays of same size. 27385903Ssowmini */ 27395903Ssowmini switch (dip->pr_valsize) { 27405903Ssowmini case 1: 27415903Ssowmini u8 = vdp->vd_val; 27425903Ssowmini val = &u8; 27435903Ssowmini break; 27445903Ssowmini case 2: 27455903Ssowmini u16 = vdp->vd_val; 27465903Ssowmini val = &u16; 27475903Ssowmini break; 27485903Ssowmini case 4: 27495903Ssowmini u32 = vdp->vd_val; 27505903Ssowmini val = &u32; 27515903Ssowmini break; 27525903Ssowmini default: 27535903Ssowmini val = &vdp->vd_val; 27545903Ssowmini break; 27555903Ssowmini } 27565903Ssowmini } 27575903Ssowmini 27587342SAruna.Ramakrishna@Sun.COM if (val != NULL) 27597342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 27607342SAruna.Ramakrishna@Sun.COM else 27617342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 27627342SAruna.Ramakrishna@Sun.COM 27638453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 27647663SSowmini.Varadhan@Sun.COM 27657663SSowmini.Varadhan@Sun.COM done: 27667663SSowmini.Varadhan@Sun.COM free(dip); 27677663SSowmini.Varadhan@Sun.COM return (status); 27687663SSowmini.Varadhan@Sun.COM } 27697663SSowmini.Varadhan@Sun.COM 27707663SSowmini.Varadhan@Sun.COM dladm_status_t 27718453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 27727663SSowmini.Varadhan@Sun.COM { 27737663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 27747663SSowmini.Varadhan@Sun.COM 27758453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 27768453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 27775903Ssowmini status = dladm_errno2status(errno); 27788453SAnurag.Maskey@Sun.COM 27795903Ssowmini return (status); 27805903Ssowmini } 27815903Ssowmini 27826789Sam223141 static dld_ioc_macprop_t * 27838453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 27848453SAnurag.Maskey@Sun.COM char *prop_name, uint_t flags, dladm_status_t *status, uint_t *perm_flags) 27855903Ssowmini { 27866789Sam223141 dld_ioc_macprop_t *dip = NULL; 27876512Ssowmini 27887663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 27896512Ssowmini if (dip == NULL) 27906512Ssowmini return (NULL); 27915903Ssowmini 27928453SAnurag.Maskey@Sun.COM *status = i_dladm_macprop(handle, dip, B_FALSE); 27936512Ssowmini if (*status != DLADM_STATUS_OK) { 27946512Ssowmini free(dip); 27956512Ssowmini return (NULL); 27966512Ssowmini } 27978275SEric Cheng if (perm_flags != NULL) 27988275SEric Cheng *perm_flags = dip->pr_perm_flags; 27998275SEric Cheng 28006512Ssowmini return (dip); 28015903Ssowmini } 28025903Ssowmini 28035903Ssowmini /* ARGSUSED */ 28045903Ssowmini static dladm_status_t 280510491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check(dladm_handle_t handle, prop_desc_t *pdp, 28068453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *v, 28078453SAnurag.Maskey@Sun.COM datalink_media_t media) 28085903Ssowmini { 28095903Ssowmini if (val_cnt != 1) 28105903Ssowmini return (DLADM_STATUS_BADVAL); 281110491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 28125903Ssowmini return (DLADM_STATUS_OK); 28135903Ssowmini } 28145903Ssowmini 28155903Ssowmini /* ARGSUSED */ 28165903Ssowmini static dladm_status_t 28178453SAnurag.Maskey@Sun.COM i_dladm_duplex_get(dladm_handle_t handle, prop_desc_t *pdp, 28188453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28198453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28205903Ssowmini { 28215903Ssowmini link_duplex_t link_duplex; 28225903Ssowmini dladm_status_t status; 28235903Ssowmini 28248453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 28255903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 28265903Ssowmini return (status); 28275903Ssowmini 28285903Ssowmini switch (link_duplex) { 28295903Ssowmini case LINK_DUPLEX_FULL: 28305903Ssowmini (void) strcpy(*prop_val, "full"); 28315903Ssowmini break; 28325903Ssowmini case LINK_DUPLEX_HALF: 28335903Ssowmini (void) strcpy(*prop_val, "half"); 28345903Ssowmini break; 28355903Ssowmini default: 28365903Ssowmini (void) strcpy(*prop_val, "unknown"); 28375903Ssowmini break; 28385903Ssowmini } 28395903Ssowmini *val_cnt = 1; 28405903Ssowmini return (DLADM_STATUS_OK); 28415903Ssowmini } 28425903Ssowmini 28435903Ssowmini /* ARGSUSED */ 28445903Ssowmini static dladm_status_t 28458453SAnurag.Maskey@Sun.COM i_dladm_speed_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 28468275SEric Cheng char **prop_val, uint_t *val_cnt, uint_t flags, uint_t *perm_flags) 28475903Ssowmini { 28485903Ssowmini uint64_t ifspeed = 0; 28495903Ssowmini dladm_status_t status; 28505903Ssowmini 28518453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 28525903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 28535903Ssowmini return (status); 28546512Ssowmini 28555960Ssowmini if ((ifspeed % 1000000) != 0) { 28565960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 28575960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 28585960Ssowmini } else { 28595960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 28605960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 28615960Ssowmini } 28625903Ssowmini *val_cnt = 1; 28638275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 28645903Ssowmini return (DLADM_STATUS_OK); 28655903Ssowmini } 28665903Ssowmini 28675903Ssowmini /* ARGSUSED */ 28685903Ssowmini static dladm_status_t 28698453SAnurag.Maskey@Sun.COM i_dladm_status_get(dladm_handle_t handle, prop_desc_t *pdp, 28708453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28718453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28725903Ssowmini { 28738275SEric Cheng link_state_t link_state; 28748275SEric Cheng dladm_status_t status; 28758306SSowmini.Varadhan@Sun.COM 28768453SAnurag.Maskey@Sun.COM status = i_dladm_get_state(handle, linkid, &link_state); 28776512Ssowmini if (status != DLADM_STATUS_OK) 28785903Ssowmini return (status); 28798275SEric Cheng 28805903Ssowmini switch (link_state) { 28815903Ssowmini case LINK_STATE_UP: 28825903Ssowmini (void) strcpy(*prop_val, "up"); 28835903Ssowmini break; 28845903Ssowmini case LINK_STATE_DOWN: 28855903Ssowmini (void) strcpy(*prop_val, "down"); 28865903Ssowmini break; 28875903Ssowmini default: 28885903Ssowmini (void) strcpy(*prop_val, "unknown"); 28895903Ssowmini break; 28905903Ssowmini } 28915903Ssowmini *val_cnt = 1; 28928306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 28935903Ssowmini return (DLADM_STATUS_OK); 28945903Ssowmini } 28955903Ssowmini 28965903Ssowmini /* ARGSUSED */ 28975903Ssowmini static dladm_status_t 28988453SAnurag.Maskey@Sun.COM i_dladm_binary_get(dladm_handle_t handle, prop_desc_t *pdp, 28998453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29008453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29015903Ssowmini { 29026789Sam223141 dld_ioc_macprop_t *dip; 29035903Ssowmini dladm_status_t status; 29045903Ssowmini 29058453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29068275SEric Cheng &status, perm_flags); 29076512Ssowmini if (dip == NULL) 29085903Ssowmini return (status); 29098275SEric Cheng 29105903Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 29115903Ssowmini free(dip); 29125903Ssowmini *val_cnt = 1; 29135903Ssowmini return (DLADM_STATUS_OK); 29145903Ssowmini } 29155903Ssowmini 29165960Ssowmini /* ARGSUSED */ 29175903Ssowmini static dladm_status_t 29188453SAnurag.Maskey@Sun.COM i_dladm_uint32_get(dladm_handle_t handle, prop_desc_t *pdp, 29198453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29208453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29215903Ssowmini { 29226789Sam223141 dld_ioc_macprop_t *dip; 29238275SEric Cheng uint32_t v = 0; 29245903Ssowmini uchar_t *cp; 29255903Ssowmini dladm_status_t status; 29265903Ssowmini 29278453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29288275SEric Cheng &status, perm_flags); 29296512Ssowmini if (dip == NULL) 29305903Ssowmini return (status); 29318275SEric Cheng 29325903Ssowmini cp = (uchar_t *)dip->pr_val; 29335903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 29346512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 29355903Ssowmini free(dip); 29365903Ssowmini *val_cnt = 1; 29375903Ssowmini return (DLADM_STATUS_OK); 29385903Ssowmini } 29395903Ssowmini 29409514SGirish.Moodalbail@Sun.COM /* 29419514SGirish.Moodalbail@Sun.COM * Determines the size of the structure that needs to be sent to drivers 29429514SGirish.Moodalbail@Sun.COM * for retrieving the property range values. 29439514SGirish.Moodalbail@Sun.COM */ 29449514SGirish.Moodalbail@Sun.COM static int 29459514SGirish.Moodalbail@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 29469514SGirish.Moodalbail@Sun.COM { 29479514SGirish.Moodalbail@Sun.COM uint_t count = r->mpr_count; 29489514SGirish.Moodalbail@Sun.COM 29499514SGirish.Moodalbail@Sun.COM *sz = sizeof (mac_propval_range_t); 29509514SGirish.Moodalbail@Sun.COM --count; 29519514SGirish.Moodalbail@Sun.COM 29529514SGirish.Moodalbail@Sun.COM switch (r->mpr_type) { 29539514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: 29549514SGirish.Moodalbail@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 29559514SGirish.Moodalbail@Sun.COM return (0); 29569514SGirish.Moodalbail@Sun.COM default: 29579514SGirish.Moodalbail@Sun.COM break; 29589514SGirish.Moodalbail@Sun.COM } 29599514SGirish.Moodalbail@Sun.COM *sz = 0; 29609514SGirish.Moodalbail@Sun.COM return (EINVAL); 29619514SGirish.Moodalbail@Sun.COM } 29629514SGirish.Moodalbail@Sun.COM 29639514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 29649514SGirish.Moodalbail@Sun.COM static dladm_status_t 29659514SGirish.Moodalbail@Sun.COM i_dladm_range_get(dladm_handle_t handle, prop_desc_t *pdp, 29669514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29679514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29689514SGirish.Moodalbail@Sun.COM { 29699514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 29709514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 29719514SGirish.Moodalbail@Sun.COM size_t sz; 29729514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 29739514SGirish.Moodalbail@Sun.COM 29749514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 29759514SGirish.Moodalbail@Sun.COM 29769514SGirish.Moodalbail@Sun.COM /* 29779514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 29789514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 29799514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 29809514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 29819514SGirish.Moodalbail@Sun.COM */ 29829514SGirish.Moodalbail@Sun.COM retry: 29839514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 29849514SGirish.Moodalbail@Sun.COM &status)) == NULL) 29859514SGirish.Moodalbail@Sun.COM return (status); 29869514SGirish.Moodalbail@Sun.COM 29879514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 29889514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 29899514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 29909514SGirish.Moodalbail@Sun.COM int err; 29919514SGirish.Moodalbail@Sun.COM 29929514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 29939514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 29949514SGirish.Moodalbail@Sun.COM free(dip); 29959514SGirish.Moodalbail@Sun.COM goto retry; 29969514SGirish.Moodalbail@Sun.COM } else { 29979514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 29989514SGirish.Moodalbail@Sun.COM } 29999514SGirish.Moodalbail@Sun.COM } 30009514SGirish.Moodalbail@Sun.COM free(dip); 30019514SGirish.Moodalbail@Sun.COM return (status); 30029514SGirish.Moodalbail@Sun.COM } 30039514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 30049514SGirish.Moodalbail@Sun.COM 30059514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 30069514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 30079514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 30089514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 30099514SGirish.Moodalbail@Sun.COM 30109514SGirish.Moodalbail@Sun.COM ur = &rangep->range_uint32[0]; 30119514SGirish.Moodalbail@Sun.COM 30129514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 30139514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 30149514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 30159514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 30169514SGirish.Moodalbail@Sun.COM } else { 30179514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 30189514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 30199514SGirish.Moodalbail@Sun.COM } 30209514SGirish.Moodalbail@Sun.COM } 30219514SGirish.Moodalbail@Sun.COM *val_cnt = count; 30229514SGirish.Moodalbail@Sun.COM break; 30239514SGirish.Moodalbail@Sun.COM } 30249514SGirish.Moodalbail@Sun.COM default: 30259514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 30269514SGirish.Moodalbail@Sun.COM break; 30279514SGirish.Moodalbail@Sun.COM } 30289514SGirish.Moodalbail@Sun.COM free(dip); 30299514SGirish.Moodalbail@Sun.COM return (status); 30309514SGirish.Moodalbail@Sun.COM } 30319514SGirish.Moodalbail@Sun.COM 30325960Ssowmini /* ARGSUSED */ 30335903Ssowmini static dladm_status_t 30348874SSebastien.Roy@Sun.COM i_dladm_tagmode_get(dladm_handle_t handle, prop_desc_t *pdp, 30358874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30368874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30378874SSebastien.Roy@Sun.COM { 30388874SSebastien.Roy@Sun.COM dld_ioc_macprop_t *dip; 30398874SSebastien.Roy@Sun.COM link_tagmode_t mode; 30408874SSebastien.Roy@Sun.COM dladm_status_t status; 30418874SSebastien.Roy@Sun.COM 30428874SSebastien.Roy@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 30438874SSebastien.Roy@Sun.COM &status, perm_flags); 30448874SSebastien.Roy@Sun.COM if (dip == NULL) 30458874SSebastien.Roy@Sun.COM return (status); 30468874SSebastien.Roy@Sun.COM (void) memcpy(&mode, dip->pr_val, sizeof (mode)); 30478874SSebastien.Roy@Sun.COM free(dip); 30488874SSebastien.Roy@Sun.COM 30498874SSebastien.Roy@Sun.COM switch (mode) { 30508874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 30518874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 30528874SSebastien.Roy@Sun.COM break; 30538874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 30548874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 30558874SSebastien.Roy@Sun.COM break; 30568874SSebastien.Roy@Sun.COM default: 30578874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 30588874SSebastien.Roy@Sun.COM } 30598874SSebastien.Roy@Sun.COM *val_cnt = 1; 30608874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 30618874SSebastien.Roy@Sun.COM } 30628874SSebastien.Roy@Sun.COM 30638874SSebastien.Roy@Sun.COM /* ARGSUSED */ 30648874SSebastien.Roy@Sun.COM static dladm_status_t 30658453SAnurag.Maskey@Sun.COM i_dladm_flowctl_get(dladm_handle_t handle, prop_desc_t *pdp, 30668453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30678453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30685903Ssowmini { 30696789Sam223141 dld_ioc_macprop_t *dip; 30705903Ssowmini link_flowctrl_t v; 30715903Ssowmini dladm_status_t status; 30725903Ssowmini uchar_t *cp; 30735903Ssowmini 30748453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 30758275SEric Cheng &status, perm_flags); 30766512Ssowmini if (dip == NULL) 30775903Ssowmini return (status); 30788275SEric Cheng 30795903Ssowmini cp = (uchar_t *)dip->pr_val; 30805903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 30815903Ssowmini switch (v) { 30825903Ssowmini case LINK_FLOWCTRL_NONE: 30835903Ssowmini (void) sprintf(*prop_val, "no"); 30845903Ssowmini break; 30855903Ssowmini case LINK_FLOWCTRL_RX: 30865903Ssowmini (void) sprintf(*prop_val, "rx"); 30875903Ssowmini break; 30885903Ssowmini case LINK_FLOWCTRL_TX: 30895903Ssowmini (void) sprintf(*prop_val, "tx"); 30905903Ssowmini break; 30915903Ssowmini case LINK_FLOWCTRL_BI: 30925903Ssowmini (void) sprintf(*prop_val, "bi"); 30935903Ssowmini break; 30945903Ssowmini } 30955903Ssowmini free(dip); 30965903Ssowmini *val_cnt = 1; 30975903Ssowmini return (DLADM_STATUS_OK); 30985903Ssowmini } 30995903Ssowmini 31005903Ssowmini 31015903Ssowmini /* ARGSUSED */ 31025903Ssowmini static dladm_status_t 31039692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 31048453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 31058453SAnurag.Maskey@Sun.COM 31065903Ssowmini { 31077663SSowmini.Varadhan@Sun.COM int i, slen; 31087408SSebastien.Roy@Sun.COM int bufsize = 0; 31096789Sam223141 dld_ioc_macprop_t *dip = NULL; 31105903Ssowmini uchar_t *dp; 31117663SSowmini.Varadhan@Sun.COM link_attr_t *p; 31126512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 31135903Ssowmini 31145903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 31155903Ssowmini (prop_val != NULL && val_cnt == 0)) 31165903Ssowmini return (DLADM_STATUS_BADARG); 31175903Ssowmini p = dladm_name2prop(prop_name); 31186789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 31195903Ssowmini return (DLADM_STATUS_BADARG); 31205903Ssowmini 31219692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 31229692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 31239692SRishi.Srivatsavai@Sun.COM 31245903Ssowmini /* 31255903Ssowmini * private properties: all parsing is done in the kernel. 31265903Ssowmini * allocate a enough space for each property + its separator (','). 31275903Ssowmini */ 31285903Ssowmini for (i = 0; i < val_cnt; i++) { 31295903Ssowmini bufsize += strlen(prop_val[i]) + 1; 31305903Ssowmini } 31316512Ssowmini 31326512Ssowmini if (prop_val == NULL) { 31336512Ssowmini /* 31346512Ssowmini * getting default value. so use more buffer space. 31356512Ssowmini */ 31367663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 31376512Ssowmini } 31386512Ssowmini 31397663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 31406789Sam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 31415903Ssowmini if (dip == NULL) 31425903Ssowmini return (status); 31435903Ssowmini 31445903Ssowmini dp = (uchar_t *)dip->pr_val; 31455903Ssowmini slen = 0; 31467663SSowmini.Varadhan@Sun.COM 31476512Ssowmini if (prop_val == NULL) { 31488453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 31498460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 31506512Ssowmini } else { 31516512Ssowmini for (i = 0; i < val_cnt; i++) { 31526512Ssowmini int plen = 0; 31535903Ssowmini 31546512Ssowmini plen = strlen(prop_val[i]); 31556512Ssowmini bcopy(prop_val[i], dp, plen); 31566512Ssowmini slen += plen; 31576512Ssowmini /* 31586512Ssowmini * add a "," separator and update dp. 31596512Ssowmini */ 31606512Ssowmini if (i != (val_cnt -1)) 31616512Ssowmini dp[slen++] = ','; 31626512Ssowmini dp += (plen + 1); 31636512Ssowmini } 31648460SArtem.Kachitchkin@Sun.COM } 31658460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 31668453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 31676512Ssowmini 31685903Ssowmini free(dip); 31696512Ssowmini return (status); 31705903Ssowmini } 31715903Ssowmini 31725903Ssowmini static dladm_status_t 31738460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 31748453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 31758453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 31765903Ssowmini { 31777663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 31786789Sam223141 dld_ioc_macprop_t *dip = NULL; 31797663SSowmini.Varadhan@Sun.COM link_attr_t *p; 31805903Ssowmini 31815903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 31825903Ssowmini (prop_val != NULL && val_cnt == 0)) 31835903Ssowmini return (DLADM_STATUS_BADARG); 31845903Ssowmini 31855903Ssowmini p = dladm_name2prop(prop_name); 31866789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 31875903Ssowmini return (DLADM_STATUS_BADARG); 31885903Ssowmini 31895903Ssowmini /* 31905903Ssowmini * private properties: all parsing is done in the kernel. 31915903Ssowmini */ 31927663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 31937663SSowmini.Varadhan@Sun.COM dld_flags, &status); 31945903Ssowmini if (dip == NULL) 31955903Ssowmini return (status); 31965903Ssowmini 31978453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 31988453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 31998118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 32008275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 32018460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 32028460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 32038118SVasumathi.Sundaram@Sun.COM } else { 32048118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 32058118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 32068118SVasumathi.Sundaram@Sun.COM } 32075903Ssowmini *val_cnt = 1; 32088460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 32098460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 32108460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 32115903Ssowmini } 32126512Ssowmini free(dip); 32135903Ssowmini return (status); 32145903Ssowmini } 32156512Ssowmini 32166512Ssowmini 32176512Ssowmini static dladm_status_t 32188453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 32198453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 32206512Ssowmini { 32216512Ssowmini dladm_status_t status; 32226512Ssowmini char **prop_vals = NULL, *buf; 32236512Ssowmini size_t bufsize; 32246512Ssowmini uint_t cnt; 32256512Ssowmini int i; 32268118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 32276512Ssowmini 32286512Ssowmini /* 32296512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 32306512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 32316512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 32326512Ssowmini */ 32336512Ssowmini bufsize = 32346512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 32356512Ssowmini buf = malloc(bufsize); 32366512Ssowmini prop_vals = (char **)(void *)buf; 32376512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 32386512Ssowmini prop_vals[i] = buf + 32396512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 32406512Ssowmini i * DLADM_PROP_VAL_MAX; 32416512Ssowmini } 32426768Sar224390 32436768Sar224390 /* 32447342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 32457342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 32467342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 32477342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 32487342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 32497342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 32507342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 32517342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 32526768Sar224390 */ 32538453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 32548118SVasumathi.Sundaram@Sun.COM MAC_PROP_DEFAULT, &perm_flags); 32556512Ssowmini if (status == DLADM_STATUS_OK) { 32568118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 32578453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 32588453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 32598118SVasumathi.Sundaram@Sun.COM } 32608118SVasumathi.Sundaram@Sun.COM else 32618118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 32626512Ssowmini } 32636512Ssowmini free(buf); 32646512Ssowmini return (status); 32656512Ssowmini } 32667663SSowmini.Varadhan@Sun.COM 326710491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 326810491SRishi.Srivatsavai@Sun.COM static dladm_status_t 326910491SRishi.Srivatsavai@Sun.COM get_stp_prop(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 327010491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 327110491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 327210491SRishi.Srivatsavai@Sun.COM { 327310491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 327410491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 327510491SRishi.Srivatsavai@Sun.COM int val, i; 327610491SRishi.Srivatsavai@Sun.COM 327710491SRishi.Srivatsavai@Sun.COM if (flags != 0) 327810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 327910491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 328010491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 328110491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 328210491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 328310491SRishi.Srivatsavai@Sun.COM break; 328410491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 328510491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 328610491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 328710491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 328810491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 328910491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 329010491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 329110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 329210491SRishi.Srivatsavai@Sun.COM } 329310491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 329410491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 329510491SRishi.Srivatsavai@Sun.COM return (retv); 329610491SRishi.Srivatsavai@Sun.COM } 329710491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 329810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 329910491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 330010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 330110491SRishi.Srivatsavai@Sun.COM } 330210491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 330310491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 330410491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 330510491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 330610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 330710491SRishi.Srivatsavai@Sun.COM } 330810491SRishi.Srivatsavai@Sun.COM } 330910491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 331010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 331110491SRishi.Srivatsavai@Sun.COM } 331210491SRishi.Srivatsavai@Sun.COM 331310491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 331410491SRishi.Srivatsavai@Sun.COM static dladm_status_t 331510491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 331610491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 331710491SRishi.Srivatsavai@Sun.COM { 331810491SRishi.Srivatsavai@Sun.COM /* 331910491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 332010491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 332110491SRishi.Srivatsavai@Sun.COM */ 332210491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 332310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 332410491SRishi.Srivatsavai@Sun.COM 332510491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 332610491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 332710491SRishi.Srivatsavai@Sun.COM } 332810491SRishi.Srivatsavai@Sun.COM 332910491SRishi.Srivatsavai@Sun.COM /* 333010491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 333110491SRishi.Srivatsavai@Sun.COM */ 333210491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 333310491SRishi.Srivatsavai@Sun.COM static dladm_status_t 333410491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 333510491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 333610491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 333710491SRishi.Srivatsavai@Sun.COM { 333810491SRishi.Srivatsavai@Sun.COM char *cp; 333910491SRishi.Srivatsavai@Sun.COM boolean_t iscost; 334010491SRishi.Srivatsavai@Sun.COM 334110491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 334210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 334310491SRishi.Srivatsavai@Sun.COM 334410491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 334510491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 334610491SRishi.Srivatsavai@Sun.COM } else { 334710491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 334810491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 334910491SRishi.Srivatsavai@Sun.COM 335010491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 335110491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 335210491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 335310491SRishi.Srivatsavai@Sun.COM } else { 335410491SRishi.Srivatsavai@Sun.COM errno = 0; 335510491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 335610491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 335710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 335810491SRishi.Srivatsavai@Sun.COM } 335910491SRishi.Srivatsavai@Sun.COM } 336010491SRishi.Srivatsavai@Sun.COM 336110491SRishi.Srivatsavai@Sun.COM if (iscost) { 336210491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 336310491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 336410491SRishi.Srivatsavai@Sun.COM } else { 336510491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 336610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 336710491SRishi.Srivatsavai@Sun.COM /* 336810491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 336910491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 337010491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 337110491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 337210491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 337310491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 337410491SRishi.Srivatsavai@Sun.COM * can't be used now. 337510491SRishi.Srivatsavai@Sun.COM */ 337610491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 337710491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 337810491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 337910491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 338010491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 338110491SRishi.Srivatsavai@Sun.COM 338210491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 338310491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 338410491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 338510491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 338610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 338710491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 338810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 338910491SRishi.Srivatsavai@Sun.COM } 339010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 339110491SRishi.Srivatsavai@Sun.COM } 339210491SRishi.Srivatsavai@Sun.COM } 339310491SRishi.Srivatsavai@Sun.COM 339410491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 339510491SRishi.Srivatsavai@Sun.COM static dladm_status_t 339610491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 339710491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 339810491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 339910491SRishi.Srivatsavai@Sun.COM { 340010491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 340110491SRishi.Srivatsavai@Sun.COM uint_t val; 340210491SRishi.Srivatsavai@Sun.COM 340310491SRishi.Srivatsavai@Sun.COM if (flags != 0) 340410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 340510491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 340610491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 340710491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 340810491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 340910491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 341010491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 341110491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 341210491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 341310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 341410491SRishi.Srivatsavai@Sun.COM } 341510491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 341610491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 341710491SRishi.Srivatsavai@Sun.COM else 341810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 341910491SRishi.Srivatsavai@Sun.COM return (retv); 342010491SRishi.Srivatsavai@Sun.COM } 342110491SRishi.Srivatsavai@Sun.COM 342210491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 342310491SRishi.Srivatsavai@Sun.COM static dladm_status_t 342410491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 342510491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 342610491SRishi.Srivatsavai@Sun.COM { 342710491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 342810491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 342910491SRishi.Srivatsavai@Sun.COM } 343010491SRishi.Srivatsavai@Sun.COM 343110491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 343210491SRishi.Srivatsavai@Sun.COM static dladm_status_t 343310491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 343410491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 343510491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 343610491SRishi.Srivatsavai@Sun.COM { 343710491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 343810491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 343910491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 344010491SRishi.Srivatsavai@Sun.COM 344110491SRishi.Srivatsavai@Sun.COM if (flags != 0) 344210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 344310491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 344410491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 344510491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 344610491SRishi.Srivatsavai@Sun.COM 0, &status); 344710491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 344810491SRishi.Srivatsavai@Sun.COM return (status); 344910491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 345010491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 345110491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 345210491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 345310491SRishi.Srivatsavai@Sun.COM } else { 345410491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 345510491SRishi.Srivatsavai@Sun.COM } 345610491SRishi.Srivatsavai@Sun.COM free(dip); 345710491SRishi.Srivatsavai@Sun.COM return (status); 345810491SRishi.Srivatsavai@Sun.COM } 345910491SRishi.Srivatsavai@Sun.COM 346010491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 346110491SRishi.Srivatsavai@Sun.COM static dladm_status_t 346210491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 346310491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 346410491SRishi.Srivatsavai@Sun.COM { 346510491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 346610491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 346710491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 346810491SRishi.Srivatsavai@Sun.COM 346910491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 347010491SRishi.Srivatsavai@Sun.COM 0, &status); 347110491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 347210491SRishi.Srivatsavai@Sun.COM return (status); 347310491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 347410491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 347510491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 347610491SRishi.Srivatsavai@Sun.COM free(dip); 347710491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 347810491SRishi.Srivatsavai@Sun.COM return (status); 347910491SRishi.Srivatsavai@Sun.COM 348010491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 348110491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 348210491SRishi.Srivatsavai@Sun.COM } 348310491SRishi.Srivatsavai@Sun.COM 348410491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 348510491SRishi.Srivatsavai@Sun.COM static dladm_status_t 348610491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 348710491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 348810491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 348910491SRishi.Srivatsavai@Sun.COM { 349010491SRishi.Srivatsavai@Sun.COM char *cp; 349110491SRishi.Srivatsavai@Sun.COM 349210491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 349310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 349410491SRishi.Srivatsavai@Sun.COM 349510491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 349610491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 349710491SRishi.Srivatsavai@Sun.COM } else { 349810491SRishi.Srivatsavai@Sun.COM errno = 0; 349910491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 350010491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 350110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 350210491SRishi.Srivatsavai@Sun.COM } 350310491SRishi.Srivatsavai@Sun.COM 350410491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 350510491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 350610491SRishi.Srivatsavai@Sun.COM } 350710491SRishi.Srivatsavai@Sun.COM 35087663SSowmini.Varadhan@Sun.COM dladm_status_t 35098453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 35108453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 35117663SSowmini.Varadhan@Sun.COM { 35127663SSowmini.Varadhan@Sun.COM uint32_t flags; 35137663SSowmini.Varadhan@Sun.COM dladm_status_t status; 35147663SSowmini.Varadhan@Sun.COM uint32_t media; 35157663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 35167663SSowmini.Varadhan@Sun.COM void *dp; 35177663SSowmini.Varadhan@Sun.COM 35188453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 35198453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 35207663SSowmini.Varadhan@Sun.COM return (status); 35217663SSowmini.Varadhan@Sun.COM } 35227663SSowmini.Varadhan@Sun.COM 35237663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 35247663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 35257663SSowmini.Varadhan@Sun.COM 35267663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 35277663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 35287663SSowmini.Varadhan@Sun.COM 35297663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 35307663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 35317663SSowmini.Varadhan@Sun.COM 35327663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 35337663SSowmini.Varadhan@Sun.COM if (dip == NULL) 35347663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 35357663SSowmini.Varadhan@Sun.COM 35367663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 35377663SSowmini.Varadhan@Sun.COM if (set) 35387663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 35397663SSowmini.Varadhan@Sun.COM 35408453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 354110191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 35427663SSowmini.Varadhan@Sun.COM if (!set) 35437663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 35447663SSowmini.Varadhan@Sun.COM } 35457663SSowmini.Varadhan@Sun.COM 35467663SSowmini.Varadhan@Sun.COM free(dip); 35477663SSowmini.Varadhan@Sun.COM return (status); 35487663SSowmini.Varadhan@Sun.COM } 35497663SSowmini.Varadhan@Sun.COM 35508275SEric Cheng dladm_status_t 35518275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 35528275SEric Cheng { 35538460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 35548275SEric Cheng } 35558275SEric Cheng 35568275SEric Cheng /* 35578275SEric Cheng * Retrieve the one link property from the database 35588275SEric Cheng */ 35598275SEric Cheng /*ARGSUSED*/ 35608275SEric Cheng static int 35618453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 35628453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 35638275SEric Cheng { 35648275SEric Cheng dladm_arg_list_t *proplist = arg; 35658275SEric Cheng dladm_arg_info_t *aip = NULL; 35668275SEric Cheng 35678275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 35688275SEric Cheng /* 35698275SEric Cheng * it is fine to point to prop_name since prop_name points to the 35708275SEric Cheng * prop_table[n].pd_name. 35718275SEric Cheng */ 35728275SEric Cheng aip->ai_name = prop_name; 35738275SEric Cheng 35748453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 35758453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 35768275SEric Cheng 35778275SEric Cheng if (aip->ai_count != 0) 35788275SEric Cheng proplist->al_count++; 35798275SEric Cheng 35808275SEric Cheng return (DLADM_WALK_CONTINUE); 35818275SEric Cheng } 35828275SEric Cheng 35838275SEric Cheng 35848275SEric Cheng /* 35858275SEric Cheng * Retrieve all link properties for a link from the database and 35868275SEric Cheng * return a property list. 35878275SEric Cheng */ 35888275SEric Cheng dladm_status_t 35898453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 35908453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 35918275SEric Cheng { 35928275SEric Cheng dladm_arg_list_t *list; 35938275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 35948275SEric Cheng 35958275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 35968275SEric Cheng if (list == NULL) 35978275SEric Cheng return (dladm_errno2status(errno)); 35988275SEric Cheng 35998453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 36008453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 36018275SEric Cheng 36028275SEric Cheng *listp = list; 36038275SEric Cheng return (status); 36048275SEric Cheng } 36058275SEric Cheng 36068275SEric Cheng /* 36078275SEric Cheng * Retrieve the named property from a proplist, check the value and 36088275SEric Cheng * convert to a kernel structure. 36098275SEric Cheng */ 36108275SEric Cheng static dladm_status_t 36118453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 3612*10734SEric Cheng dladm_arg_list_t *proplist, const char *name, void *arg) 36138275SEric Cheng { 36148275SEric Cheng dladm_status_t status; 36158275SEric Cheng dladm_arg_info_t *aip = NULL; 36168275SEric Cheng int i, j; 36178275SEric Cheng 36188275SEric Cheng /* Find named property in proplist */ 36198275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 36208275SEric Cheng aip = &proplist->al_info[i]; 36218275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 36228275SEric Cheng break; 36238275SEric Cheng } 36248275SEric Cheng 36258275SEric Cheng /* Property not in list */ 36268275SEric Cheng if (i == proplist->al_count) 36278275SEric Cheng return (DLADM_STATUS_OK); 36288275SEric Cheng 36298275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 36308275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 36318275SEric Cheng val_desc_t *vdp; 36328275SEric Cheng 36338275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 36348275SEric Cheng if (vdp == NULL) 36358275SEric Cheng return (DLADM_STATUS_NOMEM); 36368275SEric Cheng 36378275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 36388275SEric Cheng continue; 36398275SEric Cheng 36408275SEric Cheng if (aip->ai_val == NULL) 36418275SEric Cheng return (DLADM_STATUS_BADARG); 36428275SEric Cheng 36438275SEric Cheng /* Check property value */ 36448275SEric Cheng if (pdp->pd_check != NULL) { 36458453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 36468275SEric Cheng aip->ai_count, vdp, 0); 36478275SEric Cheng } else { 36488275SEric Cheng status = DLADM_STATUS_BADARG; 36498275SEric Cheng } 36508275SEric Cheng 36518275SEric Cheng if (status != DLADM_STATUS_OK) 36528275SEric Cheng return (status); 36538275SEric Cheng 36548275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 36558275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 36568275SEric Cheng 36578275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 36588275SEric Cheng continue; 36598275SEric Cheng 36608275SEric Cheng /* Extract kernel structure */ 36618275SEric Cheng if (rpp->rp_extract != NULL) { 3662*10734SEric Cheng status = rpp->rp_extract(vdp, 3663*10734SEric Cheng aip->ai_count, arg); 36648275SEric Cheng } else { 36658275SEric Cheng status = DLADM_STATUS_BADARG; 36668275SEric Cheng } 36678275SEric Cheng break; 36688275SEric Cheng } 36698275SEric Cheng 36708275SEric Cheng if (status != DLADM_STATUS_OK) 36718275SEric Cheng return (status); 36728275SEric Cheng 36738275SEric Cheng break; 36748275SEric Cheng } 36758275SEric Cheng return (status); 36768275SEric Cheng } 36778275SEric Cheng 36788275SEric Cheng /* 36798275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 36808275SEric Cheng */ 36818275SEric Cheng dladm_status_t 36828453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 36838275SEric Cheng mac_resource_props_t *mrp) 36848275SEric Cheng { 3685*10734SEric Cheng dladm_status_t status; 3686*10734SEric Cheng int i; 3687*10734SEric Cheng 3688*10734SEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 3689*10734SEric Cheng status = i_dladm_link_proplist_extract_one(handle, 3690*10734SEric Cheng proplist, rsrc_prop_table[i].rp_name, mrp); 3691*10734SEric Cheng if (status != DLADM_STATUS_OK) 3692*10734SEric Cheng return (status); 3693*10734SEric Cheng } 36948275SEric Cheng return (status); 36958275SEric Cheng } 36968275SEric Cheng 36978275SEric Cheng static const char * 36988275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 36998275SEric Cheng { 37008275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 37018275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 37028275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 37038275SEric Cheng return (buf); 37048275SEric Cheng } 37058306SSowmini.Varadhan@Sun.COM 37068306SSowmini.Varadhan@Sun.COM dladm_status_t 37078453SAnurag.Maskey@Sun.COM i_dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 37088453SAnurag.Maskey@Sun.COM link_state_t *state) 37098306SSowmini.Varadhan@Sun.COM { 37108306SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 37118306SSowmini.Varadhan@Sun.COM dladm_status_t status; 37128306SSowmini.Varadhan@Sun.COM uint_t perms; 37138306SSowmini.Varadhan@Sun.COM 37148453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, "state", 0, &status, 37158453SAnurag.Maskey@Sun.COM &perms); 37168306SSowmini.Varadhan@Sun.COM if (status != DLADM_STATUS_OK) 37178306SSowmini.Varadhan@Sun.COM return (status); 37188306SSowmini.Varadhan@Sun.COM (void) memcpy(state, dip->pr_val, sizeof (*state)); 37198306SSowmini.Varadhan@Sun.COM free(dip); 37208306SSowmini.Varadhan@Sun.COM return (status); 37218306SSowmini.Varadhan@Sun.COM } 37228460SArtem.Kachitchkin@Sun.COM 37238460SArtem.Kachitchkin@Sun.COM boolean_t 37248460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 37258460SArtem.Kachitchkin@Sun.COM { 37268460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 37278460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 37288460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 37298460SArtem.Kachitchkin@Sun.COM "name", 37308460SArtem.Kachitchkin@Sun.COM "class", 37318460SArtem.Kachitchkin@Sun.COM "media", 37328460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 37338460SArtem.Kachitchkin@Sun.COM FPHYINST, 37348460SArtem.Kachitchkin@Sun.COM FDEVNAME, 37358460SArtem.Kachitchkin@Sun.COM 37368460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 37378460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 37388460SArtem.Kachitchkin@Sun.COM }; 37398460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 37408460SArtem.Kachitchkin@Sun.COM int i; 37418460SArtem.Kachitchkin@Sun.COM 37428460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 37438460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 37448460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 37458460SArtem.Kachitchkin@Sun.COM break; 37468460SArtem.Kachitchkin@Sun.COM } 37478460SArtem.Kachitchkin@Sun.COM } 37488460SArtem.Kachitchkin@Sun.COM 37498460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 37508460SArtem.Kachitchkin@Sun.COM } 3751