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, 14110734SEric Cheng get_bridge_pvid, 14210734SEric Cheng /* the above need to be renamed to "do_get_xxx" */ 14310734SEric 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, 14810734SEric Cheng set_stp_prop, set_bridge_forward, set_bridge_pvid, 14910734SEric 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, 15410734SEric Cheng do_check_priority, check_stp_prop, check_bridge_pvid, 15510734SEric 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 34710734SEric Cheng { MAC_PROP_PROTECT, sizeof (mac_resource_props_t), "protection"}, 34810734SEric 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 39610734SEric Cheng static val_desc_t link_protect_vals[] = { 39710734SEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 39810734SEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 39910734SEric Cheng { "restricted", MPT_RESTRICTED } 40010734SEric Cheng }; 40110734SEric 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 }, 63510734SEric Cheng 63610734SEric Cheng { "protection", { "--", RESET_VAL }, 63710734SEric Cheng link_protect_vals, VALCNT(link_protect_vals), 63810734SEric Cheng do_set_protection, NULL, do_get_protection, do_check_prop, 0, 63910734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 64010734SEric Cheng 64110734SEric Cheng { "allowed-ips", { "--", 0 }, 64210734SEric Cheng NULL, 0, do_set_protection, NULL, 64310734SEric Cheng do_get_protection, do_check_allowedips, 0, 64410734SEric 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}, 65210734SEric Cheng {"cpus", do_extract_cpus}, 65310734SEric Cheng {"protection", do_extract_protection}, 65410734SEric 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 69210734SEric Cheng /* ARGSUSED */ 6935895Syz147064 static dladm_status_t 69410734SEric Cheng do_check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 69510734SEric 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++) { 70110734SEric Cheng if (strcasecmp(prop_val[j], 7025895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 7035895Syz147064 break; 7045895Syz147064 } 7055895Syz147064 } 70610734SEric Cheng if (i == pdp->pd_noptval) 70710734SEric Cheng return (DLADM_STATUS_BADVAL); 70810734SEric Cheng 70910734SEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 7105895Syz147064 } 71110734SEric 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) { 74910734SEric Cheng status = do_check_prop(handle, pdp, linkid, prop_val, 75010734SEric 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 { 1214*11021SEric.Cheng@Sun.COM char *buf, **propvals; 1215*11021SEric.Cheng@Sun.COM uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 1216*11021SEric.Cheng@Sun.COM dladm_status_t status, *retval = arg; 12175895Syz147064 12185895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 12195895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 12205895Syz147064 return (DLADM_WALK_CONTINUE); 12215895Syz147064 } 12225895Syz147064 12235895Syz147064 propvals = (char **)(void *)buf; 12245895Syz147064 for (i = 0; i < valcnt; i++) { 12255895Syz147064 propvals[i] = buf + 12265895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 12275895Syz147064 i * DLADM_PROP_VAL_MAX; 12285895Syz147064 } 12295895Syz147064 12308453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 12318453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 12325895Syz147064 goto done; 12335895Syz147064 } 12345895Syz147064 1235*11021SEric.Cheng@Sun.COM status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 1236*11021SEric.Cheng@Sun.COM valcnt, DLADM_OPT_ACTIVE); 1237*11021SEric.Cheng@Sun.COM if (status != DLADM_STATUS_OK) 1238*11021SEric.Cheng@Sun.COM *retval = status; 12395895Syz147064 12405895Syz147064 done: 12415895Syz147064 if (buf != NULL) 12425895Syz147064 free(buf); 12435895Syz147064 12445895Syz147064 return (DLADM_WALK_CONTINUE); 12455895Syz147064 } 12465895Syz147064 12475895Syz147064 /*ARGSUSED*/ 12485895Syz147064 static int 12498453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 12505895Syz147064 { 12518275SEric Cheng datalink_class_t class; 12528275SEric Cheng dladm_status_t status; 12538275SEric Cheng 12548453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 12558453SAnurag.Maskey@Sun.COM NULL, 0); 12568275SEric Cheng if (status != DLADM_STATUS_OK) 12578275SEric Cheng return (DLADM_WALK_TERMINATE); 12588275SEric Cheng 12598275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 12608453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 12618275SEric Cheng 12625895Syz147064 return (DLADM_WALK_CONTINUE); 12635895Syz147064 } 12645895Syz147064 12655895Syz147064 dladm_status_t 12668453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 12678453SAnurag.Maskey@Sun.COM boolean_t any_media) 12685895Syz147064 { 1269*11021SEric.Cheng@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 12706916Sartem datalink_media_t dmedia; 12716916Sartem uint32_t media; 12726916Sartem 12736916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 12746916Sartem 12755895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 12768453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 12778453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 12788453SAnurag.Maskey@Sun.COM } else if (any_media || 12798453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 12808453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 12816916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 1282*11021SEric.Cheng@Sun.COM (void) dladm_walk_linkprop(handle, linkid, &status, 12838453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 12843448Sdh155122 } 1285*11021SEric.Cheng@Sun.COM return (status); 12863147Sxc151355 } 12873147Sxc151355 12885903Ssowmini /* ARGSUSED */ 12895895Syz147064 static dladm_status_t 12908453SAnurag.Maskey@Sun.COM do_get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 12918275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 12928275SEric Cheng uint_t flags, uint_t *perm_flags) 12933147Sxc151355 { 12948275SEric Cheng char zone_name[ZONENAME_MAX]; 12958275SEric Cheng zoneid_t zid; 12968275SEric Cheng dladm_status_t status; 12978275SEric Cheng char *cp; 12987342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 12993147Sxc151355 13006512Ssowmini if (flags != 0) 13016512Ssowmini return (DLADM_STATUS_NOTSUP); 13026512Ssowmini 13038453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 13048275SEric Cheng &status, perm_flags); 13055895Syz147064 if (status != DLADM_STATUS_OK) 13063448Sdh155122 return (status); 13073448Sdh155122 13087342SAruna.Ramakrishna@Sun.COM cp = dip->pr_val; 13097342SAruna.Ramakrishna@Sun.COM (void) memcpy(&zid, cp, sizeof (zid)); 13107342SAruna.Ramakrishna@Sun.COM free(dip); 13117342SAruna.Ramakrishna@Sun.COM 13125895Syz147064 *val_cnt = 1; 13135895Syz147064 if (zid != GLOBAL_ZONEID) { 13148118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 13155895Syz147064 return (dladm_errno2status(errno)); 13168118SVasumathi.Sundaram@Sun.COM } 13173147Sxc151355 13185895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 13193147Sxc151355 } else { 13205895Syz147064 *prop_val[0] = '\0'; 13213147Sxc151355 } 13223147Sxc151355 13233448Sdh155122 return (DLADM_STATUS_OK); 13243448Sdh155122 } 13253448Sdh155122 13263448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 13273448Sdh155122 13283448Sdh155122 static int 13293448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 13303448Sdh155122 { 13313448Sdh155122 char root[MAXPATHLEN]; 13323448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 13333448Sdh155122 void *dlhandle; 13343448Sdh155122 void *sym; 13353448Sdh155122 int ret; 13363448Sdh155122 13373448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 13383448Sdh155122 return (-1); 13393448Sdh155122 13403448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 13413448Sdh155122 (void) dlclose(dlhandle); 13423448Sdh155122 return (-1); 13433448Sdh155122 } 13443448Sdh155122 13453448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 13463448Sdh155122 13473448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 13483448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 13493448Sdh155122 (void) dlclose(dlhandle); 13503448Sdh155122 return (ret); 13513448Sdh155122 } 13523448Sdh155122 13533448Sdh155122 static dladm_status_t 13548453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 13558453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 13563448Sdh155122 { 13573448Sdh155122 char path[MAXPATHLEN]; 13585895Syz147064 char name[MAXLINKNAMELEN]; 13593448Sdh155122 di_prof_t prof = NULL; 13603448Sdh155122 char zone_name[ZONENAME_MAX]; 13613448Sdh155122 dladm_status_t status; 13625895Syz147064 int ret; 13633448Sdh155122 13643448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 13653448Sdh155122 return (dladm_errno2status(errno)); 13663448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 13673448Sdh155122 return (dladm_errno2status(errno)); 13683448Sdh155122 if (di_prof_init(path, &prof) != 0) 13693448Sdh155122 return (dladm_errno2status(errno)); 13703448Sdh155122 13718453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 13725895Syz147064 if (status != DLADM_STATUS_OK) 13735895Syz147064 goto cleanup; 13745895Syz147064 13755895Syz147064 if (add) 13765895Syz147064 ret = di_prof_add_dev(prof, name); 13775895Syz147064 else 13785895Syz147064 ret = di_prof_add_exclude(prof, name); 13795895Syz147064 13805895Syz147064 if (ret != 0) { 13813448Sdh155122 status = dladm_errno2status(errno); 13823448Sdh155122 goto cleanup; 13833448Sdh155122 } 13843448Sdh155122 13853448Sdh155122 if (di_prof_commit(prof) != 0) 13863448Sdh155122 status = dladm_errno2status(errno); 13873448Sdh155122 cleanup: 13883448Sdh155122 if (prof) 13893448Sdh155122 di_prof_fini(prof); 13903448Sdh155122 13913448Sdh155122 return (status); 13923448Sdh155122 } 13933448Sdh155122 13945903Ssowmini /* ARGSUSED */ 13953448Sdh155122 static dladm_status_t 13968453SAnurag.Maskey@Sun.COM do_set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13978453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 13983448Sdh155122 { 13998275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 14008275SEric Cheng zoneid_t zid_old, zid_new; 14018275SEric Cheng char *cp; 14027342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 14037342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14043448Sdh155122 14053448Sdh155122 if (val_cnt != 1) 14063448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14073448Sdh155122 14087342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 14097342SAruna.Ramakrishna@Sun.COM 14108453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 14118275SEric Cheng &status, NULL); 14128275SEric Cheng if (status != DLADM_STATUS_OK) 14138275SEric Cheng return (status); 14148275SEric Cheng 14158275SEric Cheng cp = dip->pr_val; 14168275SEric Cheng (void) memcpy(&zid_old, cp, sizeof (zid_old)); 14178275SEric Cheng free(dip); 14187342SAruna.Ramakrishna@Sun.COM 14197342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 14203448Sdh155122 if (zid_new == zid_old) 142110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 142210616SSebastien.Roy@Sun.COM 142310616SSebastien.Roy@Sun.COM if ((status = i_dladm_set_public_prop(handle, pdp, linkid, vdp, val_cnt, 142410616SSebastien.Roy@Sun.COM flags, media)) != DLADM_STATUS_OK) 14255895Syz147064 return (status); 14265895Syz147064 142710616SSebastien.Roy@Sun.COM /* 142810616SSebastien.Roy@Sun.COM * It is okay to fail to update the /dev entry (some vanity-named 142910616SSebastien.Roy@Sun.COM * links do not have a /dev entry). 143010616SSebastien.Roy@Sun.COM */ 14313448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 14328453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 14338453SAnurag.Maskey@Sun.COM B_FALSE); 14345895Syz147064 } 143510616SSebastien.Roy@Sun.COM if (zid_new != GLOBAL_ZONEID) 14368453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 14373448Sdh155122 14383448Sdh155122 return (DLADM_STATUS_OK); 14393448Sdh155122 } 14403448Sdh155122 14413448Sdh155122 /* ARGSUSED */ 14423448Sdh155122 static dladm_status_t 14438453SAnurag.Maskey@Sun.COM do_check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14448453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 14453448Sdh155122 { 14467342SAruna.Ramakrishna@Sun.COM char *zone_name; 14477342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 14487342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 14497342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14503448Sdh155122 14513448Sdh155122 if (val_cnt != 1) 14523448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14533448Sdh155122 14547342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 14557342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 14567342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 14573448Sdh155122 14588275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 14597342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 14607342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14617342SAruna.Ramakrishna@Sun.COM goto done; 14627342SAruna.Ramakrishna@Sun.COM } 14637342SAruna.Ramakrishna@Sun.COM 14647342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 14653448Sdh155122 ushort_t flags; 14663448Sdh155122 14677342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 14683448Sdh155122 sizeof (flags)) < 0) { 14697342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 14707342SAruna.Ramakrishna@Sun.COM goto done; 14713448Sdh155122 } 14723448Sdh155122 14733448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 14747342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 14757342SAruna.Ramakrishna@Sun.COM goto done; 14763448Sdh155122 } 14773448Sdh155122 } 14783448Sdh155122 14797342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 14807342SAruna.Ramakrishna@Sun.COM 14817342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 148210616SSebastien.Roy@Sun.COM dzp->diz_linkid = linkid; 14837342SAruna.Ramakrishna@Sun.COM 14847342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 14855895Syz147064 return (DLADM_STATUS_OK); 14867342SAruna.Ramakrishna@Sun.COM done: 14877342SAruna.Ramakrishna@Sun.COM free(dzp); 14887342SAruna.Ramakrishna@Sun.COM return (status); 14895895Syz147064 } 14905895Syz147064 14915903Ssowmini /* ARGSUSED */ 14925895Syz147064 static dladm_status_t 14938460SArtem.Kachitchkin@Sun.COM i_dladm_maxbw_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14948275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 14958275SEric Cheng uint_t flags, uint_t *perm_flags) 14968275SEric Cheng { 14978275SEric Cheng dld_ioc_macprop_t *dip; 14988275SEric Cheng mac_resource_props_t mrp; 14998275SEric Cheng dladm_status_t status; 15008275SEric Cheng 15018453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15028275SEric Cheng &status, perm_flags); 15038275SEric Cheng if (dip == NULL) 15048275SEric Cheng return (status); 15058275SEric Cheng 15068275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 15078275SEric Cheng free(dip); 15088275SEric Cheng 15098275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 15108275SEric Cheng (*prop_val)[0] = '\0'; 15118275SEric Cheng } else { 15128275SEric Cheng (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 15138275SEric Cheng } 15148275SEric Cheng *val_cnt = 1; 15158275SEric Cheng return (DLADM_STATUS_OK); 15168275SEric Cheng } 15178275SEric Cheng 15188275SEric Cheng /* ARGSUSED */ 15198275SEric Cheng static dladm_status_t 15208453SAnurag.Maskey@Sun.COM do_check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15218453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 15228275SEric Cheng { 15238275SEric Cheng uint64_t *maxbw; 15248275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 15258275SEric Cheng 15268275SEric Cheng if (val_cnt != 1) 15278275SEric Cheng return (DLADM_STATUS_BADVALCNT); 15288275SEric Cheng 15298275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 15308275SEric Cheng if (maxbw == NULL) 15318275SEric Cheng return (DLADM_STATUS_NOMEM); 15328275SEric Cheng 15338275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 15348275SEric Cheng if (status != DLADM_STATUS_OK) { 15358275SEric Cheng free(maxbw); 15368275SEric Cheng return (status); 15378275SEric Cheng } 15388275SEric Cheng 15398275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 15408275SEric Cheng free(maxbw); 15418275SEric Cheng return (DLADM_STATUS_MINMAXBW); 15428275SEric Cheng } 15438275SEric Cheng 15448275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 15458275SEric Cheng return (DLADM_STATUS_OK); 15468275SEric Cheng } 15478275SEric Cheng 15488275SEric Cheng /* ARGSUSED */ 15498275SEric Cheng dladm_status_t 155010734SEric Cheng do_extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 15518275SEric Cheng { 155210734SEric Cheng mac_resource_props_t *mrp = arg; 15538275SEric Cheng 15548275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 15558275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 15568275SEric Cheng 15578275SEric Cheng return (DLADM_STATUS_OK); 15588275SEric Cheng } 15598275SEric Cheng 15608275SEric Cheng /* ARGSUSED */ 15618275SEric Cheng static dladm_status_t 15628460SArtem.Kachitchkin@Sun.COM i_dladm_cpus_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15638275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15648275SEric Cheng uint_t flags, uint_t *perm_flags) 15658275SEric Cheng { 15668275SEric Cheng dld_ioc_macprop_t *dip; 15678275SEric Cheng mac_resource_props_t mrp; 15688275SEric Cheng int i; 15698275SEric Cheng uint32_t ncpus; 15708275SEric Cheng uchar_t *cp; 15718275SEric Cheng dladm_status_t status; 15728275SEric Cheng 15738453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15748275SEric Cheng &status, perm_flags); 15758275SEric Cheng if (dip == NULL) 15768275SEric Cheng return (status); 15778275SEric Cheng 15788275SEric Cheng cp = (uchar_t *)dip->pr_val; 15798275SEric Cheng (void) memcpy(&mrp, cp, sizeof (mac_resource_props_t)); 15808275SEric Cheng free(dip); 15818275SEric Cheng 15828275SEric Cheng ncpus = mrp.mrp_ncpus; 15838275SEric Cheng 15848275SEric Cheng if (ncpus > *val_cnt) 15858275SEric Cheng return (DLADM_STATUS_TOOSMALL); 15868275SEric Cheng 15878275SEric Cheng if (ncpus == 0) { 15888275SEric Cheng (*prop_val)[0] = '\0'; 15898275SEric Cheng *val_cnt = 1; 15908275SEric Cheng return (DLADM_STATUS_OK); 15918275SEric Cheng } 15928275SEric Cheng 15938275SEric Cheng *val_cnt = ncpus; 15948275SEric Cheng for (i = 0; i < ncpus; i++) { 15958275SEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 15968275SEric Cheng "%u", mrp.mrp_cpu[i]); 15978275SEric Cheng } 15988275SEric Cheng return (DLADM_STATUS_OK); 15998275SEric Cheng } 16008275SEric Cheng 16018275SEric Cheng /* ARGSUSED */ 16028275SEric Cheng static dladm_status_t 16038453SAnurag.Maskey@Sun.COM do_set_res(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16048453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16058275SEric Cheng { 16068275SEric Cheng mac_resource_props_t mrp; 16078275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 16088275SEric Cheng dld_ioc_macprop_t *dip; 16098275SEric Cheng 16108275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 16118275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 16128275SEric Cheng flags, &status); 16138275SEric Cheng 16148275SEric Cheng if (dip == NULL) 16158275SEric Cheng return (status); 16168275SEric Cheng 16178275SEric Cheng if (vdp->vd_val == RESET_VAL) { 16188275SEric Cheng switch (dip->pr_num) { 16198275SEric Cheng case MAC_PROP_MAXBW: 16208275SEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 16218275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16228275SEric Cheng break; 16238275SEric Cheng case MAC_PROP_PRIO: 16248275SEric Cheng mrp.mrp_priority = MPL_RESET; 16258275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16268275SEric Cheng break; 16278275SEric Cheng default: 16288275SEric Cheng free(dip); 16298275SEric Cheng return (DLADM_STATUS_BADARG); 16308275SEric Cheng } 16318275SEric Cheng } else { 16328275SEric Cheng switch (dip->pr_num) { 16338275SEric Cheng case MAC_PROP_MAXBW: 16348275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_maxbw, 16358275SEric Cheng sizeof (uint64_t)); 16368275SEric Cheng mrp.mrp_mask = MRP_MAXBW; 16378275SEric Cheng break; 16388275SEric Cheng case MAC_PROP_PRIO: 16398275SEric Cheng bcopy((void *)vdp->vd_val, &mrp.mrp_priority, 16408275SEric Cheng sizeof (mac_priority_level_t)); 16418275SEric Cheng mrp.mrp_mask = MRP_PRIORITY; 16428275SEric Cheng break; 16438275SEric Cheng default: 16448275SEric Cheng free(dip); 16458275SEric Cheng return (DLADM_STATUS_BADARG); 16468275SEric Cheng } 16478275SEric Cheng } 16488275SEric Cheng 16498275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 16508453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 16518275SEric Cheng free(dip); 16528275SEric Cheng return (status); 16538275SEric Cheng } 16548275SEric Cheng 16558275SEric Cheng /* ARGSUSED */ 16568275SEric Cheng static dladm_status_t 16578453SAnurag.Maskey@Sun.COM do_set_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16588453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 16598275SEric Cheng { 16608275SEric Cheng mac_resource_props_t mrp; 16618275SEric Cheng dladm_status_t status; 16628275SEric Cheng dld_ioc_macprop_t *dip; 16638275SEric Cheng datalink_class_t class; 16648275SEric Cheng 16658275SEric Cheng /* 16668275SEric Cheng * CPU bindings can be set on VNIC and regular physical links. 16678275SEric Cheng * However VNICs fails the dladm_phys_info test(). So apply 16688275SEric Cheng * the phys_info test only on physical links. 16698275SEric Cheng */ 16708453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, 16718275SEric Cheng NULL, NULL, 0)) != DLADM_STATUS_OK) { 16728275SEric Cheng return (status); 16738275SEric Cheng } 16748275SEric Cheng 16758275SEric Cheng /* 16768275SEric Cheng * We set intr_cpu to -1. The interrupt will be retargetted, 16778275SEric Cheng * if possible when the setup is complete in MAC. 16788275SEric Cheng */ 16798275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 16808275SEric Cheng mrp.mrp_mask = MRP_CPUS; 16818275SEric Cheng if (vdp != NULL && vdp->vd_val != RESET_VAL) { 16828275SEric Cheng mac_resource_props_t *vmrp; 16838275SEric Cheng 16848275SEric Cheng vmrp = (mac_resource_props_t *)vdp->vd_val; 16858275SEric Cheng if (vmrp->mrp_ncpus > 0) { 16868275SEric Cheng bcopy(vmrp, &mrp, sizeof (mac_resource_props_t)); 16878275SEric Cheng mrp.mrp_mask = MRP_CPUS; 16888275SEric Cheng } 16898275SEric Cheng mrp.mrp_mask |= MRP_CPUS_USERSPEC; 16908275SEric Cheng mrp.mrp_fanout_mode = MCM_CPUS; 16918275SEric Cheng mrp.mrp_intr_cpu = -1; 16928275SEric Cheng } 16938275SEric Cheng 16948275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 16958275SEric Cheng flags, &status); 16968275SEric Cheng if (dip == NULL) 16978275SEric Cheng return (status); 16988275SEric Cheng 16998275SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 17008453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 17018275SEric Cheng free(dip); 17028275SEric Cheng return (status); 17038275SEric Cheng } 17048275SEric Cheng 17058275SEric Cheng /* ARGSUSED */ 17068275SEric Cheng static dladm_status_t 17078453SAnurag.Maskey@Sun.COM do_check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 17088453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 17098275SEric Cheng { 17108275SEric Cheng uint32_t cpuid; 17118275SEric Cheng int i, j, rc; 17128275SEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 17138275SEric Cheng mac_resource_props_t *mrp; 17148275SEric Cheng 17158275SEric Cheng mrp = malloc(sizeof (mac_resource_props_t)); 17168275SEric Cheng if (mrp == NULL) 17178275SEric Cheng return (DLADM_STATUS_NOMEM); 17188275SEric Cheng 17198275SEric Cheng for (i = 0; i < val_cnt; i++) { 17208275SEric Cheng errno = 0; 17218275SEric Cheng cpuid = strtol(prop_val[i], (char **)NULL, 10); 17228275SEric Cheng if (errno != 0 || cpuid >= nproc) { 17238275SEric Cheng free(mrp); 17248275SEric Cheng return (DLADM_STATUS_CPUMAX); 17258275SEric Cheng } 17268275SEric Cheng rc = p_online(cpuid, P_STATUS); 17278275SEric Cheng if (rc < 1) { 17288275SEric Cheng free(mrp); 17298275SEric Cheng return (DLADM_STATUS_CPUERR); 17308275SEric Cheng } 17318275SEric Cheng if (rc != P_ONLINE) { 17328275SEric Cheng free(mrp); 17338275SEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 17348275SEric Cheng } 17358275SEric Cheng mrp->mrp_cpu[i] = cpuid; 17368275SEric Cheng } 17378275SEric Cheng mrp->mrp_ncpus = (uint32_t)val_cnt; 17388275SEric Cheng 17398275SEric Cheng /* Check for duplicates */ 17408275SEric Cheng for (i = 0; i < val_cnt; i++) { 17418275SEric Cheng for (j = 0; j < val_cnt; j++) { 17428275SEric Cheng if (i != j && mrp->mrp_cpu[i] == mrp->mrp_cpu[j]) { 17438275SEric Cheng free(mrp); 17448275SEric Cheng return (DLADM_STATUS_BADARG); 17458275SEric Cheng } 17468275SEric Cheng } 17478275SEric Cheng } 17488275SEric Cheng vdp->vd_val = (uintptr_t)mrp; 17498275SEric Cheng 17508275SEric Cheng return (DLADM_STATUS_OK); 17518275SEric Cheng } 17528275SEric Cheng 17538275SEric Cheng /* ARGSUSED */ 17548275SEric Cheng dladm_status_t 175510734SEric Cheng do_extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 17568275SEric Cheng { 175710734SEric Cheng mac_resource_props_t *mrp = arg; 17588275SEric Cheng mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; 17598275SEric Cheng int i; 17608275SEric Cheng 17618275SEric Cheng for (i = 0; i < vmrp->mrp_ncpus; i++) { 17628275SEric Cheng mrp->mrp_cpu[i] = vmrp->mrp_cpu[i]; 17638275SEric Cheng } 17648275SEric Cheng mrp->mrp_ncpus = vmrp->mrp_ncpus; 17658275SEric Cheng mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 17668275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 17679055SMichael.Lim@Sun.COM mrp->mrp_intr_cpu = -1; 17688275SEric Cheng 17698275SEric Cheng return (DLADM_STATUS_OK); 17708275SEric Cheng } 17718275SEric Cheng 17728275SEric Cheng /* ARGSUSED */ 17738275SEric Cheng static dladm_status_t 17748460SArtem.Kachitchkin@Sun.COM i_dladm_priority_get(dladm_handle_t handle, prop_desc_t *pdp, 17758460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 17768460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 17778275SEric Cheng { 17788275SEric Cheng dld_ioc_macprop_t *dip; 17798275SEric Cheng mac_resource_props_t mrp; 17808275SEric Cheng mac_priority_level_t pri; 17818275SEric Cheng dladm_status_t status; 17828275SEric Cheng 17838453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 17848275SEric Cheng &status, perm_flags); 17858275SEric Cheng if (dip == NULL) 17868275SEric Cheng return (status); 17878275SEric Cheng 17888275SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 17898275SEric Cheng free(dip); 17908275SEric Cheng 17918275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 17928275SEric Cheng mrp.mrp_priority; 17938275SEric Cheng 17948275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 17958275SEric Cheng *val_cnt = 1; 17968275SEric Cheng return (DLADM_STATUS_OK); 17978275SEric Cheng } 17988275SEric Cheng 17998275SEric Cheng /* ARGSUSED */ 18008275SEric Cheng static dladm_status_t 18018453SAnurag.Maskey@Sun.COM do_check_priority(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18028453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 18038275SEric Cheng { 18048275SEric Cheng mac_priority_level_t *pri; 18058275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 18068275SEric Cheng 18078275SEric Cheng if (val_cnt != 1) 18088275SEric Cheng return (DLADM_STATUS_BADVALCNT); 18098275SEric Cheng 18108275SEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 18118275SEric Cheng if (pri == NULL) 18128275SEric Cheng return (DLADM_STATUS_NOMEM); 18138275SEric Cheng 18148275SEric Cheng status = dladm_str2pri(*prop_val, pri); 18158275SEric Cheng if (status != DLADM_STATUS_OK) { 18168275SEric Cheng free(pri); 18178275SEric Cheng return (status); 18188275SEric Cheng } 18198275SEric Cheng 18208275SEric Cheng if (*pri < MPL_LOW || *pri > MPL_HIGH) { 18218275SEric Cheng free(pri); 18228275SEric Cheng return (DLADM_STATUS_BADVAL); 18238275SEric Cheng } 18248275SEric Cheng 18258275SEric Cheng vdp->vd_val = (uintptr_t)pri; 18268275SEric Cheng return (DLADM_STATUS_OK); 18278275SEric Cheng } 18288275SEric Cheng 18298275SEric Cheng /* ARGSUSED */ 18308275SEric Cheng dladm_status_t 183110734SEric Cheng do_extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 18328275SEric Cheng { 183310734SEric Cheng mac_resource_props_t *mrp = arg; 18348275SEric Cheng 18358275SEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_priority, 18368275SEric Cheng sizeof (mac_priority_level_t)); 18378275SEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 18388275SEric Cheng 18398275SEric Cheng return (DLADM_STATUS_OK); 18408275SEric Cheng } 18418275SEric Cheng 18428275SEric Cheng /* ARGSUSED */ 18438275SEric Cheng static dladm_status_t 184410734SEric Cheng do_set_protection(dladm_handle_t handle, prop_desc_t *pdp, 184510734SEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 184610734SEric Cheng uint_t flags, datalink_media_t media) 184710734SEric Cheng { 184810734SEric Cheng mac_resource_props_t mrp; 184910734SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 185010734SEric Cheng dld_ioc_macprop_t *dip; 185110734SEric Cheng 185210734SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 185310734SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, "protection", 185410734SEric Cheng flags, &status); 185510734SEric Cheng 185610734SEric Cheng if (dip == NULL) 185710734SEric Cheng return (status); 185810734SEric Cheng 185910734SEric Cheng if (strcmp(pdp->pd_name, "protection") == 0) { 186010734SEric Cheng status = do_extract_protection(vdp, val_cnt, &mrp); 186110734SEric Cheng if (status != DLADM_STATUS_OK) 186210734SEric Cheng goto done; 186310734SEric Cheng 186410734SEric Cheng } else if (strcmp(pdp->pd_name, "allowed-ips") == 0) { 186510734SEric Cheng status = do_extract_allowedips(vdp, val_cnt, &mrp); 186610734SEric Cheng if (status != DLADM_STATUS_OK) 186710734SEric Cheng goto done; 186810734SEric Cheng } else { 186910734SEric Cheng status = DLADM_STATUS_BADARG; 187010734SEric Cheng goto done; 187110734SEric Cheng } 187210734SEric Cheng 187310734SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 187410734SEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 187510734SEric Cheng 187610734SEric Cheng done: 187710734SEric Cheng free(dip); 187810734SEric Cheng return (status); 187910734SEric Cheng } 188010734SEric Cheng 188110734SEric Cheng /* ARGSUSED */ 188210734SEric Cheng static dladm_status_t 188310734SEric Cheng do_get_protection(dladm_handle_t handle, prop_desc_t *pdp, 188410734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 188510734SEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 188610734SEric Cheng { 188710734SEric Cheng dld_ioc_macprop_t *dip; 188810734SEric Cheng mac_resource_props_t mrp; 188910734SEric Cheng mac_protect_t *p; 189010734SEric Cheng dladm_status_t status; 189110734SEric Cheng int i; 189210734SEric Cheng 189310734SEric Cheng dip = i_dladm_get_public_prop(handle, linkid, "protection", flags, 189410734SEric Cheng &status, perm_flags); 189510734SEric Cheng if (dip == NULL) 189610734SEric Cheng return (status); 189710734SEric Cheng 189810734SEric Cheng bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); 189910734SEric Cheng free(dip); 190010734SEric Cheng 190110734SEric Cheng p = &mrp.mrp_protect; 190210734SEric Cheng if ((mrp.mrp_mask & MRP_PROTECT) != 0 && 190310734SEric Cheng strcmp(pdp->pd_name, "protection") == 0) { 190410734SEric Cheng uint32_t cnt = 0, setbits[32]; 190510734SEric Cheng 190610734SEric Cheng dladm_find_setbits32(p->mp_types, setbits, &cnt); 190710734SEric Cheng if (cnt > *val_cnt) 190810734SEric Cheng return (DLADM_STATUS_BADVALCNT); 190910734SEric Cheng 191010734SEric Cheng for (i = 0; i < cnt; i++) 191110734SEric Cheng (void) dladm_protect2str(setbits[i], prop_val[i]); 191210734SEric Cheng 191310734SEric Cheng *val_cnt = cnt; 191410734SEric Cheng return (DLADM_STATUS_OK); 191510734SEric Cheng } 191610734SEric Cheng 191710734SEric Cheng if (p->mp_ipaddrcnt > 0 && 191810734SEric Cheng strcmp(pdp->pd_name, "allowed-ips") == 0) { 191910734SEric Cheng if (p->mp_ipaddrcnt > *val_cnt) 192010734SEric Cheng return (DLADM_STATUS_BADVALCNT); 192110734SEric Cheng 192210734SEric Cheng for (i = 0; i < p->mp_ipaddrcnt; i++) { 192310734SEric Cheng (void) dladm_ipv4addr2str(&p->mp_ipaddrs[i], 192410734SEric Cheng prop_val[i]); 192510734SEric Cheng } 192610734SEric Cheng *val_cnt = p->mp_ipaddrcnt; 192710734SEric Cheng return (DLADM_STATUS_OK); 192810734SEric Cheng } 192910734SEric Cheng 193010734SEric Cheng *val_cnt = 0; 193110734SEric Cheng return (DLADM_STATUS_OK); 193210734SEric Cheng } 193310734SEric Cheng 193410734SEric Cheng dladm_status_t 193510734SEric Cheng do_extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 193610734SEric Cheng { 193710734SEric Cheng mac_resource_props_t *mrp = arg; 193810734SEric Cheng uint32_t types = 0; 193910734SEric Cheng int i; 194010734SEric Cheng 194110734SEric Cheng for (i = 0; i < cnt; i++) 194210734SEric Cheng types |= (uint32_t)vdp[i].vd_val; 194310734SEric Cheng 194410734SEric Cheng mrp->mrp_protect.mp_types = types; 194510734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 194610734SEric Cheng return (DLADM_STATUS_OK); 194710734SEric Cheng } 194810734SEric Cheng 194910734SEric Cheng dladm_status_t 195010734SEric Cheng do_extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 195110734SEric Cheng { 195210734SEric Cheng mac_resource_props_t *mrp = arg; 195310734SEric Cheng mac_protect_t *p = &mrp->mrp_protect; 195410734SEric Cheng int i; 195510734SEric Cheng 195610734SEric Cheng if (vdp->vd_val == 0) { 195710734SEric Cheng cnt = (uint_t)-1; 195810734SEric Cheng } else { 195910734SEric Cheng for (i = 0; i < cnt; i++) 196010734SEric Cheng p->mp_ipaddrs[i] = (ipaddr_t)vdp[i].vd_val; 196110734SEric Cheng } 196210734SEric Cheng p->mp_ipaddrcnt = cnt; 196310734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 196410734SEric Cheng return (DLADM_STATUS_OK); 196510734SEric Cheng } 196610734SEric Cheng 196710734SEric Cheng /* ARGSUSED */ 196810734SEric Cheng static dladm_status_t 196910734SEric Cheng do_check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 197010734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t val_cnt, 197110734SEric Cheng val_desc_t *vdp, datalink_media_t media) 197210734SEric Cheng { 197310734SEric Cheng dladm_status_t status; 197410734SEric Cheng ipaddr_t addr; 197510734SEric Cheng int i; 197610734SEric Cheng 197710734SEric Cheng if (val_cnt > MPT_MAXIPADDR) 197810734SEric Cheng return (DLADM_STATUS_BADVALCNT); 197910734SEric Cheng 198010734SEric Cheng for (i = 0; i < val_cnt; i++) { 198110734SEric Cheng status = dladm_str2ipv4addr(prop_val[i], &addr); 198210734SEric Cheng if (status != DLADM_STATUS_OK) 198310734SEric Cheng return (status); 198410734SEric Cheng 198510734SEric Cheng if (addr == 0) 198610734SEric Cheng return (DLADM_STATUS_BADVAL); 198710734SEric Cheng 198810734SEric Cheng vdp[i].vd_val = (uintptr_t)addr; 198910734SEric Cheng } 199010734SEric Cheng return (DLADM_STATUS_OK); 199110734SEric Cheng } 199210734SEric Cheng 199310734SEric Cheng /* ARGSUSED */ 199410734SEric Cheng static dladm_status_t 19958453SAnurag.Maskey@Sun.COM do_get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19968275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 19978275SEric Cheng uint_t flags, uint_t *perm_flags) 19985895Syz147064 { 19997342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 20007342SAruna.Ramakrishna@Sun.COM int i, len; 20017342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 20027342SAruna.Ramakrishna@Sun.COM dld_ioc_macprop_t *dip; 20035895Syz147064 20046789Sam223141 if (flags & MAC_PROP_DEFAULT) 20057776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 20066512Ssowmini 20075895Syz147064 *val_cnt = 1; 20088453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 20098275SEric Cheng &status, perm_flags); 20107342SAruna.Ramakrishna@Sun.COM if (dip == NULL) { 20115895Syz147064 (*prop_val)[0] = '\0'; 20128275SEric Cheng return (DLADM_STATUS_OK); 20135895Syz147064 } 20147342SAruna.Ramakrishna@Sun.COM (void) memcpy(&dlap, dip->pr_val, sizeof (dlap)); 20155895Syz147064 20167342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 20175895Syz147064 if (i != 0) { 20185895Syz147064 (void) snprintf(*prop_val + len, 20195895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 20205895Syz147064 len += 1; 20215895Syz147064 } 20225895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 20237342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 20247342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 20257342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 20265895Syz147064 (void) snprintf(*prop_val + len, 20275895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 20285895Syz147064 AP_ANCHOR); 20295895Syz147064 len += (strlen(AP_ANCHOR) + 1); 20305895Syz147064 } 20315895Syz147064 } 20327342SAruna.Ramakrishna@Sun.COM free(dip); 20335895Syz147064 done: 20345895Syz147064 return (DLADM_STATUS_OK); 20355895Syz147064 } 20365895Syz147064 20375895Syz147064 /* 20385895Syz147064 * Add the specified module to the dlautopush structure; returns a 20395895Syz147064 * DLADM_STATUS_* code. 20405895Syz147064 */ 20415895Syz147064 dladm_status_t 20425895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 20435895Syz147064 { 20445895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 20455895Syz147064 return (DLADM_STATUS_BADVAL); 20465895Syz147064 20475895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 20485895Syz147064 /* 20495895Syz147064 * We don't allow multiple anchors, and the anchor must 20505895Syz147064 * be after at least one module. 20515895Syz147064 */ 20525895Syz147064 if (dlap->dap_anchor != 0) 20535895Syz147064 return (DLADM_STATUS_BADVAL); 20545895Syz147064 if (dlap->dap_npush == 0) 20555895Syz147064 return (DLADM_STATUS_BADVAL); 20565895Syz147064 20575895Syz147064 dlap->dap_anchor = dlap->dap_npush; 20585895Syz147064 return (DLADM_STATUS_OK); 20595895Syz147064 } 20608957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 20615895Syz147064 return (DLADM_STATUS_BADVALCNT); 20625895Syz147064 20635895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 20645895Syz147064 FMNAMESZ + 1); 20655895Syz147064 20665895Syz147064 return (DLADM_STATUS_OK); 20675895Syz147064 } 20685895Syz147064 20695895Syz147064 /* 20705895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 20715895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 20725895Syz147064 * latter is used in the autopush(1M) file. 20735895Syz147064 */ 20745895Syz147064 /* ARGSUSED */ 20755895Syz147064 static dladm_status_t 20768453SAnurag.Maskey@Sun.COM do_check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 20778453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 20785895Syz147064 { 20795895Syz147064 char *module; 20805895Syz147064 struct dlautopush *dlap; 20815895Syz147064 dladm_status_t status; 20825895Syz147064 char val[DLADM_PROP_VAL_MAX]; 20835895Syz147064 char delimiters[4]; 20845895Syz147064 20855895Syz147064 if (val_cnt != 1) 20865895Syz147064 return (DLADM_STATUS_BADVALCNT); 20875895Syz147064 20887342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 20897342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 20907342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 20917342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 20923448Sdh155122 20937342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 20947342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 20957342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 20967342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 20977342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 20987342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 20997342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 21007342SAruna.Ramakrishna@Sun.COM return (status); 21017342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 21027342SAruna.Ramakrishna@Sun.COM } 21037342SAruna.Ramakrishna@Sun.COM 21047342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 21057342SAruna.Ramakrishna@Sun.COM } else { 21067342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 21075895Syz147064 } 21083448Sdh155122 return (DLADM_STATUS_OK); 21093448Sdh155122 } 21103448Sdh155122 21117663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 21127663SSowmini.Varadhan@Sun.COM 21135903Ssowmini /* ARGSUSED */ 21143448Sdh155122 static dladm_status_t 21158453SAnurag.Maskey@Sun.COM do_get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 21168453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 21178453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 21183448Sdh155122 { 21195895Syz147064 wl_rates_t *wrp; 21205895Syz147064 uint_t i; 21215895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 21225895Syz147064 21237663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 21247663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 21257663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 21265895Syz147064 21278453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 21288453SAnurag.Maskey@Sun.COM B_FALSE); 21295895Syz147064 if (status != DLADM_STATUS_OK) 21305895Syz147064 goto done; 21315895Syz147064 21325895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 21335895Syz147064 status = DLADM_STATUS_TOOSMALL; 21345895Syz147064 goto done; 21355895Syz147064 } 21365895Syz147064 21375895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 21385895Syz147064 prop_val[0][0] = '\0'; 21395895Syz147064 *val_cnt = 1; 21405895Syz147064 goto done; 21415895Syz147064 } 21425895Syz147064 21435895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 21445895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 21455895Syz147064 wrp->wl_rates_rates[i] % 2, 21465895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 21475895Syz147064 } 21485895Syz147064 *val_cnt = wrp->wl_rates_num; 21498275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 21503448Sdh155122 21515895Syz147064 done: 21527663SSowmini.Varadhan@Sun.COM free(wrp); 21535895Syz147064 return (status); 21545895Syz147064 } 21555895Syz147064 21565895Syz147064 static dladm_status_t 21578453SAnurag.Maskey@Sun.COM do_get_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21588275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 21598275SEric Cheng uint_t flags, uint_t *perm_flags) 21605895Syz147064 { 21618118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 21628453SAnurag.Maskey@Sun.COM return (i_dladm_speed_get(handle, pdp, linkid, prop_val, 21638275SEric Cheng val_cnt, flags, perm_flags)); 21648118SVasumathi.Sundaram@Sun.COM } 21655960Ssowmini 21668453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 21678275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 21685895Syz147064 } 21695895Syz147064 21706512Ssowmini /* ARGSUSED */ 21715895Syz147064 static dladm_status_t 21728453SAnurag.Maskey@Sun.COM do_get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21738275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 21748275SEric Cheng uint_t flags, uint_t *perm_flags) 21755895Syz147064 { 21765960Ssowmini switch (media) { 21775960Ssowmini case DL_ETHER: 21786512Ssowmini /* 21796512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 21806512Ssowmini * links can have a speed of 5.5 Gbps. 21816512Ssowmini */ 21826512Ssowmini return (DLADM_STATUS_NOTSUP); 21835960Ssowmini 21845960Ssowmini case DL_WIFI: 21858453SAnurag.Maskey@Sun.COM return (do_get_rate_common(handle, pdp, linkid, prop_val, 21868453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 21875960Ssowmini default: 21885960Ssowmini return (DLADM_STATUS_BADARG); 21895960Ssowmini } 21905895Syz147064 } 21915895Syz147064 21925895Syz147064 static dladm_status_t 21938453SAnurag.Maskey@Sun.COM do_set_rate(dladm_handle_t handle, datalink_id_t linkid, 21948453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 21955895Syz147064 { 21965895Syz147064 int i; 21975895Syz147064 uint_t len; 21985895Syz147064 wl_rates_t *wrp; 21995895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 22005895Syz147064 22017663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 22027663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 22035895Syz147064 return (DLADM_STATUS_NOMEM); 22045895Syz147064 22057663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 22065895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 22075895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 22085895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 22095895Syz147064 22105895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 22115895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 22128453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 22138453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 22145895Syz147064 22157663SSowmini.Varadhan@Sun.COM free(wrp); 22165895Syz147064 return (status); 22175895Syz147064 } 22183448Sdh155122 22195903Ssowmini /* ARGSUSED */ 22205895Syz147064 static dladm_status_t 22218453SAnurag.Maskey@Sun.COM do_set_rate_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22225960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 22235895Syz147064 { 22245895Syz147064 dladm_wlan_rates_t rates; 22255895Syz147064 dladm_status_t status; 22265895Syz147064 22275960Ssowmini /* 22285960Ssowmini * can currently set rate on WIFI links only. 22295960Ssowmini */ 22305960Ssowmini if (media != DL_WIFI) 22315960Ssowmini return (DLADM_STATUS_PROPRDONLY); 22325960Ssowmini 22335895Syz147064 if (val_cnt != 1) 22345895Syz147064 return (DLADM_STATUS_BADVALCNT); 22355895Syz147064 22365895Syz147064 rates.wr_cnt = 1; 22375895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 22385895Syz147064 22398453SAnurag.Maskey@Sun.COM status = do_set_rate(handle, linkid, &rates); 22405895Syz147064 22415895Syz147064 done: 22425895Syz147064 return (status); 22435895Syz147064 } 22443448Sdh155122 22455895Syz147064 /* ARGSUSED */ 22465895Syz147064 static dladm_status_t 22478453SAnurag.Maskey@Sun.COM do_check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22488453SAnurag.Maskey@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 22495895Syz147064 { 22505895Syz147064 int i; 22515895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 22525895Syz147064 char *buf, **modval; 22535895Syz147064 dladm_status_t status; 22548118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 22555895Syz147064 22565895Syz147064 if (val_cnt != 1) 22575895Syz147064 return (DLADM_STATUS_BADVALCNT); 22585895Syz147064 22595895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 22605895Syz147064 MAX_SUPPORT_RATES); 22615895Syz147064 if (buf == NULL) { 22625895Syz147064 status = DLADM_STATUS_NOMEM; 22635895Syz147064 goto done; 22645895Syz147064 } 22653448Sdh155122 22665895Syz147064 modval = (char **)(void *)buf; 22675895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 22685895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 22695895Syz147064 i * DLADM_STRSIZE; 22705895Syz147064 } 22715895Syz147064 22728453SAnurag.Maskey@Sun.COM status = do_get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 22738453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 22745895Syz147064 if (status != DLADM_STATUS_OK) 22755895Syz147064 goto done; 22765895Syz147064 22775895Syz147064 for (i = 0; i < modval_cnt; i++) { 22785895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 22795903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 22805903Ssowmini (atof(*prop_val) * 2); 22815895Syz147064 status = DLADM_STATUS_OK; 22823448Sdh155122 break; 22833448Sdh155122 } 22845895Syz147064 } 22855895Syz147064 if (i == modval_cnt) 22865895Syz147064 status = DLADM_STATUS_BADVAL; 22875895Syz147064 done: 22885895Syz147064 free(buf); 22895895Syz147064 return (status); 22905895Syz147064 } 22915895Syz147064 22925895Syz147064 static dladm_status_t 22938453SAnurag.Maskey@Sun.COM do_get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 22948453SAnurag.Maskey@Sun.COM int buflen) 22955895Syz147064 { 22968453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 22977663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 22985895Syz147064 } 22995895Syz147064 23005903Ssowmini /* ARGSUSED */ 23015895Syz147064 static dladm_status_t 23028453SAnurag.Maskey@Sun.COM do_get_channel_prop(dladm_handle_t handle, prop_desc_t *pdp, 23038453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 23048453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 23055895Syz147064 { 23065895Syz147064 uint32_t channel; 23077663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 23085895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 23097663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 23105895Syz147064 23118453SAnurag.Maskey@Sun.COM if ((status = do_get_phyconf(handle, linkid, buf, sizeof (buf))) 23127663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 23135895Syz147064 goto done; 23145895Syz147064 23157663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 23167663SSowmini.Varadhan@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { 23175895Syz147064 status = DLADM_STATUS_NOTFOUND; 23185895Syz147064 goto done; 23195895Syz147064 } 23205895Syz147064 23215895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 23225895Syz147064 *val_cnt = 1; 23238275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 23245895Syz147064 done: 23255895Syz147064 return (status); 23265895Syz147064 } 23275895Syz147064 23285895Syz147064 static dladm_status_t 23298453SAnurag.Maskey@Sun.COM do_get_powermode(dladm_handle_t handle, datalink_id_t linkid, void *buf, 23308453SAnurag.Maskey@Sun.COM int buflen) 23315895Syz147064 { 23328453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_POWER_MODE, 23337663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 23345895Syz147064 } 23355895Syz147064 23365903Ssowmini /* ARGSUSED */ 23375895Syz147064 static dladm_status_t 23388453SAnurag.Maskey@Sun.COM do_get_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 23398453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 23408453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 23415895Syz147064 { 23427663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 23435895Syz147064 const char *s; 23447663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 23455895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 23465895Syz147064 23478453SAnurag.Maskey@Sun.COM if ((status = do_get_powermode(handle, linkid, buf, sizeof (buf))) 23487663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 23495895Syz147064 goto done; 23505895Syz147064 23517663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 23527663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 23535895Syz147064 case WL_PM_AM: 23545895Syz147064 s = "off"; 23555895Syz147064 break; 23565895Syz147064 case WL_PM_MPS: 23575895Syz147064 s = "max"; 23585895Syz147064 break; 23595895Syz147064 case WL_PM_FAST: 23605895Syz147064 s = "fast"; 23613448Sdh155122 break; 23623448Sdh155122 default: 23635895Syz147064 status = DLADM_STATUS_NOTFOUND; 23645895Syz147064 goto done; 23655895Syz147064 } 23665895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 23675895Syz147064 *val_cnt = 1; 23688275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 23695895Syz147064 done: 23705895Syz147064 return (status); 23715895Syz147064 } 23725895Syz147064 23735895Syz147064 static dladm_status_t 23748453SAnurag.Maskey@Sun.COM do_set_powermode(dladm_handle_t handle, datalink_id_t linkid, 23758453SAnurag.Maskey@Sun.COM dladm_wlan_powermode_t *pm) 23765895Syz147064 { 23775895Syz147064 wl_ps_mode_t ps_mode; 23785895Syz147064 23795895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 23805895Syz147064 23815895Syz147064 switch (*pm) { 23825895Syz147064 case DLADM_WLAN_PM_OFF: 23835895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 23843448Sdh155122 break; 23855895Syz147064 case DLADM_WLAN_PM_MAX: 23865895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 23875895Syz147064 break; 23885895Syz147064 case DLADM_WLAN_PM_FAST: 23895895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 23905895Syz147064 break; 23915895Syz147064 default: 23925895Syz147064 return (DLADM_STATUS_NOTSUP); 23933448Sdh155122 } 23948453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 23958453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 23965895Syz147064 } 23975895Syz147064 23985895Syz147064 /* ARGSUSED */ 23995895Syz147064 static dladm_status_t 24008453SAnurag.Maskey@Sun.COM do_set_powermode_prop(dladm_handle_t handle, prop_desc_t *pdp, 24018453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 24028453SAnurag.Maskey@Sun.COM datalink_media_t media) 24035895Syz147064 { 24045895Syz147064 dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; 24055895Syz147064 dladm_status_t status; 24065895Syz147064 24075895Syz147064 if (val_cnt != 1) 24085895Syz147064 return (DLADM_STATUS_BADVALCNT); 24095895Syz147064 24108453SAnurag.Maskey@Sun.COM status = do_set_powermode(handle, linkid, &powermode); 24113448Sdh155122 24123448Sdh155122 return (status); 24133448Sdh155122 } 24143448Sdh155122 24153448Sdh155122 static dladm_status_t 24168453SAnurag.Maskey@Sun.COM do_get_radio(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen) 24173448Sdh155122 { 24188453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_RADIO, 24198453SAnurag.Maskey@Sun.COM buflen, B_FALSE)); 24205895Syz147064 } 24213448Sdh155122 24225903Ssowmini /* ARGSUSED */ 24235895Syz147064 static dladm_status_t 24248453SAnurag.Maskey@Sun.COM do_get_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 24258275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 24268275SEric Cheng uint_t flags, uint_t *perm_flags) 24275895Syz147064 { 24285895Syz147064 wl_radio_t radio; 24295895Syz147064 const char *s; 24307663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 24315895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 24323448Sdh155122 24338453SAnurag.Maskey@Sun.COM if ((status = do_get_radio(handle, linkid, buf, sizeof (buf))) 24347663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 24355895Syz147064 goto done; 24363448Sdh155122 24377663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 24385895Syz147064 switch (radio) { 24395895Syz147064 case B_TRUE: 24405895Syz147064 s = "on"; 24415895Syz147064 break; 24425895Syz147064 case B_FALSE: 24435895Syz147064 s = "off"; 24445895Syz147064 break; 24455895Syz147064 default: 24465895Syz147064 status = DLADM_STATUS_NOTFOUND; 24475895Syz147064 goto done; 24485895Syz147064 } 24495895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 24505895Syz147064 *val_cnt = 1; 24518275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 24525895Syz147064 done: 24533448Sdh155122 return (status); 24543448Sdh155122 } 24553448Sdh155122 24563448Sdh155122 static dladm_status_t 24578453SAnurag.Maskey@Sun.COM do_set_radio(dladm_handle_t handle, datalink_id_t linkid, 24588453SAnurag.Maskey@Sun.COM dladm_wlan_radio_t *radio) 24593448Sdh155122 { 24605895Syz147064 wl_radio_t r; 24613448Sdh155122 24625895Syz147064 switch (*radio) { 24635895Syz147064 case DLADM_WLAN_RADIO_ON: 24645895Syz147064 r = B_TRUE; 24655895Syz147064 break; 24665895Syz147064 case DLADM_WLAN_RADIO_OFF: 24675895Syz147064 r = B_FALSE; 24685895Syz147064 break; 24695895Syz147064 default: 24705895Syz147064 return (DLADM_STATUS_NOTSUP); 24715895Syz147064 } 24728453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 24737663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 24745895Syz147064 } 24753448Sdh155122 24765895Syz147064 /* ARGSUSED */ 24775895Syz147064 static dladm_status_t 24788453SAnurag.Maskey@Sun.COM do_set_radio_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 247910616SSebastien.Roy@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 24805895Syz147064 { 24815895Syz147064 dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; 24825895Syz147064 dladm_status_t status; 24833448Sdh155122 24845895Syz147064 if (val_cnt != 1) 24855895Syz147064 return (DLADM_STATUS_BADVALCNT); 24865895Syz147064 24878453SAnurag.Maskey@Sun.COM status = do_set_radio(handle, linkid, &radio); 24883448Sdh155122 24893448Sdh155122 return (status); 24903448Sdh155122 } 24913448Sdh155122 249210616SSebastien.Roy@Sun.COM /* ARGSUSED */ 249310616SSebastien.Roy@Sun.COM static dladm_status_t 249410616SSebastien.Roy@Sun.COM do_check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 249510616SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 249610616SSebastien.Roy@Sun.COM datalink_media_t media) 249710616SSebastien.Roy@Sun.COM { 249810616SSebastien.Roy@Sun.COM int32_t hlim; 249910616SSebastien.Roy@Sun.COM char *ep; 250010616SSebastien.Roy@Sun.COM 250110616SSebastien.Roy@Sun.COM if (val_cnt != 1) 250210616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 250310616SSebastien.Roy@Sun.COM 250410616SSebastien.Roy@Sun.COM errno = 0; 250510616SSebastien.Roy@Sun.COM hlim = strtol(*prop_val, &ep, 10); 250610616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || hlim < 1 || 250710616SSebastien.Roy@Sun.COM hlim > (int32_t)UINT8_MAX) 250810616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 250910616SSebastien.Roy@Sun.COM vdp->vd_val = hlim; 251010616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 251110616SSebastien.Roy@Sun.COM } 251210616SSebastien.Roy@Sun.COM 251310616SSebastien.Roy@Sun.COM /* ARGSUSED */ 251410616SSebastien.Roy@Sun.COM static dladm_status_t 251510616SSebastien.Roy@Sun.COM do_check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 251610616SSebastien.Roy@Sun.COM char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) 251710616SSebastien.Roy@Sun.COM { 251810616SSebastien.Roy@Sun.COM int32_t elim; 251910616SSebastien.Roy@Sun.COM char *ep; 252010616SSebastien.Roy@Sun.COM 252110616SSebastien.Roy@Sun.COM if (media != DL_IPV6) 252210616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG); 252310616SSebastien.Roy@Sun.COM 252410616SSebastien.Roy@Sun.COM if (val_cnt != 1) 252510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 252610616SSebastien.Roy@Sun.COM 252710616SSebastien.Roy@Sun.COM errno = 0; 252810616SSebastien.Roy@Sun.COM elim = strtol(*prop_val, &ep, 10); 252910616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || elim < 0 || 253010616SSebastien.Roy@Sun.COM elim > (int32_t)UINT8_MAX) 253110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 253210616SSebastien.Roy@Sun.COM vdp->vd_val = elim; 253310616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 253410616SSebastien.Roy@Sun.COM } 253510616SSebastien.Roy@Sun.COM 25365895Syz147064 static dladm_status_t 25378453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 25388453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 25393448Sdh155122 { 25405895Syz147064 char buf[MAXLINELEN]; 25415895Syz147064 int i; 25425895Syz147064 dladm_conf_t conf; 25435895Syz147064 dladm_status_t status; 25443448Sdh155122 25458453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 25465895Syz147064 if (status != DLADM_STATUS_OK) 25475895Syz147064 return (status); 25483448Sdh155122 25495895Syz147064 /* 25505895Syz147064 * reset case. 25515895Syz147064 */ 25525895Syz147064 if (val_cnt == 0) { 25538453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 25545895Syz147064 if (status == DLADM_STATUS_OK) 25558453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 25565895Syz147064 goto done; 25575895Syz147064 } 25583448Sdh155122 25595895Syz147064 buf[0] = '\0'; 25605895Syz147064 for (i = 0; i < val_cnt; i++) { 25615895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 25625895Syz147064 if (i != val_cnt - 1) 25635895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 25643448Sdh155122 } 25653448Sdh155122 25668453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 25678453SAnurag.Maskey@Sun.COM buf); 25685895Syz147064 if (status == DLADM_STATUS_OK) 25698453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 25705895Syz147064 25715895Syz147064 done: 25728453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 25735895Syz147064 return (status); 25743448Sdh155122 } 25755895Syz147064 25765895Syz147064 static dladm_status_t 25778453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 25788453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 25795895Syz147064 { 25805895Syz147064 char buf[MAXLINELEN], *str; 25815895Syz147064 uint_t cnt = 0; 25825895Syz147064 dladm_conf_t conf; 25835895Syz147064 dladm_status_t status; 25845895Syz147064 25858453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 25865895Syz147064 if (status != DLADM_STATUS_OK) 25875895Syz147064 return (status); 25885895Syz147064 25898453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 25905895Syz147064 if (status != DLADM_STATUS_OK) 25915895Syz147064 goto done; 25925895Syz147064 25935895Syz147064 str = strtok(buf, ","); 25945895Syz147064 while (str != NULL) { 25955895Syz147064 if (cnt == *val_cntp) { 25965895Syz147064 status = DLADM_STATUS_TOOSMALL; 25975895Syz147064 goto done; 25985895Syz147064 } 25995895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 26005895Syz147064 str = strtok(NULL, ","); 26015895Syz147064 } 26025895Syz147064 26035895Syz147064 *val_cntp = cnt; 26045895Syz147064 26055895Syz147064 done: 26068453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 26075895Syz147064 return (status); 26085895Syz147064 } 26095903Ssowmini 26108460SArtem.Kachitchkin@Sun.COM /* 26118460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 26128460SArtem.Kachitchkin@Sun.COM */ 26138460SArtem.Kachitchkin@Sun.COM static dladm_status_t 26148460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 26158460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 26168460SArtem.Kachitchkin@Sun.COM { 26178460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 26188460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 26198460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 26208460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 26218460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 26228460SArtem.Kachitchkin@Sun.COM size_t attrsz; 26238460SArtem.Kachitchkin@Sun.COM 26248460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 26258460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 26268460SArtem.Kachitchkin@Sun.COM 26278460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 26288460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 26298460SArtem.Kachitchkin@Sun.COM return (status); 26308460SArtem.Kachitchkin@Sun.COM 26318460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 26328460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 26338460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 26348460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 26358460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 26368460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 26378460SArtem.Kachitchkin@Sun.COM break; 26388460SArtem.Kachitchkin@Sun.COM } 26398460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 26408460SArtem.Kachitchkin@Sun.COM } 26418460SArtem.Kachitchkin@Sun.COM 26428460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 26438460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 26448460SArtem.Kachitchkin@Sun.COM } 26458460SArtem.Kachitchkin@Sun.COM 26467663SSowmini.Varadhan@Sun.COM static link_attr_t * 26475903Ssowmini dladm_name2prop(const char *prop_name) 26485903Ssowmini { 26497663SSowmini.Varadhan@Sun.COM link_attr_t *p; 26505903Ssowmini 26517663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 26525903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 26535903Ssowmini break; 26545903Ssowmini } 26555903Ssowmini return (p); 26565903Ssowmini } 26575903Ssowmini 26587663SSowmini.Varadhan@Sun.COM static link_attr_t * 26597663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 26607663SSowmini.Varadhan@Sun.COM { 26617663SSowmini.Varadhan@Sun.COM link_attr_t *p; 26627663SSowmini.Varadhan@Sun.COM 26637663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 26647663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 26657663SSowmini.Varadhan@Sun.COM break; 26667663SSowmini.Varadhan@Sun.COM } 26677663SSowmini.Varadhan@Sun.COM return (p); 26687663SSowmini.Varadhan@Sun.COM } 26695903Ssowmini 26706789Sam223141 static dld_ioc_macprop_t * 26717663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 26727663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 26737663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 26745903Ssowmini { 26755903Ssowmini int dsize; 26766789Sam223141 dld_ioc_macprop_t *dip; 26775903Ssowmini 26785903Ssowmini *status = DLADM_STATUS_OK; 26796789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 26805903Ssowmini dip = malloc(dsize); 26815903Ssowmini if (dip == NULL) { 26825903Ssowmini *status = DLADM_STATUS_NOMEM; 26835903Ssowmini return (NULL); 26845903Ssowmini } 26855903Ssowmini bzero(dip, dsize); 26865903Ssowmini dip->pr_valsize = valsize; 26876512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 26886789Sam223141 dip->pr_version = MAC_PROP_VERSION; 26895960Ssowmini dip->pr_linkid = linkid; 26907663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 26916512Ssowmini dip->pr_flags = flags; 26925903Ssowmini return (dip); 26935903Ssowmini } 26945903Ssowmini 26957663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 26967663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 26977663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 26987663SSowmini.Varadhan@Sun.COM { 26997663SSowmini.Varadhan@Sun.COM link_attr_t *p; 27007663SSowmini.Varadhan@Sun.COM 27017663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 27027663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 27037663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 27047663SSowmini.Varadhan@Sun.COM flags, status)); 27057663SSowmini.Varadhan@Sun.COM } 27067663SSowmini.Varadhan@Sun.COM 27077663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 27087663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 27097663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 27107663SSowmini.Varadhan@Sun.COM { 27117663SSowmini.Varadhan@Sun.COM link_attr_t *p; 27127663SSowmini.Varadhan@Sun.COM 27137663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 27147663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 27157663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 27167663SSowmini.Varadhan@Sun.COM flags, status)); 27177663SSowmini.Varadhan@Sun.COM } 27187663SSowmini.Varadhan@Sun.COM 27195903Ssowmini /* ARGSUSED */ 27205903Ssowmini static dladm_status_t 27218453SAnurag.Maskey@Sun.COM i_dladm_set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 27228453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 27238453SAnurag.Maskey@Sun.COM datalink_media_t media) 27245903Ssowmini { 27256789Sam223141 dld_ioc_macprop_t *dip; 27265903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 27275903Ssowmini uint8_t u8; 27285903Ssowmini uint16_t u16; 27295903Ssowmini uint32_t u32; 27305903Ssowmini void *val; 27315903Ssowmini 27328275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 27335903Ssowmini if (dip == NULL) 27345903Ssowmini return (status); 27355903Ssowmini 27368275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 27375903Ssowmini val = (void *)vdp->vd_val; 27385903Ssowmini else { 27395903Ssowmini /* 27405903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 27415903Ssowmini * No need (yet) to distinguish these from arrays of same size. 27425903Ssowmini */ 27435903Ssowmini switch (dip->pr_valsize) { 27445903Ssowmini case 1: 27455903Ssowmini u8 = vdp->vd_val; 27465903Ssowmini val = &u8; 27475903Ssowmini break; 27485903Ssowmini case 2: 27495903Ssowmini u16 = vdp->vd_val; 27505903Ssowmini val = &u16; 27515903Ssowmini break; 27525903Ssowmini case 4: 27535903Ssowmini u32 = vdp->vd_val; 27545903Ssowmini val = &u32; 27555903Ssowmini break; 27565903Ssowmini default: 27575903Ssowmini val = &vdp->vd_val; 27585903Ssowmini break; 27595903Ssowmini } 27605903Ssowmini } 27615903Ssowmini 27627342SAruna.Ramakrishna@Sun.COM if (val != NULL) 27637342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 27647342SAruna.Ramakrishna@Sun.COM else 27657342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 27667342SAruna.Ramakrishna@Sun.COM 27678453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 27687663SSowmini.Varadhan@Sun.COM 27697663SSowmini.Varadhan@Sun.COM done: 27707663SSowmini.Varadhan@Sun.COM free(dip); 27717663SSowmini.Varadhan@Sun.COM return (status); 27727663SSowmini.Varadhan@Sun.COM } 27737663SSowmini.Varadhan@Sun.COM 27747663SSowmini.Varadhan@Sun.COM dladm_status_t 27758453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 27767663SSowmini.Varadhan@Sun.COM { 27777663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 27787663SSowmini.Varadhan@Sun.COM 27798453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 27808453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 27815903Ssowmini status = dladm_errno2status(errno); 27828453SAnurag.Maskey@Sun.COM 27835903Ssowmini return (status); 27845903Ssowmini } 27855903Ssowmini 27866789Sam223141 static dld_ioc_macprop_t * 27878453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 27888453SAnurag.Maskey@Sun.COM char *prop_name, uint_t flags, dladm_status_t *status, uint_t *perm_flags) 27895903Ssowmini { 27906789Sam223141 dld_ioc_macprop_t *dip = NULL; 27916512Ssowmini 27927663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); 27936512Ssowmini if (dip == NULL) 27946512Ssowmini return (NULL); 27955903Ssowmini 27968453SAnurag.Maskey@Sun.COM *status = i_dladm_macprop(handle, dip, B_FALSE); 27976512Ssowmini if (*status != DLADM_STATUS_OK) { 27986512Ssowmini free(dip); 27996512Ssowmini return (NULL); 28006512Ssowmini } 28018275SEric Cheng if (perm_flags != NULL) 28028275SEric Cheng *perm_flags = dip->pr_perm_flags; 28038275SEric Cheng 28046512Ssowmini return (dip); 28055903Ssowmini } 28065903Ssowmini 28075903Ssowmini /* ARGSUSED */ 28085903Ssowmini static dladm_status_t 280910491SRishi.Srivatsavai@Sun.COM i_dladm_uint32_check(dladm_handle_t handle, prop_desc_t *pdp, 28108453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *v, 28118453SAnurag.Maskey@Sun.COM datalink_media_t media) 28125903Ssowmini { 28135903Ssowmini if (val_cnt != 1) 28145903Ssowmini return (DLADM_STATUS_BADVAL); 281510491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 28165903Ssowmini return (DLADM_STATUS_OK); 28175903Ssowmini } 28185903Ssowmini 28195903Ssowmini /* ARGSUSED */ 28205903Ssowmini static dladm_status_t 28218453SAnurag.Maskey@Sun.COM i_dladm_duplex_get(dladm_handle_t handle, prop_desc_t *pdp, 28228453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28238453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28245903Ssowmini { 28255903Ssowmini link_duplex_t link_duplex; 28265903Ssowmini dladm_status_t status; 28275903Ssowmini 28288453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 28295903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 28305903Ssowmini return (status); 28315903Ssowmini 28325903Ssowmini switch (link_duplex) { 28335903Ssowmini case LINK_DUPLEX_FULL: 28345903Ssowmini (void) strcpy(*prop_val, "full"); 28355903Ssowmini break; 28365903Ssowmini case LINK_DUPLEX_HALF: 28375903Ssowmini (void) strcpy(*prop_val, "half"); 28385903Ssowmini break; 28395903Ssowmini default: 28405903Ssowmini (void) strcpy(*prop_val, "unknown"); 28415903Ssowmini break; 28425903Ssowmini } 28435903Ssowmini *val_cnt = 1; 28445903Ssowmini return (DLADM_STATUS_OK); 28455903Ssowmini } 28465903Ssowmini 28475903Ssowmini /* ARGSUSED */ 28485903Ssowmini static dladm_status_t 28498453SAnurag.Maskey@Sun.COM i_dladm_speed_get(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 28508275SEric Cheng char **prop_val, uint_t *val_cnt, uint_t flags, uint_t *perm_flags) 28515903Ssowmini { 28525903Ssowmini uint64_t ifspeed = 0; 28535903Ssowmini dladm_status_t status; 28545903Ssowmini 28558453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 28565903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 28575903Ssowmini return (status); 28586512Ssowmini 28595960Ssowmini if ((ifspeed % 1000000) != 0) { 28605960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 28615960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 28625960Ssowmini } else { 28635960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 28645960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 28655960Ssowmini } 28665903Ssowmini *val_cnt = 1; 28678275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 28685903Ssowmini return (DLADM_STATUS_OK); 28695903Ssowmini } 28705903Ssowmini 28715903Ssowmini /* ARGSUSED */ 28725903Ssowmini static dladm_status_t 28738453SAnurag.Maskey@Sun.COM i_dladm_status_get(dladm_handle_t handle, prop_desc_t *pdp, 28748453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28758453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 28765903Ssowmini { 28778275SEric Cheng link_state_t link_state; 28788275SEric Cheng dladm_status_t status; 28798306SSowmini.Varadhan@Sun.COM 28808453SAnurag.Maskey@Sun.COM status = i_dladm_get_state(handle, linkid, &link_state); 28816512Ssowmini if (status != DLADM_STATUS_OK) 28825903Ssowmini return (status); 28838275SEric Cheng 28845903Ssowmini switch (link_state) { 28855903Ssowmini case LINK_STATE_UP: 28865903Ssowmini (void) strcpy(*prop_val, "up"); 28875903Ssowmini break; 28885903Ssowmini case LINK_STATE_DOWN: 28895903Ssowmini (void) strcpy(*prop_val, "down"); 28905903Ssowmini break; 28915903Ssowmini default: 28925903Ssowmini (void) strcpy(*prop_val, "unknown"); 28935903Ssowmini break; 28945903Ssowmini } 28955903Ssowmini *val_cnt = 1; 28968306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 28975903Ssowmini return (DLADM_STATUS_OK); 28985903Ssowmini } 28995903Ssowmini 29005903Ssowmini /* ARGSUSED */ 29015903Ssowmini static dladm_status_t 29028453SAnurag.Maskey@Sun.COM i_dladm_binary_get(dladm_handle_t handle, prop_desc_t *pdp, 29038453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29048453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29055903Ssowmini { 29066789Sam223141 dld_ioc_macprop_t *dip; 29075903Ssowmini dladm_status_t status; 29085903Ssowmini 29098453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29108275SEric Cheng &status, perm_flags); 29116512Ssowmini if (dip == NULL) 29125903Ssowmini return (status); 29138275SEric Cheng 29145903Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]); 29155903Ssowmini free(dip); 29165903Ssowmini *val_cnt = 1; 29175903Ssowmini return (DLADM_STATUS_OK); 29185903Ssowmini } 29195903Ssowmini 29205960Ssowmini /* ARGSUSED */ 29215903Ssowmini static dladm_status_t 29228453SAnurag.Maskey@Sun.COM i_dladm_uint32_get(dladm_handle_t handle, prop_desc_t *pdp, 29238453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29248453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29255903Ssowmini { 29266789Sam223141 dld_ioc_macprop_t *dip; 29278275SEric Cheng uint32_t v = 0; 29285903Ssowmini uchar_t *cp; 29295903Ssowmini dladm_status_t status; 29305903Ssowmini 29318453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29328275SEric Cheng &status, perm_flags); 29336512Ssowmini if (dip == NULL) 29345903Ssowmini return (status); 29358275SEric Cheng 29365903Ssowmini cp = (uchar_t *)dip->pr_val; 29375903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 29386512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 29395903Ssowmini free(dip); 29405903Ssowmini *val_cnt = 1; 29415903Ssowmini return (DLADM_STATUS_OK); 29425903Ssowmini } 29435903Ssowmini 29449514SGirish.Moodalbail@Sun.COM /* 29459514SGirish.Moodalbail@Sun.COM * Determines the size of the structure that needs to be sent to drivers 29469514SGirish.Moodalbail@Sun.COM * for retrieving the property range values. 29479514SGirish.Moodalbail@Sun.COM */ 29489514SGirish.Moodalbail@Sun.COM static int 29499514SGirish.Moodalbail@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 29509514SGirish.Moodalbail@Sun.COM { 29519514SGirish.Moodalbail@Sun.COM uint_t count = r->mpr_count; 29529514SGirish.Moodalbail@Sun.COM 29539514SGirish.Moodalbail@Sun.COM *sz = sizeof (mac_propval_range_t); 29549514SGirish.Moodalbail@Sun.COM --count; 29559514SGirish.Moodalbail@Sun.COM 29569514SGirish.Moodalbail@Sun.COM switch (r->mpr_type) { 29579514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: 29589514SGirish.Moodalbail@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 29599514SGirish.Moodalbail@Sun.COM return (0); 29609514SGirish.Moodalbail@Sun.COM default: 29619514SGirish.Moodalbail@Sun.COM break; 29629514SGirish.Moodalbail@Sun.COM } 29639514SGirish.Moodalbail@Sun.COM *sz = 0; 29649514SGirish.Moodalbail@Sun.COM return (EINVAL); 29659514SGirish.Moodalbail@Sun.COM } 29669514SGirish.Moodalbail@Sun.COM 29679514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 29689514SGirish.Moodalbail@Sun.COM static dladm_status_t 29699514SGirish.Moodalbail@Sun.COM i_dladm_range_get(dladm_handle_t handle, prop_desc_t *pdp, 29709514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29719514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 29729514SGirish.Moodalbail@Sun.COM { 29739514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 29749514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 29759514SGirish.Moodalbail@Sun.COM size_t sz; 29769514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 29779514SGirish.Moodalbail@Sun.COM 29789514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 29799514SGirish.Moodalbail@Sun.COM 29809514SGirish.Moodalbail@Sun.COM /* 29819514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 29829514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 29839514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 29849514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 29859514SGirish.Moodalbail@Sun.COM */ 29869514SGirish.Moodalbail@Sun.COM retry: 29879514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 29889514SGirish.Moodalbail@Sun.COM &status)) == NULL) 29899514SGirish.Moodalbail@Sun.COM return (status); 29909514SGirish.Moodalbail@Sun.COM 29919514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 29929514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 29939514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 29949514SGirish.Moodalbail@Sun.COM int err; 29959514SGirish.Moodalbail@Sun.COM 29969514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 29979514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 29989514SGirish.Moodalbail@Sun.COM free(dip); 29999514SGirish.Moodalbail@Sun.COM goto retry; 30009514SGirish.Moodalbail@Sun.COM } else { 30019514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 30029514SGirish.Moodalbail@Sun.COM } 30039514SGirish.Moodalbail@Sun.COM } 30049514SGirish.Moodalbail@Sun.COM free(dip); 30059514SGirish.Moodalbail@Sun.COM return (status); 30069514SGirish.Moodalbail@Sun.COM } 30079514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 30089514SGirish.Moodalbail@Sun.COM 30099514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 30109514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 30119514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 30129514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 30139514SGirish.Moodalbail@Sun.COM 30149514SGirish.Moodalbail@Sun.COM ur = &rangep->range_uint32[0]; 30159514SGirish.Moodalbail@Sun.COM 30169514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 30179514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 30189514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 30199514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 30209514SGirish.Moodalbail@Sun.COM } else { 30219514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 30229514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 30239514SGirish.Moodalbail@Sun.COM } 30249514SGirish.Moodalbail@Sun.COM } 30259514SGirish.Moodalbail@Sun.COM *val_cnt = count; 30269514SGirish.Moodalbail@Sun.COM break; 30279514SGirish.Moodalbail@Sun.COM } 30289514SGirish.Moodalbail@Sun.COM default: 30299514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 30309514SGirish.Moodalbail@Sun.COM break; 30319514SGirish.Moodalbail@Sun.COM } 30329514SGirish.Moodalbail@Sun.COM free(dip); 30339514SGirish.Moodalbail@Sun.COM return (status); 30349514SGirish.Moodalbail@Sun.COM } 30359514SGirish.Moodalbail@Sun.COM 30365960Ssowmini /* ARGSUSED */ 30375903Ssowmini static dladm_status_t 30388874SSebastien.Roy@Sun.COM i_dladm_tagmode_get(dladm_handle_t handle, prop_desc_t *pdp, 30398874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30408874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30418874SSebastien.Roy@Sun.COM { 30428874SSebastien.Roy@Sun.COM dld_ioc_macprop_t *dip; 30438874SSebastien.Roy@Sun.COM link_tagmode_t mode; 30448874SSebastien.Roy@Sun.COM dladm_status_t status; 30458874SSebastien.Roy@Sun.COM 30468874SSebastien.Roy@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 30478874SSebastien.Roy@Sun.COM &status, perm_flags); 30488874SSebastien.Roy@Sun.COM if (dip == NULL) 30498874SSebastien.Roy@Sun.COM return (status); 30508874SSebastien.Roy@Sun.COM (void) memcpy(&mode, dip->pr_val, sizeof (mode)); 30518874SSebastien.Roy@Sun.COM free(dip); 30528874SSebastien.Roy@Sun.COM 30538874SSebastien.Roy@Sun.COM switch (mode) { 30548874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 30558874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 30568874SSebastien.Roy@Sun.COM break; 30578874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 30588874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 30598874SSebastien.Roy@Sun.COM break; 30608874SSebastien.Roy@Sun.COM default: 30618874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 30628874SSebastien.Roy@Sun.COM } 30638874SSebastien.Roy@Sun.COM *val_cnt = 1; 30648874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 30658874SSebastien.Roy@Sun.COM } 30668874SSebastien.Roy@Sun.COM 30678874SSebastien.Roy@Sun.COM /* ARGSUSED */ 30688874SSebastien.Roy@Sun.COM static dladm_status_t 30698453SAnurag.Maskey@Sun.COM i_dladm_flowctl_get(dladm_handle_t handle, prop_desc_t *pdp, 30708453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30718453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30725903Ssowmini { 30736789Sam223141 dld_ioc_macprop_t *dip; 30745903Ssowmini link_flowctrl_t v; 30755903Ssowmini dladm_status_t status; 30765903Ssowmini uchar_t *cp; 30775903Ssowmini 30788453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 30798275SEric Cheng &status, perm_flags); 30806512Ssowmini if (dip == NULL) 30815903Ssowmini return (status); 30828275SEric Cheng 30835903Ssowmini cp = (uchar_t *)dip->pr_val; 30845903Ssowmini (void) memcpy(&v, cp, sizeof (v)); 30855903Ssowmini switch (v) { 30865903Ssowmini case LINK_FLOWCTRL_NONE: 30875903Ssowmini (void) sprintf(*prop_val, "no"); 30885903Ssowmini break; 30895903Ssowmini case LINK_FLOWCTRL_RX: 30905903Ssowmini (void) sprintf(*prop_val, "rx"); 30915903Ssowmini break; 30925903Ssowmini case LINK_FLOWCTRL_TX: 30935903Ssowmini (void) sprintf(*prop_val, "tx"); 30945903Ssowmini break; 30955903Ssowmini case LINK_FLOWCTRL_BI: 30965903Ssowmini (void) sprintf(*prop_val, "bi"); 30975903Ssowmini break; 30985903Ssowmini } 30995903Ssowmini free(dip); 31005903Ssowmini *val_cnt = 1; 31015903Ssowmini return (DLADM_STATUS_OK); 31025903Ssowmini } 31035903Ssowmini 31045903Ssowmini 31055903Ssowmini /* ARGSUSED */ 31065903Ssowmini static dladm_status_t 31079692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 31088453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 31098453SAnurag.Maskey@Sun.COM 31105903Ssowmini { 31117663SSowmini.Varadhan@Sun.COM int i, slen; 31127408SSebastien.Roy@Sun.COM int bufsize = 0; 31136789Sam223141 dld_ioc_macprop_t *dip = NULL; 31145903Ssowmini uchar_t *dp; 31157663SSowmini.Varadhan@Sun.COM link_attr_t *p; 31166512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 31175903Ssowmini 31185903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 31195903Ssowmini (prop_val != NULL && val_cnt == 0)) 31205903Ssowmini return (DLADM_STATUS_BADARG); 31215903Ssowmini p = dladm_name2prop(prop_name); 31226789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 31235903Ssowmini return (DLADM_STATUS_BADARG); 31245903Ssowmini 31259692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 31269692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 31279692SRishi.Srivatsavai@Sun.COM 31285903Ssowmini /* 31295903Ssowmini * private properties: all parsing is done in the kernel. 31305903Ssowmini * allocate a enough space for each property + its separator (','). 31315903Ssowmini */ 31325903Ssowmini for (i = 0; i < val_cnt; i++) { 31335903Ssowmini bufsize += strlen(prop_val[i]) + 1; 31345903Ssowmini } 31356512Ssowmini 31366512Ssowmini if (prop_val == NULL) { 31376512Ssowmini /* 31386512Ssowmini * getting default value. so use more buffer space. 31396512Ssowmini */ 31407663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 31416512Ssowmini } 31426512Ssowmini 31437663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 31446789Sam223141 (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); 31455903Ssowmini if (dip == NULL) 31465903Ssowmini return (status); 31475903Ssowmini 31485903Ssowmini dp = (uchar_t *)dip->pr_val; 31495903Ssowmini slen = 0; 31507663SSowmini.Varadhan@Sun.COM 31516512Ssowmini if (prop_val == NULL) { 31528453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 31538460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 31546512Ssowmini } else { 31556512Ssowmini for (i = 0; i < val_cnt; i++) { 31566512Ssowmini int plen = 0; 31575903Ssowmini 31586512Ssowmini plen = strlen(prop_val[i]); 31596512Ssowmini bcopy(prop_val[i], dp, plen); 31606512Ssowmini slen += plen; 31616512Ssowmini /* 31626512Ssowmini * add a "," separator and update dp. 31636512Ssowmini */ 31646512Ssowmini if (i != (val_cnt -1)) 31656512Ssowmini dp[slen++] = ','; 31666512Ssowmini dp += (plen + 1); 31676512Ssowmini } 31688460SArtem.Kachitchkin@Sun.COM } 31698460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 31708453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 31716512Ssowmini 31725903Ssowmini free(dip); 31736512Ssowmini return (status); 31745903Ssowmini } 31755903Ssowmini 31765903Ssowmini static dladm_status_t 31778460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 31788453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 31798453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 31805903Ssowmini { 31817663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 31826789Sam223141 dld_ioc_macprop_t *dip = NULL; 31837663SSowmini.Varadhan@Sun.COM link_attr_t *p; 31845903Ssowmini 31855903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 31865903Ssowmini (prop_val != NULL && val_cnt == 0)) 31875903Ssowmini return (DLADM_STATUS_BADARG); 31885903Ssowmini 31895903Ssowmini p = dladm_name2prop(prop_name); 31906789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 31915903Ssowmini return (DLADM_STATUS_BADARG); 31925903Ssowmini 31935903Ssowmini /* 31945903Ssowmini * private properties: all parsing is done in the kernel. 31955903Ssowmini */ 31967663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 31977663SSowmini.Varadhan@Sun.COM dld_flags, &status); 31985903Ssowmini if (dip == NULL) 31995903Ssowmini return (status); 32005903Ssowmini 32018453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 32028453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 32038118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 32048275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 32058460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 32068460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 32078118SVasumathi.Sundaram@Sun.COM } else { 32088118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 32098118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 32108118SVasumathi.Sundaram@Sun.COM } 32115903Ssowmini *val_cnt = 1; 32128460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 32138460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 32148460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 32155903Ssowmini } 32166512Ssowmini free(dip); 32175903Ssowmini return (status); 32185903Ssowmini } 32196512Ssowmini 32206512Ssowmini 32216512Ssowmini static dladm_status_t 32228453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 32238453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 32246512Ssowmini { 32256512Ssowmini dladm_status_t status; 32266512Ssowmini char **prop_vals = NULL, *buf; 32276512Ssowmini size_t bufsize; 32286512Ssowmini uint_t cnt; 32296512Ssowmini int i; 32308118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 32316512Ssowmini 32326512Ssowmini /* 32336512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 32346512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 32356512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 32366512Ssowmini */ 32376512Ssowmini bufsize = 32386512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 32396512Ssowmini buf = malloc(bufsize); 32406512Ssowmini prop_vals = (char **)(void *)buf; 32416512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 32426512Ssowmini prop_vals[i] = buf + 32436512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 32446512Ssowmini i * DLADM_PROP_VAL_MAX; 32456512Ssowmini } 32466768Sar224390 32476768Sar224390 /* 32487342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 32497342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 32507342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 32517342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 32527342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 32537342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 32547342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 32557342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 32566768Sar224390 */ 32578453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 32588118SVasumathi.Sundaram@Sun.COM MAC_PROP_DEFAULT, &perm_flags); 32596512Ssowmini if (status == DLADM_STATUS_OK) { 32608118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 32618453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 32628453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 32638118SVasumathi.Sundaram@Sun.COM } 32648118SVasumathi.Sundaram@Sun.COM else 32658118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 32666512Ssowmini } 32676512Ssowmini free(buf); 32686512Ssowmini return (status); 32696512Ssowmini } 32707663SSowmini.Varadhan@Sun.COM 327110491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 327210491SRishi.Srivatsavai@Sun.COM static dladm_status_t 327310491SRishi.Srivatsavai@Sun.COM get_stp_prop(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 327410491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 327510491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 327610491SRishi.Srivatsavai@Sun.COM { 327710491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 327810491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 327910491SRishi.Srivatsavai@Sun.COM int val, i; 328010491SRishi.Srivatsavai@Sun.COM 328110491SRishi.Srivatsavai@Sun.COM if (flags != 0) 328210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 328310491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 328410491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 328510491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 328610491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 328710491SRishi.Srivatsavai@Sun.COM break; 328810491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 328910491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 329010491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 329110491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 329210491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 329310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 329410491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 329510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 329610491SRishi.Srivatsavai@Sun.COM } 329710491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 329810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 329910491SRishi.Srivatsavai@Sun.COM return (retv); 330010491SRishi.Srivatsavai@Sun.COM } 330110491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 330210491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 330310491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 330410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 330510491SRishi.Srivatsavai@Sun.COM } 330610491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 330710491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 330810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 330910491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 331010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 331110491SRishi.Srivatsavai@Sun.COM } 331210491SRishi.Srivatsavai@Sun.COM } 331310491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 331410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 331510491SRishi.Srivatsavai@Sun.COM } 331610491SRishi.Srivatsavai@Sun.COM 331710491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 331810491SRishi.Srivatsavai@Sun.COM static dladm_status_t 331910491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 332010491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 332110491SRishi.Srivatsavai@Sun.COM { 332210491SRishi.Srivatsavai@Sun.COM /* 332310491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 332410491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 332510491SRishi.Srivatsavai@Sun.COM */ 332610491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 332710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 332810491SRishi.Srivatsavai@Sun.COM 332910491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 333010491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 333110491SRishi.Srivatsavai@Sun.COM } 333210491SRishi.Srivatsavai@Sun.COM 333310491SRishi.Srivatsavai@Sun.COM /* 333410491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 333510491SRishi.Srivatsavai@Sun.COM */ 333610491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 333710491SRishi.Srivatsavai@Sun.COM static dladm_status_t 333810491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 333910491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 334010491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 334110491SRishi.Srivatsavai@Sun.COM { 334210491SRishi.Srivatsavai@Sun.COM char *cp; 334310491SRishi.Srivatsavai@Sun.COM boolean_t iscost; 334410491SRishi.Srivatsavai@Sun.COM 334510491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 334610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 334710491SRishi.Srivatsavai@Sun.COM 334810491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 334910491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 335010491SRishi.Srivatsavai@Sun.COM } else { 335110491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 335210491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 335310491SRishi.Srivatsavai@Sun.COM 335410491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 335510491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 335610491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 335710491SRishi.Srivatsavai@Sun.COM } else { 335810491SRishi.Srivatsavai@Sun.COM errno = 0; 335910491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 336010491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 336110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 336210491SRishi.Srivatsavai@Sun.COM } 336310491SRishi.Srivatsavai@Sun.COM } 336410491SRishi.Srivatsavai@Sun.COM 336510491SRishi.Srivatsavai@Sun.COM if (iscost) { 336610491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 336710491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 336810491SRishi.Srivatsavai@Sun.COM } else { 336910491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 337010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 337110491SRishi.Srivatsavai@Sun.COM /* 337210491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 337310491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 337410491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 337510491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 337610491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 337710491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 337810491SRishi.Srivatsavai@Sun.COM * can't be used now. 337910491SRishi.Srivatsavai@Sun.COM */ 338010491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 338110491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 338210491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 338310491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 338410491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 338510491SRishi.Srivatsavai@Sun.COM 338610491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 338710491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 338810491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 338910491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 339010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 339110491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 339210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 339310491SRishi.Srivatsavai@Sun.COM } 339410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 339510491SRishi.Srivatsavai@Sun.COM } 339610491SRishi.Srivatsavai@Sun.COM } 339710491SRishi.Srivatsavai@Sun.COM 339810491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 339910491SRishi.Srivatsavai@Sun.COM static dladm_status_t 340010491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 340110491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 340210491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 340310491SRishi.Srivatsavai@Sun.COM { 340410491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 340510491SRishi.Srivatsavai@Sun.COM uint_t val; 340610491SRishi.Srivatsavai@Sun.COM 340710491SRishi.Srivatsavai@Sun.COM if (flags != 0) 340810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 340910491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 341010491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 341110491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 341210491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 341310491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 341410491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 341510491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 341610491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 341710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 341810491SRishi.Srivatsavai@Sun.COM } 341910491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 342010491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 342110491SRishi.Srivatsavai@Sun.COM else 342210491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 342310491SRishi.Srivatsavai@Sun.COM return (retv); 342410491SRishi.Srivatsavai@Sun.COM } 342510491SRishi.Srivatsavai@Sun.COM 342610491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 342710491SRishi.Srivatsavai@Sun.COM static dladm_status_t 342810491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 342910491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 343010491SRishi.Srivatsavai@Sun.COM { 343110491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 343210491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 343310491SRishi.Srivatsavai@Sun.COM } 343410491SRishi.Srivatsavai@Sun.COM 343510491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 343610491SRishi.Srivatsavai@Sun.COM static dladm_status_t 343710491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 343810491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 343910491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 344010491SRishi.Srivatsavai@Sun.COM { 344110491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 344210491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 344310491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 344410491SRishi.Srivatsavai@Sun.COM 344510491SRishi.Srivatsavai@Sun.COM if (flags != 0) 344610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 344710491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 344810491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 344910491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 345010491SRishi.Srivatsavai@Sun.COM 0, &status); 345110491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 345210491SRishi.Srivatsavai@Sun.COM return (status); 345310491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 345410491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 345510491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 345610491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 345710491SRishi.Srivatsavai@Sun.COM } else { 345810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 345910491SRishi.Srivatsavai@Sun.COM } 346010491SRishi.Srivatsavai@Sun.COM free(dip); 346110491SRishi.Srivatsavai@Sun.COM return (status); 346210491SRishi.Srivatsavai@Sun.COM } 346310491SRishi.Srivatsavai@Sun.COM 346410491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 346510491SRishi.Srivatsavai@Sun.COM static dladm_status_t 346610491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 346710491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 346810491SRishi.Srivatsavai@Sun.COM { 346910491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 347010491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 347110491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 347210491SRishi.Srivatsavai@Sun.COM 347310491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 347410491SRishi.Srivatsavai@Sun.COM 0, &status); 347510491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 347610491SRishi.Srivatsavai@Sun.COM return (status); 347710491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 347810491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 347910491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 348010491SRishi.Srivatsavai@Sun.COM free(dip); 348110491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 348210491SRishi.Srivatsavai@Sun.COM return (status); 348310491SRishi.Srivatsavai@Sun.COM 348410491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 348510491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 348610491SRishi.Srivatsavai@Sun.COM } 348710491SRishi.Srivatsavai@Sun.COM 348810491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 348910491SRishi.Srivatsavai@Sun.COM static dladm_status_t 349010491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 349110491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, val_desc_t *vdp, 349210491SRishi.Srivatsavai@Sun.COM datalink_media_t media) 349310491SRishi.Srivatsavai@Sun.COM { 349410491SRishi.Srivatsavai@Sun.COM char *cp; 349510491SRishi.Srivatsavai@Sun.COM 349610491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 349710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 349810491SRishi.Srivatsavai@Sun.COM 349910491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 350010491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 350110491SRishi.Srivatsavai@Sun.COM } else { 350210491SRishi.Srivatsavai@Sun.COM errno = 0; 350310491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 350410491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 350510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 350610491SRishi.Srivatsavai@Sun.COM } 350710491SRishi.Srivatsavai@Sun.COM 350810491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 350910491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 351010491SRishi.Srivatsavai@Sun.COM } 351110491SRishi.Srivatsavai@Sun.COM 35127663SSowmini.Varadhan@Sun.COM dladm_status_t 35138453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 35148453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 35157663SSowmini.Varadhan@Sun.COM { 35167663SSowmini.Varadhan@Sun.COM uint32_t flags; 35177663SSowmini.Varadhan@Sun.COM dladm_status_t status; 35187663SSowmini.Varadhan@Sun.COM uint32_t media; 35197663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 35207663SSowmini.Varadhan@Sun.COM void *dp; 35217663SSowmini.Varadhan@Sun.COM 35228453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 35238453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 35247663SSowmini.Varadhan@Sun.COM return (status); 35257663SSowmini.Varadhan@Sun.COM } 35267663SSowmini.Varadhan@Sun.COM 35277663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 35287663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 35297663SSowmini.Varadhan@Sun.COM 35307663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 35317663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 35327663SSowmini.Varadhan@Sun.COM 35337663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 35347663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 35357663SSowmini.Varadhan@Sun.COM 35367663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 35377663SSowmini.Varadhan@Sun.COM if (dip == NULL) 35387663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 35397663SSowmini.Varadhan@Sun.COM 35407663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 35417663SSowmini.Varadhan@Sun.COM if (set) 35427663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 35437663SSowmini.Varadhan@Sun.COM 35448453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 354510191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 35467663SSowmini.Varadhan@Sun.COM if (!set) 35477663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 35487663SSowmini.Varadhan@Sun.COM } 35497663SSowmini.Varadhan@Sun.COM 35507663SSowmini.Varadhan@Sun.COM free(dip); 35517663SSowmini.Varadhan@Sun.COM return (status); 35527663SSowmini.Varadhan@Sun.COM } 35537663SSowmini.Varadhan@Sun.COM 35548275SEric Cheng dladm_status_t 35558275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 35568275SEric Cheng { 35578460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 35588275SEric Cheng } 35598275SEric Cheng 35608275SEric Cheng /* 35618275SEric Cheng * Retrieve the one link property from the database 35628275SEric Cheng */ 35638275SEric Cheng /*ARGSUSED*/ 35648275SEric Cheng static int 35658453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 35668453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 35678275SEric Cheng { 35688275SEric Cheng dladm_arg_list_t *proplist = arg; 35698275SEric Cheng dladm_arg_info_t *aip = NULL; 35708275SEric Cheng 35718275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 35728275SEric Cheng /* 35738275SEric Cheng * it is fine to point to prop_name since prop_name points to the 35748275SEric Cheng * prop_table[n].pd_name. 35758275SEric Cheng */ 35768275SEric Cheng aip->ai_name = prop_name; 35778275SEric Cheng 35788453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 35798453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 35808275SEric Cheng 35818275SEric Cheng if (aip->ai_count != 0) 35828275SEric Cheng proplist->al_count++; 35838275SEric Cheng 35848275SEric Cheng return (DLADM_WALK_CONTINUE); 35858275SEric Cheng } 35868275SEric Cheng 35878275SEric Cheng 35888275SEric Cheng /* 35898275SEric Cheng * Retrieve all link properties for a link from the database and 35908275SEric Cheng * return a property list. 35918275SEric Cheng */ 35928275SEric Cheng dladm_status_t 35938453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 35948453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 35958275SEric Cheng { 35968275SEric Cheng dladm_arg_list_t *list; 35978275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 35988275SEric Cheng 35998275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 36008275SEric Cheng if (list == NULL) 36018275SEric Cheng return (dladm_errno2status(errno)); 36028275SEric Cheng 36038453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 36048453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 36058275SEric Cheng 36068275SEric Cheng *listp = list; 36078275SEric Cheng return (status); 36088275SEric Cheng } 36098275SEric Cheng 36108275SEric Cheng /* 36118275SEric Cheng * Retrieve the named property from a proplist, check the value and 36128275SEric Cheng * convert to a kernel structure. 36138275SEric Cheng */ 36148275SEric Cheng static dladm_status_t 36158453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 361610734SEric Cheng dladm_arg_list_t *proplist, const char *name, void *arg) 36178275SEric Cheng { 36188275SEric Cheng dladm_status_t status; 36198275SEric Cheng dladm_arg_info_t *aip = NULL; 36208275SEric Cheng int i, j; 36218275SEric Cheng 36228275SEric Cheng /* Find named property in proplist */ 36238275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 36248275SEric Cheng aip = &proplist->al_info[i]; 36258275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 36268275SEric Cheng break; 36278275SEric Cheng } 36288275SEric Cheng 36298275SEric Cheng /* Property not in list */ 36308275SEric Cheng if (i == proplist->al_count) 36318275SEric Cheng return (DLADM_STATUS_OK); 36328275SEric Cheng 36338275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 36348275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 36358275SEric Cheng val_desc_t *vdp; 36368275SEric Cheng 36378275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 36388275SEric Cheng if (vdp == NULL) 36398275SEric Cheng return (DLADM_STATUS_NOMEM); 36408275SEric Cheng 36418275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 36428275SEric Cheng continue; 36438275SEric Cheng 36448275SEric Cheng if (aip->ai_val == NULL) 36458275SEric Cheng return (DLADM_STATUS_BADARG); 36468275SEric Cheng 36478275SEric Cheng /* Check property value */ 36488275SEric Cheng if (pdp->pd_check != NULL) { 36498453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 36508275SEric Cheng aip->ai_count, vdp, 0); 36518275SEric Cheng } else { 36528275SEric Cheng status = DLADM_STATUS_BADARG; 36538275SEric Cheng } 36548275SEric Cheng 36558275SEric Cheng if (status != DLADM_STATUS_OK) 36568275SEric Cheng return (status); 36578275SEric Cheng 36588275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 36598275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 36608275SEric Cheng 36618275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 36628275SEric Cheng continue; 36638275SEric Cheng 36648275SEric Cheng /* Extract kernel structure */ 36658275SEric Cheng if (rpp->rp_extract != NULL) { 366610734SEric Cheng status = rpp->rp_extract(vdp, 366710734SEric Cheng aip->ai_count, arg); 36688275SEric Cheng } else { 36698275SEric Cheng status = DLADM_STATUS_BADARG; 36708275SEric Cheng } 36718275SEric Cheng break; 36728275SEric Cheng } 36738275SEric Cheng 36748275SEric Cheng if (status != DLADM_STATUS_OK) 36758275SEric Cheng return (status); 36768275SEric Cheng 36778275SEric Cheng break; 36788275SEric Cheng } 36798275SEric Cheng return (status); 36808275SEric Cheng } 36818275SEric Cheng 36828275SEric Cheng /* 36838275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 36848275SEric Cheng */ 36858275SEric Cheng dladm_status_t 36868453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 36878275SEric Cheng mac_resource_props_t *mrp) 36888275SEric Cheng { 368910734SEric Cheng dladm_status_t status; 369010734SEric Cheng int i; 369110734SEric Cheng 369210734SEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 369310734SEric Cheng status = i_dladm_link_proplist_extract_one(handle, 369410734SEric Cheng proplist, rsrc_prop_table[i].rp_name, mrp); 369510734SEric Cheng if (status != DLADM_STATUS_OK) 369610734SEric Cheng return (status); 369710734SEric Cheng } 36988275SEric Cheng return (status); 36998275SEric Cheng } 37008275SEric Cheng 37018275SEric Cheng static const char * 37028275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 37038275SEric Cheng { 37048275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 37058275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 37068275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 37078275SEric Cheng return (buf); 37088275SEric Cheng } 37098306SSowmini.Varadhan@Sun.COM 37108306SSowmini.Varadhan@Sun.COM dladm_status_t 37118453SAnurag.Maskey@Sun.COM i_dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 37128453SAnurag.Maskey@Sun.COM link_state_t *state) 37138306SSowmini.Varadhan@Sun.COM { 37148306SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 37158306SSowmini.Varadhan@Sun.COM dladm_status_t status; 37168306SSowmini.Varadhan@Sun.COM uint_t perms; 37178306SSowmini.Varadhan@Sun.COM 37188453SAnurag.Maskey@Sun.COM dip = i_dladm_get_public_prop(handle, linkid, "state", 0, &status, 37198453SAnurag.Maskey@Sun.COM &perms); 37208306SSowmini.Varadhan@Sun.COM if (status != DLADM_STATUS_OK) 37218306SSowmini.Varadhan@Sun.COM return (status); 37228306SSowmini.Varadhan@Sun.COM (void) memcpy(state, dip->pr_val, sizeof (*state)); 37238306SSowmini.Varadhan@Sun.COM free(dip); 37248306SSowmini.Varadhan@Sun.COM return (status); 37258306SSowmini.Varadhan@Sun.COM } 37268460SArtem.Kachitchkin@Sun.COM 37278460SArtem.Kachitchkin@Sun.COM boolean_t 37288460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 37298460SArtem.Kachitchkin@Sun.COM { 37308460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 37318460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 37328460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 37338460SArtem.Kachitchkin@Sun.COM "name", 37348460SArtem.Kachitchkin@Sun.COM "class", 37358460SArtem.Kachitchkin@Sun.COM "media", 37368460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 37378460SArtem.Kachitchkin@Sun.COM FPHYINST, 37388460SArtem.Kachitchkin@Sun.COM FDEVNAME, 37398460SArtem.Kachitchkin@Sun.COM 37408460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 37418460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 37428460SArtem.Kachitchkin@Sun.COM }; 37438460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 37448460SArtem.Kachitchkin@Sun.COM int i; 37458460SArtem.Kachitchkin@Sun.COM 37468460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 37478460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 37488460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 37498460SArtem.Kachitchkin@Sun.COM break; 37508460SArtem.Kachitchkin@Sun.COM } 37518460SArtem.Kachitchkin@Sun.COM } 37528460SArtem.Kachitchkin@Sun.COM 37538460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 37548460SArtem.Kachitchkin@Sun.COM } 3755