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 /* 2212163SRamaswamy.Tummala@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 233147Sxc151355 */ 243147Sxc151355 253147Sxc151355 #include <stdlib.h> 2612742Smichael.l.lim@oracle.com #include <string.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> 4512163SRamaswamy.Tummala@Sun.COM #include <libdlib.h> 468275SEric Cheng #include <libintl.h> 473448Sdh155122 #include <dlfcn.h> 483448Sdh155122 #include <link.h> 495895Syz147064 #include <inet/wifi_ioctl.h> 505903Ssowmini #include <libdladm.h> 518275SEric Cheng #include <libdlstat.h> 525903Ssowmini #include <sys/param.h> 538275SEric Cheng #include <sys/debug.h> 548275SEric Cheng #include <sys/dld.h> 555903Ssowmini #include <inttypes.h> 565903Ssowmini #include <sys/ethernet.h> 5710616SSebastien.Roy@Sun.COM #include <inet/iptun.h> 587663SSowmini.Varadhan@Sun.COM #include <net/wpa.h> 597663SSowmini.Varadhan@Sun.COM #include <sys/sysmacros.h> 6010491SRishi.Srivatsavai@Sun.COM #include <sys/vlan.h> 6110491SRishi.Srivatsavai@Sun.COM #include <libdlbridge.h> 6210491SRishi.Srivatsavai@Sun.COM #include <stp_in.h> 6311878SVenu.Iyer@Sun.COM #include <netinet/dhcp.h> 6411878SVenu.Iyer@Sun.COM #include <netinet/dhcp6.h> 6511878SVenu.Iyer@Sun.COM #include <net/if_types.h> 6611878SVenu.Iyer@Sun.COM #include <libinetutil.h> 6711878SVenu.Iyer@Sun.COM #include <pool.h> 683448Sdh155122 695895Syz147064 /* 705895Syz147064 * The linkprop get() callback. 718275SEric Cheng * - pd: pointer to the prop_desc_t 725895Syz147064 * - propstrp: a property string array to keep the returned property. 735895Syz147064 * Caller allocated. 745895Syz147064 * - cntp: number of returned properties. 755895Syz147064 * Caller also uses it to indicate how many it expects. 765895Syz147064 */ 775903Ssowmini struct prop_desc; 788275SEric Cheng typedef struct prop_desc prop_desc_t; 798275SEric Cheng 808453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 815960Ssowmini datalink_id_t, char **propstp, uint_t *cntp, 828118SVasumathi.Sundaram@Sun.COM datalink_media_t, uint_t, uint_t *); 835895Syz147064 845895Syz147064 /* 855895Syz147064 * The linkprop set() callback. 865895Syz147064 * - propval: a val_desc_t array which keeps the property values to be set. 875895Syz147064 * - cnt: number of properties to be set. 885903Ssowmini * - flags: additional flags passed down the system call. 895903Ssowmini * 905903Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 915903Ssowmini * a format suitable for kernel consumption. This may require allocation 925903Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 935903Ssowmini * by all other pd_sets) which invokes the ioctl. 945895Syz147064 */ 958453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 968275SEric Cheng val_desc_t *propval, uint_t cnt, uint_t flags, 978275SEric Cheng datalink_media_t); 983448Sdh155122 995895Syz147064 /* 1005895Syz147064 * The linkprop check() callback. 1015895Syz147064 * - propstrp: property string array which keeps the property to be checked. 1025895Syz147064 * - cnt: number of properties. 1035895Syz147064 * - propval: return value; the property values of the given property strings. 1045903Ssowmini * 1055903Ssowmini * pd_check checks that the input values are valid. It does so by 1065903Ssowmini * iteraring through the pd_modval list for the property. If 1075903Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 1085903Ssowmini * specific to this property can be used. If the input values are 1095903Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 1105903Ssowmini * with either a val_desc_t found on the pd_modval list or something 1115903Ssowmini * generated on the fly. 1125895Syz147064 */ 1138453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 11412742Smichael.l.lim@oracle.com datalink_id_t, char **propstrp, uint_t *cnt, 11512742Smichael.l.lim@oracle.com uint_t flags, val_desc_t **propval, 11611878SVenu.Iyer@Sun.COM datalink_media_t); 1173448Sdh155122 1187663SSowmini.Varadhan@Sun.COM typedef struct link_attr_s { 1196789Sam223141 mac_prop_id_t pp_id; 1205903Ssowmini size_t pp_valsize; 1215903Ssowmini char *pp_name; 1227663SSowmini.Varadhan@Sun.COM } link_attr_t; 1235903Ssowmini 12411878SVenu.Iyer@Sun.COM typedef struct dladm_linkprop_args_s { 12511878SVenu.Iyer@Sun.COM dladm_status_t dla_status; 12611878SVenu.Iyer@Sun.COM uint_t dla_flags; 12711878SVenu.Iyer@Sun.COM } dladm_linkprop_args_t; 12811878SVenu.Iyer@Sun.COM 1297663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 1308275SEric Cheng const char *, uint_t, dladm_status_t *); 1317663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 1328275SEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 13311878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 13411878SVenu.Iyer@Sun.COM char *, uint_t, uint_t *, void *, size_t); 13511878SVenu.Iyer@Sun.COM 13611878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1378453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 13811878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1398453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *, dladm_prop_type_t, 1408453SAnurag.Maskey@Sun.COM uint_t); 1418453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1428275SEric Cheng static const char *dladm_perm2str(uint_t, char *); 14311878SVenu.Iyer@Sun.COM static link_attr_t *dladm_name2prop(const char *); 14411878SVenu.Iyer@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 14511878SVenu.Iyer@Sun.COM 14611878SVenu.Iyer@Sun.COM static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 14711878SVenu.Iyer@Sun.COM get_speed, get_channel, get_powermode, get_radio, 14811878SVenu.Iyer@Sun.COM get_duplex, get_link_state, get_binary, get_uint32, 14911878SVenu.Iyer@Sun.COM get_flowctl, get_maxbw, get_cpus, get_priority, 15011878SVenu.Iyer@Sun.COM get_tagmode, get_range, get_stp, get_bridge_forward, 15111878SVenu.Iyer@Sun.COM get_bridge_pvid, get_protection, get_rxrings, 15211878SVenu.Iyer@Sun.COM get_txrings, get_cntavail, 15311878SVenu.Iyer@Sun.COM get_allowedips, get_allowedcids, get_pool, 15412163SRamaswamy.Tummala@Sun.COM get_rings_range, get_linkmode_prop; 15511878SVenu.Iyer@Sun.COM 15611878SVenu.Iyer@Sun.COM static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 15711878SVenu.Iyer@Sun.COM set_public_prop, set_resource, set_stp_prop, 15811878SVenu.Iyer@Sun.COM set_bridge_forward, set_bridge_pvid; 15911878SVenu.Iyer@Sun.COM 16011878SVenu.Iyer@Sun.COM static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 16111878SVenu.Iyer@Sun.COM check_encaplim, check_uint32, check_maxbw, check_cpus, 16211878SVenu.Iyer@Sun.COM check_stp_prop, check_bridge_pvid, check_allowedips, 16311878SVenu.Iyer@Sun.COM check_allowedcids, check_rings, 16411878SVenu.Iyer@Sun.COM check_pool, check_prop; 1658275SEric Cheng 1668275SEric Cheng struct prop_desc { 1675895Syz147064 /* 1685895Syz147064 * link property name 1695895Syz147064 */ 1705895Syz147064 char *pd_name; 1715895Syz147064 1725895Syz147064 /* 1735895Syz147064 * default property value, can be set to { "", NULL } 1745895Syz147064 */ 1755895Syz147064 val_desc_t pd_defval; 1765895Syz147064 1775895Syz147064 /* 1785895Syz147064 * list of optional property values, can be NULL. 1795895Syz147064 * 1805895Syz147064 * This is set to non-NULL if there is a list of possible property 1815895Syz147064 * values. pd_optval would point to the array of possible values. 1825895Syz147064 */ 1835895Syz147064 val_desc_t *pd_optval; 1845895Syz147064 1855895Syz147064 /* 1865895Syz147064 * count of the above optional property values. 0 if pd_optval is NULL. 1875895Syz147064 */ 1885895Syz147064 uint_t pd_noptval; 1895895Syz147064 1905895Syz147064 /* 19110491SRishi.Srivatsavai@Sun.COM * callback to set link property; set to NULL if this property is 19210491SRishi.Srivatsavai@Sun.COM * read-only and may be called before or after permanent update; see 19310491SRishi.Srivatsavai@Sun.COM * flags. 1945895Syz147064 */ 1955895Syz147064 pd_setf_t *pd_set; 1965895Syz147064 1975895Syz147064 /* 1985895Syz147064 * callback to get modifiable link property 1995895Syz147064 */ 2005895Syz147064 pd_getf_t *pd_getmod; 2015895Syz147064 2025895Syz147064 /* 2035895Syz147064 * callback to get current link property 2045895Syz147064 */ 2055895Syz147064 pd_getf_t *pd_get; 2065895Syz147064 2075895Syz147064 /* 2085895Syz147064 * callback to validate link property value, set to NULL if pd_optval 2095895Syz147064 * is not NULL. In that case, validate the value by comparing it with 2105895Syz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 2115895Syz147064 * valid. 2125895Syz147064 */ 2135895Syz147064 pd_checkf_t *pd_check; 2145895Syz147064 2155895Syz147064 uint_t pd_flags; 2165903Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 2175903Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 21810491SRishi.Srivatsavai@Sun.COM #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 2195895Syz147064 /* 2205895Syz147064 * indicate link classes this property applies to. 2215895Syz147064 */ 2225895Syz147064 datalink_class_t pd_class; 2235895Syz147064 2245895Syz147064 /* 2255895Syz147064 * indicate link media type this property applies to. 2265895Syz147064 */ 2275895Syz147064 datalink_media_t pd_dmedia; 2288275SEric Cheng }; 2293448Sdh155122 2306789Sam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 2315903Ssowmini 2327663SSowmini.Varadhan@Sun.COM /* 2337663SSowmini.Varadhan@Sun.COM * Supported link properties enumerated in the prop_table[] array are 2347663SSowmini.Varadhan@Sun.COM * computed using the callback functions in that array. To compute the 2357663SSowmini.Varadhan@Sun.COM * property value, multiple distinct system calls may be needed (e.g., 2367663SSowmini.Varadhan@Sun.COM * for wifi speed, we need to issue system calls to get desired/supported 2377663SSowmini.Varadhan@Sun.COM * rates). The link_attr[] table enumerates the interfaces to the kernel, 2387663SSowmini.Varadhan@Sun.COM * and the type/size of the data passed in the user-kernel interface. 2397663SSowmini.Varadhan@Sun.COM */ 2407663SSowmini.Varadhan@Sun.COM static link_attr_t link_attr[] = { 2417663SSowmini.Varadhan@Sun.COM { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 2425903Ssowmini 2437663SSowmini.Varadhan@Sun.COM { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 2447663SSowmini.Varadhan@Sun.COM 2457663SSowmini.Varadhan@Sun.COM { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 2467663SSowmini.Varadhan@Sun.COM 2477663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 2485903Ssowmini 2497663SSowmini.Varadhan@Sun.COM { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 2505903Ssowmini 2517663SSowmini.Varadhan@Sun.COM { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 2527663SSowmini.Varadhan@Sun.COM 2537663SSowmini.Varadhan@Sun.COM { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 2545903Ssowmini 2557663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2567663SSowmini.Varadhan@Sun.COM 2579449Sxiuyan.wang@Sun.COM { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 2589449Sxiuyan.wang@Sun.COM 2599449Sxiuyan.wang@Sun.COM { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 2609449Sxiuyan.wang@Sun.COM 2617663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2627663SSowmini.Varadhan@Sun.COM 2637663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 2645903Ssowmini 2657663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 2665903Ssowmini 2677663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 2687663SSowmini.Varadhan@Sun.COM 2697663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 2707342SAruna.Ramakrishna@Sun.COM 2717663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 2727663SSowmini.Varadhan@Sun.COM 2737663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 2747663SSowmini.Varadhan@Sun.COM 2757663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 2767342SAruna.Ramakrishna@Sun.COM 2777663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 2787663SSowmini.Varadhan@Sun.COM 2797663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 2805903Ssowmini 2817663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 2827663SSowmini.Varadhan@Sun.COM 2837663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 2845903Ssowmini 2857663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 2867663SSowmini.Varadhan@Sun.COM 2877663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 2885903Ssowmini 2897663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 2907663SSowmini.Varadhan@Sun.COM 2917663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 2927663SSowmini.Varadhan@Sun.COM 2937663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2947663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 2955903Ssowmini 2967663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2977663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 2987663SSowmini.Varadhan@Sun.COM 2997663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 3005903Ssowmini 3017663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 3027663SSowmini.Varadhan@Sun.COM 3037663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 3045903Ssowmini 3057663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 3067663SSowmini.Varadhan@Sun.COM 3077663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 3085903Ssowmini 3097663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 3107663SSowmini.Varadhan@Sun.COM 3117663SSowmini.Varadhan@Sun.COM /* wl_wpa_ess_t has variable length */ 3127663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 3135903Ssowmini 3147663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 3157663SSowmini.Varadhan@Sun.COM 3167663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 3175903Ssowmini 3187663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 3197663SSowmini.Varadhan@Sun.COM 3207663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 3215903Ssowmini 3227663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 3237663SSowmini.Varadhan@Sun.COM 3247663SSowmini.Varadhan@Sun.COM /* wl_wpa_ie_t has variable length */ 3257663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 3265903Ssowmini 3277663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 3287663SSowmini.Varadhan@Sun.COM 3297663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 3305903Ssowmini 3317663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 3327663SSowmini.Varadhan@Sun.COM 3338874SSebastien.Roy@Sun.COM { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 3348874SSebastien.Roy@Sun.COM 33510616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 33610616SSebastien.Roy@Sun.COM 33710616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 33810616SSebastien.Roy@Sun.COM 33910491SRishi.Srivatsavai@Sun.COM { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 34010491SRishi.Srivatsavai@Sun.COM 34110491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 34210491SRishi.Srivatsavai@Sun.COM 34310491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 34410491SRishi.Srivatsavai@Sun.COM 34511878SVenu.Iyer@Sun.COM { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 34611878SVenu.Iyer@Sun.COM 34711878SVenu.Iyer@Sun.COM { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 34811878SVenu.Iyer@Sun.COM "resource-effective"}, 34911878SVenu.Iyer@Sun.COM 35011878SVenu.Iyer@Sun.COM { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 35111878SVenu.Iyer@Sun.COM 35211878SVenu.Iyer@Sun.COM { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 35311878SVenu.Iyer@Sun.COM 35411878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 35511878SVenu.Iyer@Sun.COM "txrings-available"}, 35611878SVenu.Iyer@Sun.COM 35711878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 35811878SVenu.Iyer@Sun.COM "rxrings-available"}, 35911878SVenu.Iyer@Sun.COM 36011878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 36111878SVenu.Iyer@Sun.COM 36211878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 36310734SEric Cheng 36412163SRamaswamy.Tummala@Sun.COM { MAC_PROP_IB_LINKMODE, sizeof (uint32_t), "linkmode"}, 36512163SRamaswamy.Tummala@Sun.COM 3667663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3675903Ssowmini }; 3685903Ssowmini 36910491SRishi.Srivatsavai@Sun.COM typedef struct bridge_public_prop_s { 37010491SRishi.Srivatsavai@Sun.COM const char *bpp_name; 37110491SRishi.Srivatsavai@Sun.COM int bpp_code; 37210491SRishi.Srivatsavai@Sun.COM } bridge_public_prop_t; 37310491SRishi.Srivatsavai@Sun.COM 37410491SRishi.Srivatsavai@Sun.COM static const bridge_public_prop_t bridge_prop[] = { 37510491SRishi.Srivatsavai@Sun.COM { "stp", PT_CFG_NON_STP }, 37610491SRishi.Srivatsavai@Sun.COM { "stp_priority", PT_CFG_PRIO }, 37710491SRishi.Srivatsavai@Sun.COM { "stp_cost", PT_CFG_COST }, 37810491SRishi.Srivatsavai@Sun.COM { "stp_edge", PT_CFG_EDGE }, 37910491SRishi.Srivatsavai@Sun.COM { "stp_p2p", PT_CFG_P2P }, 38010491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", PT_CFG_MCHECK }, 38110491SRishi.Srivatsavai@Sun.COM { NULL, 0 } 38210491SRishi.Srivatsavai@Sun.COM }; 38310491SRishi.Srivatsavai@Sun.COM 3845903Ssowmini static val_desc_t link_duplex_vals[] = { 3855903Ssowmini { "half", LINK_DUPLEX_HALF }, 3865903Ssowmini { "full", LINK_DUPLEX_HALF } 3875903Ssowmini }; 3885903Ssowmini static val_desc_t link_status_vals[] = { 3895903Ssowmini { "up", LINK_STATE_UP }, 3905903Ssowmini { "down", LINK_STATE_DOWN } 3915903Ssowmini }; 3925903Ssowmini static val_desc_t link_01_vals[] = { 3935903Ssowmini { "1", 1 }, 3945903Ssowmini { "0", 0 } 3955903Ssowmini }; 3965903Ssowmini static val_desc_t link_flow_vals[] = { 3975903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3985903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3995903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 4005903Ssowmini { "bi", LINK_FLOWCTRL_BI } 4015903Ssowmini }; 4028275SEric Cheng static val_desc_t link_priority_vals[] = { 4038275SEric Cheng { "low", MPL_LOW }, 4048275SEric Cheng { "medium", MPL_MEDIUM }, 4058275SEric Cheng { "high", MPL_HIGH } 4068275SEric Cheng }; 4075903Ssowmini 4088874SSebastien.Roy@Sun.COM static val_desc_t link_tagmode_vals[] = { 4098874SSebastien.Roy@Sun.COM { "normal", LINK_TAGMODE_NORMAL }, 4108874SSebastien.Roy@Sun.COM { "vlanonly", LINK_TAGMODE_VLANONLY } 4118874SSebastien.Roy@Sun.COM }; 4128874SSebastien.Roy@Sun.COM 41310734SEric Cheng static val_desc_t link_protect_vals[] = { 41410734SEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 41511878SVenu.Iyer@Sun.COM { "restricted", MPT_RESTRICTED }, 41610734SEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 41711878SVenu.Iyer@Sun.COM { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 41810734SEric Cheng }; 41910734SEric Cheng 4205895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 4215895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 4225895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 4235895Syz147064 }; 4245895Syz147064 4255895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 4265895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 4275895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 4285895Syz147064 { "max", DLADM_WLAN_PM_MAX } 4295895Syz147064 }; 4305895Syz147064 43110491SRishi.Srivatsavai@Sun.COM static val_desc_t stp_p2p_vals[] = { 43210491SRishi.Srivatsavai@Sun.COM { "true", P2P_FORCE_TRUE }, 43310491SRishi.Srivatsavai@Sun.COM { "false", P2P_FORCE_FALSE }, 43410491SRishi.Srivatsavai@Sun.COM { "auto", P2P_AUTO } 43510491SRishi.Srivatsavai@Sun.COM }; 43610491SRishi.Srivatsavai@Sun.COM 43712303SRajkumar.Sivaprakasam@Sun.COM static val_desc_t dladm_part_linkmode_vals[] = { 43812303SRajkumar.Sivaprakasam@Sun.COM { "cm", DLADM_PART_CM_MODE }, 43912303SRajkumar.Sivaprakasam@Sun.COM { "ud", DLADM_PART_UD_MODE }, 44012163SRamaswamy.Tummala@Sun.COM }; 44112163SRamaswamy.Tummala@Sun.COM 4428275SEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 4438275SEric Cheng #define RESET_VAL ((uintptr_t)-1) 44411878SVenu.Iyer@Sun.COM #define UNSPEC_VAL ((uintptr_t)-2) 4458275SEric Cheng 4463448Sdh155122 static prop_desc_t prop_table[] = { 4475903Ssowmini { "channel", { NULL, 0 }, 4485903Ssowmini NULL, 0, NULL, NULL, 44911878SVenu.Iyer@Sun.COM get_channel, NULL, 0, 4505903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4515895Syz147064 4525895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 4535895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 45411878SVenu.Iyer@Sun.COM set_powermode, NULL, 45511878SVenu.Iyer@Sun.COM get_powermode, NULL, 0, 4565903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4575895Syz147064 4585895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 4595895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 46011878SVenu.Iyer@Sun.COM set_radio, NULL, 46111878SVenu.Iyer@Sun.COM get_radio, NULL, 0, 4625903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4635895Syz147064 46412303SRajkumar.Sivaprakasam@Sun.COM { "linkmode", { "cm", DLADM_PART_CM_MODE }, 46512303SRajkumar.Sivaprakasam@Sun.COM dladm_part_linkmode_vals, VALCNT(dladm_part_linkmode_vals), 46612163SRamaswamy.Tummala@Sun.COM set_public_prop, NULL, get_linkmode_prop, NULL, 0, 46712163SRamaswamy.Tummala@Sun.COM DATALINK_CLASS_PART, DL_IB }, 46812163SRamaswamy.Tummala@Sun.COM 4695895Syz147064 { "speed", { "", 0 }, NULL, 0, 47011878SVenu.Iyer@Sun.COM set_rate, get_rate_mod, 47111878SVenu.Iyer@Sun.COM get_rate, check_rate, 0, 4725960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 4735895Syz147064 4746512Ssowmini { "autopush", { "", 0 }, NULL, 0, 47511878SVenu.Iyer@Sun.COM set_public_prop, NULL, 47611878SVenu.Iyer@Sun.COM get_autopush, check_autopush, PD_CHECK_ALLOC, 4775903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4785895Syz147064 4796512Ssowmini { "zone", { "", 0 }, NULL, 0, 48011878SVenu.Iyer@Sun.COM set_zone, NULL, 48111878SVenu.Iyer@Sun.COM get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 4825903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4835903Ssowmini 4848275SEric Cheng { "duplex", { "", 0 }, 4855903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 48611878SVenu.Iyer@Sun.COM NULL, NULL, get_duplex, NULL, 4875903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4885903Ssowmini 4898275SEric Cheng { "state", { "up", LINK_STATE_UP }, 4905903Ssowmini link_status_vals, VALCNT(link_status_vals), 49111878SVenu.Iyer@Sun.COM NULL, NULL, get_link_state, NULL, 4926512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4935903Ssowmini 49410191SSowmini.Varadhan@Sun.COM { "adv_autoneg_cap", { "", 0 }, 4955903Ssowmini link_01_vals, VALCNT(link_01_vals), 49611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 4975903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4985903Ssowmini 4996512Ssowmini { "mtu", { "", 0 }, NULL, 0, 50011878SVenu.Iyer@Sun.COM set_public_prop, get_range, 50111878SVenu.Iyer@Sun.COM get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 5027342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 5035903Ssowmini 5046512Ssowmini { "flowctrl", { "", 0 }, 5055903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 50611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_flowctl, NULL, 5075903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5085903Ssowmini 5099449Sxiuyan.wang@Sun.COM { "adv_10gfdx_cap", { "", 0 }, 5109449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 51111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5129449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5139449Sxiuyan.wang@Sun.COM 5149449Sxiuyan.wang@Sun.COM { "en_10gfdx_cap", { "", 0 }, 5159449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 51611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5179449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5189449Sxiuyan.wang@Sun.COM 5196512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 5206512Ssowmini link_01_vals, VALCNT(link_01_vals), 52111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5225903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5235903Ssowmini 5246512Ssowmini { "en_1000fdx_cap", { "", 0 }, 5255903Ssowmini link_01_vals, VALCNT(link_01_vals), 52611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5275903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5285903Ssowmini 5296512Ssowmini { "adv_1000hdx_cap", { "", 0 }, 5305903Ssowmini link_01_vals, VALCNT(link_01_vals), 53111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5325903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5335903Ssowmini 5346512Ssowmini { "en_1000hdx_cap", { "", 0 }, 5355903Ssowmini link_01_vals, VALCNT(link_01_vals), 53611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5375903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5385903Ssowmini 5396512Ssowmini { "adv_100fdx_cap", { "", 0 }, 5405903Ssowmini link_01_vals, VALCNT(link_01_vals), 54111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5425903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5435903Ssowmini 5446512Ssowmini { "en_100fdx_cap", { "", 0 }, 5455903Ssowmini link_01_vals, VALCNT(link_01_vals), 54611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5475903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5485903Ssowmini 5496512Ssowmini { "adv_100hdx_cap", { "", 0 }, 5505903Ssowmini link_01_vals, VALCNT(link_01_vals), 55111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5525903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5535903Ssowmini 5546512Ssowmini { "en_100hdx_cap", { "", 0 }, 5555903Ssowmini link_01_vals, VALCNT(link_01_vals), 55611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5575903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5585903Ssowmini 5596512Ssowmini { "adv_10fdx_cap", { "", 0 }, 5605903Ssowmini link_01_vals, VALCNT(link_01_vals), 56111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5625903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5635903Ssowmini 5646512Ssowmini { "en_10fdx_cap", { "", 0 }, 5655903Ssowmini link_01_vals, VALCNT(link_01_vals), 56611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5675903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5685903Ssowmini 5696512Ssowmini { "adv_10hdx_cap", { "", 0 }, 5705903Ssowmini link_01_vals, VALCNT(link_01_vals), 57111878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5725903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5735903Ssowmini 5746512Ssowmini { "en_10hdx_cap", { "", 0 }, 5755903Ssowmini link_01_vals, VALCNT(link_01_vals), 57611878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5778275SEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5788275SEric Cheng 5798275SEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 58011878SVenu.Iyer@Sun.COM set_resource, NULL, 58111878SVenu.Iyer@Sun.COM get_maxbw, check_maxbw, PD_CHECK_ALLOC, 5828275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5838275SEric Cheng 5848275SEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 58511878SVenu.Iyer@Sun.COM set_resource, NULL, 58611878SVenu.Iyer@Sun.COM get_cpus, check_cpus, 0, 58711878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 58811878SVenu.Iyer@Sun.COM 58911878SVenu.Iyer@Sun.COM { "cpus-effective", { "--", 0 }, 59011878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 59111878SVenu.Iyer@Sun.COM get_cpus, 0, 0, 5928275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5938275SEric Cheng 59411878SVenu.Iyer@Sun.COM { "pool", { "--", RESET_VAL }, NULL, 0, 59511878SVenu.Iyer@Sun.COM set_resource, NULL, 59611878SVenu.Iyer@Sun.COM get_pool, check_pool, 0, 59711878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 59811878SVenu.Iyer@Sun.COM 59911878SVenu.Iyer@Sun.COM { "pool-effective", { "--", 0 }, 60011878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 60111878SVenu.Iyer@Sun.COM get_pool, 0, 0, 60211878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 60311878SVenu.Iyer@Sun.COM 60411878SVenu.Iyer@Sun.COM { "priority", { "high", MPL_RESET }, 60511878SVenu.Iyer@Sun.COM link_priority_vals, VALCNT(link_priority_vals), set_resource, 60611878SVenu.Iyer@Sun.COM NULL, get_priority, check_prop, 0, 6078275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6088874SSebastien.Roy@Sun.COM 6098874SSebastien.Roy@Sun.COM { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 6108874SSebastien.Roy@Sun.COM link_tagmode_vals, VALCNT(link_tagmode_vals), 61111878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_tagmode, 6128874SSebastien.Roy@Sun.COM NULL, 0, 6138874SSebastien.Roy@Sun.COM DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 61410491SRishi.Srivatsavai@Sun.COM DL_ETHER }, 61510491SRishi.Srivatsavai@Sun.COM 61610616SSebastien.Roy@Sun.COM { "hoplimit", { "", 0 }, NULL, 0, 61711878SVenu.Iyer@Sun.COM set_public_prop, get_range, get_uint32, 61811878SVenu.Iyer@Sun.COM check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 61910616SSebastien.Roy@Sun.COM 62010616SSebastien.Roy@Sun.COM { "encaplimit", { "", 0 }, NULL, 0, 62111878SVenu.Iyer@Sun.COM set_public_prop, get_range, get_uint32, 62211878SVenu.Iyer@Sun.COM check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 62310616SSebastien.Roy@Sun.COM 62410491SRishi.Srivatsavai@Sun.COM { "forward", { "1", 1 }, 62510491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 62610491SRishi.Srivatsavai@Sun.COM set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 62710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 62810491SRishi.Srivatsavai@Sun.COM 62910491SRishi.Srivatsavai@Sun.COM { "default_tag", { "1", 1 }, NULL, 0, 63010491SRishi.Srivatsavai@Sun.COM set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 63110491SRishi.Srivatsavai@Sun.COM 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 63210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 63310491SRishi.Srivatsavai@Sun.COM 63410491SRishi.Srivatsavai@Sun.COM { "learn_limit", { "1000", 1000 }, NULL, 0, 63511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_uint32, 63611878SVenu.Iyer@Sun.COM check_uint32, 0, 63710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 63810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 63910491SRishi.Srivatsavai@Sun.COM 64010491SRishi.Srivatsavai@Sun.COM { "learn_decay", { "200", 200 }, NULL, 0, 64111878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_uint32, 64211878SVenu.Iyer@Sun.COM check_uint32, 0, 64310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 64410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 64510491SRishi.Srivatsavai@Sun.COM 64610491SRishi.Srivatsavai@Sun.COM { "stp", { "1", 1 }, 64710491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 64811878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 64910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 65010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 65110491SRishi.Srivatsavai@Sun.COM 65210491SRishi.Srivatsavai@Sun.COM { "stp_priority", { "128", 128 }, NULL, 0, 65311878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 65410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 65510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 65610491SRishi.Srivatsavai@Sun.COM 65710491SRishi.Srivatsavai@Sun.COM { "stp_cost", { "auto", 0 }, NULL, 0, 65811878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 65910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 66010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 66110491SRishi.Srivatsavai@Sun.COM 66210491SRishi.Srivatsavai@Sun.COM { "stp_edge", { "1", 1 }, 66310491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 66411878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 66510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 66610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 66710491SRishi.Srivatsavai@Sun.COM 66810491SRishi.Srivatsavai@Sun.COM { "stp_p2p", { "auto", P2P_AUTO }, 66910491SRishi.Srivatsavai@Sun.COM stp_p2p_vals, VALCNT(stp_p2p_vals), 67011878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 67110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 67210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 67310491SRishi.Srivatsavai@Sun.COM 67410491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", { "0", 0 }, 67510491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 67611878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 67710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 67810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 67910734SEric Cheng 68010734SEric Cheng { "protection", { "--", RESET_VAL }, 68110734SEric Cheng link_protect_vals, VALCNT(link_protect_vals), 68211878SVenu.Iyer@Sun.COM set_resource, NULL, get_protection, check_prop, 0, 68310734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 68410734SEric Cheng 68510734SEric Cheng { "allowed-ips", { "--", 0 }, 68611878SVenu.Iyer@Sun.COM NULL, 0, set_resource, NULL, 68711878SVenu.Iyer@Sun.COM get_allowedips, check_allowedips, PD_CHECK_ALLOC, 68811878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 68911878SVenu.Iyer@Sun.COM 69011878SVenu.Iyer@Sun.COM { "allowed-dhcp-cids", { "--", 0 }, 69111878SVenu.Iyer@Sun.COM NULL, 0, set_resource, NULL, 69211878SVenu.Iyer@Sun.COM get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 69311878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 69411878SVenu.Iyer@Sun.COM 69511878SVenu.Iyer@Sun.COM { "rxrings", { "--", RESET_VAL }, NULL, 0, 69611878SVenu.Iyer@Sun.COM set_resource, get_rings_range, get_rxrings, check_rings, 0, 69711878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 69811878SVenu.Iyer@Sun.COM 69911878SVenu.Iyer@Sun.COM { "rxrings-effective", { "--", 0 }, 70011878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 70111878SVenu.Iyer@Sun.COM get_rxrings, NULL, 0, 70211878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 70311878SVenu.Iyer@Sun.COM 70411878SVenu.Iyer@Sun.COM { "txrings", { "--", RESET_VAL }, NULL, 0, 70511878SVenu.Iyer@Sun.COM set_resource, get_rings_range, get_txrings, check_rings, 0, 70610734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 70711878SVenu.Iyer@Sun.COM 70811878SVenu.Iyer@Sun.COM { "txrings-effective", { "--", 0 }, 70911878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 71011878SVenu.Iyer@Sun.COM get_txrings, NULL, 0, 71111878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 71211878SVenu.Iyer@Sun.COM 71311878SVenu.Iyer@Sun.COM { "txrings-available", { "", 0 }, NULL, 0, 71411878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 71511878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 71611878SVenu.Iyer@Sun.COM 71711878SVenu.Iyer@Sun.COM { "rxrings-available", { "", 0 }, NULL, 0, 71811878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 71911878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 72011878SVenu.Iyer@Sun.COM 72111878SVenu.Iyer@Sun.COM { "rxhwclnt-available", { "", 0 }, NULL, 0, 72211878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 72311878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 72411878SVenu.Iyer@Sun.COM 72511878SVenu.Iyer@Sun.COM { "txhwclnt-available", { "", 0 }, NULL, 0, 72611878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 72711878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 72811878SVenu.Iyer@Sun.COM 7293448Sdh155122 }; 7303448Sdh155122 7315895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 7325895Syz147064 7338275SEric Cheng static resource_prop_t rsrc_prop_table[] = { 73411878SVenu.Iyer@Sun.COM {"maxbw", extract_maxbw}, 73511878SVenu.Iyer@Sun.COM {"priority", extract_priority}, 73611878SVenu.Iyer@Sun.COM {"cpus", extract_cpus}, 73711878SVenu.Iyer@Sun.COM {"cpus-effective", extract_cpus}, 73811878SVenu.Iyer@Sun.COM {"pool", extract_pool}, 73911878SVenu.Iyer@Sun.COM {"pool-effective", extract_pool}, 74011878SVenu.Iyer@Sun.COM {"protection", extract_protection}, 74111878SVenu.Iyer@Sun.COM {"allowed-ips", extract_allowedips}, 74211878SVenu.Iyer@Sun.COM {"allowed-dhcp-cids", extract_allowedcids}, 74311878SVenu.Iyer@Sun.COM {"rxrings", extract_rxrings}, 74411878SVenu.Iyer@Sun.COM {"rxrings-effective", extract_rxrings}, 74511878SVenu.Iyer@Sun.COM {"txrings", extract_txrings}, 74611878SVenu.Iyer@Sun.COM {"txrings-effective", extract_txrings} 7478275SEric Cheng }; 7488275SEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 7498275SEric Cheng sizeof (resource_prop_t)) 7508275SEric Cheng 7517663SSowmini.Varadhan@Sun.COM /* 7527663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 7537663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 7547663SSowmini.Varadhan@Sun.COM */ 7557663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 7567663SSowmini.Varadhan@Sun.COM 7578453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 7588453SAnurag.Maskey@Sun.COM const char *, char **, uint_t); 7598453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 7608453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *); 7618460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 7628460SArtem.Kachitchkin@Sun.COM datalink_id_t, void *, int (*)(dladm_handle_t, 7638460SArtem.Kachitchkin@Sun.COM datalink_id_t, const char *, void *)); 7648453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 7658453SAnurag.Maskey@Sun.COM datalink_class_t, uint32_t, prop_desc_t *, char **, 7668453SAnurag.Maskey@Sun.COM uint_t, uint_t); 7678453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 7688453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 7698453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 7708453SAnurag.Maskey@Sun.COM datalink_id_t, datalink_media_t, uint_t); 7718275SEric Cheng 7725895Syz147064 /* 7735895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 7745895Syz147064 * rates to be retrieved. However, we cannot increase it at this 7755895Syz147064 * time because it will break binary compatibility with unbundled 7765895Syz147064 * WiFi drivers and utilities. So for now we define an additional 7775895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 7785895Syz147064 */ 7795895Syz147064 #define MAX_SUPPORT_RATES 64 7805895Syz147064 7815895Syz147064 #define AP_ANCHOR "[anchor]" 7825895Syz147064 #define AP_DELIMITER '.' 7835895Syz147064 78410734SEric Cheng /* ARGSUSED */ 7855895Syz147064 static dladm_status_t 78611878SVenu.Iyer@Sun.COM check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 78712742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 78811878SVenu.Iyer@Sun.COM datalink_media_t media) 7895895Syz147064 { 7905895Syz147064 int i, j; 79112742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 79212742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 7933147Sxc151355 7945895Syz147064 for (j = 0; j < val_cnt; j++) { 7955895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 79610734SEric Cheng if (strcasecmp(prop_val[j], 7975895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 7985895Syz147064 break; 7995895Syz147064 } 8005895Syz147064 } 80110734SEric Cheng if (i == pdp->pd_noptval) 80210734SEric Cheng return (DLADM_STATUS_BADVAL); 80310734SEric Cheng 80410734SEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 8055895Syz147064 } 80610734SEric Cheng return (DLADM_STATUS_OK); 8075895Syz147064 } 8085895Syz147064 8095895Syz147064 static dladm_status_t 8108453SAnurag.Maskey@Sun.COM i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 8118453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 8128453SAnurag.Maskey@Sun.COM uint_t val_cnt, uint_t flags) 8133147Sxc151355 { 8145895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8155895Syz147064 val_desc_t *vdp = NULL; 8165895Syz147064 boolean_t needfree = B_FALSE; 8175895Syz147064 uint_t cnt, i; 8183147Sxc151355 8195895Syz147064 if (!(pdp->pd_class & class)) 8205895Syz147064 return (DLADM_STATUS_BADARG); 8215895Syz147064 8225895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 8233147Sxc151355 return (DLADM_STATUS_BADARG); 8243147Sxc151355 8255895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 8265895Syz147064 return (DLADM_STATUS_TEMPONLY); 8275895Syz147064 8285895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 8295895Syz147064 return (DLADM_STATUS_OK); 8305895Syz147064 8315895Syz147064 if (pdp->pd_set == NULL) 8325895Syz147064 return (DLADM_STATUS_PROPRDONLY); 8333448Sdh155122 8345895Syz147064 if (prop_val != NULL) { 83511878SVenu.Iyer@Sun.COM vdp = calloc(val_cnt, sizeof (val_desc_t)); 8365895Syz147064 if (vdp == NULL) 8375895Syz147064 return (DLADM_STATUS_NOMEM); 8385895Syz147064 8395895Syz147064 if (pdp->pd_check != NULL) { 8408275SEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 8418453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, prop_val, 84212742Smichael.l.lim@oracle.com &val_cnt, flags, &vdp, media); 8435895Syz147064 } else if (pdp->pd_optval != NULL) { 84411878SVenu.Iyer@Sun.COM status = check_prop(handle, pdp, linkid, prop_val, 84512742Smichael.l.lim@oracle.com &val_cnt, flags, &vdp, media); 8465895Syz147064 } else { 8473448Sdh155122 status = DLADM_STATUS_BADARG; 8483147Sxc151355 } 8495895Syz147064 8503147Sxc151355 if (status != DLADM_STATUS_OK) 8515895Syz147064 goto done; 8525895Syz147064 8535895Syz147064 cnt = val_cnt; 8545895Syz147064 } else { 8558275SEric Cheng boolean_t defval = B_FALSE; 8568275SEric Cheng 8575895Syz147064 if (pdp->pd_defval.vd_name == NULL) 8585895Syz147064 return (DLADM_STATUS_NOTSUP); 8595895Syz147064 8607342SAruna.Ramakrishna@Sun.COM cnt = 1; 8618275SEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 8628275SEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 86311878SVenu.Iyer@Sun.COM if ((vdp = calloc(1, sizeof (val_desc_t))) == NULL) 8646512Ssowmini return (DLADM_STATUS_NOMEM); 8657342SAruna.Ramakrishna@Sun.COM 8668275SEric Cheng if (defval) { 8678275SEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 8688275SEric Cheng sizeof (val_desc_t)); 8698275SEric Cheng } else if (pdp->pd_check != NULL) { 8708453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 87112742Smichael.l.lim@oracle.com prop_val, &cnt, flags, &vdp, media); 8727342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 8737342SAruna.Ramakrishna@Sun.COM goto done; 8747342SAruna.Ramakrishna@Sun.COM } 8756512Ssowmini } else { 8768453SAnurag.Maskey@Sun.COM status = i_dladm_getset_defval(handle, pdp, linkid, 8776512Ssowmini media, flags); 8786512Ssowmini return (status); 8796512Ssowmini } 8805895Syz147064 } 88110491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_AFTER_PERM) 88210491SRishi.Srivatsavai@Sun.COM status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 88310491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_PERMONLY; 88410491SRishi.Srivatsavai@Sun.COM else 88510491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 88610491SRishi.Srivatsavai@Sun.COM media); 8875895Syz147064 if (needfree) { 8885895Syz147064 for (i = 0; i < cnt; i++) 8895903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 8903147Sxc151355 } 8915895Syz147064 done: 8925895Syz147064 free(vdp); 8935895Syz147064 return (status); 8945895Syz147064 } 8955895Syz147064 8965895Syz147064 static dladm_status_t 8978453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8988453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8995895Syz147064 { 9005895Syz147064 int i; 9015895Syz147064 boolean_t found = B_FALSE; 9025895Syz147064 datalink_class_t class; 9035895Syz147064 uint32_t media; 9045895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9055895Syz147064 9068453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9078453SAnurag.Maskey@Sun.COM NULL, 0); 9085895Syz147064 if (status != DLADM_STATUS_OK) 9095895Syz147064 return (status); 9105895Syz147064 9115895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 9125895Syz147064 prop_desc_t *pdp = &prop_table[i]; 9135895Syz147064 dladm_status_t s; 9145895Syz147064 9155895Syz147064 if (prop_name != NULL && 9165895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 9175895Syz147064 continue; 9185895Syz147064 found = B_TRUE; 9198453SAnurag.Maskey@Sun.COM s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 9208453SAnurag.Maskey@Sun.COM prop_val, val_cnt, flags); 9213448Sdh155122 9225895Syz147064 if (prop_name != NULL) { 9235895Syz147064 status = s; 9245895Syz147064 break; 9255895Syz147064 } else { 9265895Syz147064 if (s != DLADM_STATUS_OK && 9275895Syz147064 s != DLADM_STATUS_NOTSUP) 9285895Syz147064 status = s; 9295895Syz147064 } 9305895Syz147064 } 9315903Ssowmini if (!found) { 9325903Ssowmini if (prop_name[0] == '_') { 9335903Ssowmini /* other private properties */ 9349692SRishi.Srivatsavai@Sun.COM status = i_dladm_set_private_prop(handle, linkid, 9359692SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cnt, flags); 9365903Ssowmini } else { 9375903Ssowmini status = DLADM_STATUS_NOTFOUND; 9385903Ssowmini } 9395903Ssowmini } 9405895Syz147064 return (status); 9415895Syz147064 } 9425895Syz147064 9435895Syz147064 /* 9445895Syz147064 * Set/reset link property for specific link 9455895Syz147064 */ 9465895Syz147064 dladm_status_t 9478453SAnurag.Maskey@Sun.COM dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9488453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 9495895Syz147064 { 9505895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9515895Syz147064 9525895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 9535895Syz147064 (prop_val == NULL && val_cnt > 0) || 9545895Syz147064 (prop_val != NULL && val_cnt == 0) || 9555895Syz147064 (prop_name == NULL && prop_val != NULL)) { 9565895Syz147064 return (DLADM_STATUS_BADARG); 9575895Syz147064 } 9585895Syz147064 9599692SRishi.Srivatsavai@Sun.COM /* 9609692SRishi.Srivatsavai@Sun.COM * Check for valid link property against the flags passed 9619692SRishi.Srivatsavai@Sun.COM * and set the link property when active flag is passed. 9629692SRishi.Srivatsavai@Sun.COM */ 9638453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 9645895Syz147064 val_cnt, flags); 9655895Syz147064 if (status != DLADM_STATUS_OK) 9665895Syz147064 return (status); 9675895Syz147064 9685895Syz147064 if (flags & DLADM_OPT_PERSIST) { 9698453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 9703147Sxc151355 prop_val, val_cnt); 97110491SRishi.Srivatsavai@Sun.COM 97210491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 97310491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp = prop_table; 97410491SRishi.Srivatsavai@Sun.COM int i; 97510491SRishi.Srivatsavai@Sun.COM 97610491SRishi.Srivatsavai@Sun.COM for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 97710491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_flags & PD_AFTER_PERM)) 97810491SRishi.Srivatsavai@Sun.COM continue; 97910491SRishi.Srivatsavai@Sun.COM if (prop_name != NULL && 98010491SRishi.Srivatsavai@Sun.COM strcasecmp(prop_name, pdp->pd_name) != 0) 98110491SRishi.Srivatsavai@Sun.COM continue; 98210491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, NULL, 98310491SRishi.Srivatsavai@Sun.COM 0, flags, 0); 98410491SRishi.Srivatsavai@Sun.COM } 98510491SRishi.Srivatsavai@Sun.COM } 9863147Sxc151355 } 9873147Sxc151355 return (status); 9883147Sxc151355 } 9893147Sxc151355 9905895Syz147064 /* 9918460SArtem.Kachitchkin@Sun.COM * Walk all link properties of the given specific link. 9928460SArtem.Kachitchkin@Sun.COM * 9938460SArtem.Kachitchkin@Sun.COM * Note: this function currently lacks the ability to walk _all_ private 9948460SArtem.Kachitchkin@Sun.COM * properties if the link, because there is no kernel interface to 9958460SArtem.Kachitchkin@Sun.COM * retrieve all known private property names. Once such an interface 9968460SArtem.Kachitchkin@Sun.COM * is added, this function should be fixed accordingly. 9975895Syz147064 */ 9983147Sxc151355 dladm_status_t 9998453SAnurag.Maskey@Sun.COM dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 10008453SAnurag.Maskey@Sun.COM int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 10013147Sxc151355 { 10025895Syz147064 dladm_status_t status; 10035895Syz147064 datalink_class_t class; 10045895Syz147064 uint_t media; 10055895Syz147064 int i; 10065895Syz147064 10075895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 10085895Syz147064 return (DLADM_STATUS_BADARG); 10095895Syz147064 10108453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10118453SAnurag.Maskey@Sun.COM NULL, 0); 10125895Syz147064 if (status != DLADM_STATUS_OK) 10135895Syz147064 return (status); 10145895Syz147064 10158460SArtem.Kachitchkin@Sun.COM /* public */ 10165895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 10175895Syz147064 if (!(prop_table[i].pd_class & class)) 10185895Syz147064 continue; 10195895Syz147064 10205895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 10215895Syz147064 continue; 10225895Syz147064 10238453SAnurag.Maskey@Sun.COM if (func(handle, linkid, prop_table[i].pd_name, arg) == 10245895Syz147064 DLADM_WALK_TERMINATE) { 10255895Syz147064 break; 10265895Syz147064 } 10275895Syz147064 } 10285895Syz147064 10298460SArtem.Kachitchkin@Sun.COM /* private */ 10308460SArtem.Kachitchkin@Sun.COM status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 10318460SArtem.Kachitchkin@Sun.COM 10328460SArtem.Kachitchkin@Sun.COM return (status); 10335895Syz147064 } 10343448Sdh155122 10355895Syz147064 /* 10365895Syz147064 * Get linkprop of the given specific link. 10375895Syz147064 */ 10385895Syz147064 dladm_status_t 10398453SAnurag.Maskey@Sun.COM dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10408453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, const char *prop_name, char **prop_val, 10418453SAnurag.Maskey@Sun.COM uint_t *val_cntp) 10425895Syz147064 { 10435895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 10445895Syz147064 datalink_class_t class; 10455895Syz147064 uint_t media; 10465895Syz147064 prop_desc_t *pdp; 10476512Ssowmini uint_t cnt, dld_flags = 0; 10485895Syz147064 int i; 10498118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 10505895Syz147064 10516512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 105211878SVenu.Iyer@Sun.COM dld_flags |= DLD_PROP_DEFAULT; 10539514SGirish.Moodalbail@Sun.COM else if (type == DLADM_PROP_VAL_MODIFIABLE) 105411878SVenu.Iyer@Sun.COM dld_flags |= DLD_PROP_POSSIBLE; 10556512Ssowmini 10565895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 10575895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 10585895Syz147064 return (DLADM_STATUS_BADARG); 10595895Syz147064 10605895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 10615895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 10625895Syz147064 break; 10635895Syz147064 10645903Ssowmini if (i == DLADM_MAX_PROPS) { 10655903Ssowmini if (prop_name[0] == '_') { 10665903Ssowmini /* 10675903Ssowmini * private property. 10685903Ssowmini */ 10698460SArtem.Kachitchkin@Sun.COM if (type == DLADM_PROP_VAL_PERSISTENT) 10708460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_linkprop_db(handle, linkid, 10718460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp)); 10728460SArtem.Kachitchkin@Sun.COM else 10738460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_priv_prop(handle, linkid, 10748460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp, type, 10758460SArtem.Kachitchkin@Sun.COM dld_flags)); 10765903Ssowmini } else { 10775903Ssowmini return (DLADM_STATUS_NOTFOUND); 10785903Ssowmini } 10795903Ssowmini } 10805895Syz147064 10815895Syz147064 pdp = &prop_table[i]; 10825895Syz147064 10838453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10848453SAnurag.Maskey@Sun.COM NULL, 0); 10855895Syz147064 if (status != DLADM_STATUS_OK) 10865895Syz147064 return (status); 10875895Syz147064 10885895Syz147064 if (!(pdp->pd_class & class)) 10895895Syz147064 return (DLADM_STATUS_BADARG); 10905895Syz147064 10915895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 10923147Sxc151355 return (DLADM_STATUS_BADARG); 10933147Sxc151355 10945895Syz147064 switch (type) { 10955895Syz147064 case DLADM_PROP_VAL_CURRENT: 10968453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 10978453SAnurag.Maskey@Sun.COM media, dld_flags, &perm_flags); 10988118SVasumathi.Sundaram@Sun.COM break; 10998118SVasumathi.Sundaram@Sun.COM 11008118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 11018118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 11028118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 11038118SVasumathi.Sundaram@Sun.COM } else { 11048453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 11058453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11068118SVasumathi.Sundaram@Sun.COM } 11078118SVasumathi.Sundaram@Sun.COM 11088118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 11099055SMichael.Lim@Sun.COM *val_cntp = 1; 11108275SEric Cheng if (status == DLADM_STATUS_OK) 11118275SEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 11125895Syz147064 break; 11135895Syz147064 11145895Syz147064 case DLADM_PROP_VAL_DEFAULT: 11156768Sar224390 /* 11166768Sar224390 * If defaults are not defined for the property, 11176768Sar224390 * pd_defval.vd_name should be null. If the driver 11186768Sar224390 * has to be contacted for the value, vd_name should 11196768Sar224390 * be the empty string (""). Otherwise, dladm will 11206768Sar224390 * just print whatever is in the table. 11216768Sar224390 */ 11225895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 11235895Syz147064 status = DLADM_STATUS_NOTSUP; 11245895Syz147064 break; 11255895Syz147064 } 11266512Ssowmini 11276512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 11288453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 11298453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11306512Ssowmini } else { 11316512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 11326512Ssowmini } 11335895Syz147064 *val_cntp = 1; 11345895Syz147064 break; 11353448Sdh155122 11365895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 11375895Syz147064 if (pdp->pd_getmod != NULL) { 11388453SAnurag.Maskey@Sun.COM status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 11398118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11405895Syz147064 break; 11415895Syz147064 } 11425895Syz147064 cnt = pdp->pd_noptval; 11435895Syz147064 if (cnt == 0) { 11445895Syz147064 status = DLADM_STATUS_NOTSUP; 11455895Syz147064 } else if (cnt > *val_cntp) { 11465895Syz147064 status = DLADM_STATUS_TOOSMALL; 11475895Syz147064 } else { 11485895Syz147064 for (i = 0; i < cnt; i++) { 11495895Syz147064 (void) strcpy(prop_val[i], 11505895Syz147064 pdp->pd_optval[i].vd_name); 11515895Syz147064 } 11525895Syz147064 *val_cntp = cnt; 11535895Syz147064 } 11545895Syz147064 break; 11555895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 11565895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 11575895Syz147064 return (DLADM_STATUS_TEMPONLY); 11588453SAnurag.Maskey@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 11595895Syz147064 prop_val, val_cntp); 11605895Syz147064 break; 11615895Syz147064 default: 11625895Syz147064 status = DLADM_STATUS_BADARG; 11635895Syz147064 break; 11643147Sxc151355 } 11653448Sdh155122 11665895Syz147064 return (status); 11675895Syz147064 } 11685895Syz147064 116910491SRishi.Srivatsavai@Sun.COM /* 117010491SRishi.Srivatsavai@Sun.COM * Get linkprop of the given specific link and run any possible conversion 117110491SRishi.Srivatsavai@Sun.COM * of the values using the check function for the property. Fails if the 117210491SRishi.Srivatsavai@Sun.COM * check function doesn't succeed for the property value. 117310491SRishi.Srivatsavai@Sun.COM */ 117410491SRishi.Srivatsavai@Sun.COM dladm_status_t 117510491SRishi.Srivatsavai@Sun.COM dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 117610491SRishi.Srivatsavai@Sun.COM dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 117710491SRishi.Srivatsavai@Sun.COM uint_t *val_cntp) 117810491SRishi.Srivatsavai@Sun.COM { 117910491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 118010491SRishi.Srivatsavai@Sun.COM datalink_class_t class; 118110491SRishi.Srivatsavai@Sun.COM uint_t media; 118210491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp; 118310491SRishi.Srivatsavai@Sun.COM uint_t dld_flags; 118410491SRishi.Srivatsavai@Sun.COM int valc, i; 118510491SRishi.Srivatsavai@Sun.COM char **prop_val; 118610491SRishi.Srivatsavai@Sun.COM uint_t perm_flags; 118710491SRishi.Srivatsavai@Sun.COM 118810491SRishi.Srivatsavai@Sun.COM if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 118910491SRishi.Srivatsavai@Sun.COM ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 119010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 119110491SRishi.Srivatsavai@Sun.COM 119210491SRishi.Srivatsavai@Sun.COM for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 119310491SRishi.Srivatsavai@Sun.COM if (strcasecmp(prop_name, pdp->pd_name) == 0) 119410491SRishi.Srivatsavai@Sun.COM break; 119510491SRishi.Srivatsavai@Sun.COM 119610491SRishi.Srivatsavai@Sun.COM if (pdp == prop_table + DLADM_MAX_PROPS) 119710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTFOUND); 119810491SRishi.Srivatsavai@Sun.COM 119910491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_CHECK_ALLOC) 120010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 120110491SRishi.Srivatsavai@Sun.COM 120210491SRishi.Srivatsavai@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 120310491SRishi.Srivatsavai@Sun.COM NULL, 0); 120410491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 120510491SRishi.Srivatsavai@Sun.COM return (status); 120610491SRishi.Srivatsavai@Sun.COM 120710491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_class & class)) 120810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 120910491SRishi.Srivatsavai@Sun.COM 121010491SRishi.Srivatsavai@Sun.COM if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 121110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 121210491SRishi.Srivatsavai@Sun.COM 121310491SRishi.Srivatsavai@Sun.COM prop_val = malloc(*val_cntp * sizeof (*prop_val) + 121410491SRishi.Srivatsavai@Sun.COM *val_cntp * DLADM_PROP_VAL_MAX); 121510491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) 121610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOMEM); 121710491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 121810491SRishi.Srivatsavai@Sun.COM prop_val[valc] = (char *)(prop_val + *val_cntp) + 121910491SRishi.Srivatsavai@Sun.COM valc * DLADM_PROP_VAL_MAX; 122010491SRishi.Srivatsavai@Sun.COM 122111878SVenu.Iyer@Sun.COM dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 122210491SRishi.Srivatsavai@Sun.COM 122310491SRishi.Srivatsavai@Sun.COM switch (type) { 122410491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_CURRENT: 122510491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 122610491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 122710491SRishi.Srivatsavai@Sun.COM break; 122810491SRishi.Srivatsavai@Sun.COM 122910491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_DEFAULT: 123010491SRishi.Srivatsavai@Sun.COM /* 123110491SRishi.Srivatsavai@Sun.COM * If defaults are not defined for the property, 123210491SRishi.Srivatsavai@Sun.COM * pd_defval.vd_name should be null. If the driver 123310491SRishi.Srivatsavai@Sun.COM * has to be contacted for the value, vd_name should 123410491SRishi.Srivatsavai@Sun.COM * be the empty string (""). Otherwise, dladm will 123510491SRishi.Srivatsavai@Sun.COM * just print whatever is in the table. 123610491SRishi.Srivatsavai@Sun.COM */ 123710491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name == NULL) { 123810491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOTSUP; 123910491SRishi.Srivatsavai@Sun.COM break; 124010491SRishi.Srivatsavai@Sun.COM } 124110491SRishi.Srivatsavai@Sun.COM 124210491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name[0] != '\0') { 124310491SRishi.Srivatsavai@Sun.COM *val_cntp = 1; 124410491SRishi.Srivatsavai@Sun.COM *ret_val = pdp->pd_defval.vd_val; 124510491SRishi.Srivatsavai@Sun.COM free(prop_val); 124610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 124710491SRishi.Srivatsavai@Sun.COM } 124810491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 124910491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 125010491SRishi.Srivatsavai@Sun.COM break; 125110491SRishi.Srivatsavai@Sun.COM 125210491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_PERSISTENT: 125310491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_TEMPONLY) 125410491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_TEMPONLY; 125510491SRishi.Srivatsavai@Sun.COM else 125610491SRishi.Srivatsavai@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, 125710491SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cntp); 125810491SRishi.Srivatsavai@Sun.COM break; 125910491SRishi.Srivatsavai@Sun.COM 126010491SRishi.Srivatsavai@Sun.COM default: 126110491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_BADARG; 126210491SRishi.Srivatsavai@Sun.COM break; 126310491SRishi.Srivatsavai@Sun.COM } 126410491SRishi.Srivatsavai@Sun.COM 126510491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 126610491SRishi.Srivatsavai@Sun.COM if (pdp->pd_check != NULL) { 126710491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp; 126810491SRishi.Srivatsavai@Sun.COM 126910491SRishi.Srivatsavai@Sun.COM vdp = malloc(sizeof (val_desc_t) * *val_cntp); 127010491SRishi.Srivatsavai@Sun.COM if (vdp == NULL) 127110491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOMEM; 127210491SRishi.Srivatsavai@Sun.COM else 127310491SRishi.Srivatsavai@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 127412742Smichael.l.lim@oracle.com prop_val, val_cntp, 0, &vdp, media); 127510491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 127610491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 127710491SRishi.Srivatsavai@Sun.COM ret_val[valc] = vdp[valc].vd_val; 127810491SRishi.Srivatsavai@Sun.COM } 127910491SRishi.Srivatsavai@Sun.COM free(vdp); 128010491SRishi.Srivatsavai@Sun.COM } else { 128110491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) { 128210491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pdp->pd_noptval; i++) { 128310491SRishi.Srivatsavai@Sun.COM if (strcmp(pdp->pd_optval[i].vd_name, 128410491SRishi.Srivatsavai@Sun.COM prop_val[valc]) == 0) { 128510491SRishi.Srivatsavai@Sun.COM ret_val[valc] = 128610491SRishi.Srivatsavai@Sun.COM pdp->pd_optval[i].vd_val; 128710491SRishi.Srivatsavai@Sun.COM break; 128810491SRishi.Srivatsavai@Sun.COM } 128910491SRishi.Srivatsavai@Sun.COM } 129010491SRishi.Srivatsavai@Sun.COM if (i == pdp->pd_noptval) { 129110491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_FAILED; 129210491SRishi.Srivatsavai@Sun.COM break; 129310491SRishi.Srivatsavai@Sun.COM } 129410491SRishi.Srivatsavai@Sun.COM } 129510491SRishi.Srivatsavai@Sun.COM } 129610491SRishi.Srivatsavai@Sun.COM } 129710491SRishi.Srivatsavai@Sun.COM 129810491SRishi.Srivatsavai@Sun.COM free(prop_val); 129910491SRishi.Srivatsavai@Sun.COM 130010491SRishi.Srivatsavai@Sun.COM return (status); 130110491SRishi.Srivatsavai@Sun.COM } 130210491SRishi.Srivatsavai@Sun.COM 13035895Syz147064 /*ARGSUSED*/ 13045895Syz147064 static int 13058453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 13068453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 13075895Syz147064 { 130811878SVenu.Iyer@Sun.COM char *buf, **propvals; 130911878SVenu.Iyer@Sun.COM uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 131011878SVenu.Iyer@Sun.COM dladm_status_t status; 131111878SVenu.Iyer@Sun.COM dladm_linkprop_args_t *dla = arg; 13125895Syz147064 13135895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 13145895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 13155895Syz147064 return (DLADM_WALK_CONTINUE); 13165895Syz147064 } 13175895Syz147064 13185895Syz147064 propvals = (char **)(void *)buf; 13195895Syz147064 for (i = 0; i < valcnt; i++) { 13205895Syz147064 propvals[i] = buf + 13215895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 13225895Syz147064 i * DLADM_PROP_VAL_MAX; 13235895Syz147064 } 13245895Syz147064 13258453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 13268453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 13275895Syz147064 goto done; 13285895Syz147064 } 13295895Syz147064 133011021SEric.Cheng@Sun.COM status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 133111878SVenu.Iyer@Sun.COM valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 133211878SVenu.Iyer@Sun.COM 133311021SEric.Cheng@Sun.COM if (status != DLADM_STATUS_OK) 133411878SVenu.Iyer@Sun.COM dla->dla_status = status; 13355895Syz147064 13365895Syz147064 done: 13375895Syz147064 if (buf != NULL) 13385895Syz147064 free(buf); 13395895Syz147064 13405895Syz147064 return (DLADM_WALK_CONTINUE); 13415895Syz147064 } 13425895Syz147064 13435895Syz147064 /*ARGSUSED*/ 13445895Syz147064 static int 13458453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 13465895Syz147064 { 13478275SEric Cheng datalink_class_t class; 13488275SEric Cheng dladm_status_t status; 13498275SEric Cheng 13508453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 13518453SAnurag.Maskey@Sun.COM NULL, 0); 13528275SEric Cheng if (status != DLADM_STATUS_OK) 13538275SEric Cheng return (DLADM_WALK_TERMINATE); 13548275SEric Cheng 13558275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 13568453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 13578275SEric Cheng 13585895Syz147064 return (DLADM_WALK_CONTINUE); 13595895Syz147064 } 13605895Syz147064 13615895Syz147064 dladm_status_t 13628453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 13638453SAnurag.Maskey@Sun.COM boolean_t any_media) 13645895Syz147064 { 136511021SEric.Cheng@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 13666916Sartem datalink_media_t dmedia; 13676916Sartem uint32_t media; 136811878SVenu.Iyer@Sun.COM dladm_linkprop_args_t *dla; 13696916Sartem 13706916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 13716916Sartem 137211878SVenu.Iyer@Sun.COM dla = malloc(sizeof (dladm_linkprop_args_t)); 137311878SVenu.Iyer@Sun.COM if (dla == NULL) 137411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 137511878SVenu.Iyer@Sun.COM dla->dla_flags = DLADM_OPT_BOOT; 137611878SVenu.Iyer@Sun.COM dla->dla_status = DLADM_STATUS_OK; 137711878SVenu.Iyer@Sun.COM 13785895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 13798453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 13808453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 13818453SAnurag.Maskey@Sun.COM } else if (any_media || 13828453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 13838453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 13846916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 138511878SVenu.Iyer@Sun.COM (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 13868453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 138711878SVenu.Iyer@Sun.COM status = dla->dla_status; 13883448Sdh155122 } 138911878SVenu.Iyer@Sun.COM free(dla); 139011021SEric.Cheng@Sun.COM return (status); 13913147Sxc151355 } 13923147Sxc151355 13935903Ssowmini /* ARGSUSED */ 13945895Syz147064 static dladm_status_t 139511878SVenu.Iyer@Sun.COM get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13968275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 13978275SEric Cheng uint_t flags, uint_t *perm_flags) 13983147Sxc151355 { 13998275SEric Cheng char zone_name[ZONENAME_MAX]; 14008275SEric Cheng zoneid_t zid; 14018275SEric Cheng dladm_status_t status; 14023147Sxc151355 14036512Ssowmini if (flags != 0) 14046512Ssowmini return (DLADM_STATUS_NOTSUP); 14056512Ssowmini 140611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 140711878SVenu.Iyer@Sun.COM perm_flags, &zid, sizeof (zid)); 14085895Syz147064 if (status != DLADM_STATUS_OK) 14093448Sdh155122 return (status); 14103448Sdh155122 14115895Syz147064 *val_cnt = 1; 14125895Syz147064 if (zid != GLOBAL_ZONEID) { 14138118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 14145895Syz147064 return (dladm_errno2status(errno)); 14158118SVasumathi.Sundaram@Sun.COM } 14163147Sxc151355 14175895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 14183147Sxc151355 } else { 14195895Syz147064 *prop_val[0] = '\0'; 14203147Sxc151355 } 14213147Sxc151355 14223448Sdh155122 return (DLADM_STATUS_OK); 14233448Sdh155122 } 14243448Sdh155122 14253448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 14263448Sdh155122 14273448Sdh155122 static int 14283448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 14293448Sdh155122 { 14303448Sdh155122 char root[MAXPATHLEN]; 14313448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 14323448Sdh155122 void *dlhandle; 14333448Sdh155122 void *sym; 14343448Sdh155122 int ret; 14353448Sdh155122 14363448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 14373448Sdh155122 return (-1); 14383448Sdh155122 14393448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 14403448Sdh155122 (void) dlclose(dlhandle); 14413448Sdh155122 return (-1); 14423448Sdh155122 } 14433448Sdh155122 14443448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 14453448Sdh155122 14463448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 14473448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 14483448Sdh155122 (void) dlclose(dlhandle); 14493448Sdh155122 return (ret); 14503448Sdh155122 } 14513448Sdh155122 14523448Sdh155122 static dladm_status_t 14538453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 14548453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 14553448Sdh155122 { 14563448Sdh155122 char path[MAXPATHLEN]; 14575895Syz147064 char name[MAXLINKNAMELEN]; 14583448Sdh155122 di_prof_t prof = NULL; 14593448Sdh155122 char zone_name[ZONENAME_MAX]; 14603448Sdh155122 dladm_status_t status; 14615895Syz147064 int ret; 14623448Sdh155122 14633448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 14643448Sdh155122 return (dladm_errno2status(errno)); 14653448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 14663448Sdh155122 return (dladm_errno2status(errno)); 14673448Sdh155122 if (di_prof_init(path, &prof) != 0) 14683448Sdh155122 return (dladm_errno2status(errno)); 14693448Sdh155122 14708453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 14715895Syz147064 if (status != DLADM_STATUS_OK) 14725895Syz147064 goto cleanup; 14735895Syz147064 14745895Syz147064 if (add) 14755895Syz147064 ret = di_prof_add_dev(prof, name); 14765895Syz147064 else 14775895Syz147064 ret = di_prof_add_exclude(prof, name); 14785895Syz147064 14795895Syz147064 if (ret != 0) { 14803448Sdh155122 status = dladm_errno2status(errno); 14813448Sdh155122 goto cleanup; 14823448Sdh155122 } 14833448Sdh155122 14843448Sdh155122 if (di_prof_commit(prof) != 0) 14853448Sdh155122 status = dladm_errno2status(errno); 14863448Sdh155122 cleanup: 14873448Sdh155122 if (prof) 14883448Sdh155122 di_prof_fini(prof); 14893448Sdh155122 14903448Sdh155122 return (status); 14913448Sdh155122 } 14923448Sdh155122 14935903Ssowmini /* ARGSUSED */ 14943448Sdh155122 static dladm_status_t 149511878SVenu.Iyer@Sun.COM set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14968453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 14973448Sdh155122 { 14988275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 14998275SEric Cheng zoneid_t zid_old, zid_new; 15007342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 15013448Sdh155122 15023448Sdh155122 if (val_cnt != 1) 15033448Sdh155122 return (DLADM_STATUS_BADVALCNT); 15043448Sdh155122 15057342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 15067342SAruna.Ramakrishna@Sun.COM 150711878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 150811878SVenu.Iyer@Sun.COM NULL, &zid_old, sizeof (zid_old)); 15098275SEric Cheng if (status != DLADM_STATUS_OK) 15108275SEric Cheng return (status); 15118275SEric Cheng 15127342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 15133448Sdh155122 if (zid_new == zid_old) 151410616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 151510616SSebastien.Roy@Sun.COM 151611878SVenu.Iyer@Sun.COM if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 151710616SSebastien.Roy@Sun.COM flags, media)) != DLADM_STATUS_OK) 15185895Syz147064 return (status); 15195895Syz147064 152010616SSebastien.Roy@Sun.COM /* 152110616SSebastien.Roy@Sun.COM * It is okay to fail to update the /dev entry (some vanity-named 152210616SSebastien.Roy@Sun.COM * links do not have a /dev entry). 152310616SSebastien.Roy@Sun.COM */ 15243448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 15258453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 15268453SAnurag.Maskey@Sun.COM B_FALSE); 15275895Syz147064 } 152810616SSebastien.Roy@Sun.COM if (zid_new != GLOBAL_ZONEID) 15298453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 15303448Sdh155122 15313448Sdh155122 return (DLADM_STATUS_OK); 15323448Sdh155122 } 15333448Sdh155122 15343448Sdh155122 /* ARGSUSED */ 15353448Sdh155122 static dladm_status_t 153611878SVenu.Iyer@Sun.COM check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 153712742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 153811878SVenu.Iyer@Sun.COM datalink_media_t media) 15393448Sdh155122 { 15407342SAruna.Ramakrishna@Sun.COM char *zone_name; 15417342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 15427342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 15437342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 154412742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 154512742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 15463448Sdh155122 15473448Sdh155122 if (val_cnt != 1) 15483448Sdh155122 return (DLADM_STATUS_BADVALCNT); 15493448Sdh155122 15507342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 15517342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 15527342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 15533448Sdh155122 15548275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 15557342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 15567342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 15577342SAruna.Ramakrishna@Sun.COM goto done; 15587342SAruna.Ramakrishna@Sun.COM } 15597342SAruna.Ramakrishna@Sun.COM 15607342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 15613448Sdh155122 ushort_t flags; 15623448Sdh155122 15637342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 15643448Sdh155122 sizeof (flags)) < 0) { 15657342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 15667342SAruna.Ramakrishna@Sun.COM goto done; 15673448Sdh155122 } 15683448Sdh155122 15693448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 15707342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 15717342SAruna.Ramakrishna@Sun.COM goto done; 15723448Sdh155122 } 15733448Sdh155122 } 15743448Sdh155122 15757342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15767342SAruna.Ramakrishna@Sun.COM 15777342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 157810616SSebastien.Roy@Sun.COM dzp->diz_linkid = linkid; 15797342SAruna.Ramakrishna@Sun.COM 15807342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 15815895Syz147064 return (DLADM_STATUS_OK); 15827342SAruna.Ramakrishna@Sun.COM done: 15837342SAruna.Ramakrishna@Sun.COM free(dzp); 15847342SAruna.Ramakrishna@Sun.COM return (status); 15855895Syz147064 } 15865895Syz147064 15875903Ssowmini /* ARGSUSED */ 15885895Syz147064 static dladm_status_t 158911878SVenu.Iyer@Sun.COM get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15908275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15918275SEric Cheng uint_t flags, uint_t *perm_flags) 15928275SEric Cheng { 15938275SEric Cheng mac_resource_props_t mrp; 15948275SEric Cheng dladm_status_t status; 15958275SEric Cheng 159611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 159711878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 159811878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 15998275SEric Cheng return (status); 16008275SEric Cheng 16018275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 160211878SVenu.Iyer@Sun.COM *val_cnt = 0; 160311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 16048275SEric Cheng } 160511878SVenu.Iyer@Sun.COM 160611878SVenu.Iyer@Sun.COM (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 16078275SEric Cheng *val_cnt = 1; 16088275SEric Cheng return (DLADM_STATUS_OK); 16098275SEric Cheng } 16108275SEric Cheng 16118275SEric Cheng /* ARGSUSED */ 16128275SEric Cheng static dladm_status_t 161311878SVenu.Iyer@Sun.COM check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 161412742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 161511878SVenu.Iyer@Sun.COM datalink_media_t media) 16168275SEric Cheng { 16178275SEric Cheng uint64_t *maxbw; 16188275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 161912742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 162012742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 16218275SEric Cheng 16228275SEric Cheng if (val_cnt != 1) 16238275SEric Cheng return (DLADM_STATUS_BADVALCNT); 16248275SEric Cheng 16258275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 16268275SEric Cheng if (maxbw == NULL) 16278275SEric Cheng return (DLADM_STATUS_NOMEM); 16288275SEric Cheng 16298275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 16308275SEric Cheng if (status != DLADM_STATUS_OK) { 16318275SEric Cheng free(maxbw); 16328275SEric Cheng return (status); 16338275SEric Cheng } 16348275SEric Cheng 16358275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 16368275SEric Cheng free(maxbw); 16378275SEric Cheng return (DLADM_STATUS_MINMAXBW); 16388275SEric Cheng } 16398275SEric Cheng 16408275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 16418275SEric Cheng return (DLADM_STATUS_OK); 16428275SEric Cheng } 16438275SEric Cheng 16448275SEric Cheng /* ARGSUSED */ 16458275SEric Cheng dladm_status_t 164611878SVenu.Iyer@Sun.COM extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 16478275SEric Cheng { 164810734SEric Cheng mac_resource_props_t *mrp = arg; 16498275SEric Cheng 165011878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) { 165111878SVenu.Iyer@Sun.COM mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 165211878SVenu.Iyer@Sun.COM } else { 165311878SVenu.Iyer@Sun.COM bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 165411878SVenu.Iyer@Sun.COM } 16558275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 16568275SEric Cheng 16578275SEric Cheng return (DLADM_STATUS_OK); 16588275SEric Cheng } 16598275SEric Cheng 16608275SEric Cheng /* ARGSUSED */ 16618275SEric Cheng static dladm_status_t 166211878SVenu.Iyer@Sun.COM get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16638275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 16648275SEric Cheng uint_t flags, uint_t *perm_flags) 16658275SEric Cheng { 166611878SVenu.Iyer@Sun.COM dladm_status_t status; 16678275SEric Cheng mac_resource_props_t mrp; 166812742Smichael.l.lim@oracle.com mac_propval_range_t *pv_range; 166912742Smichael.l.lim@oracle.com int err; 167011878SVenu.Iyer@Sun.COM 167111878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 167211878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 167311878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 167411878SVenu.Iyer@Sun.COM sizeof (mrp)); 167511878SVenu.Iyer@Sun.COM } else { 167611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 167711878SVenu.Iyer@Sun.COM "resource", flags, perm_flags, &mrp, sizeof (mrp)); 167811878SVenu.Iyer@Sun.COM } 167911878SVenu.Iyer@Sun.COM 168011878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 16818275SEric Cheng return (status); 16828275SEric Cheng 168312742Smichael.l.lim@oracle.com if (mrp.mrp_ncpus > *val_cnt) 16848275SEric Cheng return (DLADM_STATUS_TOOSMALL); 16858275SEric Cheng 168612742Smichael.l.lim@oracle.com if (mrp.mrp_ncpus == 0) { 168711878SVenu.Iyer@Sun.COM *val_cnt = 0; 16888275SEric Cheng return (DLADM_STATUS_OK); 16898275SEric Cheng } 16908275SEric Cheng 169112742Smichael.l.lim@oracle.com /* Sort CPU list and convert it to a mac_propval_range */ 169212742Smichael.l.lim@oracle.com status = dladm_list2range(mrp.mrp_cpu, mrp.mrp_ncpus, 169312742Smichael.l.lim@oracle.com MAC_PROPVAL_UINT32, &pv_range); 169412742Smichael.l.lim@oracle.com if (status != DLADM_STATUS_OK) 169512742Smichael.l.lim@oracle.com return (status); 169612742Smichael.l.lim@oracle.com 169712742Smichael.l.lim@oracle.com /* Write CPU ranges and individual CPUs */ 169812742Smichael.l.lim@oracle.com err = dladm_range2strs(pv_range, prop_val); 169912742Smichael.l.lim@oracle.com if (err != 0) { 170012742Smichael.l.lim@oracle.com free(pv_range); 170112742Smichael.l.lim@oracle.com return (dladm_errno2status(err)); 17028275SEric Cheng } 170312742Smichael.l.lim@oracle.com 170412742Smichael.l.lim@oracle.com *val_cnt = pv_range->mpr_count; 170512742Smichael.l.lim@oracle.com free(pv_range); 170612742Smichael.l.lim@oracle.com 17078275SEric Cheng return (DLADM_STATUS_OK); 17088275SEric Cheng } 17098275SEric Cheng 17108275SEric Cheng /* ARGSUSED */ 17118275SEric Cheng static dladm_status_t 171211878SVenu.Iyer@Sun.COM check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 171312742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 171411878SVenu.Iyer@Sun.COM datalink_media_t media) 17158275SEric Cheng { 171611878SVenu.Iyer@Sun.COM int i, j, rc; 171711878SVenu.Iyer@Sun.COM long nproc = sysconf(_SC_NPROCESSORS_CONF); 17188275SEric Cheng mac_resource_props_t mrp; 171912742Smichael.l.lim@oracle.com mac_propval_range_t *pv_range; 172011878SVenu.Iyer@Sun.COM uint_t perm_flags; 172112742Smichael.l.lim@oracle.com uint32_t ncpus; 172212742Smichael.l.lim@oracle.com uint32_t *cpus = mrp.mrp_cpu; 172312742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 172412742Smichael.l.lim@oracle.com val_desc_t *newvdp; 172512742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 172612742Smichael.l.lim@oracle.com dladm_status_t status = DLADM_STATUS_OK; 172711878SVenu.Iyer@Sun.COM 172811878SVenu.Iyer@Sun.COM /* Get the current pool property */ 172911878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 173011878SVenu.Iyer@Sun.COM &perm_flags, &mrp, sizeof (mrp)); 173111878SVenu.Iyer@Sun.COM 173211878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) { 173311878SVenu.Iyer@Sun.COM /* Can't set cpus if a pool is set */ 173411878SVenu.Iyer@Sun.COM if (strlen(mrp.mrp_pool) != 0) 173511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_POOLCPU); 173611878SVenu.Iyer@Sun.COM } 17378275SEric Cheng 173812742Smichael.l.lim@oracle.com /* Read ranges and convert to mac_propval_range */ 173912742Smichael.l.lim@oracle.com status = dladm_strs2range(prop_val, val_cnt, MAC_PROPVAL_UINT32, 174012742Smichael.l.lim@oracle.com &pv_range); 174112742Smichael.l.lim@oracle.com if (status != DLADM_STATUS_OK) 174212742Smichael.l.lim@oracle.com goto done1; 174312742Smichael.l.lim@oracle.com 174412742Smichael.l.lim@oracle.com /* Convert mac_propval_range to a single CPU list */ 174512742Smichael.l.lim@oracle.com ncpus = MRP_NCPUS; 174612742Smichael.l.lim@oracle.com status = dladm_range2list(pv_range, cpus, &ncpus); 174712742Smichael.l.lim@oracle.com if (status != DLADM_STATUS_OK) 174812742Smichael.l.lim@oracle.com goto done1; 174912742Smichael.l.lim@oracle.com 175012742Smichael.l.lim@oracle.com /* 175112742Smichael.l.lim@oracle.com * If a range of CPUs was entered, update value count and reallocate 175212742Smichael.l.lim@oracle.com * the array of val_desc_t's. The array allocated was sized for 175312742Smichael.l.lim@oracle.com * indvidual elements, but needs to be reallocated to accomodate the 175412742Smichael.l.lim@oracle.com * expanded list of CPUs. 175512742Smichael.l.lim@oracle.com */ 175612742Smichael.l.lim@oracle.com if (val_cnt < ncpus) { 175712742Smichael.l.lim@oracle.com newvdp = calloc(*val_cntp, sizeof (val_desc_t)); 175812742Smichael.l.lim@oracle.com if (newvdp == NULL) { 175912742Smichael.l.lim@oracle.com status = DLADM_STATUS_NOMEM; 176012742Smichael.l.lim@oracle.com goto done1; 176112742Smichael.l.lim@oracle.com } 176212742Smichael.l.lim@oracle.com vdp = newvdp; 176311878SVenu.Iyer@Sun.COM } 176411878SVenu.Iyer@Sun.COM 176512742Smichael.l.lim@oracle.com /* Check if all CPUs in the list are online */ 176612742Smichael.l.lim@oracle.com for (i = 0; i < ncpus; i++) { 176712742Smichael.l.lim@oracle.com if (cpus[i] >= nproc) { 176812742Smichael.l.lim@oracle.com status = DLADM_STATUS_BADCPUID; 176912742Smichael.l.lim@oracle.com goto done2; 177012742Smichael.l.lim@oracle.com } 177112742Smichael.l.lim@oracle.com 177212742Smichael.l.lim@oracle.com rc = p_online(cpus[i], P_STATUS); 177312742Smichael.l.lim@oracle.com if (rc < 1) { 177412742Smichael.l.lim@oracle.com status = DLADM_STATUS_CPUERR; 177512742Smichael.l.lim@oracle.com goto done2; 177612742Smichael.l.lim@oracle.com } 177712742Smichael.l.lim@oracle.com 177812742Smichael.l.lim@oracle.com if (rc != P_ONLINE) { 177912742Smichael.l.lim@oracle.com status = DLADM_STATUS_CPUNOTONLINE; 178012742Smichael.l.lim@oracle.com goto done2; 178112742Smichael.l.lim@oracle.com } 178212742Smichael.l.lim@oracle.com 178312742Smichael.l.lim@oracle.com vdp[i].vd_val = (uintptr_t)cpus[i]; 178412742Smichael.l.lim@oracle.com } 178512742Smichael.l.lim@oracle.com 178612742Smichael.l.lim@oracle.com /* Check for duplicate CPUs */ 178712742Smichael.l.lim@oracle.com for (i = 0; i < *val_cntp; i++) { 178812742Smichael.l.lim@oracle.com for (j = 0; j < *val_cntp; j++) { 178912742Smichael.l.lim@oracle.com if (i != j && vdp[i].vd_val == vdp[j].vd_val) { 179012742Smichael.l.lim@oracle.com status = DLADM_STATUS_BADVAL; 179112742Smichael.l.lim@oracle.com goto done2; 179212742Smichael.l.lim@oracle.com } 17938275SEric Cheng } 17948275SEric Cheng } 179512742Smichael.l.lim@oracle.com 179612742Smichael.l.lim@oracle.com /* Update *val_cntp and *vdpp if everything was OK */ 179712742Smichael.l.lim@oracle.com if (val_cnt < ncpus) { 179812742Smichael.l.lim@oracle.com *val_cntp = ncpus; 179912742Smichael.l.lim@oracle.com free(*vdpp); 180012742Smichael.l.lim@oracle.com *vdpp = newvdp; 180112742Smichael.l.lim@oracle.com } 180212742Smichael.l.lim@oracle.com 180312742Smichael.l.lim@oracle.com status = DLADM_STATUS_OK; 180412742Smichael.l.lim@oracle.com goto done1; 180512742Smichael.l.lim@oracle.com 180612742Smichael.l.lim@oracle.com done2: 180712742Smichael.l.lim@oracle.com free(newvdp); 180812742Smichael.l.lim@oracle.com done1: 180912742Smichael.l.lim@oracle.com free(pv_range); 181012742Smichael.l.lim@oracle.com return (status); 181111878SVenu.Iyer@Sun.COM } 181211878SVenu.Iyer@Sun.COM 181311878SVenu.Iyer@Sun.COM /* ARGSUSED */ 181411878SVenu.Iyer@Sun.COM dladm_status_t 181511878SVenu.Iyer@Sun.COM extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 181611878SVenu.Iyer@Sun.COM { 181711878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 181811878SVenu.Iyer@Sun.COM int i; 181911878SVenu.Iyer@Sun.COM 182011878SVenu.Iyer@Sun.COM if (vdp[0].vd_val == RESET_VAL) { 182111878SVenu.Iyer@Sun.COM bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 182211878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_CPUS; 182311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 182411878SVenu.Iyer@Sun.COM } 182511878SVenu.Iyer@Sun.COM 182611878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) 182711878SVenu.Iyer@Sun.COM mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 182811878SVenu.Iyer@Sun.COM 182911878SVenu.Iyer@Sun.COM mrp->mrp_ncpus = cnt; 183011878SVenu.Iyer@Sun.COM mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 183111878SVenu.Iyer@Sun.COM mrp->mrp_fanout_mode = MCM_CPUS; 183211878SVenu.Iyer@Sun.COM mrp->mrp_rx_intr_cpu = -1; 183311878SVenu.Iyer@Sun.COM 183411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 183511878SVenu.Iyer@Sun.COM } 183611878SVenu.Iyer@Sun.COM 183711878SVenu.Iyer@Sun.COM /* 183811878SVenu.Iyer@Sun.COM * Get the pool datalink property from the kernel. This is used 183911878SVenu.Iyer@Sun.COM * for both the user specified pool and effective pool properties. 184011878SVenu.Iyer@Sun.COM */ 184111878SVenu.Iyer@Sun.COM /* ARGSUSED */ 184211878SVenu.Iyer@Sun.COM static dladm_status_t 184311878SVenu.Iyer@Sun.COM get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 184411878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 184511878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 184611878SVenu.Iyer@Sun.COM { 184711878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 184811878SVenu.Iyer@Sun.COM dladm_status_t status; 184911878SVenu.Iyer@Sun.COM 185011878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "pool-effective") == 0) { 185111878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 185211878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 185311878SVenu.Iyer@Sun.COM sizeof (mrp)); 185411878SVenu.Iyer@Sun.COM } else { 185511878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 185611878SVenu.Iyer@Sun.COM "resource", flags, perm_flags, &mrp, sizeof (mrp)); 185711878SVenu.Iyer@Sun.COM } 185811878SVenu.Iyer@Sun.COM 185911878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 186011878SVenu.Iyer@Sun.COM return (status); 186111878SVenu.Iyer@Sun.COM 186211878SVenu.Iyer@Sun.COM if (strlen(mrp.mrp_pool) == 0) { 186311878SVenu.Iyer@Sun.COM (*prop_val)[0] = '\0'; 186411878SVenu.Iyer@Sun.COM } else { 186511878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 186611878SVenu.Iyer@Sun.COM "%s", mrp.mrp_pool); 186711878SVenu.Iyer@Sun.COM } 186811878SVenu.Iyer@Sun.COM *val_cnt = 1; 186911878SVenu.Iyer@Sun.COM 187011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 18718275SEric Cheng } 18728275SEric Cheng 18738275SEric Cheng /* ARGSUSED */ 18748275SEric Cheng static dladm_status_t 187511878SVenu.Iyer@Sun.COM check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 187612742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 187711878SVenu.Iyer@Sun.COM datalink_media_t media) 18788275SEric Cheng { 187911878SVenu.Iyer@Sun.COM pool_conf_t *poolconf; 188011878SVenu.Iyer@Sun.COM pool_t *pool; 18818275SEric Cheng mac_resource_props_t mrp; 18828275SEric Cheng dladm_status_t status; 188311878SVenu.Iyer@Sun.COM uint_t perm_flags; 188411878SVenu.Iyer@Sun.COM char *poolname; 188512742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 188611878SVenu.Iyer@Sun.COM 188711878SVenu.Iyer@Sun.COM /* Get the current cpus property */ 188811878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 188911878SVenu.Iyer@Sun.COM &perm_flags, &mrp, sizeof (mrp)); 189011878SVenu.Iyer@Sun.COM 189111878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) { 189211878SVenu.Iyer@Sun.COM /* Can't set pool if cpus are set */ 189311878SVenu.Iyer@Sun.COM if (mrp.mrp_ncpus != 0) 189411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_POOLCPU); 18958275SEric Cheng } 18968275SEric Cheng 189711878SVenu.Iyer@Sun.COM poolname = malloc(sizeof (mrp.mrp_pool)); 189811878SVenu.Iyer@Sun.COM if (poolname == NULL) 18998275SEric Cheng return (DLADM_STATUS_NOMEM); 19008275SEric Cheng 190111878SVenu.Iyer@Sun.COM /* Check for pool's availability if not booting */ 190211878SVenu.Iyer@Sun.COM if ((flags & DLADM_OPT_BOOT) == 0) { 190311878SVenu.Iyer@Sun.COM 190411878SVenu.Iyer@Sun.COM /* Allocate and open pool configuration */ 190511878SVenu.Iyer@Sun.COM if ((poolconf = pool_conf_alloc()) == NULL) 190611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 190711878SVenu.Iyer@Sun.COM 190811878SVenu.Iyer@Sun.COM if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 190911878SVenu.Iyer@Sun.COM != PO_SUCCESS) { 191011878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 191111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 19128275SEric Cheng } 191311878SVenu.Iyer@Sun.COM 191411878SVenu.Iyer@Sun.COM /* Look for pool name */ 191511878SVenu.Iyer@Sun.COM if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 191611878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 191711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 19188275SEric Cheng } 191911878SVenu.Iyer@Sun.COM 192011878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 192111878SVenu.Iyer@Sun.COM free(pool); 19228275SEric Cheng } 192311878SVenu.Iyer@Sun.COM 192411878SVenu.Iyer@Sun.COM (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 192511878SVenu.Iyer@Sun.COM vdp->vd_val = (uintptr_t)poolname; 19268275SEric Cheng 19278275SEric Cheng return (DLADM_STATUS_OK); 19288275SEric Cheng } 19298275SEric Cheng 19308275SEric Cheng /* ARGSUSED */ 19318275SEric Cheng dladm_status_t 193211878SVenu.Iyer@Sun.COM extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 19338275SEric Cheng { 193411878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 193511878SVenu.Iyer@Sun.COM 193611878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) { 193711878SVenu.Iyer@Sun.COM bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 193811878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_POOL; 193911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 19408275SEric Cheng } 194111878SVenu.Iyer@Sun.COM 194211878SVenu.Iyer@Sun.COM (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 194311878SVenu.Iyer@Sun.COM sizeof (mrp->mrp_pool)); 194411878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_POOL; 194511878SVenu.Iyer@Sun.COM /* 194611878SVenu.Iyer@Sun.COM * Use MCM_CPUS since the fanout count is not user specified 194711878SVenu.Iyer@Sun.COM * and will be determined by the cpu list generated from the 194811878SVenu.Iyer@Sun.COM * pool. 194911878SVenu.Iyer@Sun.COM */ 19508275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 19518275SEric Cheng 19528275SEric Cheng return (DLADM_STATUS_OK); 19538275SEric Cheng } 19548275SEric Cheng 19558275SEric Cheng /* ARGSUSED */ 19568275SEric Cheng static dladm_status_t 195711878SVenu.Iyer@Sun.COM get_priority(dladm_handle_t handle, prop_desc_t *pdp, 19588460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 19598460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 19608275SEric Cheng { 19618275SEric Cheng mac_resource_props_t mrp; 19628275SEric Cheng mac_priority_level_t pri; 19638275SEric Cheng dladm_status_t status; 19648275SEric Cheng 196511878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 196611878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 196711878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 19688275SEric Cheng return (status); 19698275SEric Cheng 19708275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 19718275SEric Cheng mrp.mrp_priority; 19728275SEric Cheng 19738275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 19748275SEric Cheng *val_cnt = 1; 19758275SEric Cheng return (DLADM_STATUS_OK); 19768275SEric Cheng } 19778275SEric Cheng 19788275SEric Cheng /* ARGSUSED */ 197911878SVenu.Iyer@Sun.COM dladm_status_t 198011878SVenu.Iyer@Sun.COM extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 198111878SVenu.Iyer@Sun.COM { 198211878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 198311878SVenu.Iyer@Sun.COM 198411878SVenu.Iyer@Sun.COM if (cnt != 1) 198511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 198611878SVenu.Iyer@Sun.COM 198711878SVenu.Iyer@Sun.COM mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 198811878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_PRIORITY; 198911878SVenu.Iyer@Sun.COM 199011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 199111878SVenu.Iyer@Sun.COM } 199211878SVenu.Iyer@Sun.COM 199311878SVenu.Iyer@Sun.COM /* 199411878SVenu.Iyer@Sun.COM * Determines the size of the structure that needs to be sent to drivers 199511878SVenu.Iyer@Sun.COM * for retrieving the property range values. 199611878SVenu.Iyer@Sun.COM */ 199711878SVenu.Iyer@Sun.COM static int 199811878SVenu.Iyer@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 19998275SEric Cheng { 200011878SVenu.Iyer@Sun.COM uint_t count = r->mpr_count; 200111878SVenu.Iyer@Sun.COM 200211878SVenu.Iyer@Sun.COM *sz = sizeof (mac_propval_range_t); 200311878SVenu.Iyer@Sun.COM --count; 200411878SVenu.Iyer@Sun.COM 200511878SVenu.Iyer@Sun.COM switch (r->mpr_type) { 200611878SVenu.Iyer@Sun.COM case MAC_PROPVAL_UINT32: 200711878SVenu.Iyer@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 200811878SVenu.Iyer@Sun.COM return (0); 200911878SVenu.Iyer@Sun.COM default: 201011878SVenu.Iyer@Sun.COM break; 201111878SVenu.Iyer@Sun.COM } 201211878SVenu.Iyer@Sun.COM *sz = 0; 201311878SVenu.Iyer@Sun.COM return (EINVAL); 201411878SVenu.Iyer@Sun.COM } 201511878SVenu.Iyer@Sun.COM 201611878SVenu.Iyer@Sun.COM 201711878SVenu.Iyer@Sun.COM /* ARGSUSED */ 201811878SVenu.Iyer@Sun.COM static dladm_status_t 201911878SVenu.Iyer@Sun.COM check_rings(dladm_handle_t handle, prop_desc_t *pdp, 202012742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 202112742Smichael.l.lim@oracle.com val_desc_t **vp, datalink_media_t media) 202211878SVenu.Iyer@Sun.COM { 202312742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 202412742Smichael.l.lim@oracle.com val_desc_t *v = *vp; 202512742Smichael.l.lim@oracle.com 20268275SEric Cheng if (val_cnt != 1) 202711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 202811878SVenu.Iyer@Sun.COM if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 202911878SVenu.Iyer@Sun.COM v->vd_val = UNSPEC_VAL; 203011878SVenu.Iyer@Sun.COM } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 203111878SVenu.Iyer@Sun.COM v->vd_val = 0; 203211878SVenu.Iyer@Sun.COM } else { 203311878SVenu.Iyer@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 203411878SVenu.Iyer@Sun.COM if (v->vd_val == 0) 203511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 203611878SVenu.Iyer@Sun.COM } 203711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 203811878SVenu.Iyer@Sun.COM } 203911878SVenu.Iyer@Sun.COM 204011878SVenu.Iyer@Sun.COM /* ARGSUSED */ 204111878SVenu.Iyer@Sun.COM static dladm_status_t 204211878SVenu.Iyer@Sun.COM get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 204311878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 204411878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 204511878SVenu.Iyer@Sun.COM { 204611878SVenu.Iyer@Sun.COM dld_ioc_macprop_t *dip; 204711878SVenu.Iyer@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 204811878SVenu.Iyer@Sun.COM mac_propval_range_t *rangep; 204911878SVenu.Iyer@Sun.COM size_t sz; 205011878SVenu.Iyer@Sun.COM mac_propval_uint32_range_t *ur; 205111878SVenu.Iyer@Sun.COM 205211878SVenu.Iyer@Sun.COM sz = sizeof (mac_propval_range_t); 205311878SVenu.Iyer@Sun.COM 205411878SVenu.Iyer@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 205511878SVenu.Iyer@Sun.COM &status)) == NULL) 205611878SVenu.Iyer@Sun.COM return (status); 205711878SVenu.Iyer@Sun.COM 205811878SVenu.Iyer@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 205911878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 20608275SEric Cheng return (status); 206111878SVenu.Iyer@Sun.COM 206211878SVenu.Iyer@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 206311878SVenu.Iyer@Sun.COM *val_cnt = 1; 206411878SVenu.Iyer@Sun.COM ur = &rangep->mpr_range_uint32[0]; 206511878SVenu.Iyer@Sun.COM /* This is the case where the dev doesn't have any rings/groups */ 206611878SVenu.Iyer@Sun.COM if (rangep->mpr_count == 0) { 206711878SVenu.Iyer@Sun.COM (*prop_val)[0] = '\0'; 206811878SVenu.Iyer@Sun.COM /* 206911878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings, but static 207011878SVenu.Iyer@Sun.COM * grouping. 207111878SVenu.Iyer@Sun.COM */ 207211878SVenu.Iyer@Sun.COM } else if (ur->mpur_min == ur->mpur_max && 207311878SVenu.Iyer@Sun.COM ur->mpur_max == 0) { 207411878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 207511878SVenu.Iyer@Sun.COM /* 207611878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings and dynamic 207711878SVenu.Iyer@Sun.COM * grouping, but has only one value (say 2 rings and 2 groups). 207811878SVenu.Iyer@Sun.COM */ 207911878SVenu.Iyer@Sun.COM } else if (ur->mpur_min == ur->mpur_max) { 208011878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 208111878SVenu.Iyer@Sun.COM ur->mpur_min); 208211878SVenu.Iyer@Sun.COM /* 208311878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings and dynamic 208411878SVenu.Iyer@Sun.COM * grouping and has a range of rings. 208511878SVenu.Iyer@Sun.COM */ 208611878SVenu.Iyer@Sun.COM } else { 208711878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 208811878SVenu.Iyer@Sun.COM "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 20898275SEric Cheng } 209011878SVenu.Iyer@Sun.COM free(dip); 209111878SVenu.Iyer@Sun.COM return (status); 209211878SVenu.Iyer@Sun.COM } 209311878SVenu.Iyer@Sun.COM 209411878SVenu.Iyer@Sun.COM 209511878SVenu.Iyer@Sun.COM /* ARGSUSED */ 209611878SVenu.Iyer@Sun.COM static dladm_status_t 209711878SVenu.Iyer@Sun.COM get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 209811878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 209911878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 210011878SVenu.Iyer@Sun.COM { 210111878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 210211878SVenu.Iyer@Sun.COM dladm_status_t status; 210311878SVenu.Iyer@Sun.COM uint32_t nrings = 0; 210411878SVenu.Iyer@Sun.COM 210511878SVenu.Iyer@Sun.COM /* 210611878SVenu.Iyer@Sun.COM * Get the number of (effective-)rings from the resource property. 210711878SVenu.Iyer@Sun.COM */ 210811878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 210911878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 211011878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 211111878SVenu.Iyer@Sun.COM sizeof (mrp)); 211211878SVenu.Iyer@Sun.COM } else { 211311878SVenu.Iyer@Sun.COM /* 211411878SVenu.Iyer@Sun.COM * Get the permissions from the "rxrings" property. 211511878SVenu.Iyer@Sun.COM */ 211611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "rxrings", 211711878SVenu.Iyer@Sun.COM flags, perm_flags, NULL, 0); 211811878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 211911878SVenu.Iyer@Sun.COM return (status); 212011878SVenu.Iyer@Sun.COM 212111878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 212211878SVenu.Iyer@Sun.COM "resource", flags, NULL, &mrp, sizeof (mrp)); 21238275SEric Cheng } 21248275SEric Cheng 212511878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 212611878SVenu.Iyer@Sun.COM return (status); 212711878SVenu.Iyer@Sun.COM 212811878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 212911878SVenu.Iyer@Sun.COM *val_cnt = 0; 213011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 213111878SVenu.Iyer@Sun.COM } 213211878SVenu.Iyer@Sun.COM nrings = mrp.mrp_nrxrings; 213311878SVenu.Iyer@Sun.COM *val_cnt = 1; 213411878SVenu.Iyer@Sun.COM if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 213511878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 213611878SVenu.Iyer@Sun.COM else if (nrings == 0) 213711878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 213811878SVenu.Iyer@Sun.COM else 213911878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 21408275SEric Cheng return (DLADM_STATUS_OK); 21418275SEric Cheng } 21428275SEric Cheng 21438275SEric Cheng /* ARGSUSED */ 21448275SEric Cheng dladm_status_t 214511878SVenu.Iyer@Sun.COM extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 21468275SEric Cheng { 214711878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 214811878SVenu.Iyer@Sun.COM 214911878SVenu.Iyer@Sun.COM mrp->mrp_nrxrings = 0; 215011878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) 215111878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RINGS_RESET; 215211878SVenu.Iyer@Sun.COM else if (vdp->vd_val == UNSPEC_VAL) 215311878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 215411878SVenu.Iyer@Sun.COM else 215511878SVenu.Iyer@Sun.COM mrp->mrp_nrxrings = vdp->vd_val; 215611878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_RX_RINGS; 21578275SEric Cheng 21588275SEric Cheng return (DLADM_STATUS_OK); 21598275SEric Cheng } 21608275SEric Cheng 21618275SEric Cheng /* ARGSUSED */ 21628275SEric Cheng static dladm_status_t 216311878SVenu.Iyer@Sun.COM get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 216411878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 216511878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 216611878SVenu.Iyer@Sun.COM { 216711878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 216811878SVenu.Iyer@Sun.COM dladm_status_t status; 216911878SVenu.Iyer@Sun.COM uint32_t nrings = 0; 217011878SVenu.Iyer@Sun.COM 217111878SVenu.Iyer@Sun.COM 217211878SVenu.Iyer@Sun.COM /* 217311878SVenu.Iyer@Sun.COM * Get the number of (effective-)rings from the resource property. 217411878SVenu.Iyer@Sun.COM */ 217511878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 217611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 217711878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 217811878SVenu.Iyer@Sun.COM sizeof (mrp)); 217911878SVenu.Iyer@Sun.COM } else { 218011878SVenu.Iyer@Sun.COM /* 218111878SVenu.Iyer@Sun.COM * Get the permissions from the "txrings" property. 218211878SVenu.Iyer@Sun.COM */ 218311878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "txrings", 218411878SVenu.Iyer@Sun.COM flags, perm_flags, NULL, 0); 218511878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 218611878SVenu.Iyer@Sun.COM return (status); 218711878SVenu.Iyer@Sun.COM 218811878SVenu.Iyer@Sun.COM /* 218911878SVenu.Iyer@Sun.COM * Get the number of rings from the "resource" property. 219011878SVenu.Iyer@Sun.COM */ 219111878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 219211878SVenu.Iyer@Sun.COM flags, NULL, &mrp, sizeof (mrp)); 219311878SVenu.Iyer@Sun.COM } 219411878SVenu.Iyer@Sun.COM 219511878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 219611878SVenu.Iyer@Sun.COM return (status); 219711878SVenu.Iyer@Sun.COM 219811878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 219911878SVenu.Iyer@Sun.COM *val_cnt = 0; 220011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 220111878SVenu.Iyer@Sun.COM } 220211878SVenu.Iyer@Sun.COM nrings = mrp.mrp_ntxrings; 220311878SVenu.Iyer@Sun.COM *val_cnt = 1; 220411878SVenu.Iyer@Sun.COM if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 220511878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 220611878SVenu.Iyer@Sun.COM else if (nrings == 0) 220711878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 220811878SVenu.Iyer@Sun.COM else 220911878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 221011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 221111878SVenu.Iyer@Sun.COM } 221211878SVenu.Iyer@Sun.COM 221311878SVenu.Iyer@Sun.COM /* ARGSUSED */ 221411878SVenu.Iyer@Sun.COM dladm_status_t 221511878SVenu.Iyer@Sun.COM extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 221611878SVenu.Iyer@Sun.COM { 221711878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 221811878SVenu.Iyer@Sun.COM 221911878SVenu.Iyer@Sun.COM mrp->mrp_ntxrings = 0; 222011878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) 222111878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RINGS_RESET; 222211878SVenu.Iyer@Sun.COM else if (vdp->vd_val == UNSPEC_VAL) 222311878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 222411878SVenu.Iyer@Sun.COM else 222511878SVenu.Iyer@Sun.COM mrp->mrp_ntxrings = vdp->vd_val; 222611878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_TX_RINGS; 222711878SVenu.Iyer@Sun.COM 222811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 222911878SVenu.Iyer@Sun.COM } 223011878SVenu.Iyer@Sun.COM 223111878SVenu.Iyer@Sun.COM /* ARGSUSED */ 223211878SVenu.Iyer@Sun.COM static dladm_status_t 223311878SVenu.Iyer@Sun.COM get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 223411878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 223511878SVenu.Iyer@Sun.COM uint_t *perm_flags) 223611878SVenu.Iyer@Sun.COM { 223711878SVenu.Iyer@Sun.COM if (flags & DLD_PROP_DEFAULT) 223811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTDEFINED); 223911878SVenu.Iyer@Sun.COM 224011878SVenu.Iyer@Sun.COM return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 224111878SVenu.Iyer@Sun.COM flags, perm_flags)); 224211878SVenu.Iyer@Sun.COM } 224311878SVenu.Iyer@Sun.COM 224411878SVenu.Iyer@Sun.COM /* ARGSUSED */ 224511878SVenu.Iyer@Sun.COM static dladm_status_t 224611878SVenu.Iyer@Sun.COM set_resource(dladm_handle_t handle, prop_desc_t *pdp, 224710734SEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 224810734SEric Cheng uint_t flags, datalink_media_t media) 224910734SEric Cheng { 225010734SEric Cheng mac_resource_props_t mrp; 225110734SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 225210734SEric Cheng dld_ioc_macprop_t *dip; 225311878SVenu.Iyer@Sun.COM int i; 225410734SEric Cheng 225510734SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 225611878SVenu.Iyer@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 225710734SEric Cheng flags, &status); 225810734SEric Cheng 225910734SEric Cheng if (dip == NULL) 226010734SEric Cheng return (status); 226110734SEric Cheng 226211878SVenu.Iyer@Sun.COM for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 226311878SVenu.Iyer@Sun.COM resource_prop_t *rp = &rsrc_prop_table[i]; 226411878SVenu.Iyer@Sun.COM 226511878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, rp->rp_name) != 0) 226611878SVenu.Iyer@Sun.COM continue; 226711878SVenu.Iyer@Sun.COM 226811878SVenu.Iyer@Sun.COM status = rp->rp_extract(vdp, val_cnt, &mrp); 226910734SEric Cheng if (status != DLADM_STATUS_OK) 227010734SEric Cheng goto done; 227110734SEric Cheng 227211878SVenu.Iyer@Sun.COM break; 227310734SEric Cheng } 227410734SEric Cheng 227510734SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 227610734SEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 227710734SEric Cheng 227810734SEric Cheng done: 227910734SEric Cheng free(dip); 228010734SEric Cheng return (status); 228110734SEric Cheng } 228210734SEric Cheng 228310734SEric Cheng /* ARGSUSED */ 228410734SEric Cheng static dladm_status_t 228511878SVenu.Iyer@Sun.COM get_protection(dladm_handle_t handle, prop_desc_t *pdp, 228610734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 228710734SEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 228810734SEric Cheng { 228911878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 229011878SVenu.Iyer@Sun.COM mac_protect_t *p; 229111878SVenu.Iyer@Sun.COM dladm_status_t status; 229211878SVenu.Iyer@Sun.COM uint32_t i, cnt = 0, setbits[32]; 229311878SVenu.Iyer@Sun.COM 229411878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 229511878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 229611878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 229711878SVenu.Iyer@Sun.COM return (status); 229811878SVenu.Iyer@Sun.COM 229911878SVenu.Iyer@Sun.COM p = &mrp.mrp_protect; 230011878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 230111878SVenu.Iyer@Sun.COM *val_cnt = 0; 230211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 230311878SVenu.Iyer@Sun.COM } 230411878SVenu.Iyer@Sun.COM dladm_find_setbits32(p->mp_types, setbits, &cnt); 230511878SVenu.Iyer@Sun.COM if (cnt > *val_cnt) 230611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 230711878SVenu.Iyer@Sun.COM 230811878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) 230911878SVenu.Iyer@Sun.COM (void) dladm_protect2str(setbits[i], prop_val[i]); 231011878SVenu.Iyer@Sun.COM 231111878SVenu.Iyer@Sun.COM *val_cnt = cnt; 231211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 231311878SVenu.Iyer@Sun.COM } 231411878SVenu.Iyer@Sun.COM 231511878SVenu.Iyer@Sun.COM /* ARGSUSED */ 231611878SVenu.Iyer@Sun.COM static dladm_status_t 231711878SVenu.Iyer@Sun.COM get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 231811878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 231911878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 232011878SVenu.Iyer@Sun.COM { 232110734SEric Cheng mac_resource_props_t mrp; 232210734SEric Cheng mac_protect_t *p; 232310734SEric Cheng dladm_status_t status; 232410734SEric Cheng int i; 232510734SEric Cheng 232611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 232711878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 232811878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 232910734SEric Cheng return (status); 233010734SEric Cheng 233110734SEric Cheng p = &mrp.mrp_protect; 233211878SVenu.Iyer@Sun.COM if (p->mp_ipaddrcnt == 0) { 233311878SVenu.Iyer@Sun.COM *val_cnt = 0; 233410734SEric Cheng return (DLADM_STATUS_OK); 233510734SEric Cheng } 233611878SVenu.Iyer@Sun.COM if (p->mp_ipaddrcnt > *val_cnt) 233711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 233811878SVenu.Iyer@Sun.COM 233911878SVenu.Iyer@Sun.COM for (i = 0; i < p->mp_ipaddrcnt; i++) { 234011878SVenu.Iyer@Sun.COM if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 234111878SVenu.Iyer@Sun.COM ipaddr_t v4addr; 234211878SVenu.Iyer@Sun.COM 234311878SVenu.Iyer@Sun.COM v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 234411878SVenu.Iyer@Sun.COM (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 234511878SVenu.Iyer@Sun.COM } else { 234611878SVenu.Iyer@Sun.COM (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 234710734SEric Cheng prop_val[i]); 234810734SEric Cheng } 234910734SEric Cheng } 235011878SVenu.Iyer@Sun.COM *val_cnt = p->mp_ipaddrcnt; 235110734SEric Cheng return (DLADM_STATUS_OK); 235210734SEric Cheng } 235310734SEric Cheng 235410734SEric Cheng dladm_status_t 235511878SVenu.Iyer@Sun.COM extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 235610734SEric Cheng { 235710734SEric Cheng mac_resource_props_t *mrp = arg; 235810734SEric Cheng uint32_t types = 0; 235910734SEric Cheng int i; 236010734SEric Cheng 236110734SEric Cheng for (i = 0; i < cnt; i++) 236210734SEric Cheng types |= (uint32_t)vdp[i].vd_val; 236310734SEric Cheng 236410734SEric Cheng mrp->mrp_protect.mp_types = types; 236510734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 236610734SEric Cheng return (DLADM_STATUS_OK); 236710734SEric Cheng } 236810734SEric Cheng 236910734SEric Cheng dladm_status_t 237011878SVenu.Iyer@Sun.COM extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 237110734SEric Cheng { 237210734SEric Cheng mac_resource_props_t *mrp = arg; 237310734SEric Cheng mac_protect_t *p = &mrp->mrp_protect; 237410734SEric Cheng int i; 237510734SEric Cheng 237610734SEric Cheng if (vdp->vd_val == 0) { 237710734SEric Cheng cnt = (uint_t)-1; 237810734SEric Cheng } else { 237911878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) { 238011878SVenu.Iyer@Sun.COM bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 238111878SVenu.Iyer@Sun.COM sizeof (mac_ipaddr_t)); 238211878SVenu.Iyer@Sun.COM } 238310734SEric Cheng } 238410734SEric Cheng p->mp_ipaddrcnt = cnt; 238510734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 238610734SEric Cheng return (DLADM_STATUS_OK); 238710734SEric Cheng } 238810734SEric Cheng 238911878SVenu.Iyer@Sun.COM static dladm_status_t 239011878SVenu.Iyer@Sun.COM check_single_ip(char *buf, mac_ipaddr_t *addr) 239111878SVenu.Iyer@Sun.COM { 239211878SVenu.Iyer@Sun.COM dladm_status_t status; 239311878SVenu.Iyer@Sun.COM ipaddr_t v4addr; 239411878SVenu.Iyer@Sun.COM in6_addr_t v6addr; 239511878SVenu.Iyer@Sun.COM boolean_t isv4 = B_TRUE; 239611878SVenu.Iyer@Sun.COM 239711878SVenu.Iyer@Sun.COM status = dladm_str2ipv4addr(buf, &v4addr); 239811878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_INVALID_IP) { 239911878SVenu.Iyer@Sun.COM status = dladm_str2ipv6addr(buf, &v6addr); 240011878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) 240111878SVenu.Iyer@Sun.COM isv4 = B_FALSE; 240211878SVenu.Iyer@Sun.COM } 240311878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 240411878SVenu.Iyer@Sun.COM return (status); 240511878SVenu.Iyer@Sun.COM 240611878SVenu.Iyer@Sun.COM if (isv4) { 240711878SVenu.Iyer@Sun.COM if (v4addr == INADDR_ANY) 240811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_INVALID_IP); 240911878SVenu.Iyer@Sun.COM 241011878SVenu.Iyer@Sun.COM IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 241111878SVenu.Iyer@Sun.COM addr->ip_version = IPV4_VERSION; 241211878SVenu.Iyer@Sun.COM } else { 241311878SVenu.Iyer@Sun.COM if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 241411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_INVALID_IP); 241511878SVenu.Iyer@Sun.COM 241611878SVenu.Iyer@Sun.COM addr->ip_addr = v6addr; 241711878SVenu.Iyer@Sun.COM addr->ip_version = IPV6_VERSION; 241811878SVenu.Iyer@Sun.COM } 241911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 242011878SVenu.Iyer@Sun.COM } 242111878SVenu.Iyer@Sun.COM 242210734SEric Cheng /* ARGSUSED */ 242310734SEric Cheng static dladm_status_t 242411878SVenu.Iyer@Sun.COM check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 242512742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 242612742Smichael.l.lim@oracle.com val_desc_t **vdpp, datalink_media_t media) 242710734SEric Cheng { 242810734SEric Cheng dladm_status_t status; 242911878SVenu.Iyer@Sun.COM mac_ipaddr_t *addr; 243010734SEric Cheng int i; 243112742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 243212742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 243310734SEric Cheng 243410734SEric Cheng if (val_cnt > MPT_MAXIPADDR) 243510734SEric Cheng return (DLADM_STATUS_BADVALCNT); 243610734SEric Cheng 243710734SEric Cheng for (i = 0; i < val_cnt; i++) { 243811878SVenu.Iyer@Sun.COM if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 243911878SVenu.Iyer@Sun.COM status = DLADM_STATUS_NOMEM; 244011878SVenu.Iyer@Sun.COM goto fail; 244111878SVenu.Iyer@Sun.COM } 244211878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)addr; 244311878SVenu.Iyer@Sun.COM 244411878SVenu.Iyer@Sun.COM status = check_single_ip(prop_val[i], addr); 244510734SEric Cheng if (status != DLADM_STATUS_OK) 244611878SVenu.Iyer@Sun.COM goto fail; 244711878SVenu.Iyer@Sun.COM } 244811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 244911878SVenu.Iyer@Sun.COM 245011878SVenu.Iyer@Sun.COM fail: 245111878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 245211878SVenu.Iyer@Sun.COM free((void *)vdp[i].vd_val); 245311878SVenu.Iyer@Sun.COM vdp[i].vd_val = NULL; 245411878SVenu.Iyer@Sun.COM } 245511878SVenu.Iyer@Sun.COM return (status); 245611878SVenu.Iyer@Sun.COM } 245711878SVenu.Iyer@Sun.COM 245811878SVenu.Iyer@Sun.COM static void 245911878SVenu.Iyer@Sun.COM dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 246011878SVenu.Iyer@Sun.COM { 246111878SVenu.Iyer@Sun.COM char tmp_buf[DLADM_STRSIZE]; 246211878SVenu.Iyer@Sun.COM uint_t hexlen; 246311878SVenu.Iyer@Sun.COM 246411878SVenu.Iyer@Sun.COM switch (cid->dc_form) { 246511878SVenu.Iyer@Sun.COM case CIDFORM_TYPED: { 246611878SVenu.Iyer@Sun.COM uint16_t duidtype, hwtype; 246711878SVenu.Iyer@Sun.COM uint32_t timestamp, ennum; 246811878SVenu.Iyer@Sun.COM char *lladdr; 246911878SVenu.Iyer@Sun.COM 247011878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (duidtype)) 247111878SVenu.Iyer@Sun.COM goto fail; 247211878SVenu.Iyer@Sun.COM 247311878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 247411878SVenu.Iyer@Sun.COM duidtype = ntohs(duidtype); 247511878SVenu.Iyer@Sun.COM switch (duidtype) { 247611878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LLT: { 247711878SVenu.Iyer@Sun.COM duid_llt_t llt; 247811878SVenu.Iyer@Sun.COM 247911878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (llt)) 248011878SVenu.Iyer@Sun.COM goto fail; 248111878SVenu.Iyer@Sun.COM 248211878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &llt, sizeof (llt)); 248311878SVenu.Iyer@Sun.COM hwtype = ntohs(llt.dllt_hwtype); 248411878SVenu.Iyer@Sun.COM timestamp = ntohl(llt.dllt_time); 248511878SVenu.Iyer@Sun.COM lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 248611878SVenu.Iyer@Sun.COM NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 248711878SVenu.Iyer@Sun.COM if (lladdr == NULL) 248811878SVenu.Iyer@Sun.COM goto fail; 248911878SVenu.Iyer@Sun.COM 249011878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 249111878SVenu.Iyer@Sun.COM duidtype, hwtype, timestamp, lladdr); 249211878SVenu.Iyer@Sun.COM free(lladdr); 249311878SVenu.Iyer@Sun.COM break; 249411878SVenu.Iyer@Sun.COM } 249511878SVenu.Iyer@Sun.COM case DHCPV6_DUID_EN: { 249611878SVenu.Iyer@Sun.COM duid_en_t en; 249711878SVenu.Iyer@Sun.COM 249811878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (en)) 249911878SVenu.Iyer@Sun.COM goto fail; 250011878SVenu.Iyer@Sun.COM 250111878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &en, sizeof (en)); 250211878SVenu.Iyer@Sun.COM ennum = DHCPV6_GET_ENTNUM(&en); 250311878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 250411878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id + sizeof (en), 250511878SVenu.Iyer@Sun.COM cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 250611878SVenu.Iyer@Sun.COM goto fail; 250711878SVenu.Iyer@Sun.COM 250811878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 250911878SVenu.Iyer@Sun.COM duidtype, ennum, tmp_buf); 251011878SVenu.Iyer@Sun.COM break; 251111878SVenu.Iyer@Sun.COM } 251211878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LL: { 251311878SVenu.Iyer@Sun.COM duid_ll_t ll; 251411878SVenu.Iyer@Sun.COM 251511878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (ll)) 251611878SVenu.Iyer@Sun.COM goto fail; 251711878SVenu.Iyer@Sun.COM 251811878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &ll, sizeof (ll)); 251911878SVenu.Iyer@Sun.COM hwtype = ntohs(ll.dll_hwtype); 252011878SVenu.Iyer@Sun.COM lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 252111878SVenu.Iyer@Sun.COM NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 252211878SVenu.Iyer@Sun.COM if (lladdr == NULL) 252311878SVenu.Iyer@Sun.COM goto fail; 252411878SVenu.Iyer@Sun.COM 252511878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 252611878SVenu.Iyer@Sun.COM duidtype, hwtype, lladdr); 252711878SVenu.Iyer@Sun.COM free(lladdr); 252811878SVenu.Iyer@Sun.COM break; 252911878SVenu.Iyer@Sun.COM } 253011878SVenu.Iyer@Sun.COM default: { 253111878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 253211878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 253311878SVenu.Iyer@Sun.COM cid->dc_len - sizeof (duidtype), 253411878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 253511878SVenu.Iyer@Sun.COM goto fail; 253611878SVenu.Iyer@Sun.COM 253711878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 253811878SVenu.Iyer@Sun.COM duidtype, tmp_buf); 253911878SVenu.Iyer@Sun.COM } 254011878SVenu.Iyer@Sun.COM } 254111878SVenu.Iyer@Sun.COM break; 254211878SVenu.Iyer@Sun.COM } 254311878SVenu.Iyer@Sun.COM case CIDFORM_HEX: { 254411878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 254511878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id, cid->dc_len, 254611878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 254711878SVenu.Iyer@Sun.COM goto fail; 254811878SVenu.Iyer@Sun.COM 254911878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 255011878SVenu.Iyer@Sun.COM break; 255111878SVenu.Iyer@Sun.COM } 255211878SVenu.Iyer@Sun.COM case CIDFORM_STR: { 255311878SVenu.Iyer@Sun.COM int i; 255411878SVenu.Iyer@Sun.COM 255511878SVenu.Iyer@Sun.COM for (i = 0; i < cid->dc_len; i++) { 255611878SVenu.Iyer@Sun.COM if (!isprint(cid->dc_id[i])) 255711878SVenu.Iyer@Sun.COM goto fail; 255811878SVenu.Iyer@Sun.COM } 255911878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 256011878SVenu.Iyer@Sun.COM break; 256111878SVenu.Iyer@Sun.COM } 256211878SVenu.Iyer@Sun.COM default: 256311878SVenu.Iyer@Sun.COM goto fail; 256410734SEric Cheng } 256511878SVenu.Iyer@Sun.COM return; 256611878SVenu.Iyer@Sun.COM 256711878SVenu.Iyer@Sun.COM fail: 256811878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 256911878SVenu.Iyer@Sun.COM } 257011878SVenu.Iyer@Sun.COM 257111878SVenu.Iyer@Sun.COM static dladm_status_t 257211878SVenu.Iyer@Sun.COM dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 257311878SVenu.Iyer@Sun.COM { 257411878SVenu.Iyer@Sun.COM char *ptr = buf; 257511878SVenu.Iyer@Sun.COM char tmp_buf[DLADM_STRSIZE]; 257611878SVenu.Iyer@Sun.COM uint_t hexlen, cidlen; 257711878SVenu.Iyer@Sun.COM 257811878SVenu.Iyer@Sun.COM bzero(cid, sizeof (*cid)); 257911878SVenu.Iyer@Sun.COM if (isdigit(*ptr) && 258011878SVenu.Iyer@Sun.COM ptr[strspn(ptr, "0123456789")] == '.') { 258111878SVenu.Iyer@Sun.COM char *cp; 258211878SVenu.Iyer@Sun.COM ulong_t duidtype; 258311878SVenu.Iyer@Sun.COM ulong_t subtype; 258411878SVenu.Iyer@Sun.COM ulong_t timestamp; 258511878SVenu.Iyer@Sun.COM uchar_t *lladdr; 258611878SVenu.Iyer@Sun.COM int addrlen; 258711878SVenu.Iyer@Sun.COM 258811878SVenu.Iyer@Sun.COM errno = 0; 258911878SVenu.Iyer@Sun.COM duidtype = strtoul(ptr, &cp, 0); 259011878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.' || 259111878SVenu.Iyer@Sun.COM duidtype > USHRT_MAX) 259211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 259311878SVenu.Iyer@Sun.COM ptr = cp + 1; 259411878SVenu.Iyer@Sun.COM 259511878SVenu.Iyer@Sun.COM if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 259611878SVenu.Iyer@Sun.COM errno = 0; 259711878SVenu.Iyer@Sun.COM subtype = strtoul(ptr, &cp, 0); 259811878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.') 259911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 260011878SVenu.Iyer@Sun.COM ptr = cp + 1; 260111878SVenu.Iyer@Sun.COM } 260211878SVenu.Iyer@Sun.COM switch (duidtype) { 260311878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LLT: { 260411878SVenu.Iyer@Sun.COM duid_llt_t llt; 260511878SVenu.Iyer@Sun.COM 260611878SVenu.Iyer@Sun.COM errno = 0; 260711878SVenu.Iyer@Sun.COM timestamp = strtoul(ptr, &cp, 0); 260811878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.') 260911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 261011878SVenu.Iyer@Sun.COM 261111878SVenu.Iyer@Sun.COM ptr = cp + 1; 261211878SVenu.Iyer@Sun.COM lladdr = _link_aton(ptr, &addrlen); 261311878SVenu.Iyer@Sun.COM if (lladdr == NULL) 261411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 261511878SVenu.Iyer@Sun.COM 261611878SVenu.Iyer@Sun.COM cidlen = sizeof (llt) + addrlen; 261711878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) { 261811878SVenu.Iyer@Sun.COM free(lladdr); 261911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 262011878SVenu.Iyer@Sun.COM } 262111878SVenu.Iyer@Sun.COM llt.dllt_dutype = htons(duidtype); 262211878SVenu.Iyer@Sun.COM llt.dllt_hwtype = htons(subtype); 262311878SVenu.Iyer@Sun.COM llt.dllt_time = htonl(timestamp); 262411878SVenu.Iyer@Sun.COM bcopy(&llt, cid->dc_id, sizeof (llt)); 262511878SVenu.Iyer@Sun.COM bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 262611878SVenu.Iyer@Sun.COM free(lladdr); 262711878SVenu.Iyer@Sun.COM break; 262811878SVenu.Iyer@Sun.COM } 262911878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LL: { 263011878SVenu.Iyer@Sun.COM duid_ll_t ll; 263111878SVenu.Iyer@Sun.COM 263211878SVenu.Iyer@Sun.COM lladdr = _link_aton(ptr, &addrlen); 263311878SVenu.Iyer@Sun.COM if (lladdr == NULL) 263411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 263511878SVenu.Iyer@Sun.COM 263611878SVenu.Iyer@Sun.COM cidlen = sizeof (ll) + addrlen; 263711878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) { 263811878SVenu.Iyer@Sun.COM free(lladdr); 263911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 264011878SVenu.Iyer@Sun.COM } 264111878SVenu.Iyer@Sun.COM ll.dll_dutype = htons(duidtype); 264211878SVenu.Iyer@Sun.COM ll.dll_hwtype = htons(subtype); 264311878SVenu.Iyer@Sun.COM bcopy(&ll, cid->dc_id, sizeof (ll)); 264411878SVenu.Iyer@Sun.COM bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 264511878SVenu.Iyer@Sun.COM free(lladdr); 264611878SVenu.Iyer@Sun.COM break; 264711878SVenu.Iyer@Sun.COM } 264811878SVenu.Iyer@Sun.COM default: { 264911878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 265011878SVenu.Iyer@Sun.COM if (hexascii_to_octet(ptr, strlen(ptr), 265111878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 265211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 265311878SVenu.Iyer@Sun.COM 265411878SVenu.Iyer@Sun.COM if (duidtype == DHCPV6_DUID_EN) { 265511878SVenu.Iyer@Sun.COM duid_en_t en; 265611878SVenu.Iyer@Sun.COM 265711878SVenu.Iyer@Sun.COM en.den_dutype = htons(duidtype); 265811878SVenu.Iyer@Sun.COM DHCPV6_SET_ENTNUM(&en, subtype); 265911878SVenu.Iyer@Sun.COM 266011878SVenu.Iyer@Sun.COM cidlen = sizeof (en) + hexlen; 266111878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 266211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 266311878SVenu.Iyer@Sun.COM 266411878SVenu.Iyer@Sun.COM bcopy(&en, cid->dc_id, sizeof (en)); 266511878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id + sizeof (en), 266611878SVenu.Iyer@Sun.COM hexlen); 266711878SVenu.Iyer@Sun.COM } else { 266811878SVenu.Iyer@Sun.COM uint16_t dutype = htons(duidtype); 266911878SVenu.Iyer@Sun.COM 267011878SVenu.Iyer@Sun.COM cidlen = sizeof (dutype) + hexlen; 267111878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 267211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 267311878SVenu.Iyer@Sun.COM 267411878SVenu.Iyer@Sun.COM bcopy(&dutype, cid->dc_id, sizeof (dutype)); 267511878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 267611878SVenu.Iyer@Sun.COM hexlen); 267711878SVenu.Iyer@Sun.COM } 267811878SVenu.Iyer@Sun.COM break; 267911878SVenu.Iyer@Sun.COM } 268011878SVenu.Iyer@Sun.COM } 268111878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_TYPED; 268211878SVenu.Iyer@Sun.COM } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 268311878SVenu.Iyer@Sun.COM ptr += 2; 268411878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 268511878SVenu.Iyer@Sun.COM if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 268611878SVenu.Iyer@Sun.COM &hexlen) != 0) { 268711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 268811878SVenu.Iyer@Sun.COM } 268911878SVenu.Iyer@Sun.COM cidlen = hexlen; 269011878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 269111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 269211878SVenu.Iyer@Sun.COM 269311878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id, cidlen); 269411878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_HEX; 269511878SVenu.Iyer@Sun.COM } else { 269611878SVenu.Iyer@Sun.COM cidlen = strlen(ptr); 269711878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 269811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 269911878SVenu.Iyer@Sun.COM 270011878SVenu.Iyer@Sun.COM bcopy(ptr, cid->dc_id, cidlen); 270111878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_STR; 270211878SVenu.Iyer@Sun.COM } 270311878SVenu.Iyer@Sun.COM cid->dc_len = cidlen; 270410734SEric Cheng return (DLADM_STATUS_OK); 270510734SEric Cheng } 270610734SEric Cheng 270710734SEric Cheng /* ARGSUSED */ 270810734SEric Cheng static dladm_status_t 270911878SVenu.Iyer@Sun.COM get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 271011878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 271111878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 271211878SVenu.Iyer@Sun.COM { 271311878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 271411878SVenu.Iyer@Sun.COM mac_protect_t *p; 271511878SVenu.Iyer@Sun.COM dladm_status_t status; 271611878SVenu.Iyer@Sun.COM int i; 271711878SVenu.Iyer@Sun.COM 271811878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 271911878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 272011878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 272111878SVenu.Iyer@Sun.COM return (status); 272211878SVenu.Iyer@Sun.COM 272311878SVenu.Iyer@Sun.COM p = &mrp.mrp_protect; 272411878SVenu.Iyer@Sun.COM if (p->mp_cidcnt == 0) { 272511878SVenu.Iyer@Sun.COM *val_cnt = 0; 272611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 272711878SVenu.Iyer@Sun.COM } 272811878SVenu.Iyer@Sun.COM if (p->mp_cidcnt > *val_cnt) 272911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 273011878SVenu.Iyer@Sun.COM 273111878SVenu.Iyer@Sun.COM for (i = 0; i < p->mp_cidcnt; i++) { 273211878SVenu.Iyer@Sun.COM mac_dhcpcid_t *cid = &p->mp_cids[i]; 273311878SVenu.Iyer@Sun.COM 273411878SVenu.Iyer@Sun.COM dladm_cid2str(cid, prop_val[i]); 273511878SVenu.Iyer@Sun.COM } 273611878SVenu.Iyer@Sun.COM *val_cnt = p->mp_cidcnt; 273711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 273811878SVenu.Iyer@Sun.COM } 273911878SVenu.Iyer@Sun.COM 274011878SVenu.Iyer@Sun.COM dladm_status_t 274111878SVenu.Iyer@Sun.COM extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 274211878SVenu.Iyer@Sun.COM { 274311878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 274411878SVenu.Iyer@Sun.COM mac_protect_t *p = &mrp->mrp_protect; 274511878SVenu.Iyer@Sun.COM int i; 274611878SVenu.Iyer@Sun.COM 274711878SVenu.Iyer@Sun.COM if (vdp->vd_val == 0) { 274811878SVenu.Iyer@Sun.COM cnt = (uint_t)-1; 274911878SVenu.Iyer@Sun.COM } else { 275011878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) { 275111878SVenu.Iyer@Sun.COM bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 275211878SVenu.Iyer@Sun.COM sizeof (mac_dhcpcid_t)); 275311878SVenu.Iyer@Sun.COM } 275411878SVenu.Iyer@Sun.COM } 275511878SVenu.Iyer@Sun.COM p->mp_cidcnt = cnt; 275611878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_PROTECT; 275711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 275811878SVenu.Iyer@Sun.COM } 275911878SVenu.Iyer@Sun.COM 276011878SVenu.Iyer@Sun.COM /* ARGSUSED */ 276111878SVenu.Iyer@Sun.COM static dladm_status_t 276211878SVenu.Iyer@Sun.COM check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 276312742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, 276412742Smichael.l.lim@oracle.com uint_t flags, val_desc_t **vdpp, datalink_media_t media) 276511878SVenu.Iyer@Sun.COM { 276611878SVenu.Iyer@Sun.COM dladm_status_t status; 276711878SVenu.Iyer@Sun.COM mac_dhcpcid_t *cid; 276811878SVenu.Iyer@Sun.COM int i; 276912742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 277012742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 277111878SVenu.Iyer@Sun.COM 277211878SVenu.Iyer@Sun.COM if (val_cnt > MPT_MAXCID) 277311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 277411878SVenu.Iyer@Sun.COM 277511878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 277611878SVenu.Iyer@Sun.COM if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 277711878SVenu.Iyer@Sun.COM status = DLADM_STATUS_NOMEM; 277811878SVenu.Iyer@Sun.COM goto fail; 277911878SVenu.Iyer@Sun.COM } 278011878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)cid; 278111878SVenu.Iyer@Sun.COM 278211878SVenu.Iyer@Sun.COM status = dladm_str2cid(prop_val[i], cid); 278311878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 278411878SVenu.Iyer@Sun.COM goto fail; 278511878SVenu.Iyer@Sun.COM } 278611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 278711878SVenu.Iyer@Sun.COM 278811878SVenu.Iyer@Sun.COM fail: 278911878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 279011878SVenu.Iyer@Sun.COM free((void *)vdp[i].vd_val); 279111878SVenu.Iyer@Sun.COM vdp[i].vd_val = NULL; 279211878SVenu.Iyer@Sun.COM } 279311878SVenu.Iyer@Sun.COM return (status); 279411878SVenu.Iyer@Sun.COM } 279511878SVenu.Iyer@Sun.COM 279611878SVenu.Iyer@Sun.COM /* ARGSUSED */ 279711878SVenu.Iyer@Sun.COM static dladm_status_t 279811878SVenu.Iyer@Sun.COM get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 27998275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 28008275SEric Cheng uint_t flags, uint_t *perm_flags) 28015895Syz147064 { 28027342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 28037342SAruna.Ramakrishna@Sun.COM int i, len; 28047342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 280511878SVenu.Iyer@Sun.COM 280611878SVenu.Iyer@Sun.COM if (flags & DLD_PROP_DEFAULT) 28077776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 28086512Ssowmini 280911878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 281011878SVenu.Iyer@Sun.COM perm_flags, &dlap, sizeof (dlap)); 281111878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 281211878SVenu.Iyer@Sun.COM return (status); 281311878SVenu.Iyer@Sun.COM 281411878SVenu.Iyer@Sun.COM if (dlap.dap_npush == 0) { 281511878SVenu.Iyer@Sun.COM *val_cnt = 0; 28168275SEric Cheng return (DLADM_STATUS_OK); 28175895Syz147064 } 28187342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 28195895Syz147064 if (i != 0) { 28205895Syz147064 (void) snprintf(*prop_val + len, 28215895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 28225895Syz147064 len += 1; 28235895Syz147064 } 28245895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 28257342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 28267342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 28277342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 28285895Syz147064 (void) snprintf(*prop_val + len, 28295895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 28305895Syz147064 AP_ANCHOR); 28315895Syz147064 len += (strlen(AP_ANCHOR) + 1); 28325895Syz147064 } 28335895Syz147064 } 283411878SVenu.Iyer@Sun.COM *val_cnt = 1; 28355895Syz147064 return (DLADM_STATUS_OK); 28365895Syz147064 } 28375895Syz147064 28385895Syz147064 /* 28395895Syz147064 * Add the specified module to the dlautopush structure; returns a 28405895Syz147064 * DLADM_STATUS_* code. 28415895Syz147064 */ 28425895Syz147064 dladm_status_t 28435895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 28445895Syz147064 { 28455895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 28465895Syz147064 return (DLADM_STATUS_BADVAL); 28475895Syz147064 28485895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 28495895Syz147064 /* 28505895Syz147064 * We don't allow multiple anchors, and the anchor must 28515895Syz147064 * be after at least one module. 28525895Syz147064 */ 28535895Syz147064 if (dlap->dap_anchor != 0) 28545895Syz147064 return (DLADM_STATUS_BADVAL); 28555895Syz147064 if (dlap->dap_npush == 0) 28565895Syz147064 return (DLADM_STATUS_BADVAL); 28575895Syz147064 28585895Syz147064 dlap->dap_anchor = dlap->dap_npush; 28595895Syz147064 return (DLADM_STATUS_OK); 28605895Syz147064 } 28618957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 28625895Syz147064 return (DLADM_STATUS_BADVALCNT); 28635895Syz147064 28645895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 28655895Syz147064 FMNAMESZ + 1); 28665895Syz147064 28675895Syz147064 return (DLADM_STATUS_OK); 28685895Syz147064 } 28695895Syz147064 28705895Syz147064 /* 28715895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 28725895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 28735895Syz147064 * latter is used in the autopush(1M) file. 28745895Syz147064 */ 28755895Syz147064 /* ARGSUSED */ 28765895Syz147064 static dladm_status_t 287711878SVenu.Iyer@Sun.COM check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 287812742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 287911878SVenu.Iyer@Sun.COM datalink_media_t media) 28805895Syz147064 { 28815895Syz147064 char *module; 28825895Syz147064 struct dlautopush *dlap; 28835895Syz147064 dladm_status_t status; 28845895Syz147064 char val[DLADM_PROP_VAL_MAX]; 28855895Syz147064 char delimiters[4]; 288612742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 288712742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 28885895Syz147064 28895895Syz147064 if (val_cnt != 1) 28905895Syz147064 return (DLADM_STATUS_BADVALCNT); 28915895Syz147064 28927342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 28937342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 28947342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 28957342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 28963448Sdh155122 28977342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 28987342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 28997342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 29007342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 29017342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 29027342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 29037342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 29047342SAruna.Ramakrishna@Sun.COM return (status); 29057342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 29067342SAruna.Ramakrishna@Sun.COM } 29077342SAruna.Ramakrishna@Sun.COM 29087342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 29097342SAruna.Ramakrishna@Sun.COM } else { 29107342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 29115895Syz147064 } 29123448Sdh155122 return (DLADM_STATUS_OK); 29133448Sdh155122 } 29143448Sdh155122 29157663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 29167663SSowmini.Varadhan@Sun.COM 29175903Ssowmini /* ARGSUSED */ 29183448Sdh155122 static dladm_status_t 291911878SVenu.Iyer@Sun.COM get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 29208453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 29218453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 29223448Sdh155122 { 29235895Syz147064 wl_rates_t *wrp; 29245895Syz147064 uint_t i; 29255895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 29265895Syz147064 29277663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 29287663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 29297663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 29305895Syz147064 29318453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 29328453SAnurag.Maskey@Sun.COM B_FALSE); 29335895Syz147064 if (status != DLADM_STATUS_OK) 29345895Syz147064 goto done; 29355895Syz147064 29365895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 29375895Syz147064 status = DLADM_STATUS_TOOSMALL; 29385895Syz147064 goto done; 29395895Syz147064 } 29405895Syz147064 29415895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 29425895Syz147064 prop_val[0][0] = '\0'; 29435895Syz147064 *val_cnt = 1; 29445895Syz147064 goto done; 29455895Syz147064 } 29465895Syz147064 29475895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 29485895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 29495895Syz147064 wrp->wl_rates_rates[i] % 2, 29505895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 29515895Syz147064 } 29525895Syz147064 *val_cnt = wrp->wl_rates_num; 29538275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 29543448Sdh155122 29555895Syz147064 done: 29567663SSowmini.Varadhan@Sun.COM free(wrp); 29575895Syz147064 return (status); 29585895Syz147064 } 29595895Syz147064 29605895Syz147064 static dladm_status_t 296111878SVenu.Iyer@Sun.COM get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 29628275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 29638275SEric Cheng uint_t flags, uint_t *perm_flags) 29645895Syz147064 { 29658118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 296611878SVenu.Iyer@Sun.COM return (get_speed(handle, pdp, linkid, prop_val, 296711878SVenu.Iyer@Sun.COM val_cnt, media, flags, perm_flags)); 29688118SVasumathi.Sundaram@Sun.COM } 29695960Ssowmini 297011878SVenu.Iyer@Sun.COM return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 29718275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 29725895Syz147064 } 29735895Syz147064 29746512Ssowmini /* ARGSUSED */ 29755895Syz147064 static dladm_status_t 297611878SVenu.Iyer@Sun.COM get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 29778275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 29788275SEric Cheng uint_t flags, uint_t *perm_flags) 29795895Syz147064 { 29805960Ssowmini switch (media) { 29815960Ssowmini case DL_ETHER: 29826512Ssowmini /* 29836512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 29846512Ssowmini * links can have a speed of 5.5 Gbps. 29856512Ssowmini */ 29866512Ssowmini return (DLADM_STATUS_NOTSUP); 29875960Ssowmini 29885960Ssowmini case DL_WIFI: 298911878SVenu.Iyer@Sun.COM return (get_rate_common(handle, pdp, linkid, prop_val, 29908453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 29915960Ssowmini default: 29925960Ssowmini return (DLADM_STATUS_BADARG); 29935960Ssowmini } 29945895Syz147064 } 29955895Syz147064 29965895Syz147064 static dladm_status_t 299711878SVenu.Iyer@Sun.COM set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 29988453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 29995895Syz147064 { 30005895Syz147064 int i; 30015895Syz147064 uint_t len; 30025895Syz147064 wl_rates_t *wrp; 30035895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 30045895Syz147064 30057663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 30067663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 30075895Syz147064 return (DLADM_STATUS_NOMEM); 30085895Syz147064 30097663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 30105895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 30115895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 30125895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 30135895Syz147064 30145895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 30155895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 30168453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 30178453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 30185895Syz147064 30197663SSowmini.Varadhan@Sun.COM free(wrp); 30205895Syz147064 return (status); 30215895Syz147064 } 30223448Sdh155122 30235903Ssowmini /* ARGSUSED */ 30245895Syz147064 static dladm_status_t 302511878SVenu.Iyer@Sun.COM set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 30265960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 30275895Syz147064 { 30285895Syz147064 dladm_wlan_rates_t rates; 30295895Syz147064 dladm_status_t status; 30305895Syz147064 30315960Ssowmini /* 30325960Ssowmini * can currently set rate on WIFI links only. 30335960Ssowmini */ 30345960Ssowmini if (media != DL_WIFI) 30355960Ssowmini return (DLADM_STATUS_PROPRDONLY); 30365960Ssowmini 30375895Syz147064 if (val_cnt != 1) 30385895Syz147064 return (DLADM_STATUS_BADVALCNT); 30395895Syz147064 30405895Syz147064 rates.wr_cnt = 1; 30415895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 30425895Syz147064 304311878SVenu.Iyer@Sun.COM status = set_wlan_rate(handle, linkid, &rates); 304411878SVenu.Iyer@Sun.COM 30455895Syz147064 return (status); 30465895Syz147064 } 30473448Sdh155122 30485895Syz147064 /* ARGSUSED */ 30495895Syz147064 static dladm_status_t 305011878SVenu.Iyer@Sun.COM check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 305112742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 305211878SVenu.Iyer@Sun.COM datalink_media_t media) 30535895Syz147064 { 30545895Syz147064 int i; 30555895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 30565895Syz147064 char *buf, **modval; 30575895Syz147064 dladm_status_t status; 30588118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 305912742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 306012742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 30615895Syz147064 30625895Syz147064 if (val_cnt != 1) 30635895Syz147064 return (DLADM_STATUS_BADVALCNT); 30645895Syz147064 30655895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 30665895Syz147064 MAX_SUPPORT_RATES); 30675895Syz147064 if (buf == NULL) { 30685895Syz147064 status = DLADM_STATUS_NOMEM; 30695895Syz147064 goto done; 30705895Syz147064 } 30713448Sdh155122 30725895Syz147064 modval = (char **)(void *)buf; 30735895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 30745895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 30755895Syz147064 i * DLADM_STRSIZE; 30765895Syz147064 } 30775895Syz147064 307811878SVenu.Iyer@Sun.COM status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 30798453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 30805895Syz147064 if (status != DLADM_STATUS_OK) 30815895Syz147064 goto done; 30825895Syz147064 30835895Syz147064 for (i = 0; i < modval_cnt; i++) { 30845895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 30855903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 30865903Ssowmini (atof(*prop_val) * 2); 30875895Syz147064 status = DLADM_STATUS_OK; 30883448Sdh155122 break; 30893448Sdh155122 } 30905895Syz147064 } 30915895Syz147064 if (i == modval_cnt) 30925895Syz147064 status = DLADM_STATUS_BADVAL; 30935895Syz147064 done: 30945895Syz147064 free(buf); 30955895Syz147064 return (status); 30965895Syz147064 } 30975895Syz147064 30985895Syz147064 static dladm_status_t 309911878SVenu.Iyer@Sun.COM get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 31008453SAnurag.Maskey@Sun.COM int buflen) 31015895Syz147064 { 31028453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 31037663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 31045895Syz147064 } 31055895Syz147064 31065903Ssowmini /* ARGSUSED */ 31075895Syz147064 static dladm_status_t 310811878SVenu.Iyer@Sun.COM get_channel(dladm_handle_t handle, prop_desc_t *pdp, 31098453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 31108453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 31115895Syz147064 { 31125895Syz147064 uint32_t channel; 31137663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 311411878SVenu.Iyer@Sun.COM dladm_status_t status; 31157663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 31165895Syz147064 311711878SVenu.Iyer@Sun.COM if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 31187663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 311911878SVenu.Iyer@Sun.COM return (status); 31205895Syz147064 31217663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 312211878SVenu.Iyer@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 312311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 31245895Syz147064 31255895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 31265895Syz147064 *val_cnt = 1; 31278275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 312811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 31295895Syz147064 } 31305895Syz147064 31315903Ssowmini /* ARGSUSED */ 31325895Syz147064 static dladm_status_t 313311878SVenu.Iyer@Sun.COM get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 31348453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 31358453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 31365895Syz147064 { 31377663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 31385895Syz147064 const char *s; 31397663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 314011878SVenu.Iyer@Sun.COM dladm_status_t status; 314111878SVenu.Iyer@Sun.COM 314211878SVenu.Iyer@Sun.COM if ((status = i_dladm_wlan_param(handle, linkid, buf, 314311878SVenu.Iyer@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 314411878SVenu.Iyer@Sun.COM return (status); 31455895Syz147064 31467663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 31477663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 31485895Syz147064 case WL_PM_AM: 31495895Syz147064 s = "off"; 31505895Syz147064 break; 31515895Syz147064 case WL_PM_MPS: 31525895Syz147064 s = "max"; 31535895Syz147064 break; 31545895Syz147064 case WL_PM_FAST: 31555895Syz147064 s = "fast"; 31563448Sdh155122 break; 31573448Sdh155122 default: 315811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 31595895Syz147064 } 31605895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 31615895Syz147064 *val_cnt = 1; 31628275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 316311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 31645895Syz147064 } 31655895Syz147064 316611878SVenu.Iyer@Sun.COM /* ARGSUSED */ 31675895Syz147064 static dladm_status_t 316811878SVenu.Iyer@Sun.COM set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 316911878SVenu.Iyer@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 317011878SVenu.Iyer@Sun.COM datalink_media_t media) 31715895Syz147064 { 317211878SVenu.Iyer@Sun.COM dladm_wlan_powermode_t powermode = vdp->vd_val; 317311878SVenu.Iyer@Sun.COM wl_ps_mode_t ps_mode; 317411878SVenu.Iyer@Sun.COM 317511878SVenu.Iyer@Sun.COM if (val_cnt != 1) 317611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 31775895Syz147064 31785895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 31795895Syz147064 318011878SVenu.Iyer@Sun.COM switch (powermode) { 31815895Syz147064 case DLADM_WLAN_PM_OFF: 31825895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 31833448Sdh155122 break; 31845895Syz147064 case DLADM_WLAN_PM_MAX: 31855895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 31865895Syz147064 break; 31875895Syz147064 case DLADM_WLAN_PM_FAST: 31885895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 31895895Syz147064 break; 31905895Syz147064 default: 31915895Syz147064 return (DLADM_STATUS_NOTSUP); 31923448Sdh155122 } 31938453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 31948453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 31955895Syz147064 } 31965895Syz147064 31975895Syz147064 /* ARGSUSED */ 31985895Syz147064 static dladm_status_t 319911878SVenu.Iyer@Sun.COM get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 32008275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 32018275SEric Cheng uint_t flags, uint_t *perm_flags) 32025895Syz147064 { 32035895Syz147064 wl_radio_t radio; 32045895Syz147064 const char *s; 32057663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 320611878SVenu.Iyer@Sun.COM dladm_status_t status; 320711878SVenu.Iyer@Sun.COM 320811878SVenu.Iyer@Sun.COM if ((status = i_dladm_wlan_param(handle, linkid, buf, 320911878SVenu.Iyer@Sun.COM MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 321011878SVenu.Iyer@Sun.COM return (status); 32113448Sdh155122 32127663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 32135895Syz147064 switch (radio) { 32145895Syz147064 case B_TRUE: 32155895Syz147064 s = "on"; 32165895Syz147064 break; 32175895Syz147064 case B_FALSE: 32185895Syz147064 s = "off"; 32195895Syz147064 break; 32205895Syz147064 default: 322111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 32225895Syz147064 } 32235895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 32245895Syz147064 *val_cnt = 1; 32258275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 322611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 32273448Sdh155122 } 32283448Sdh155122 322911878SVenu.Iyer@Sun.COM /* ARGSUSED */ 32303448Sdh155122 static dladm_status_t 323111878SVenu.Iyer@Sun.COM set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 323211878SVenu.Iyer@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 32333448Sdh155122 { 323411878SVenu.Iyer@Sun.COM dladm_wlan_radio_t radio = vdp->vd_val; 323511878SVenu.Iyer@Sun.COM wl_radio_t r; 323611878SVenu.Iyer@Sun.COM 323711878SVenu.Iyer@Sun.COM if (val_cnt != 1) 323811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 323911878SVenu.Iyer@Sun.COM 324011878SVenu.Iyer@Sun.COM switch (radio) { 32415895Syz147064 case DLADM_WLAN_RADIO_ON: 32425895Syz147064 r = B_TRUE; 32435895Syz147064 break; 32445895Syz147064 case DLADM_WLAN_RADIO_OFF: 32455895Syz147064 r = B_FALSE; 32465895Syz147064 break; 32475895Syz147064 default: 32485895Syz147064 return (DLADM_STATUS_NOTSUP); 32495895Syz147064 } 32508453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 32517663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 32525895Syz147064 } 32533448Sdh155122 32545895Syz147064 /* ARGSUSED */ 32555895Syz147064 static dladm_status_t 325611878SVenu.Iyer@Sun.COM check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 325712742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 325812742Smichael.l.lim@oracle.com val_desc_t **vdpp, datalink_media_t media) 325910616SSebastien.Roy@Sun.COM { 326012742Smichael.l.lim@oracle.com int32_t hlim; 326112742Smichael.l.lim@oracle.com char *ep; 326212742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 326312742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 326410616SSebastien.Roy@Sun.COM 326510616SSebastien.Roy@Sun.COM if (val_cnt != 1) 326610616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 326710616SSebastien.Roy@Sun.COM 326810616SSebastien.Roy@Sun.COM errno = 0; 326910616SSebastien.Roy@Sun.COM hlim = strtol(*prop_val, &ep, 10); 327010616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || hlim < 1 || 327110616SSebastien.Roy@Sun.COM hlim > (int32_t)UINT8_MAX) 327210616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 327310616SSebastien.Roy@Sun.COM vdp->vd_val = hlim; 327410616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 327510616SSebastien.Roy@Sun.COM } 327610616SSebastien.Roy@Sun.COM 327710616SSebastien.Roy@Sun.COM /* ARGSUSED */ 327810616SSebastien.Roy@Sun.COM static dladm_status_t 327911878SVenu.Iyer@Sun.COM check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 328012742Smichael.l.lim@oracle.com char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 328111878SVenu.Iyer@Sun.COM datalink_media_t media) 328210616SSebastien.Roy@Sun.COM { 328312742Smichael.l.lim@oracle.com int32_t elim; 328412742Smichael.l.lim@oracle.com char *ep; 328512742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 328612742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 328710616SSebastien.Roy@Sun.COM 328810616SSebastien.Roy@Sun.COM if (media != DL_IPV6) 328910616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG); 329010616SSebastien.Roy@Sun.COM 329110616SSebastien.Roy@Sun.COM if (val_cnt != 1) 329210616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 329310616SSebastien.Roy@Sun.COM 329410616SSebastien.Roy@Sun.COM errno = 0; 329510616SSebastien.Roy@Sun.COM elim = strtol(*prop_val, &ep, 10); 329610616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || elim < 0 || 329710616SSebastien.Roy@Sun.COM elim > (int32_t)UINT8_MAX) 329810616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 329910616SSebastien.Roy@Sun.COM vdp->vd_val = elim; 330010616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 330110616SSebastien.Roy@Sun.COM } 330210616SSebastien.Roy@Sun.COM 33035895Syz147064 static dladm_status_t 33048453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 33058453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 33063448Sdh155122 { 33075895Syz147064 char buf[MAXLINELEN]; 33085895Syz147064 int i; 33095895Syz147064 dladm_conf_t conf; 33105895Syz147064 dladm_status_t status; 33113448Sdh155122 33128453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 33135895Syz147064 if (status != DLADM_STATUS_OK) 33145895Syz147064 return (status); 33153448Sdh155122 33165895Syz147064 /* 33175895Syz147064 * reset case. 33185895Syz147064 */ 33195895Syz147064 if (val_cnt == 0) { 33208453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 33215895Syz147064 if (status == DLADM_STATUS_OK) 33228453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 33235895Syz147064 goto done; 33245895Syz147064 } 33253448Sdh155122 33265895Syz147064 buf[0] = '\0'; 33275895Syz147064 for (i = 0; i < val_cnt; i++) { 33285895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 33295895Syz147064 if (i != val_cnt - 1) 33305895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 33313448Sdh155122 } 33323448Sdh155122 33338453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 33348453SAnurag.Maskey@Sun.COM buf); 33355895Syz147064 if (status == DLADM_STATUS_OK) 33368453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 33375895Syz147064 33385895Syz147064 done: 33398453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 33405895Syz147064 return (status); 33413448Sdh155122 } 33425895Syz147064 33435895Syz147064 static dladm_status_t 33448453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 33458453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 33465895Syz147064 { 33475895Syz147064 char buf[MAXLINELEN], *str; 33485895Syz147064 uint_t cnt = 0; 33495895Syz147064 dladm_conf_t conf; 33505895Syz147064 dladm_status_t status; 33515895Syz147064 33528453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 33535895Syz147064 if (status != DLADM_STATUS_OK) 33545895Syz147064 return (status); 33555895Syz147064 33568453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 33575895Syz147064 if (status != DLADM_STATUS_OK) 33585895Syz147064 goto done; 33595895Syz147064 33605895Syz147064 str = strtok(buf, ","); 33615895Syz147064 while (str != NULL) { 33625895Syz147064 if (cnt == *val_cntp) { 33635895Syz147064 status = DLADM_STATUS_TOOSMALL; 33645895Syz147064 goto done; 33655895Syz147064 } 33665895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 33675895Syz147064 str = strtok(NULL, ","); 33685895Syz147064 } 33695895Syz147064 33705895Syz147064 *val_cntp = cnt; 33715895Syz147064 33725895Syz147064 done: 33738453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 33745895Syz147064 return (status); 33755895Syz147064 } 33765903Ssowmini 33778460SArtem.Kachitchkin@Sun.COM /* 33788460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 33798460SArtem.Kachitchkin@Sun.COM */ 33808460SArtem.Kachitchkin@Sun.COM static dladm_status_t 33818460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 33828460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 33838460SArtem.Kachitchkin@Sun.COM { 33848460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 33858460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 33868460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 33878460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 33888460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 33898460SArtem.Kachitchkin@Sun.COM size_t attrsz; 33908460SArtem.Kachitchkin@Sun.COM 33918460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 33928460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 33938460SArtem.Kachitchkin@Sun.COM 33948460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 33958460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 33968460SArtem.Kachitchkin@Sun.COM return (status); 33978460SArtem.Kachitchkin@Sun.COM 33988460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 33998460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 34008460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 34018460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 34028460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 34038460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 34048460SArtem.Kachitchkin@Sun.COM break; 34058460SArtem.Kachitchkin@Sun.COM } 34068460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 34078460SArtem.Kachitchkin@Sun.COM } 34088460SArtem.Kachitchkin@Sun.COM 34098460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 34108460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 34118460SArtem.Kachitchkin@Sun.COM } 34128460SArtem.Kachitchkin@Sun.COM 34137663SSowmini.Varadhan@Sun.COM static link_attr_t * 34145903Ssowmini dladm_name2prop(const char *prop_name) 34155903Ssowmini { 34167663SSowmini.Varadhan@Sun.COM link_attr_t *p; 34175903Ssowmini 34187663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 34195903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 34205903Ssowmini break; 34215903Ssowmini } 34225903Ssowmini return (p); 34235903Ssowmini } 34245903Ssowmini 34257663SSowmini.Varadhan@Sun.COM static link_attr_t * 34267663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 34277663SSowmini.Varadhan@Sun.COM { 34287663SSowmini.Varadhan@Sun.COM link_attr_t *p; 34297663SSowmini.Varadhan@Sun.COM 34307663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 34317663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 34327663SSowmini.Varadhan@Sun.COM break; 34337663SSowmini.Varadhan@Sun.COM } 34347663SSowmini.Varadhan@Sun.COM return (p); 34357663SSowmini.Varadhan@Sun.COM } 34365903Ssowmini 34376789Sam223141 static dld_ioc_macprop_t * 34387663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 34397663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 34407663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 34415903Ssowmini { 34425903Ssowmini int dsize; 34436789Sam223141 dld_ioc_macprop_t *dip; 34445903Ssowmini 34455903Ssowmini *status = DLADM_STATUS_OK; 34466789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 34475903Ssowmini dip = malloc(dsize); 34485903Ssowmini if (dip == NULL) { 34495903Ssowmini *status = DLADM_STATUS_NOMEM; 34505903Ssowmini return (NULL); 34515903Ssowmini } 34525903Ssowmini bzero(dip, dsize); 34535903Ssowmini dip->pr_valsize = valsize; 34546512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 34555960Ssowmini dip->pr_linkid = linkid; 34567663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 34576512Ssowmini dip->pr_flags = flags; 34585903Ssowmini return (dip); 34595903Ssowmini } 34605903Ssowmini 34617663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 34627663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 34637663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 34647663SSowmini.Varadhan@Sun.COM { 34657663SSowmini.Varadhan@Sun.COM link_attr_t *p; 34667663SSowmini.Varadhan@Sun.COM 34677663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 34687663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 34697663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 34707663SSowmini.Varadhan@Sun.COM flags, status)); 34717663SSowmini.Varadhan@Sun.COM } 34727663SSowmini.Varadhan@Sun.COM 34737663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 34747663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 34757663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 34767663SSowmini.Varadhan@Sun.COM { 34777663SSowmini.Varadhan@Sun.COM link_attr_t *p; 34787663SSowmini.Varadhan@Sun.COM 34797663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 34807663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 34817663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 34827663SSowmini.Varadhan@Sun.COM flags, status)); 34837663SSowmini.Varadhan@Sun.COM } 34847663SSowmini.Varadhan@Sun.COM 34855903Ssowmini /* ARGSUSED */ 34865903Ssowmini static dladm_status_t 348711878SVenu.Iyer@Sun.COM set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 34888453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 34898453SAnurag.Maskey@Sun.COM datalink_media_t media) 34905903Ssowmini { 34916789Sam223141 dld_ioc_macprop_t *dip; 34925903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 34935903Ssowmini uint8_t u8; 34945903Ssowmini uint16_t u16; 34955903Ssowmini uint32_t u32; 34965903Ssowmini void *val; 34975903Ssowmini 34988275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 34995903Ssowmini if (dip == NULL) 35005903Ssowmini return (status); 35015903Ssowmini 35028275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 35035903Ssowmini val = (void *)vdp->vd_val; 35045903Ssowmini else { 35055903Ssowmini /* 35065903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 35075903Ssowmini * No need (yet) to distinguish these from arrays of same size. 35085903Ssowmini */ 35095903Ssowmini switch (dip->pr_valsize) { 35105903Ssowmini case 1: 35115903Ssowmini u8 = vdp->vd_val; 35125903Ssowmini val = &u8; 35135903Ssowmini break; 35145903Ssowmini case 2: 35155903Ssowmini u16 = vdp->vd_val; 35165903Ssowmini val = &u16; 35175903Ssowmini break; 35185903Ssowmini case 4: 35195903Ssowmini u32 = vdp->vd_val; 35205903Ssowmini val = &u32; 35215903Ssowmini break; 35225903Ssowmini default: 35235903Ssowmini val = &vdp->vd_val; 35245903Ssowmini break; 35255903Ssowmini } 35265903Ssowmini } 35275903Ssowmini 35287342SAruna.Ramakrishna@Sun.COM if (val != NULL) 35297342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 35307342SAruna.Ramakrishna@Sun.COM else 35317342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 35327342SAruna.Ramakrishna@Sun.COM 35338453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 35347663SSowmini.Varadhan@Sun.COM 35357663SSowmini.Varadhan@Sun.COM done: 35367663SSowmini.Varadhan@Sun.COM free(dip); 35377663SSowmini.Varadhan@Sun.COM return (status); 35387663SSowmini.Varadhan@Sun.COM } 35397663SSowmini.Varadhan@Sun.COM 35407663SSowmini.Varadhan@Sun.COM dladm_status_t 35418453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 35427663SSowmini.Varadhan@Sun.COM { 35437663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 35447663SSowmini.Varadhan@Sun.COM 35458453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 35468453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 35475903Ssowmini status = dladm_errno2status(errno); 35488453SAnurag.Maskey@Sun.COM 35495903Ssowmini return (status); 35505903Ssowmini } 35515903Ssowmini 355211878SVenu.Iyer@Sun.COM static dladm_status_t 35538453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 355411878SVenu.Iyer@Sun.COM char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 35555903Ssowmini { 355611878SVenu.Iyer@Sun.COM dld_ioc_macprop_t *dip; 355711878SVenu.Iyer@Sun.COM dladm_status_t status; 355811878SVenu.Iyer@Sun.COM 355911878SVenu.Iyer@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 35606512Ssowmini if (dip == NULL) 356111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 356211878SVenu.Iyer@Sun.COM 356311878SVenu.Iyer@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 356411878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) { 35656512Ssowmini free(dip); 356611878SVenu.Iyer@Sun.COM return (status); 35676512Ssowmini } 356811878SVenu.Iyer@Sun.COM 35698275SEric Cheng if (perm_flags != NULL) 35708275SEric Cheng *perm_flags = dip->pr_perm_flags; 35718275SEric Cheng 357211878SVenu.Iyer@Sun.COM if (arg != NULL) 357311878SVenu.Iyer@Sun.COM (void) memcpy(arg, dip->pr_val, size); 357411878SVenu.Iyer@Sun.COM free(dip); 357511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 35765903Ssowmini } 35775903Ssowmini 35785903Ssowmini /* ARGSUSED */ 35795903Ssowmini static dladm_status_t 358011878SVenu.Iyer@Sun.COM check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 358112742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 358212742Smichael.l.lim@oracle.com val_desc_t **vp, datalink_media_t media) 35835903Ssowmini { 358412742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 358512742Smichael.l.lim@oracle.com val_desc_t *v = *vp; 358612742Smichael.l.lim@oracle.com 35875903Ssowmini if (val_cnt != 1) 35885903Ssowmini return (DLADM_STATUS_BADVAL); 358910491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 35905903Ssowmini return (DLADM_STATUS_OK); 35915903Ssowmini } 35925903Ssowmini 35935903Ssowmini /* ARGSUSED */ 35945903Ssowmini static dladm_status_t 359511878SVenu.Iyer@Sun.COM get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 35968453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35978453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35985903Ssowmini { 35995903Ssowmini link_duplex_t link_duplex; 36005903Ssowmini dladm_status_t status; 36015903Ssowmini 36028453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 36035903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 36045903Ssowmini return (status); 36055903Ssowmini 36065903Ssowmini switch (link_duplex) { 36075903Ssowmini case LINK_DUPLEX_FULL: 36085903Ssowmini (void) strcpy(*prop_val, "full"); 36095903Ssowmini break; 36105903Ssowmini case LINK_DUPLEX_HALF: 36115903Ssowmini (void) strcpy(*prop_val, "half"); 36125903Ssowmini break; 36135903Ssowmini default: 36145903Ssowmini (void) strcpy(*prop_val, "unknown"); 36155903Ssowmini break; 36165903Ssowmini } 36175903Ssowmini *val_cnt = 1; 36185903Ssowmini return (DLADM_STATUS_OK); 36195903Ssowmini } 36205903Ssowmini 36215903Ssowmini /* ARGSUSED */ 36225903Ssowmini static dladm_status_t 362311878SVenu.Iyer@Sun.COM get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 362411878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 362511878SVenu.Iyer@Sun.COM uint_t *perm_flags) 36265903Ssowmini { 36275903Ssowmini uint64_t ifspeed = 0; 36285903Ssowmini dladm_status_t status; 36295903Ssowmini 36308453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 36315903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 36325903Ssowmini return (status); 36336512Ssowmini 36345960Ssowmini if ((ifspeed % 1000000) != 0) { 36355960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 36365960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 36375960Ssowmini } else { 36385960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 36395960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 36405960Ssowmini } 36415903Ssowmini *val_cnt = 1; 36428275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 36435903Ssowmini return (DLADM_STATUS_OK); 36445903Ssowmini } 36455903Ssowmini 36465903Ssowmini /* ARGSUSED */ 36475903Ssowmini static dladm_status_t 364811878SVenu.Iyer@Sun.COM get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 36498453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36508453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36515903Ssowmini { 36528275SEric Cheng link_state_t link_state; 36538275SEric Cheng dladm_status_t status; 36548306SSowmini.Varadhan@Sun.COM 365511878SVenu.Iyer@Sun.COM status = dladm_get_state(handle, linkid, &link_state); 36566512Ssowmini if (status != DLADM_STATUS_OK) 36575903Ssowmini return (status); 36588275SEric Cheng 36595903Ssowmini switch (link_state) { 36605903Ssowmini case LINK_STATE_UP: 36615903Ssowmini (void) strcpy(*prop_val, "up"); 36625903Ssowmini break; 36635903Ssowmini case LINK_STATE_DOWN: 36645903Ssowmini (void) strcpy(*prop_val, "down"); 36655903Ssowmini break; 36665903Ssowmini default: 36675903Ssowmini (void) strcpy(*prop_val, "unknown"); 36685903Ssowmini break; 36695903Ssowmini } 36705903Ssowmini *val_cnt = 1; 36718306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 36725903Ssowmini return (DLADM_STATUS_OK); 36735903Ssowmini } 36745903Ssowmini 36755903Ssowmini /* ARGSUSED */ 36765903Ssowmini static dladm_status_t 367711878SVenu.Iyer@Sun.COM get_binary(dladm_handle_t handle, prop_desc_t *pdp, 36788453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36798453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36805903Ssowmini { 368111878SVenu.Iyer@Sun.COM dladm_status_t status; 368211878SVenu.Iyer@Sun.COM uint_t v = 0; 368311878SVenu.Iyer@Sun.COM 368411878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 368511878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 368611878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 36875903Ssowmini return (status); 36888275SEric Cheng 368911878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 36905903Ssowmini *val_cnt = 1; 36915903Ssowmini return (DLADM_STATUS_OK); 36925903Ssowmini } 36935903Ssowmini 36945960Ssowmini /* ARGSUSED */ 36955903Ssowmini static dladm_status_t 369611878SVenu.Iyer@Sun.COM get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 36978453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36988453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36995903Ssowmini { 370011878SVenu.Iyer@Sun.COM dladm_status_t status; 370111878SVenu.Iyer@Sun.COM uint32_t v = 0; 370211878SVenu.Iyer@Sun.COM 370311878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 370411878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 370511878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 37065903Ssowmini return (status); 37078275SEric Cheng 37086512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 37095903Ssowmini *val_cnt = 1; 37105903Ssowmini return (DLADM_STATUS_OK); 37115903Ssowmini } 37125903Ssowmini 37139514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 37149514SGirish.Moodalbail@Sun.COM static dladm_status_t 371511878SVenu.Iyer@Sun.COM get_range(dladm_handle_t handle, prop_desc_t *pdp, 37169514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37179514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 37189514SGirish.Moodalbail@Sun.COM { 37199514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 37209514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 37219514SGirish.Moodalbail@Sun.COM size_t sz; 37229514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 37239514SGirish.Moodalbail@Sun.COM 37249514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 37259514SGirish.Moodalbail@Sun.COM 37269514SGirish.Moodalbail@Sun.COM /* 37279514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 37289514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 37299514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 37309514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 37319514SGirish.Moodalbail@Sun.COM */ 37329514SGirish.Moodalbail@Sun.COM retry: 37339514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 37349514SGirish.Moodalbail@Sun.COM &status)) == NULL) 37359514SGirish.Moodalbail@Sun.COM return (status); 37369514SGirish.Moodalbail@Sun.COM 37379514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 37389514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 37399514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 37409514SGirish.Moodalbail@Sun.COM int err; 37419514SGirish.Moodalbail@Sun.COM 37429514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 37439514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 37449514SGirish.Moodalbail@Sun.COM free(dip); 37459514SGirish.Moodalbail@Sun.COM goto retry; 37469514SGirish.Moodalbail@Sun.COM } else { 37479514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 37489514SGirish.Moodalbail@Sun.COM } 37499514SGirish.Moodalbail@Sun.COM } 37509514SGirish.Moodalbail@Sun.COM free(dip); 37519514SGirish.Moodalbail@Sun.COM return (status); 37529514SGirish.Moodalbail@Sun.COM } 375311878SVenu.Iyer@Sun.COM 37549514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 375511878SVenu.Iyer@Sun.COM if (rangep->mpr_count == 0) { 375611878SVenu.Iyer@Sun.COM *val_cnt = 1; 375711878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 375811878SVenu.Iyer@Sun.COM goto done; 375911878SVenu.Iyer@Sun.COM } 37609514SGirish.Moodalbail@Sun.COM 37619514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 37629514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 37639514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 37649514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 37659514SGirish.Moodalbail@Sun.COM 376611878SVenu.Iyer@Sun.COM ur = &rangep->mpr_range_uint32[0]; 37679514SGirish.Moodalbail@Sun.COM 37689514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 37699514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 37709514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 37719514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 37729514SGirish.Moodalbail@Sun.COM } else { 37739514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 37749514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 37759514SGirish.Moodalbail@Sun.COM } 37769514SGirish.Moodalbail@Sun.COM } 37779514SGirish.Moodalbail@Sun.COM *val_cnt = count; 37789514SGirish.Moodalbail@Sun.COM break; 37799514SGirish.Moodalbail@Sun.COM } 37809514SGirish.Moodalbail@Sun.COM default: 37819514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 37829514SGirish.Moodalbail@Sun.COM break; 37839514SGirish.Moodalbail@Sun.COM } 378411878SVenu.Iyer@Sun.COM done: 37859514SGirish.Moodalbail@Sun.COM free(dip); 37869514SGirish.Moodalbail@Sun.COM return (status); 37879514SGirish.Moodalbail@Sun.COM } 37889514SGirish.Moodalbail@Sun.COM 37895960Ssowmini /* ARGSUSED */ 37905903Ssowmini static dladm_status_t 379111878SVenu.Iyer@Sun.COM get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 37928874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37938874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 37948874SSebastien.Roy@Sun.COM { 37958874SSebastien.Roy@Sun.COM link_tagmode_t mode; 37968874SSebastien.Roy@Sun.COM dladm_status_t status; 37978874SSebastien.Roy@Sun.COM 379811878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 379911878SVenu.Iyer@Sun.COM perm_flags, &mode, sizeof (mode)); 380011878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 38018874SSebastien.Roy@Sun.COM return (status); 38028874SSebastien.Roy@Sun.COM 38038874SSebastien.Roy@Sun.COM switch (mode) { 38048874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 38058874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 38068874SSebastien.Roy@Sun.COM break; 38078874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 38088874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 38098874SSebastien.Roy@Sun.COM break; 38108874SSebastien.Roy@Sun.COM default: 38118874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 38128874SSebastien.Roy@Sun.COM } 38138874SSebastien.Roy@Sun.COM *val_cnt = 1; 38148874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 38158874SSebastien.Roy@Sun.COM } 38168874SSebastien.Roy@Sun.COM 38178874SSebastien.Roy@Sun.COM /* ARGSUSED */ 38188874SSebastien.Roy@Sun.COM static dladm_status_t 381911878SVenu.Iyer@Sun.COM get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 38208453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 38218453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 38225903Ssowmini { 382311878SVenu.Iyer@Sun.COM link_flowctrl_t v; 382411878SVenu.Iyer@Sun.COM dladm_status_t status; 382511878SVenu.Iyer@Sun.COM 382611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 382711878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 382811878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 38295903Ssowmini return (status); 38308275SEric Cheng 38315903Ssowmini switch (v) { 38325903Ssowmini case LINK_FLOWCTRL_NONE: 38335903Ssowmini (void) sprintf(*prop_val, "no"); 38345903Ssowmini break; 38355903Ssowmini case LINK_FLOWCTRL_RX: 38365903Ssowmini (void) sprintf(*prop_val, "rx"); 38375903Ssowmini break; 38385903Ssowmini case LINK_FLOWCTRL_TX: 38395903Ssowmini (void) sprintf(*prop_val, "tx"); 38405903Ssowmini break; 38415903Ssowmini case LINK_FLOWCTRL_BI: 38425903Ssowmini (void) sprintf(*prop_val, "bi"); 38435903Ssowmini break; 38445903Ssowmini } 38455903Ssowmini *val_cnt = 1; 38465903Ssowmini return (DLADM_STATUS_OK); 38475903Ssowmini } 38485903Ssowmini 38495903Ssowmini 38505903Ssowmini /* ARGSUSED */ 38515903Ssowmini static dladm_status_t 38529692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 38538453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 38548453SAnurag.Maskey@Sun.COM 38555903Ssowmini { 38567663SSowmini.Varadhan@Sun.COM int i, slen; 38577408SSebastien.Roy@Sun.COM int bufsize = 0; 38586789Sam223141 dld_ioc_macprop_t *dip = NULL; 38595903Ssowmini uchar_t *dp; 38607663SSowmini.Varadhan@Sun.COM link_attr_t *p; 38616512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 38625903Ssowmini 38635903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 38645903Ssowmini (prop_val != NULL && val_cnt == 0)) 38655903Ssowmini return (DLADM_STATUS_BADARG); 38665903Ssowmini p = dladm_name2prop(prop_name); 38676789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 38685903Ssowmini return (DLADM_STATUS_BADARG); 38695903Ssowmini 38709692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 38719692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 38729692SRishi.Srivatsavai@Sun.COM 38735903Ssowmini /* 38745903Ssowmini * private properties: all parsing is done in the kernel. 38755903Ssowmini * allocate a enough space for each property + its separator (','). 38765903Ssowmini */ 38775903Ssowmini for (i = 0; i < val_cnt; i++) { 38785903Ssowmini bufsize += strlen(prop_val[i]) + 1; 38795903Ssowmini } 38806512Ssowmini 38816512Ssowmini if (prop_val == NULL) { 38826512Ssowmini /* 38836512Ssowmini * getting default value. so use more buffer space. 38846512Ssowmini */ 38857663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 38866512Ssowmini } 38876512Ssowmini 38887663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 388911878SVenu.Iyer@Sun.COM (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 38905903Ssowmini if (dip == NULL) 38915903Ssowmini return (status); 38925903Ssowmini 38935903Ssowmini dp = (uchar_t *)dip->pr_val; 38945903Ssowmini slen = 0; 38957663SSowmini.Varadhan@Sun.COM 38966512Ssowmini if (prop_val == NULL) { 38978453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 38988460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 38996512Ssowmini } else { 39006512Ssowmini for (i = 0; i < val_cnt; i++) { 39016512Ssowmini int plen = 0; 39025903Ssowmini 39036512Ssowmini plen = strlen(prop_val[i]); 39046512Ssowmini bcopy(prop_val[i], dp, plen); 39056512Ssowmini slen += plen; 39066512Ssowmini /* 39076512Ssowmini * add a "," separator and update dp. 39086512Ssowmini */ 39096512Ssowmini if (i != (val_cnt -1)) 39106512Ssowmini dp[slen++] = ','; 39116512Ssowmini dp += (plen + 1); 39126512Ssowmini } 39138460SArtem.Kachitchkin@Sun.COM } 39148460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 39158453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 39166512Ssowmini 39175903Ssowmini free(dip); 39186512Ssowmini return (status); 39195903Ssowmini } 39205903Ssowmini 39215903Ssowmini static dladm_status_t 39228460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 39238453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 39248453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 39255903Ssowmini { 39267663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 39276789Sam223141 dld_ioc_macprop_t *dip = NULL; 39287663SSowmini.Varadhan@Sun.COM link_attr_t *p; 39295903Ssowmini 39305903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 39315903Ssowmini (prop_val != NULL && val_cnt == 0)) 39325903Ssowmini return (DLADM_STATUS_BADARG); 39335903Ssowmini 39345903Ssowmini p = dladm_name2prop(prop_name); 39356789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 39365903Ssowmini return (DLADM_STATUS_BADARG); 39375903Ssowmini 39385903Ssowmini /* 39395903Ssowmini * private properties: all parsing is done in the kernel. 39405903Ssowmini */ 39417663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 39427663SSowmini.Varadhan@Sun.COM dld_flags, &status); 39435903Ssowmini if (dip == NULL) 39445903Ssowmini return (status); 39455903Ssowmini 39468453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 39478453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 39488118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 39498275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 39508460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 39518460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 39528118SVasumathi.Sundaram@Sun.COM } else { 39538118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 39548118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 39558118SVasumathi.Sundaram@Sun.COM } 39565903Ssowmini *val_cnt = 1; 39578460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 39588460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 39598460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 39605903Ssowmini } 39616512Ssowmini free(dip); 39625903Ssowmini return (status); 39635903Ssowmini } 39646512Ssowmini 39656512Ssowmini 39666512Ssowmini static dladm_status_t 39678453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 39688453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 39696512Ssowmini { 39706512Ssowmini dladm_status_t status; 39716512Ssowmini char **prop_vals = NULL, *buf; 39726512Ssowmini size_t bufsize; 39736512Ssowmini uint_t cnt; 39746512Ssowmini int i; 39758118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 39766512Ssowmini 39776512Ssowmini /* 39786512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 39796512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 39806512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 39816512Ssowmini */ 39826512Ssowmini bufsize = 39836512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 39846512Ssowmini buf = malloc(bufsize); 39856512Ssowmini prop_vals = (char **)(void *)buf; 39866512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 39876512Ssowmini prop_vals[i] = buf + 39886512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 39896512Ssowmini i * DLADM_PROP_VAL_MAX; 39906512Ssowmini } 39916768Sar224390 39926768Sar224390 /* 39937342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 39947342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 39957342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 39967342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 39977342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 39987342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 39997342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 40007342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 40016768Sar224390 */ 40028453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 400311878SVenu.Iyer@Sun.COM DLD_PROP_DEFAULT, &perm_flags); 40046512Ssowmini if (status == DLADM_STATUS_OK) { 40058118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 40068453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 40078453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 40088118SVasumathi.Sundaram@Sun.COM } 40098118SVasumathi.Sundaram@Sun.COM else 40108118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 40116512Ssowmini } 40126512Ssowmini free(buf); 40136512Ssowmini return (status); 40146512Ssowmini } 40157663SSowmini.Varadhan@Sun.COM 401610491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 401710491SRishi.Srivatsavai@Sun.COM static dladm_status_t 401811878SVenu.Iyer@Sun.COM get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 401910491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 402010491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 402110491SRishi.Srivatsavai@Sun.COM { 402210491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 402310491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 402410491SRishi.Srivatsavai@Sun.COM int val, i; 402510491SRishi.Srivatsavai@Sun.COM 402610491SRishi.Srivatsavai@Sun.COM if (flags != 0) 402710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 402810491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 402910491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 403010491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 403110491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 403210491SRishi.Srivatsavai@Sun.COM break; 403310491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 403410491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 403510491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 403610491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 403710491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 403810491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 403910491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 404010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 404110491SRishi.Srivatsavai@Sun.COM } 404210491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 404310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 404410491SRishi.Srivatsavai@Sun.COM return (retv); 404510491SRishi.Srivatsavai@Sun.COM } 404610491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 404710491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 404810491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 404910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 405010491SRishi.Srivatsavai@Sun.COM } 405110491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 405210491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 405310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 405410491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 405510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 405610491SRishi.Srivatsavai@Sun.COM } 405710491SRishi.Srivatsavai@Sun.COM } 405810491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 405910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 406010491SRishi.Srivatsavai@Sun.COM } 406110491SRishi.Srivatsavai@Sun.COM 406210491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 406310491SRishi.Srivatsavai@Sun.COM static dladm_status_t 406410491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 406510491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 406610491SRishi.Srivatsavai@Sun.COM { 406710491SRishi.Srivatsavai@Sun.COM /* 406810491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 406910491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 407010491SRishi.Srivatsavai@Sun.COM */ 407110491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 407210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 407310491SRishi.Srivatsavai@Sun.COM 407410491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 407510491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 407610491SRishi.Srivatsavai@Sun.COM } 407710491SRishi.Srivatsavai@Sun.COM 407810491SRishi.Srivatsavai@Sun.COM /* 407910491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 408010491SRishi.Srivatsavai@Sun.COM */ 408110491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 408210491SRishi.Srivatsavai@Sun.COM static dladm_status_t 408310491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 408412742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 408512742Smichael.l.lim@oracle.com val_desc_t **vdpp, datalink_media_t media) 408610491SRishi.Srivatsavai@Sun.COM { 408712742Smichael.l.lim@oracle.com char *cp; 408812742Smichael.l.lim@oracle.com boolean_t iscost; 408912742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 409012742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 409110491SRishi.Srivatsavai@Sun.COM 409210491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 409310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 409410491SRishi.Srivatsavai@Sun.COM 409510491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 409610491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 409710491SRishi.Srivatsavai@Sun.COM } else { 409810491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 409910491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 410010491SRishi.Srivatsavai@Sun.COM 410110491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 410210491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 410310491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 410410491SRishi.Srivatsavai@Sun.COM } else { 410510491SRishi.Srivatsavai@Sun.COM errno = 0; 410610491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 410710491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 410810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 410910491SRishi.Srivatsavai@Sun.COM } 411010491SRishi.Srivatsavai@Sun.COM } 411110491SRishi.Srivatsavai@Sun.COM 411210491SRishi.Srivatsavai@Sun.COM if (iscost) { 411310491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 411410491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 411510491SRishi.Srivatsavai@Sun.COM } else { 411610491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 411710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 411810491SRishi.Srivatsavai@Sun.COM /* 411910491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 412010491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 412110491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 412210491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 412310491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 412410491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 412510491SRishi.Srivatsavai@Sun.COM * can't be used now. 412610491SRishi.Srivatsavai@Sun.COM */ 412710491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 412810491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 412910491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 413010491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 413110491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 413210491SRishi.Srivatsavai@Sun.COM 413310491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 413410491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 413510491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 413610491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 413710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 413810491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 413910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 414010491SRishi.Srivatsavai@Sun.COM } 414110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 414210491SRishi.Srivatsavai@Sun.COM } 414310491SRishi.Srivatsavai@Sun.COM } 414410491SRishi.Srivatsavai@Sun.COM 414510491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 414610491SRishi.Srivatsavai@Sun.COM static dladm_status_t 414710491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 414810491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 414910491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 415010491SRishi.Srivatsavai@Sun.COM { 415110491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 415210491SRishi.Srivatsavai@Sun.COM uint_t val; 415310491SRishi.Srivatsavai@Sun.COM 415410491SRishi.Srivatsavai@Sun.COM if (flags != 0) 415510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 415610491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 415710491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 415810491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 415910491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 416010491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 416110491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 416210491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 416310491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 416410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 416510491SRishi.Srivatsavai@Sun.COM } 416610491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 416710491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 416810491SRishi.Srivatsavai@Sun.COM else 416910491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 417010491SRishi.Srivatsavai@Sun.COM return (retv); 417110491SRishi.Srivatsavai@Sun.COM } 417210491SRishi.Srivatsavai@Sun.COM 417310491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 417410491SRishi.Srivatsavai@Sun.COM static dladm_status_t 417510491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 417610491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 417710491SRishi.Srivatsavai@Sun.COM { 417810491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 417910491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 418010491SRishi.Srivatsavai@Sun.COM } 418110491SRishi.Srivatsavai@Sun.COM 418210491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 418310491SRishi.Srivatsavai@Sun.COM static dladm_status_t 418410491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 418510491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 418610491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 418710491SRishi.Srivatsavai@Sun.COM { 418810491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 418910491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 419010491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 419110491SRishi.Srivatsavai@Sun.COM 419210491SRishi.Srivatsavai@Sun.COM if (flags != 0) 419310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 419410491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 419510491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 419610491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 419710491SRishi.Srivatsavai@Sun.COM 0, &status); 419810491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 419910491SRishi.Srivatsavai@Sun.COM return (status); 420010491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 420110491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 420210491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 420310491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 420410491SRishi.Srivatsavai@Sun.COM } else { 420510491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 420610491SRishi.Srivatsavai@Sun.COM } 420710491SRishi.Srivatsavai@Sun.COM free(dip); 420810491SRishi.Srivatsavai@Sun.COM return (status); 420910491SRishi.Srivatsavai@Sun.COM } 421010491SRishi.Srivatsavai@Sun.COM 421110491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 421210491SRishi.Srivatsavai@Sun.COM static dladm_status_t 421310491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 421410491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 421510491SRishi.Srivatsavai@Sun.COM { 421610491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 421710491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 421810491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 421910491SRishi.Srivatsavai@Sun.COM 422010491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 422110491SRishi.Srivatsavai@Sun.COM 0, &status); 422210491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 422310491SRishi.Srivatsavai@Sun.COM return (status); 422410491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 422510491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 422610491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 422710491SRishi.Srivatsavai@Sun.COM free(dip); 422810491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 422910491SRishi.Srivatsavai@Sun.COM return (status); 423010491SRishi.Srivatsavai@Sun.COM 423110491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 423210491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 423310491SRishi.Srivatsavai@Sun.COM } 423410491SRishi.Srivatsavai@Sun.COM 423510491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 423610491SRishi.Srivatsavai@Sun.COM static dladm_status_t 423710491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 423812742Smichael.l.lim@oracle.com datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 423912742Smichael.l.lim@oracle.com val_desc_t **vdpp, datalink_media_t media) 424010491SRishi.Srivatsavai@Sun.COM { 424112742Smichael.l.lim@oracle.com char *cp; 424212742Smichael.l.lim@oracle.com uint_t val_cnt = *val_cntp; 424312742Smichael.l.lim@oracle.com val_desc_t *vdp = *vdpp; 424410491SRishi.Srivatsavai@Sun.COM 424510491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 424610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 424710491SRishi.Srivatsavai@Sun.COM 424810491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 424910491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 425010491SRishi.Srivatsavai@Sun.COM } else { 425110491SRishi.Srivatsavai@Sun.COM errno = 0; 425210491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 425310491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 425410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 425510491SRishi.Srivatsavai@Sun.COM } 425610491SRishi.Srivatsavai@Sun.COM 425710491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 425810491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 425910491SRishi.Srivatsavai@Sun.COM } 426010491SRishi.Srivatsavai@Sun.COM 42617663SSowmini.Varadhan@Sun.COM dladm_status_t 42628453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 42638453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 42647663SSowmini.Varadhan@Sun.COM { 42657663SSowmini.Varadhan@Sun.COM uint32_t flags; 42667663SSowmini.Varadhan@Sun.COM dladm_status_t status; 42677663SSowmini.Varadhan@Sun.COM uint32_t media; 42687663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 42697663SSowmini.Varadhan@Sun.COM void *dp; 42707663SSowmini.Varadhan@Sun.COM 42718453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 42728453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 42737663SSowmini.Varadhan@Sun.COM return (status); 42747663SSowmini.Varadhan@Sun.COM } 42757663SSowmini.Varadhan@Sun.COM 42767663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 42777663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 42787663SSowmini.Varadhan@Sun.COM 42797663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 42807663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 42817663SSowmini.Varadhan@Sun.COM 42827663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 42837663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 42847663SSowmini.Varadhan@Sun.COM 42857663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 42867663SSowmini.Varadhan@Sun.COM if (dip == NULL) 42877663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 42887663SSowmini.Varadhan@Sun.COM 42897663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 42907663SSowmini.Varadhan@Sun.COM if (set) 42917663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 42927663SSowmini.Varadhan@Sun.COM 42938453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 429410191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 42957663SSowmini.Varadhan@Sun.COM if (!set) 42967663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 42977663SSowmini.Varadhan@Sun.COM } 42987663SSowmini.Varadhan@Sun.COM 42997663SSowmini.Varadhan@Sun.COM free(dip); 43007663SSowmini.Varadhan@Sun.COM return (status); 43017663SSowmini.Varadhan@Sun.COM } 43027663SSowmini.Varadhan@Sun.COM 43038275SEric Cheng dladm_status_t 43048275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 43058275SEric Cheng { 43068460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 43078275SEric Cheng } 43088275SEric Cheng 43098275SEric Cheng /* 43108275SEric Cheng * Retrieve the one link property from the database 43118275SEric Cheng */ 43128275SEric Cheng /*ARGSUSED*/ 43138275SEric Cheng static int 43148453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 43158453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 43168275SEric Cheng { 43178275SEric Cheng dladm_arg_list_t *proplist = arg; 43188275SEric Cheng dladm_arg_info_t *aip = NULL; 43198275SEric Cheng 43208275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 43218275SEric Cheng /* 43228275SEric Cheng * it is fine to point to prop_name since prop_name points to the 43238275SEric Cheng * prop_table[n].pd_name. 43248275SEric Cheng */ 43258275SEric Cheng aip->ai_name = prop_name; 43268275SEric Cheng 43278453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 43288453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 43298275SEric Cheng 43308275SEric Cheng if (aip->ai_count != 0) 43318275SEric Cheng proplist->al_count++; 43328275SEric Cheng 43338275SEric Cheng return (DLADM_WALK_CONTINUE); 43348275SEric Cheng } 43358275SEric Cheng 43368275SEric Cheng 43378275SEric Cheng /* 43388275SEric Cheng * Retrieve all link properties for a link from the database and 43398275SEric Cheng * return a property list. 43408275SEric Cheng */ 43418275SEric Cheng dladm_status_t 43428453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 43438453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 43448275SEric Cheng { 43458275SEric Cheng dladm_arg_list_t *list; 43468275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 43478275SEric Cheng 43488275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 43498275SEric Cheng if (list == NULL) 43508275SEric Cheng return (dladm_errno2status(errno)); 43518275SEric Cheng 43528453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 43538453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 43548275SEric Cheng 43558275SEric Cheng *listp = list; 43568275SEric Cheng return (status); 43578275SEric Cheng } 43588275SEric Cheng 43598275SEric Cheng /* 43608275SEric Cheng * Retrieve the named property from a proplist, check the value and 43618275SEric Cheng * convert to a kernel structure. 43628275SEric Cheng */ 43638275SEric Cheng static dladm_status_t 43648453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 436511878SVenu.Iyer@Sun.COM dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 43668275SEric Cheng { 43678275SEric Cheng dladm_status_t status; 43688275SEric Cheng dladm_arg_info_t *aip = NULL; 43698275SEric Cheng int i, j; 43708275SEric Cheng 43718275SEric Cheng /* Find named property in proplist */ 43728275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 43738275SEric Cheng aip = &proplist->al_info[i]; 43748275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 43758275SEric Cheng break; 43768275SEric Cheng } 43778275SEric Cheng 43788275SEric Cheng /* Property not in list */ 43798275SEric Cheng if (i == proplist->al_count) 43808275SEric Cheng return (DLADM_STATUS_OK); 43818275SEric Cheng 43828275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 43838275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 43848275SEric Cheng val_desc_t *vdp; 43858275SEric Cheng 43868275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 43878275SEric Cheng if (vdp == NULL) 43888275SEric Cheng return (DLADM_STATUS_NOMEM); 43898275SEric Cheng 43908275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 43918275SEric Cheng continue; 43928275SEric Cheng 43938275SEric Cheng if (aip->ai_val == NULL) 43948275SEric Cheng return (DLADM_STATUS_BADARG); 43958275SEric Cheng 43968275SEric Cheng /* Check property value */ 43978275SEric Cheng if (pdp->pd_check != NULL) { 43988453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 439912742Smichael.l.lim@oracle.com &(aip->ai_count), flags, &vdp, 0); 44008275SEric Cheng } else { 44018275SEric Cheng status = DLADM_STATUS_BADARG; 44028275SEric Cheng } 44038275SEric Cheng 44048275SEric Cheng if (status != DLADM_STATUS_OK) 44058275SEric Cheng return (status); 44068275SEric Cheng 44078275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 44088275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 44098275SEric Cheng 44108275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 44118275SEric Cheng continue; 44128275SEric Cheng 44138275SEric Cheng /* Extract kernel structure */ 44148275SEric Cheng if (rpp->rp_extract != NULL) { 441510734SEric Cheng status = rpp->rp_extract(vdp, 441610734SEric Cheng aip->ai_count, arg); 44178275SEric Cheng } else { 44188275SEric Cheng status = DLADM_STATUS_BADARG; 44198275SEric Cheng } 44208275SEric Cheng break; 44218275SEric Cheng } 44228275SEric Cheng 44238275SEric Cheng if (status != DLADM_STATUS_OK) 44248275SEric Cheng return (status); 44258275SEric Cheng 44268275SEric Cheng break; 44278275SEric Cheng } 44288275SEric Cheng return (status); 44298275SEric Cheng } 44308275SEric Cheng 44318275SEric Cheng /* 44328275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 44338275SEric Cheng */ 44348275SEric Cheng dladm_status_t 44358453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 443611878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp, uint_t flags) 44378275SEric Cheng { 443810734SEric Cheng dladm_status_t status; 443910734SEric Cheng int i; 444010734SEric Cheng 444110734SEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 444210734SEric Cheng status = i_dladm_link_proplist_extract_one(handle, 444311878SVenu.Iyer@Sun.COM proplist, rsrc_prop_table[i].rp_name, flags, mrp); 444410734SEric Cheng if (status != DLADM_STATUS_OK) 444510734SEric Cheng return (status); 444610734SEric Cheng } 44478275SEric Cheng return (status); 44488275SEric Cheng } 44498275SEric Cheng 44508275SEric Cheng static const char * 44518275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 44528275SEric Cheng { 44538275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 44548275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 44558275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 44568275SEric Cheng return (buf); 44578275SEric Cheng } 44588306SSowmini.Varadhan@Sun.COM 44598306SSowmini.Varadhan@Sun.COM dladm_status_t 446011878SVenu.Iyer@Sun.COM dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 44618453SAnurag.Maskey@Sun.COM link_state_t *state) 44628306SSowmini.Varadhan@Sun.COM { 44638306SSowmini.Varadhan@Sun.COM uint_t perms; 44648306SSowmini.Varadhan@Sun.COM 446511878SVenu.Iyer@Sun.COM return (i_dladm_get_public_prop(handle, linkid, "state", 0, 446611878SVenu.Iyer@Sun.COM &perms, state, sizeof (*state))); 44678306SSowmini.Varadhan@Sun.COM } 44688460SArtem.Kachitchkin@Sun.COM 44698460SArtem.Kachitchkin@Sun.COM boolean_t 44708460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 44718460SArtem.Kachitchkin@Sun.COM { 44728460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 44738460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 44748460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 44758460SArtem.Kachitchkin@Sun.COM "name", 44768460SArtem.Kachitchkin@Sun.COM "class", 44778460SArtem.Kachitchkin@Sun.COM "media", 44788460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 44798460SArtem.Kachitchkin@Sun.COM FPHYINST, 44808460SArtem.Kachitchkin@Sun.COM FDEVNAME, 44818460SArtem.Kachitchkin@Sun.COM 44828460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 44838460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 44848460SArtem.Kachitchkin@Sun.COM }; 44858460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 44868460SArtem.Kachitchkin@Sun.COM int i; 44878460SArtem.Kachitchkin@Sun.COM 44888460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 44898460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 44908460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 44918460SArtem.Kachitchkin@Sun.COM break; 44928460SArtem.Kachitchkin@Sun.COM } 44938460SArtem.Kachitchkin@Sun.COM } 44948460SArtem.Kachitchkin@Sun.COM 44958460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 44968460SArtem.Kachitchkin@Sun.COM } 449711878SVenu.Iyer@Sun.COM 449811878SVenu.Iyer@Sun.COM dladm_status_t 449911878SVenu.Iyer@Sun.COM dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 450011878SVenu.Iyer@Sun.COM dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 450111878SVenu.Iyer@Sun.COM { 450211878SVenu.Iyer@Sun.COM char *buf, **propvals; 450311878SVenu.Iyer@Sun.COM uint_t valcnt = DLADM_MAX_PROP_VALCNT; 450411878SVenu.Iyer@Sun.COM int i; 450511878SVenu.Iyer@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 4506*12748SSowmini.Varadhan@oracle.COM size_t bufsize; 450711878SVenu.Iyer@Sun.COM 450811878SVenu.Iyer@Sun.COM *is_set = B_FALSE; 450911878SVenu.Iyer@Sun.COM 4510*12748SSowmini.Varadhan@oracle.COM bufsize = (sizeof (char *) + DLADM_PROP_VAL_MAX) * 4511*12748SSowmini.Varadhan@oracle.COM DLADM_MAX_PROP_VALCNT; 4512*12748SSowmini.Varadhan@oracle.COM if ((buf = calloc(1, bufsize)) == NULL) 451311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 451411878SVenu.Iyer@Sun.COM 451511878SVenu.Iyer@Sun.COM propvals = (char **)(void *)buf; 451611878SVenu.Iyer@Sun.COM for (i = 0; i < valcnt; i++) { 451711878SVenu.Iyer@Sun.COM propvals[i] = buf + 451811878SVenu.Iyer@Sun.COM sizeof (char *) * DLADM_MAX_PROP_VALCNT + 451911878SVenu.Iyer@Sun.COM i * DLADM_PROP_VAL_MAX; 452011878SVenu.Iyer@Sun.COM } 452111878SVenu.Iyer@Sun.COM 452211878SVenu.Iyer@Sun.COM if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 452311878SVenu.Iyer@Sun.COM &valcnt) != DLADM_STATUS_OK) { 452411878SVenu.Iyer@Sun.COM goto done; 452511878SVenu.Iyer@Sun.COM } 452611878SVenu.Iyer@Sun.COM 4527*12748SSowmini.Varadhan@oracle.COM /* 4528*12748SSowmini.Varadhan@oracle.COM * valcnt is always set to 1 by get_pool(), hence we need to check 4529*12748SSowmini.Varadhan@oracle.COM * for a non-null string to see if it is set. For protection and 4530*12748SSowmini.Varadhan@oracle.COM * allowed-ips, we can check either the *propval or the valcnt. 4531*12748SSowmini.Varadhan@oracle.COM */ 4532*12748SSowmini.Varadhan@oracle.COM if ((strcmp(prop_name, "pool") == 0 || 4533*12748SSowmini.Varadhan@oracle.COM strcmp(prop_name, "protection") == 0 || 4534*12748SSowmini.Varadhan@oracle.COM strcmp(prop_name, "allowed-ips") == 0) && 4535*12748SSowmini.Varadhan@oracle.COM (strlen(*propvals) != 0)) { 453611878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 453711878SVenu.Iyer@Sun.COM } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 453811878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 453911878SVenu.Iyer@Sun.COM } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 454011878SVenu.Iyer@Sun.COM (strcmp(propvals[0], "true") == 0)) { 454111878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 454211878SVenu.Iyer@Sun.COM } 454311878SVenu.Iyer@Sun.COM 454411878SVenu.Iyer@Sun.COM done: 454511878SVenu.Iyer@Sun.COM if (buf != NULL) 454611878SVenu.Iyer@Sun.COM free(buf); 454711878SVenu.Iyer@Sun.COM return (status); 454811878SVenu.Iyer@Sun.COM } 454912163SRamaswamy.Tummala@Sun.COM 455012163SRamaswamy.Tummala@Sun.COM /* ARGSUSED */ 455112163SRamaswamy.Tummala@Sun.COM static dladm_status_t 455212163SRamaswamy.Tummala@Sun.COM get_linkmode_prop(dladm_handle_t handle, prop_desc_t *pdp, 455312163SRamaswamy.Tummala@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 455412163SRamaswamy.Tummala@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 455512163SRamaswamy.Tummala@Sun.COM { 455612163SRamaswamy.Tummala@Sun.COM char *s; 455712163SRamaswamy.Tummala@Sun.COM uint32_t v; 455812163SRamaswamy.Tummala@Sun.COM dladm_status_t status; 455912163SRamaswamy.Tummala@Sun.COM 456012163SRamaswamy.Tummala@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 456112163SRamaswamy.Tummala@Sun.COM perm_flags, &v, sizeof (v)); 456212163SRamaswamy.Tummala@Sun.COM if (status != DLADM_STATUS_OK) 456312163SRamaswamy.Tummala@Sun.COM return (status); 456412163SRamaswamy.Tummala@Sun.COM 456512163SRamaswamy.Tummala@Sun.COM switch (v) { 456612303SRajkumar.Sivaprakasam@Sun.COM case DLADM_PART_CM_MODE: 456712163SRamaswamy.Tummala@Sun.COM s = "cm"; 456812163SRamaswamy.Tummala@Sun.COM break; 456912303SRajkumar.Sivaprakasam@Sun.COM case DLADM_PART_UD_MODE: 457012163SRamaswamy.Tummala@Sun.COM s = "ud"; 457112163SRamaswamy.Tummala@Sun.COM break; 457212163SRamaswamy.Tummala@Sun.COM default: 457312163SRamaswamy.Tummala@Sun.COM s = ""; 457412163SRamaswamy.Tummala@Sun.COM break; 457512163SRamaswamy.Tummala@Sun.COM } 457612163SRamaswamy.Tummala@Sun.COM (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); 457712163SRamaswamy.Tummala@Sun.COM 457812163SRamaswamy.Tummala@Sun.COM *val_cnt = 1; 457912163SRamaswamy.Tummala@Sun.COM return (DLADM_STATUS_OK); 458012163SRamaswamy.Tummala@Sun.COM } 4581