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 /* 22*11878SVenu.Iyer@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 233147Sxc151355 * Use is subject to license terms. 243147Sxc151355 */ 253147Sxc151355 263147Sxc151355 #include <stdlib.h> 273147Sxc151355 #include <strings.h> 283147Sxc151355 #include <errno.h> 293147Sxc151355 #include <ctype.h> 305895Syz147064 #include <stddef.h> 313448Sdh155122 #include <sys/types.h> 323147Sxc151355 #include <sys/stat.h> 333448Sdh155122 #include <sys/dld.h> 343448Sdh155122 #include <sys/zone.h> 353448Sdh155122 #include <fcntl.h> 363448Sdh155122 #include <unistd.h> 373448Sdh155122 #include <libdevinfo.h> 383448Sdh155122 #include <zone.h> 393871Syz147064 #include <libdllink.h> 403147Sxc151355 #include <libdladm_impl.h> 415895Syz147064 #include <libdlwlan_impl.h> 423871Syz147064 #include <libdlwlan.h> 435895Syz147064 #include <libdlvlan.h> 448275SEric Cheng #include <libdlvnic.h> 458275SEric Cheng #include <libintl.h> 463448Sdh155122 #include <dlfcn.h> 473448Sdh155122 #include <link.h> 485895Syz147064 #include <inet/wifi_ioctl.h> 495903Ssowmini #include <libdladm.h> 508275SEric Cheng #include <libdlstat.h> 515903Ssowmini #include <sys/param.h> 528275SEric Cheng #include <sys/debug.h> 538275SEric Cheng #include <sys/dld.h> 545903Ssowmini #include <inttypes.h> 555903Ssowmini #include <sys/ethernet.h> 5610616SSebastien.Roy@Sun.COM #include <inet/iptun.h> 577663SSowmini.Varadhan@Sun.COM #include <net/wpa.h> 587663SSowmini.Varadhan@Sun.COM #include <sys/sysmacros.h> 5910491SRishi.Srivatsavai@Sun.COM #include <sys/vlan.h> 6010491SRishi.Srivatsavai@Sun.COM #include <libdlbridge.h> 6110491SRishi.Srivatsavai@Sun.COM #include <stp_in.h> 62*11878SVenu.Iyer@Sun.COM #include <netinet/dhcp.h> 63*11878SVenu.Iyer@Sun.COM #include <netinet/dhcp6.h> 64*11878SVenu.Iyer@Sun.COM #include <net/if_types.h> 65*11878SVenu.Iyer@Sun.COM #include <libinetutil.h> 66*11878SVenu.Iyer@Sun.COM #include <pool.h> 673448Sdh155122 685895Syz147064 /* 695895Syz147064 * The linkprop get() callback. 708275SEric Cheng * - pd: pointer to the prop_desc_t 715895Syz147064 * - propstrp: a property string array to keep the returned property. 725895Syz147064 * Caller allocated. 735895Syz147064 * - cntp: number of returned properties. 745895Syz147064 * Caller also uses it to indicate how many it expects. 755895Syz147064 */ 765903Ssowmini struct prop_desc; 778275SEric Cheng typedef struct prop_desc prop_desc_t; 788275SEric Cheng 798453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 805960Ssowmini datalink_id_t, char **propstp, uint_t *cntp, 818118SVasumathi.Sundaram@Sun.COM datalink_media_t, uint_t, uint_t *); 825895Syz147064 835895Syz147064 /* 845895Syz147064 * The linkprop set() callback. 855895Syz147064 * - propval: a val_desc_t array which keeps the property values to be set. 865895Syz147064 * - cnt: number of properties to be set. 875903Ssowmini * - flags: additional flags passed down the system call. 885903Ssowmini * 895903Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 905903Ssowmini * a format suitable for kernel consumption. This may require allocation 915903Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 925903Ssowmini * by all other pd_sets) which invokes the ioctl. 935895Syz147064 */ 948453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 958275SEric Cheng val_desc_t *propval, uint_t cnt, uint_t flags, 968275SEric Cheng datalink_media_t); 973448Sdh155122 985895Syz147064 /* 995895Syz147064 * The linkprop check() callback. 1005895Syz147064 * - propstrp: property string array which keeps the property to be checked. 1015895Syz147064 * - cnt: number of properties. 1025895Syz147064 * - propval: return value; the property values of the given property strings. 1035903Ssowmini * 1045903Ssowmini * pd_check checks that the input values are valid. It does so by 1055903Ssowmini * iteraring through the pd_modval list for the property. If 1065903Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 1075903Ssowmini * specific to this property can be used. If the input values are 1085903Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 1095903Ssowmini * with either a val_desc_t found on the pd_modval list or something 1105903Ssowmini * generated on the fly. 1115895Syz147064 */ 1128453SAnurag.Maskey@Sun.COM typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 1138453SAnurag.Maskey@Sun.COM datalink_id_t, char **propstrp, uint_t cnt, 114*11878SVenu.Iyer@Sun.COM uint_t flags, val_desc_t *propval, 115*11878SVenu.Iyer@Sun.COM datalink_media_t); 1163448Sdh155122 1177663SSowmini.Varadhan@Sun.COM typedef struct link_attr_s { 1186789Sam223141 mac_prop_id_t pp_id; 1195903Ssowmini size_t pp_valsize; 1205903Ssowmini char *pp_name; 1217663SSowmini.Varadhan@Sun.COM } link_attr_t; 1225903Ssowmini 123*11878SVenu.Iyer@Sun.COM typedef struct dladm_linkprop_args_s { 124*11878SVenu.Iyer@Sun.COM dladm_status_t dla_status; 125*11878SVenu.Iyer@Sun.COM uint_t dla_flags; 126*11878SVenu.Iyer@Sun.COM } dladm_linkprop_args_t; 127*11878SVenu.Iyer@Sun.COM 1287663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 1298275SEric Cheng const char *, uint_t, dladm_status_t *); 1307663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 1318275SEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 132*11878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 133*11878SVenu.Iyer@Sun.COM char *, uint_t, uint_t *, void *, size_t); 134*11878SVenu.Iyer@Sun.COM 135*11878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1368453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 137*11878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1388453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *, dladm_prop_type_t, 1398453SAnurag.Maskey@Sun.COM uint_t); 1408453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1418275SEric Cheng static const char *dladm_perm2str(uint_t, char *); 142*11878SVenu.Iyer@Sun.COM static link_attr_t *dladm_name2prop(const char *); 143*11878SVenu.Iyer@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 144*11878SVenu.Iyer@Sun.COM 145*11878SVenu.Iyer@Sun.COM static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 146*11878SVenu.Iyer@Sun.COM get_speed, get_channel, get_powermode, get_radio, 147*11878SVenu.Iyer@Sun.COM get_duplex, get_link_state, get_binary, get_uint32, 148*11878SVenu.Iyer@Sun.COM get_flowctl, get_maxbw, get_cpus, get_priority, 149*11878SVenu.Iyer@Sun.COM get_tagmode, get_range, get_stp, get_bridge_forward, 150*11878SVenu.Iyer@Sun.COM get_bridge_pvid, get_protection, get_rxrings, 151*11878SVenu.Iyer@Sun.COM get_txrings, get_cntavail, 152*11878SVenu.Iyer@Sun.COM get_allowedips, get_allowedcids, get_pool, 153*11878SVenu.Iyer@Sun.COM get_rings_range; 154*11878SVenu.Iyer@Sun.COM 155*11878SVenu.Iyer@Sun.COM static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 156*11878SVenu.Iyer@Sun.COM set_public_prop, set_resource, set_stp_prop, 157*11878SVenu.Iyer@Sun.COM set_bridge_forward, set_bridge_pvid; 158*11878SVenu.Iyer@Sun.COM 159*11878SVenu.Iyer@Sun.COM static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 160*11878SVenu.Iyer@Sun.COM check_encaplim, check_uint32, check_maxbw, check_cpus, 161*11878SVenu.Iyer@Sun.COM check_stp_prop, check_bridge_pvid, check_allowedips, 162*11878SVenu.Iyer@Sun.COM check_allowedcids, check_rings, 163*11878SVenu.Iyer@Sun.COM check_pool, check_prop; 1648275SEric Cheng 1658275SEric Cheng struct prop_desc { 1665895Syz147064 /* 1675895Syz147064 * link property name 1685895Syz147064 */ 1695895Syz147064 char *pd_name; 1705895Syz147064 1715895Syz147064 /* 1725895Syz147064 * default property value, can be set to { "", NULL } 1735895Syz147064 */ 1745895Syz147064 val_desc_t pd_defval; 1755895Syz147064 1765895Syz147064 /* 1775895Syz147064 * list of optional property values, can be NULL. 1785895Syz147064 * 1795895Syz147064 * This is set to non-NULL if there is a list of possible property 1805895Syz147064 * values. pd_optval would point to the array of possible values. 1815895Syz147064 */ 1825895Syz147064 val_desc_t *pd_optval; 1835895Syz147064 1845895Syz147064 /* 1855895Syz147064 * count of the above optional property values. 0 if pd_optval is NULL. 1865895Syz147064 */ 1875895Syz147064 uint_t pd_noptval; 1885895Syz147064 1895895Syz147064 /* 19010491SRishi.Srivatsavai@Sun.COM * callback to set link property; set to NULL if this property is 19110491SRishi.Srivatsavai@Sun.COM * read-only and may be called before or after permanent update; see 19210491SRishi.Srivatsavai@Sun.COM * flags. 1935895Syz147064 */ 1945895Syz147064 pd_setf_t *pd_set; 1955895Syz147064 1965895Syz147064 /* 1975895Syz147064 * callback to get modifiable link property 1985895Syz147064 */ 1995895Syz147064 pd_getf_t *pd_getmod; 2005895Syz147064 2015895Syz147064 /* 2025895Syz147064 * callback to get current link property 2035895Syz147064 */ 2045895Syz147064 pd_getf_t *pd_get; 2055895Syz147064 2065895Syz147064 /* 2075895Syz147064 * callback to validate link property value, set to NULL if pd_optval 2085895Syz147064 * is not NULL. In that case, validate the value by comparing it with 2095895Syz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 2105895Syz147064 * valid. 2115895Syz147064 */ 2125895Syz147064 pd_checkf_t *pd_check; 2135895Syz147064 2145895Syz147064 uint_t pd_flags; 2155903Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 2165903Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 21710491SRishi.Srivatsavai@Sun.COM #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 2185895Syz147064 /* 2195895Syz147064 * indicate link classes this property applies to. 2205895Syz147064 */ 2215895Syz147064 datalink_class_t pd_class; 2225895Syz147064 2235895Syz147064 /* 2245895Syz147064 * indicate link media type this property applies to. 2255895Syz147064 */ 2265895Syz147064 datalink_media_t pd_dmedia; 2278275SEric Cheng }; 2283448Sdh155122 2296789Sam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 2305903Ssowmini 2317663SSowmini.Varadhan@Sun.COM /* 2327663SSowmini.Varadhan@Sun.COM * Supported link properties enumerated in the prop_table[] array are 2337663SSowmini.Varadhan@Sun.COM * computed using the callback functions in that array. To compute the 2347663SSowmini.Varadhan@Sun.COM * property value, multiple distinct system calls may be needed (e.g., 2357663SSowmini.Varadhan@Sun.COM * for wifi speed, we need to issue system calls to get desired/supported 2367663SSowmini.Varadhan@Sun.COM * rates). The link_attr[] table enumerates the interfaces to the kernel, 2377663SSowmini.Varadhan@Sun.COM * and the type/size of the data passed in the user-kernel interface. 2387663SSowmini.Varadhan@Sun.COM */ 2397663SSowmini.Varadhan@Sun.COM static link_attr_t link_attr[] = { 2407663SSowmini.Varadhan@Sun.COM { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 2415903Ssowmini 2427663SSowmini.Varadhan@Sun.COM { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 2437663SSowmini.Varadhan@Sun.COM 2447663SSowmini.Varadhan@Sun.COM { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 2457663SSowmini.Varadhan@Sun.COM 2467663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 2475903Ssowmini 2487663SSowmini.Varadhan@Sun.COM { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 2495903Ssowmini 2507663SSowmini.Varadhan@Sun.COM { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 2517663SSowmini.Varadhan@Sun.COM 2527663SSowmini.Varadhan@Sun.COM { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 2535903Ssowmini 2547663SSowmini.Varadhan@Sun.COM { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2557663SSowmini.Varadhan@Sun.COM 2569449Sxiuyan.wang@Sun.COM { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 2579449Sxiuyan.wang@Sun.COM 2589449Sxiuyan.wang@Sun.COM { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 2599449Sxiuyan.wang@Sun.COM 2607663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2617663SSowmini.Varadhan@Sun.COM 2627663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 2635903Ssowmini 2647663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 2655903Ssowmini 2667663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 2677663SSowmini.Varadhan@Sun.COM 2687663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 2697342SAruna.Ramakrishna@Sun.COM 2707663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 2717663SSowmini.Varadhan@Sun.COM 2727663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 2737663SSowmini.Varadhan@Sun.COM 2747663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 2757342SAruna.Ramakrishna@Sun.COM 2767663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 2777663SSowmini.Varadhan@Sun.COM 2787663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 2795903Ssowmini 2807663SSowmini.Varadhan@Sun.COM { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 2817663SSowmini.Varadhan@Sun.COM 2827663SSowmini.Varadhan@Sun.COM { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 2835903Ssowmini 2847663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 2857663SSowmini.Varadhan@Sun.COM 2867663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 2875903Ssowmini 2887663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 2897663SSowmini.Varadhan@Sun.COM 2907663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 2917663SSowmini.Varadhan@Sun.COM 2927663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2937663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 2945903Ssowmini 2957663SSowmini.Varadhan@Sun.COM /* wl_rates_t has variable length */ 2967663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 2977663SSowmini.Varadhan@Sun.COM 2987663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 2995903Ssowmini 3007663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 3017663SSowmini.Varadhan@Sun.COM 3027663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 3035903Ssowmini 3047663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 3057663SSowmini.Varadhan@Sun.COM 3067663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 3075903Ssowmini 3087663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 3097663SSowmini.Varadhan@Sun.COM 3107663SSowmini.Varadhan@Sun.COM /* wl_wpa_ess_t has variable length */ 3117663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 3125903Ssowmini 3137663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 3147663SSowmini.Varadhan@Sun.COM 3157663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 3165903Ssowmini 3177663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 3187663SSowmini.Varadhan@Sun.COM 3197663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 3205903Ssowmini 3217663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 3227663SSowmini.Varadhan@Sun.COM 3237663SSowmini.Varadhan@Sun.COM /* wl_wpa_ie_t has variable length */ 3247663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 3255903Ssowmini 3267663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 3277663SSowmini.Varadhan@Sun.COM 3287663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 3295903Ssowmini 3307663SSowmini.Varadhan@Sun.COM { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 3317663SSowmini.Varadhan@Sun.COM 3328874SSebastien.Roy@Sun.COM { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 3338874SSebastien.Roy@Sun.COM 33410616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 33510616SSebastien.Roy@Sun.COM 33610616SSebastien.Roy@Sun.COM { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 33710616SSebastien.Roy@Sun.COM 33810491SRishi.Srivatsavai@Sun.COM { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 33910491SRishi.Srivatsavai@Sun.COM 34010491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 34110491SRishi.Srivatsavai@Sun.COM 34210491SRishi.Srivatsavai@Sun.COM { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 34310491SRishi.Srivatsavai@Sun.COM 344*11878SVenu.Iyer@Sun.COM { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 345*11878SVenu.Iyer@Sun.COM 346*11878SVenu.Iyer@Sun.COM { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 347*11878SVenu.Iyer@Sun.COM "resource-effective"}, 348*11878SVenu.Iyer@Sun.COM 349*11878SVenu.Iyer@Sun.COM { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 350*11878SVenu.Iyer@Sun.COM 351*11878SVenu.Iyer@Sun.COM { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 352*11878SVenu.Iyer@Sun.COM 353*11878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 354*11878SVenu.Iyer@Sun.COM "txrings-available"}, 355*11878SVenu.Iyer@Sun.COM 356*11878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 357*11878SVenu.Iyer@Sun.COM "rxrings-available"}, 358*11878SVenu.Iyer@Sun.COM 359*11878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 360*11878SVenu.Iyer@Sun.COM 361*11878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 36210734SEric Cheng 3637663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3645903Ssowmini }; 3655903Ssowmini 36610491SRishi.Srivatsavai@Sun.COM typedef struct bridge_public_prop_s { 36710491SRishi.Srivatsavai@Sun.COM const char *bpp_name; 36810491SRishi.Srivatsavai@Sun.COM int bpp_code; 36910491SRishi.Srivatsavai@Sun.COM } bridge_public_prop_t; 37010491SRishi.Srivatsavai@Sun.COM 37110491SRishi.Srivatsavai@Sun.COM static const bridge_public_prop_t bridge_prop[] = { 37210491SRishi.Srivatsavai@Sun.COM { "stp", PT_CFG_NON_STP }, 37310491SRishi.Srivatsavai@Sun.COM { "stp_priority", PT_CFG_PRIO }, 37410491SRishi.Srivatsavai@Sun.COM { "stp_cost", PT_CFG_COST }, 37510491SRishi.Srivatsavai@Sun.COM { "stp_edge", PT_CFG_EDGE }, 37610491SRishi.Srivatsavai@Sun.COM { "stp_p2p", PT_CFG_P2P }, 37710491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", PT_CFG_MCHECK }, 37810491SRishi.Srivatsavai@Sun.COM { NULL, 0 } 37910491SRishi.Srivatsavai@Sun.COM }; 38010491SRishi.Srivatsavai@Sun.COM 3815903Ssowmini static val_desc_t link_duplex_vals[] = { 3825903Ssowmini { "half", LINK_DUPLEX_HALF }, 3835903Ssowmini { "full", LINK_DUPLEX_HALF } 3845903Ssowmini }; 3855903Ssowmini static val_desc_t link_status_vals[] = { 3865903Ssowmini { "up", LINK_STATE_UP }, 3875903Ssowmini { "down", LINK_STATE_DOWN } 3885903Ssowmini }; 3895903Ssowmini static val_desc_t link_01_vals[] = { 3905903Ssowmini { "1", 1 }, 3915903Ssowmini { "0", 0 } 3925903Ssowmini }; 3935903Ssowmini static val_desc_t link_flow_vals[] = { 3945903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3955903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3965903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 3975903Ssowmini { "bi", LINK_FLOWCTRL_BI } 3985903Ssowmini }; 3998275SEric Cheng static val_desc_t link_priority_vals[] = { 4008275SEric Cheng { "low", MPL_LOW }, 4018275SEric Cheng { "medium", MPL_MEDIUM }, 4028275SEric Cheng { "high", MPL_HIGH } 4038275SEric Cheng }; 4045903Ssowmini 4058874SSebastien.Roy@Sun.COM static val_desc_t link_tagmode_vals[] = { 4068874SSebastien.Roy@Sun.COM { "normal", LINK_TAGMODE_NORMAL }, 4078874SSebastien.Roy@Sun.COM { "vlanonly", LINK_TAGMODE_VLANONLY } 4088874SSebastien.Roy@Sun.COM }; 4098874SSebastien.Roy@Sun.COM 41010734SEric Cheng static val_desc_t link_protect_vals[] = { 41110734SEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 412*11878SVenu.Iyer@Sun.COM { "restricted", MPT_RESTRICTED }, 41310734SEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 414*11878SVenu.Iyer@Sun.COM { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 41510734SEric Cheng }; 41610734SEric Cheng 4175895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 4185895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 4195895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 4205895Syz147064 }; 4215895Syz147064 4225895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 4235895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 4245895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 4255895Syz147064 { "max", DLADM_WLAN_PM_MAX } 4265895Syz147064 }; 4275895Syz147064 42810491SRishi.Srivatsavai@Sun.COM static val_desc_t stp_p2p_vals[] = { 42910491SRishi.Srivatsavai@Sun.COM { "true", P2P_FORCE_TRUE }, 43010491SRishi.Srivatsavai@Sun.COM { "false", P2P_FORCE_FALSE }, 43110491SRishi.Srivatsavai@Sun.COM { "auto", P2P_AUTO } 43210491SRishi.Srivatsavai@Sun.COM }; 43310491SRishi.Srivatsavai@Sun.COM 4348275SEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 4358275SEric Cheng #define RESET_VAL ((uintptr_t)-1) 436*11878SVenu.Iyer@Sun.COM #define UNSPEC_VAL ((uintptr_t)-2) 4378275SEric Cheng 4383448Sdh155122 static prop_desc_t prop_table[] = { 4395903Ssowmini { "channel", { NULL, 0 }, 4405903Ssowmini NULL, 0, NULL, NULL, 441*11878SVenu.Iyer@Sun.COM get_channel, NULL, 0, 4425903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4435895Syz147064 4445895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 4455895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 446*11878SVenu.Iyer@Sun.COM set_powermode, NULL, 447*11878SVenu.Iyer@Sun.COM get_powermode, NULL, 0, 4485903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4495895Syz147064 4505895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 4515895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 452*11878SVenu.Iyer@Sun.COM set_radio, NULL, 453*11878SVenu.Iyer@Sun.COM get_radio, NULL, 0, 4545903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4555895Syz147064 4565895Syz147064 { "speed", { "", 0 }, NULL, 0, 457*11878SVenu.Iyer@Sun.COM set_rate, get_rate_mod, 458*11878SVenu.Iyer@Sun.COM get_rate, check_rate, 0, 4595960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 4605895Syz147064 4616512Ssowmini { "autopush", { "", 0 }, NULL, 0, 462*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, 463*11878SVenu.Iyer@Sun.COM get_autopush, check_autopush, PD_CHECK_ALLOC, 4645903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4655895Syz147064 4666512Ssowmini { "zone", { "", 0 }, NULL, 0, 467*11878SVenu.Iyer@Sun.COM set_zone, NULL, 468*11878SVenu.Iyer@Sun.COM get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 4695903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4705903Ssowmini 4718275SEric Cheng { "duplex", { "", 0 }, 4725903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 473*11878SVenu.Iyer@Sun.COM NULL, NULL, get_duplex, NULL, 4745903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4755903Ssowmini 4768275SEric Cheng { "state", { "up", LINK_STATE_UP }, 4775903Ssowmini link_status_vals, VALCNT(link_status_vals), 478*11878SVenu.Iyer@Sun.COM NULL, NULL, get_link_state, NULL, 4796512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4805903Ssowmini 48110191SSowmini.Varadhan@Sun.COM { "adv_autoneg_cap", { "", 0 }, 4825903Ssowmini link_01_vals, VALCNT(link_01_vals), 483*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 4845903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4855903Ssowmini 4866512Ssowmini { "mtu", { "", 0 }, NULL, 0, 487*11878SVenu.Iyer@Sun.COM set_public_prop, get_range, 488*11878SVenu.Iyer@Sun.COM get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 4897342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 4905903Ssowmini 4916512Ssowmini { "flowctrl", { "", 0 }, 4925903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 493*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_flowctl, NULL, 4945903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4955903Ssowmini 4969449Sxiuyan.wang@Sun.COM { "adv_10gfdx_cap", { "", 0 }, 4979449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 498*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 4999449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5009449Sxiuyan.wang@Sun.COM 5019449Sxiuyan.wang@Sun.COM { "en_10gfdx_cap", { "", 0 }, 5029449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 503*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5049449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5059449Sxiuyan.wang@Sun.COM 5066512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 5076512Ssowmini link_01_vals, VALCNT(link_01_vals), 508*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5095903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5105903Ssowmini 5116512Ssowmini { "en_1000fdx_cap", { "", 0 }, 5125903Ssowmini link_01_vals, VALCNT(link_01_vals), 513*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5145903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5155903Ssowmini 5166512Ssowmini { "adv_1000hdx_cap", { "", 0 }, 5175903Ssowmini link_01_vals, VALCNT(link_01_vals), 518*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5195903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5205903Ssowmini 5216512Ssowmini { "en_1000hdx_cap", { "", 0 }, 5225903Ssowmini link_01_vals, VALCNT(link_01_vals), 523*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5245903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5255903Ssowmini 5266512Ssowmini { "adv_100fdx_cap", { "", 0 }, 5275903Ssowmini link_01_vals, VALCNT(link_01_vals), 528*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5295903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5305903Ssowmini 5316512Ssowmini { "en_100fdx_cap", { "", 0 }, 5325903Ssowmini link_01_vals, VALCNT(link_01_vals), 533*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5345903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5355903Ssowmini 5366512Ssowmini { "adv_100hdx_cap", { "", 0 }, 5375903Ssowmini link_01_vals, VALCNT(link_01_vals), 538*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5395903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5405903Ssowmini 5416512Ssowmini { "en_100hdx_cap", { "", 0 }, 5425903Ssowmini link_01_vals, VALCNT(link_01_vals), 543*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5445903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5455903Ssowmini 5466512Ssowmini { "adv_10fdx_cap", { "", 0 }, 5475903Ssowmini link_01_vals, VALCNT(link_01_vals), 548*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5495903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5505903Ssowmini 5516512Ssowmini { "en_10fdx_cap", { "", 0 }, 5525903Ssowmini link_01_vals, VALCNT(link_01_vals), 553*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5545903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5555903Ssowmini 5566512Ssowmini { "adv_10hdx_cap", { "", 0 }, 5575903Ssowmini link_01_vals, VALCNT(link_01_vals), 558*11878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5595903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5605903Ssowmini 5616512Ssowmini { "en_10hdx_cap", { "", 0 }, 5625903Ssowmini link_01_vals, VALCNT(link_01_vals), 563*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5648275SEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5658275SEric Cheng 5668275SEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 567*11878SVenu.Iyer@Sun.COM set_resource, NULL, 568*11878SVenu.Iyer@Sun.COM get_maxbw, check_maxbw, PD_CHECK_ALLOC, 5698275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5708275SEric Cheng 5718275SEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 572*11878SVenu.Iyer@Sun.COM set_resource, NULL, 573*11878SVenu.Iyer@Sun.COM get_cpus, check_cpus, 0, 574*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 575*11878SVenu.Iyer@Sun.COM 576*11878SVenu.Iyer@Sun.COM { "cpus-effective", { "--", 0 }, 577*11878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 578*11878SVenu.Iyer@Sun.COM get_cpus, 0, 0, 5798275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5808275SEric Cheng 581*11878SVenu.Iyer@Sun.COM { "pool", { "--", RESET_VAL }, NULL, 0, 582*11878SVenu.Iyer@Sun.COM set_resource, NULL, 583*11878SVenu.Iyer@Sun.COM get_pool, check_pool, 0, 584*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 585*11878SVenu.Iyer@Sun.COM 586*11878SVenu.Iyer@Sun.COM { "pool-effective", { "--", 0 }, 587*11878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 588*11878SVenu.Iyer@Sun.COM get_pool, 0, 0, 589*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 590*11878SVenu.Iyer@Sun.COM 591*11878SVenu.Iyer@Sun.COM { "priority", { "high", MPL_RESET }, 592*11878SVenu.Iyer@Sun.COM link_priority_vals, VALCNT(link_priority_vals), set_resource, 593*11878SVenu.Iyer@Sun.COM NULL, get_priority, check_prop, 0, 5948275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5958874SSebastien.Roy@Sun.COM 5968874SSebastien.Roy@Sun.COM { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 5978874SSebastien.Roy@Sun.COM link_tagmode_vals, VALCNT(link_tagmode_vals), 598*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_tagmode, 5998874SSebastien.Roy@Sun.COM NULL, 0, 6008874SSebastien.Roy@Sun.COM DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 60110491SRishi.Srivatsavai@Sun.COM DL_ETHER }, 60210491SRishi.Srivatsavai@Sun.COM 60310616SSebastien.Roy@Sun.COM { "hoplimit", { "", 0 }, NULL, 0, 604*11878SVenu.Iyer@Sun.COM set_public_prop, get_range, get_uint32, 605*11878SVenu.Iyer@Sun.COM check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 60610616SSebastien.Roy@Sun.COM 60710616SSebastien.Roy@Sun.COM { "encaplimit", { "", 0 }, NULL, 0, 608*11878SVenu.Iyer@Sun.COM set_public_prop, get_range, get_uint32, 609*11878SVenu.Iyer@Sun.COM check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 61010616SSebastien.Roy@Sun.COM 61110491SRishi.Srivatsavai@Sun.COM { "forward", { "1", 1 }, 61210491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 61310491SRishi.Srivatsavai@Sun.COM set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 61410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 61510491SRishi.Srivatsavai@Sun.COM 61610491SRishi.Srivatsavai@Sun.COM { "default_tag", { "1", 1 }, NULL, 0, 61710491SRishi.Srivatsavai@Sun.COM set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 61810491SRishi.Srivatsavai@Sun.COM 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 61910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 62010491SRishi.Srivatsavai@Sun.COM 62110491SRishi.Srivatsavai@Sun.COM { "learn_limit", { "1000", 1000 }, NULL, 0, 622*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_uint32, 623*11878SVenu.Iyer@Sun.COM check_uint32, 0, 62410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 62510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 62610491SRishi.Srivatsavai@Sun.COM 62710491SRishi.Srivatsavai@Sun.COM { "learn_decay", { "200", 200 }, NULL, 0, 628*11878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_uint32, 629*11878SVenu.Iyer@Sun.COM check_uint32, 0, 63010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 63110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 63210491SRishi.Srivatsavai@Sun.COM 63310491SRishi.Srivatsavai@Sun.COM { "stp", { "1", 1 }, 63410491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 635*11878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 63610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 63710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 63810491SRishi.Srivatsavai@Sun.COM 63910491SRishi.Srivatsavai@Sun.COM { "stp_priority", { "128", 128 }, NULL, 0, 640*11878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 64110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 64210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 64310491SRishi.Srivatsavai@Sun.COM 64410491SRishi.Srivatsavai@Sun.COM { "stp_cost", { "auto", 0 }, NULL, 0, 645*11878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 64610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 64710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 64810491SRishi.Srivatsavai@Sun.COM 64910491SRishi.Srivatsavai@Sun.COM { "stp_edge", { "1", 1 }, 65010491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 651*11878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 65210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 65310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 65410491SRishi.Srivatsavai@Sun.COM 65510491SRishi.Srivatsavai@Sun.COM { "stp_p2p", { "auto", P2P_AUTO }, 65610491SRishi.Srivatsavai@Sun.COM stp_p2p_vals, VALCNT(stp_p2p_vals), 657*11878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 65810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 65910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 66010491SRishi.Srivatsavai@Sun.COM 66110491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", { "0", 0 }, 66210491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 663*11878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 66410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 66510491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 66610734SEric Cheng 66710734SEric Cheng { "protection", { "--", RESET_VAL }, 66810734SEric Cheng link_protect_vals, VALCNT(link_protect_vals), 669*11878SVenu.Iyer@Sun.COM set_resource, NULL, get_protection, check_prop, 0, 67010734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 67110734SEric Cheng 67210734SEric Cheng { "allowed-ips", { "--", 0 }, 673*11878SVenu.Iyer@Sun.COM NULL, 0, set_resource, NULL, 674*11878SVenu.Iyer@Sun.COM get_allowedips, check_allowedips, PD_CHECK_ALLOC, 675*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 676*11878SVenu.Iyer@Sun.COM 677*11878SVenu.Iyer@Sun.COM { "allowed-dhcp-cids", { "--", 0 }, 678*11878SVenu.Iyer@Sun.COM NULL, 0, set_resource, NULL, 679*11878SVenu.Iyer@Sun.COM get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 680*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 681*11878SVenu.Iyer@Sun.COM 682*11878SVenu.Iyer@Sun.COM { "rxrings", { "--", RESET_VAL }, NULL, 0, 683*11878SVenu.Iyer@Sun.COM set_resource, get_rings_range, get_rxrings, check_rings, 0, 684*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 685*11878SVenu.Iyer@Sun.COM 686*11878SVenu.Iyer@Sun.COM { "rxrings-effective", { "--", 0 }, 687*11878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 688*11878SVenu.Iyer@Sun.COM get_rxrings, NULL, 0, 689*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 690*11878SVenu.Iyer@Sun.COM 691*11878SVenu.Iyer@Sun.COM { "txrings", { "--", RESET_VAL }, NULL, 0, 692*11878SVenu.Iyer@Sun.COM set_resource, get_rings_range, get_txrings, check_rings, 0, 69310734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 694*11878SVenu.Iyer@Sun.COM 695*11878SVenu.Iyer@Sun.COM { "txrings-effective", { "--", 0 }, 696*11878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 697*11878SVenu.Iyer@Sun.COM get_txrings, NULL, 0, 698*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 699*11878SVenu.Iyer@Sun.COM 700*11878SVenu.Iyer@Sun.COM { "txrings-available", { "", 0 }, NULL, 0, 701*11878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 702*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 703*11878SVenu.Iyer@Sun.COM 704*11878SVenu.Iyer@Sun.COM { "rxrings-available", { "", 0 }, NULL, 0, 705*11878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 706*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 707*11878SVenu.Iyer@Sun.COM 708*11878SVenu.Iyer@Sun.COM { "rxhwclnt-available", { "", 0 }, NULL, 0, 709*11878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 710*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 711*11878SVenu.Iyer@Sun.COM 712*11878SVenu.Iyer@Sun.COM { "txhwclnt-available", { "", 0 }, NULL, 0, 713*11878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 714*11878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 715*11878SVenu.Iyer@Sun.COM 7163448Sdh155122 }; 7173448Sdh155122 7185895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 7195895Syz147064 7208275SEric Cheng static resource_prop_t rsrc_prop_table[] = { 721*11878SVenu.Iyer@Sun.COM {"maxbw", extract_maxbw}, 722*11878SVenu.Iyer@Sun.COM {"priority", extract_priority}, 723*11878SVenu.Iyer@Sun.COM {"cpus", extract_cpus}, 724*11878SVenu.Iyer@Sun.COM {"cpus-effective", extract_cpus}, 725*11878SVenu.Iyer@Sun.COM {"pool", extract_pool}, 726*11878SVenu.Iyer@Sun.COM {"pool-effective", extract_pool}, 727*11878SVenu.Iyer@Sun.COM {"protection", extract_protection}, 728*11878SVenu.Iyer@Sun.COM {"allowed-ips", extract_allowedips}, 729*11878SVenu.Iyer@Sun.COM {"allowed-dhcp-cids", extract_allowedcids}, 730*11878SVenu.Iyer@Sun.COM {"rxrings", extract_rxrings}, 731*11878SVenu.Iyer@Sun.COM {"rxrings-effective", extract_rxrings}, 732*11878SVenu.Iyer@Sun.COM {"txrings", extract_txrings}, 733*11878SVenu.Iyer@Sun.COM {"txrings-effective", extract_txrings} 7348275SEric Cheng }; 7358275SEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 7368275SEric Cheng sizeof (resource_prop_t)) 7378275SEric Cheng 7387663SSowmini.Varadhan@Sun.COM /* 7397663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 7407663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 7417663SSowmini.Varadhan@Sun.COM */ 7427663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 7437663SSowmini.Varadhan@Sun.COM 7448453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 7458453SAnurag.Maskey@Sun.COM const char *, char **, uint_t); 7468453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 7478453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *); 7488460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 7498460SArtem.Kachitchkin@Sun.COM datalink_id_t, void *, int (*)(dladm_handle_t, 7508460SArtem.Kachitchkin@Sun.COM datalink_id_t, const char *, void *)); 7518453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 7528453SAnurag.Maskey@Sun.COM datalink_class_t, uint32_t, prop_desc_t *, char **, 7538453SAnurag.Maskey@Sun.COM uint_t, uint_t); 7548453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 7558453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 7568453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 7578453SAnurag.Maskey@Sun.COM datalink_id_t, datalink_media_t, uint_t); 7588275SEric Cheng 7595895Syz147064 /* 7605895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 7615895Syz147064 * rates to be retrieved. However, we cannot increase it at this 7625895Syz147064 * time because it will break binary compatibility with unbundled 7635895Syz147064 * WiFi drivers and utilities. So for now we define an additional 7645895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 7655895Syz147064 */ 7665895Syz147064 #define MAX_SUPPORT_RATES 64 7675895Syz147064 7685895Syz147064 #define AP_ANCHOR "[anchor]" 7695895Syz147064 #define AP_DELIMITER '.' 7705895Syz147064 77110734SEric Cheng /* ARGSUSED */ 7725895Syz147064 static dladm_status_t 773*11878SVenu.Iyer@Sun.COM check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 774*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 775*11878SVenu.Iyer@Sun.COM datalink_media_t media) 7765895Syz147064 { 7775895Syz147064 int i, j; 7783147Sxc151355 7795895Syz147064 for (j = 0; j < val_cnt; j++) { 7805895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 78110734SEric Cheng if (strcasecmp(prop_val[j], 7825895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 7835895Syz147064 break; 7845895Syz147064 } 7855895Syz147064 } 78610734SEric Cheng if (i == pdp->pd_noptval) 78710734SEric Cheng return (DLADM_STATUS_BADVAL); 78810734SEric Cheng 78910734SEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 7905895Syz147064 } 79110734SEric Cheng return (DLADM_STATUS_OK); 7925895Syz147064 } 7935895Syz147064 7945895Syz147064 static dladm_status_t 7958453SAnurag.Maskey@Sun.COM i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 7968453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 7978453SAnurag.Maskey@Sun.COM uint_t val_cnt, uint_t flags) 7983147Sxc151355 { 7995895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8005895Syz147064 val_desc_t *vdp = NULL; 8015895Syz147064 boolean_t needfree = B_FALSE; 8025895Syz147064 uint_t cnt, i; 8033147Sxc151355 8045895Syz147064 if (!(pdp->pd_class & class)) 8055895Syz147064 return (DLADM_STATUS_BADARG); 8065895Syz147064 8075895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 8083147Sxc151355 return (DLADM_STATUS_BADARG); 8093147Sxc151355 8105895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 8115895Syz147064 return (DLADM_STATUS_TEMPONLY); 8125895Syz147064 8135895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 8145895Syz147064 return (DLADM_STATUS_OK); 8155895Syz147064 8165895Syz147064 if (pdp->pd_set == NULL) 8175895Syz147064 return (DLADM_STATUS_PROPRDONLY); 8183448Sdh155122 8195895Syz147064 if (prop_val != NULL) { 820*11878SVenu.Iyer@Sun.COM vdp = calloc(val_cnt, sizeof (val_desc_t)); 8215895Syz147064 if (vdp == NULL) 8225895Syz147064 return (DLADM_STATUS_NOMEM); 8235895Syz147064 8245895Syz147064 if (pdp->pd_check != NULL) { 8258275SEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 8268453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, prop_val, 827*11878SVenu.Iyer@Sun.COM val_cnt, flags, vdp, media); 8285895Syz147064 } else if (pdp->pd_optval != NULL) { 829*11878SVenu.Iyer@Sun.COM status = check_prop(handle, pdp, linkid, prop_val, 830*11878SVenu.Iyer@Sun.COM val_cnt, flags, vdp, media); 8315895Syz147064 } else { 8323448Sdh155122 status = DLADM_STATUS_BADARG; 8333147Sxc151355 } 8345895Syz147064 8353147Sxc151355 if (status != DLADM_STATUS_OK) 8365895Syz147064 goto done; 8375895Syz147064 8385895Syz147064 cnt = val_cnt; 8395895Syz147064 } else { 8408275SEric Cheng boolean_t defval = B_FALSE; 8418275SEric Cheng 8425895Syz147064 if (pdp->pd_defval.vd_name == NULL) 8435895Syz147064 return (DLADM_STATUS_NOTSUP); 8445895Syz147064 8457342SAruna.Ramakrishna@Sun.COM cnt = 1; 8468275SEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 8478275SEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 848*11878SVenu.Iyer@Sun.COM if ((vdp = calloc(1, sizeof (val_desc_t))) == NULL) 8496512Ssowmini return (DLADM_STATUS_NOMEM); 8507342SAruna.Ramakrishna@Sun.COM 8518275SEric Cheng if (defval) { 8528275SEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 8538275SEric Cheng sizeof (val_desc_t)); 8548275SEric Cheng } else if (pdp->pd_check != NULL) { 8558453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 856*11878SVenu.Iyer@Sun.COM prop_val, cnt, flags, vdp, media); 8577342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 8587342SAruna.Ramakrishna@Sun.COM goto done; 8597342SAruna.Ramakrishna@Sun.COM } 8606512Ssowmini } else { 8618453SAnurag.Maskey@Sun.COM status = i_dladm_getset_defval(handle, pdp, linkid, 8626512Ssowmini media, flags); 8636512Ssowmini return (status); 8646512Ssowmini } 8655895Syz147064 } 86610491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_AFTER_PERM) 86710491SRishi.Srivatsavai@Sun.COM status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 86810491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_PERMONLY; 86910491SRishi.Srivatsavai@Sun.COM else 87010491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 87110491SRishi.Srivatsavai@Sun.COM media); 8725895Syz147064 if (needfree) { 8735895Syz147064 for (i = 0; i < cnt; i++) 8745903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 8753147Sxc151355 } 8765895Syz147064 done: 8775895Syz147064 free(vdp); 8785895Syz147064 return (status); 8795895Syz147064 } 8805895Syz147064 8815895Syz147064 static dladm_status_t 8828453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8838453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8845895Syz147064 { 8855895Syz147064 int i; 8865895Syz147064 boolean_t found = B_FALSE; 8875895Syz147064 datalink_class_t class; 8885895Syz147064 uint32_t media; 8895895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8905895Syz147064 8918453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 8928453SAnurag.Maskey@Sun.COM NULL, 0); 8935895Syz147064 if (status != DLADM_STATUS_OK) 8945895Syz147064 return (status); 8955895Syz147064 8965895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 8975895Syz147064 prop_desc_t *pdp = &prop_table[i]; 8985895Syz147064 dladm_status_t s; 8995895Syz147064 9005895Syz147064 if (prop_name != NULL && 9015895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 9025895Syz147064 continue; 9035895Syz147064 found = B_TRUE; 9048453SAnurag.Maskey@Sun.COM s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 9058453SAnurag.Maskey@Sun.COM prop_val, val_cnt, flags); 9063448Sdh155122 9075895Syz147064 if (prop_name != NULL) { 9085895Syz147064 status = s; 9095895Syz147064 break; 9105895Syz147064 } else { 9115895Syz147064 if (s != DLADM_STATUS_OK && 9125895Syz147064 s != DLADM_STATUS_NOTSUP) 9135895Syz147064 status = s; 9145895Syz147064 } 9155895Syz147064 } 9165903Ssowmini if (!found) { 9175903Ssowmini if (prop_name[0] == '_') { 9185903Ssowmini /* other private properties */ 9199692SRishi.Srivatsavai@Sun.COM status = i_dladm_set_private_prop(handle, linkid, 9209692SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cnt, flags); 9215903Ssowmini } else { 9225903Ssowmini status = DLADM_STATUS_NOTFOUND; 9235903Ssowmini } 9245903Ssowmini } 9255895Syz147064 return (status); 9265895Syz147064 } 9275895Syz147064 9285895Syz147064 /* 9295895Syz147064 * Set/reset link property for specific link 9305895Syz147064 */ 9315895Syz147064 dladm_status_t 9328453SAnurag.Maskey@Sun.COM dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9338453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 9345895Syz147064 { 9355895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9365895Syz147064 9375895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 9385895Syz147064 (prop_val == NULL && val_cnt > 0) || 9395895Syz147064 (prop_val != NULL && val_cnt == 0) || 9405895Syz147064 (prop_name == NULL && prop_val != NULL)) { 9415895Syz147064 return (DLADM_STATUS_BADARG); 9425895Syz147064 } 9435895Syz147064 9449692SRishi.Srivatsavai@Sun.COM /* 9459692SRishi.Srivatsavai@Sun.COM * Check for valid link property against the flags passed 9469692SRishi.Srivatsavai@Sun.COM * and set the link property when active flag is passed. 9479692SRishi.Srivatsavai@Sun.COM */ 9488453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 9495895Syz147064 val_cnt, flags); 9505895Syz147064 if (status != DLADM_STATUS_OK) 9515895Syz147064 return (status); 9525895Syz147064 9535895Syz147064 if (flags & DLADM_OPT_PERSIST) { 9548453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 9553147Sxc151355 prop_val, val_cnt); 95610491SRishi.Srivatsavai@Sun.COM 95710491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 95810491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp = prop_table; 95910491SRishi.Srivatsavai@Sun.COM int i; 96010491SRishi.Srivatsavai@Sun.COM 96110491SRishi.Srivatsavai@Sun.COM for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 96210491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_flags & PD_AFTER_PERM)) 96310491SRishi.Srivatsavai@Sun.COM continue; 96410491SRishi.Srivatsavai@Sun.COM if (prop_name != NULL && 96510491SRishi.Srivatsavai@Sun.COM strcasecmp(prop_name, pdp->pd_name) != 0) 96610491SRishi.Srivatsavai@Sun.COM continue; 96710491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, NULL, 96810491SRishi.Srivatsavai@Sun.COM 0, flags, 0); 96910491SRishi.Srivatsavai@Sun.COM } 97010491SRishi.Srivatsavai@Sun.COM } 9713147Sxc151355 } 9723147Sxc151355 return (status); 9733147Sxc151355 } 9743147Sxc151355 9755895Syz147064 /* 9768460SArtem.Kachitchkin@Sun.COM * Walk all link properties of the given specific link. 9778460SArtem.Kachitchkin@Sun.COM * 9788460SArtem.Kachitchkin@Sun.COM * Note: this function currently lacks the ability to walk _all_ private 9798460SArtem.Kachitchkin@Sun.COM * properties if the link, because there is no kernel interface to 9808460SArtem.Kachitchkin@Sun.COM * retrieve all known private property names. Once such an interface 9818460SArtem.Kachitchkin@Sun.COM * is added, this function should be fixed accordingly. 9825895Syz147064 */ 9833147Sxc151355 dladm_status_t 9848453SAnurag.Maskey@Sun.COM dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 9858453SAnurag.Maskey@Sun.COM int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 9863147Sxc151355 { 9875895Syz147064 dladm_status_t status; 9885895Syz147064 datalink_class_t class; 9895895Syz147064 uint_t media; 9905895Syz147064 int i; 9915895Syz147064 9925895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 9935895Syz147064 return (DLADM_STATUS_BADARG); 9945895Syz147064 9958453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9968453SAnurag.Maskey@Sun.COM NULL, 0); 9975895Syz147064 if (status != DLADM_STATUS_OK) 9985895Syz147064 return (status); 9995895Syz147064 10008460SArtem.Kachitchkin@Sun.COM /* public */ 10015895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 10025895Syz147064 if (!(prop_table[i].pd_class & class)) 10035895Syz147064 continue; 10045895Syz147064 10055895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 10065895Syz147064 continue; 10075895Syz147064 10088453SAnurag.Maskey@Sun.COM if (func(handle, linkid, prop_table[i].pd_name, arg) == 10095895Syz147064 DLADM_WALK_TERMINATE) { 10105895Syz147064 break; 10115895Syz147064 } 10125895Syz147064 } 10135895Syz147064 10148460SArtem.Kachitchkin@Sun.COM /* private */ 10158460SArtem.Kachitchkin@Sun.COM status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 10168460SArtem.Kachitchkin@Sun.COM 10178460SArtem.Kachitchkin@Sun.COM return (status); 10185895Syz147064 } 10193448Sdh155122 10205895Syz147064 /* 10215895Syz147064 * Get linkprop of the given specific link. 10225895Syz147064 */ 10235895Syz147064 dladm_status_t 10248453SAnurag.Maskey@Sun.COM dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10258453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, const char *prop_name, char **prop_val, 10268453SAnurag.Maskey@Sun.COM uint_t *val_cntp) 10275895Syz147064 { 10285895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 10295895Syz147064 datalink_class_t class; 10305895Syz147064 uint_t media; 10315895Syz147064 prop_desc_t *pdp; 10326512Ssowmini uint_t cnt, dld_flags = 0; 10335895Syz147064 int i; 10348118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 10355895Syz147064 10366512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 1037*11878SVenu.Iyer@Sun.COM dld_flags |= DLD_PROP_DEFAULT; 10389514SGirish.Moodalbail@Sun.COM else if (type == DLADM_PROP_VAL_MODIFIABLE) 1039*11878SVenu.Iyer@Sun.COM dld_flags |= DLD_PROP_POSSIBLE; 10406512Ssowmini 10415895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 10425895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 10435895Syz147064 return (DLADM_STATUS_BADARG); 10445895Syz147064 10455895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 10465895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 10475895Syz147064 break; 10485895Syz147064 10495903Ssowmini if (i == DLADM_MAX_PROPS) { 10505903Ssowmini if (prop_name[0] == '_') { 10515903Ssowmini /* 10525903Ssowmini * private property. 10535903Ssowmini */ 10548460SArtem.Kachitchkin@Sun.COM if (type == DLADM_PROP_VAL_PERSISTENT) 10558460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_linkprop_db(handle, linkid, 10568460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp)); 10578460SArtem.Kachitchkin@Sun.COM else 10588460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_priv_prop(handle, linkid, 10598460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp, type, 10608460SArtem.Kachitchkin@Sun.COM dld_flags)); 10615903Ssowmini } else { 10625903Ssowmini return (DLADM_STATUS_NOTFOUND); 10635903Ssowmini } 10645903Ssowmini } 10655895Syz147064 10665895Syz147064 pdp = &prop_table[i]; 10675895Syz147064 10688453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10698453SAnurag.Maskey@Sun.COM NULL, 0); 10705895Syz147064 if (status != DLADM_STATUS_OK) 10715895Syz147064 return (status); 10725895Syz147064 10735895Syz147064 if (!(pdp->pd_class & class)) 10745895Syz147064 return (DLADM_STATUS_BADARG); 10755895Syz147064 10765895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 10773147Sxc151355 return (DLADM_STATUS_BADARG); 10783147Sxc151355 10795895Syz147064 switch (type) { 10805895Syz147064 case DLADM_PROP_VAL_CURRENT: 10818453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 10828453SAnurag.Maskey@Sun.COM media, dld_flags, &perm_flags); 10838118SVasumathi.Sundaram@Sun.COM break; 10848118SVasumathi.Sundaram@Sun.COM 10858118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 10868118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 10878118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 10888118SVasumathi.Sundaram@Sun.COM } else { 10898453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 10908453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 10918118SVasumathi.Sundaram@Sun.COM } 10928118SVasumathi.Sundaram@Sun.COM 10938118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 10949055SMichael.Lim@Sun.COM *val_cntp = 1; 10958275SEric Cheng if (status == DLADM_STATUS_OK) 10968275SEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 10975895Syz147064 break; 10985895Syz147064 10995895Syz147064 case DLADM_PROP_VAL_DEFAULT: 11006768Sar224390 /* 11016768Sar224390 * If defaults are not defined for the property, 11026768Sar224390 * pd_defval.vd_name should be null. If the driver 11036768Sar224390 * has to be contacted for the value, vd_name should 11046768Sar224390 * be the empty string (""). Otherwise, dladm will 11056768Sar224390 * just print whatever is in the table. 11066768Sar224390 */ 11075895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 11085895Syz147064 status = DLADM_STATUS_NOTSUP; 11095895Syz147064 break; 11105895Syz147064 } 11116512Ssowmini 11126512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 11138453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 11148453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11156512Ssowmini } else { 11166512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 11176512Ssowmini } 11185895Syz147064 *val_cntp = 1; 11195895Syz147064 break; 11203448Sdh155122 11215895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 11225895Syz147064 if (pdp->pd_getmod != NULL) { 11238453SAnurag.Maskey@Sun.COM status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 11248118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11255895Syz147064 break; 11265895Syz147064 } 11275895Syz147064 cnt = pdp->pd_noptval; 11285895Syz147064 if (cnt == 0) { 11295895Syz147064 status = DLADM_STATUS_NOTSUP; 11305895Syz147064 } else if (cnt > *val_cntp) { 11315895Syz147064 status = DLADM_STATUS_TOOSMALL; 11325895Syz147064 } else { 11335895Syz147064 for (i = 0; i < cnt; i++) { 11345895Syz147064 (void) strcpy(prop_val[i], 11355895Syz147064 pdp->pd_optval[i].vd_name); 11365895Syz147064 } 11375895Syz147064 *val_cntp = cnt; 11385895Syz147064 } 11395895Syz147064 break; 11405895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 11415895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 11425895Syz147064 return (DLADM_STATUS_TEMPONLY); 11438453SAnurag.Maskey@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 11445895Syz147064 prop_val, val_cntp); 11455895Syz147064 break; 11465895Syz147064 default: 11475895Syz147064 status = DLADM_STATUS_BADARG; 11485895Syz147064 break; 11493147Sxc151355 } 11503448Sdh155122 11515895Syz147064 return (status); 11525895Syz147064 } 11535895Syz147064 115410491SRishi.Srivatsavai@Sun.COM /* 115510491SRishi.Srivatsavai@Sun.COM * Get linkprop of the given specific link and run any possible conversion 115610491SRishi.Srivatsavai@Sun.COM * of the values using the check function for the property. Fails if the 115710491SRishi.Srivatsavai@Sun.COM * check function doesn't succeed for the property value. 115810491SRishi.Srivatsavai@Sun.COM */ 115910491SRishi.Srivatsavai@Sun.COM dladm_status_t 116010491SRishi.Srivatsavai@Sun.COM dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 116110491SRishi.Srivatsavai@Sun.COM dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 116210491SRishi.Srivatsavai@Sun.COM uint_t *val_cntp) 116310491SRishi.Srivatsavai@Sun.COM { 116410491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 116510491SRishi.Srivatsavai@Sun.COM datalink_class_t class; 116610491SRishi.Srivatsavai@Sun.COM uint_t media; 116710491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp; 116810491SRishi.Srivatsavai@Sun.COM uint_t dld_flags; 116910491SRishi.Srivatsavai@Sun.COM int valc, i; 117010491SRishi.Srivatsavai@Sun.COM char **prop_val; 117110491SRishi.Srivatsavai@Sun.COM uint_t perm_flags; 117210491SRishi.Srivatsavai@Sun.COM 117310491SRishi.Srivatsavai@Sun.COM if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 117410491SRishi.Srivatsavai@Sun.COM ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 117510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 117610491SRishi.Srivatsavai@Sun.COM 117710491SRishi.Srivatsavai@Sun.COM for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 117810491SRishi.Srivatsavai@Sun.COM if (strcasecmp(prop_name, pdp->pd_name) == 0) 117910491SRishi.Srivatsavai@Sun.COM break; 118010491SRishi.Srivatsavai@Sun.COM 118110491SRishi.Srivatsavai@Sun.COM if (pdp == prop_table + DLADM_MAX_PROPS) 118210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTFOUND); 118310491SRishi.Srivatsavai@Sun.COM 118410491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_CHECK_ALLOC) 118510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 118610491SRishi.Srivatsavai@Sun.COM 118710491SRishi.Srivatsavai@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 118810491SRishi.Srivatsavai@Sun.COM NULL, 0); 118910491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 119010491SRishi.Srivatsavai@Sun.COM return (status); 119110491SRishi.Srivatsavai@Sun.COM 119210491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_class & class)) 119310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 119410491SRishi.Srivatsavai@Sun.COM 119510491SRishi.Srivatsavai@Sun.COM if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 119610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 119710491SRishi.Srivatsavai@Sun.COM 119810491SRishi.Srivatsavai@Sun.COM prop_val = malloc(*val_cntp * sizeof (*prop_val) + 119910491SRishi.Srivatsavai@Sun.COM *val_cntp * DLADM_PROP_VAL_MAX); 120010491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) 120110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOMEM); 120210491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 120310491SRishi.Srivatsavai@Sun.COM prop_val[valc] = (char *)(prop_val + *val_cntp) + 120410491SRishi.Srivatsavai@Sun.COM valc * DLADM_PROP_VAL_MAX; 120510491SRishi.Srivatsavai@Sun.COM 1206*11878SVenu.Iyer@Sun.COM dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 120710491SRishi.Srivatsavai@Sun.COM 120810491SRishi.Srivatsavai@Sun.COM switch (type) { 120910491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_CURRENT: 121010491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 121110491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 121210491SRishi.Srivatsavai@Sun.COM break; 121310491SRishi.Srivatsavai@Sun.COM 121410491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_DEFAULT: 121510491SRishi.Srivatsavai@Sun.COM /* 121610491SRishi.Srivatsavai@Sun.COM * If defaults are not defined for the property, 121710491SRishi.Srivatsavai@Sun.COM * pd_defval.vd_name should be null. If the driver 121810491SRishi.Srivatsavai@Sun.COM * has to be contacted for the value, vd_name should 121910491SRishi.Srivatsavai@Sun.COM * be the empty string (""). Otherwise, dladm will 122010491SRishi.Srivatsavai@Sun.COM * just print whatever is in the table. 122110491SRishi.Srivatsavai@Sun.COM */ 122210491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name == NULL) { 122310491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOTSUP; 122410491SRishi.Srivatsavai@Sun.COM break; 122510491SRishi.Srivatsavai@Sun.COM } 122610491SRishi.Srivatsavai@Sun.COM 122710491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name[0] != '\0') { 122810491SRishi.Srivatsavai@Sun.COM *val_cntp = 1; 122910491SRishi.Srivatsavai@Sun.COM *ret_val = pdp->pd_defval.vd_val; 123010491SRishi.Srivatsavai@Sun.COM free(prop_val); 123110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 123210491SRishi.Srivatsavai@Sun.COM } 123310491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 123410491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 123510491SRishi.Srivatsavai@Sun.COM break; 123610491SRishi.Srivatsavai@Sun.COM 123710491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_PERSISTENT: 123810491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_TEMPONLY) 123910491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_TEMPONLY; 124010491SRishi.Srivatsavai@Sun.COM else 124110491SRishi.Srivatsavai@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, 124210491SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cntp); 124310491SRishi.Srivatsavai@Sun.COM break; 124410491SRishi.Srivatsavai@Sun.COM 124510491SRishi.Srivatsavai@Sun.COM default: 124610491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_BADARG; 124710491SRishi.Srivatsavai@Sun.COM break; 124810491SRishi.Srivatsavai@Sun.COM } 124910491SRishi.Srivatsavai@Sun.COM 125010491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 125110491SRishi.Srivatsavai@Sun.COM if (pdp->pd_check != NULL) { 125210491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp; 125310491SRishi.Srivatsavai@Sun.COM 125410491SRishi.Srivatsavai@Sun.COM vdp = malloc(sizeof (val_desc_t) * *val_cntp); 125510491SRishi.Srivatsavai@Sun.COM if (vdp == NULL) 125610491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOMEM; 125710491SRishi.Srivatsavai@Sun.COM else 125810491SRishi.Srivatsavai@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 1259*11878SVenu.Iyer@Sun.COM prop_val, *val_cntp, 0, vdp, media); 126010491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 126110491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 126210491SRishi.Srivatsavai@Sun.COM ret_val[valc] = vdp[valc].vd_val; 126310491SRishi.Srivatsavai@Sun.COM } 126410491SRishi.Srivatsavai@Sun.COM free(vdp); 126510491SRishi.Srivatsavai@Sun.COM } else { 126610491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) { 126710491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pdp->pd_noptval; i++) { 126810491SRishi.Srivatsavai@Sun.COM if (strcmp(pdp->pd_optval[i].vd_name, 126910491SRishi.Srivatsavai@Sun.COM prop_val[valc]) == 0) { 127010491SRishi.Srivatsavai@Sun.COM ret_val[valc] = 127110491SRishi.Srivatsavai@Sun.COM pdp->pd_optval[i].vd_val; 127210491SRishi.Srivatsavai@Sun.COM break; 127310491SRishi.Srivatsavai@Sun.COM } 127410491SRishi.Srivatsavai@Sun.COM } 127510491SRishi.Srivatsavai@Sun.COM if (i == pdp->pd_noptval) { 127610491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_FAILED; 127710491SRishi.Srivatsavai@Sun.COM break; 127810491SRishi.Srivatsavai@Sun.COM } 127910491SRishi.Srivatsavai@Sun.COM } 128010491SRishi.Srivatsavai@Sun.COM } 128110491SRishi.Srivatsavai@Sun.COM } 128210491SRishi.Srivatsavai@Sun.COM 128310491SRishi.Srivatsavai@Sun.COM free(prop_val); 128410491SRishi.Srivatsavai@Sun.COM 128510491SRishi.Srivatsavai@Sun.COM return (status); 128610491SRishi.Srivatsavai@Sun.COM } 128710491SRishi.Srivatsavai@Sun.COM 12885895Syz147064 /*ARGSUSED*/ 12895895Syz147064 static int 12908453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 12918453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 12925895Syz147064 { 1293*11878SVenu.Iyer@Sun.COM char *buf, **propvals; 1294*11878SVenu.Iyer@Sun.COM uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 1295*11878SVenu.Iyer@Sun.COM dladm_status_t status; 1296*11878SVenu.Iyer@Sun.COM dladm_linkprop_args_t *dla = arg; 12975895Syz147064 12985895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 12995895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 13005895Syz147064 return (DLADM_WALK_CONTINUE); 13015895Syz147064 } 13025895Syz147064 13035895Syz147064 propvals = (char **)(void *)buf; 13045895Syz147064 for (i = 0; i < valcnt; i++) { 13055895Syz147064 propvals[i] = buf + 13065895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 13075895Syz147064 i * DLADM_PROP_VAL_MAX; 13085895Syz147064 } 13095895Syz147064 13108453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 13118453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 13125895Syz147064 goto done; 13135895Syz147064 } 13145895Syz147064 131511021SEric.Cheng@Sun.COM status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 1316*11878SVenu.Iyer@Sun.COM valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 1317*11878SVenu.Iyer@Sun.COM 131811021SEric.Cheng@Sun.COM if (status != DLADM_STATUS_OK) 1319*11878SVenu.Iyer@Sun.COM dla->dla_status = status; 13205895Syz147064 13215895Syz147064 done: 13225895Syz147064 if (buf != NULL) 13235895Syz147064 free(buf); 13245895Syz147064 13255895Syz147064 return (DLADM_WALK_CONTINUE); 13265895Syz147064 } 13275895Syz147064 13285895Syz147064 /*ARGSUSED*/ 13295895Syz147064 static int 13308453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 13315895Syz147064 { 13328275SEric Cheng datalink_class_t class; 13338275SEric Cheng dladm_status_t status; 13348275SEric Cheng 13358453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 13368453SAnurag.Maskey@Sun.COM NULL, 0); 13378275SEric Cheng if (status != DLADM_STATUS_OK) 13388275SEric Cheng return (DLADM_WALK_TERMINATE); 13398275SEric Cheng 13408275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 13418453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 13428275SEric Cheng 13435895Syz147064 return (DLADM_WALK_CONTINUE); 13445895Syz147064 } 13455895Syz147064 13465895Syz147064 dladm_status_t 13478453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 13488453SAnurag.Maskey@Sun.COM boolean_t any_media) 13495895Syz147064 { 135011021SEric.Cheng@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 13516916Sartem datalink_media_t dmedia; 13526916Sartem uint32_t media; 1353*11878SVenu.Iyer@Sun.COM dladm_linkprop_args_t *dla; 13546916Sartem 13556916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 13566916Sartem 1357*11878SVenu.Iyer@Sun.COM dla = malloc(sizeof (dladm_linkprop_args_t)); 1358*11878SVenu.Iyer@Sun.COM if (dla == NULL) 1359*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 1360*11878SVenu.Iyer@Sun.COM dla->dla_flags = DLADM_OPT_BOOT; 1361*11878SVenu.Iyer@Sun.COM dla->dla_status = DLADM_STATUS_OK; 1362*11878SVenu.Iyer@Sun.COM 13635895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 13648453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 13658453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 13668453SAnurag.Maskey@Sun.COM } else if (any_media || 13678453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 13688453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 13696916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 1370*11878SVenu.Iyer@Sun.COM (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 13718453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 1372*11878SVenu.Iyer@Sun.COM status = dla->dla_status; 13733448Sdh155122 } 1374*11878SVenu.Iyer@Sun.COM free(dla); 137511021SEric.Cheng@Sun.COM return (status); 13763147Sxc151355 } 13773147Sxc151355 13785903Ssowmini /* ARGSUSED */ 13795895Syz147064 static dladm_status_t 1380*11878SVenu.Iyer@Sun.COM get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13818275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 13828275SEric Cheng uint_t flags, uint_t *perm_flags) 13833147Sxc151355 { 13848275SEric Cheng char zone_name[ZONENAME_MAX]; 13858275SEric Cheng zoneid_t zid; 13868275SEric Cheng dladm_status_t status; 13873147Sxc151355 13886512Ssowmini if (flags != 0) 13896512Ssowmini return (DLADM_STATUS_NOTSUP); 13906512Ssowmini 1391*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1392*11878SVenu.Iyer@Sun.COM perm_flags, &zid, sizeof (zid)); 13935895Syz147064 if (status != DLADM_STATUS_OK) 13943448Sdh155122 return (status); 13953448Sdh155122 13965895Syz147064 *val_cnt = 1; 13975895Syz147064 if (zid != GLOBAL_ZONEID) { 13988118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 13995895Syz147064 return (dladm_errno2status(errno)); 14008118SVasumathi.Sundaram@Sun.COM } 14013147Sxc151355 14025895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 14033147Sxc151355 } else { 14045895Syz147064 *prop_val[0] = '\0'; 14053147Sxc151355 } 14063147Sxc151355 14073448Sdh155122 return (DLADM_STATUS_OK); 14083448Sdh155122 } 14093448Sdh155122 14103448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 14113448Sdh155122 14123448Sdh155122 static int 14133448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 14143448Sdh155122 { 14153448Sdh155122 char root[MAXPATHLEN]; 14163448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 14173448Sdh155122 void *dlhandle; 14183448Sdh155122 void *sym; 14193448Sdh155122 int ret; 14203448Sdh155122 14213448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 14223448Sdh155122 return (-1); 14233448Sdh155122 14243448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 14253448Sdh155122 (void) dlclose(dlhandle); 14263448Sdh155122 return (-1); 14273448Sdh155122 } 14283448Sdh155122 14293448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 14303448Sdh155122 14313448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 14323448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 14333448Sdh155122 (void) dlclose(dlhandle); 14343448Sdh155122 return (ret); 14353448Sdh155122 } 14363448Sdh155122 14373448Sdh155122 static dladm_status_t 14388453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 14398453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 14403448Sdh155122 { 14413448Sdh155122 char path[MAXPATHLEN]; 14425895Syz147064 char name[MAXLINKNAMELEN]; 14433448Sdh155122 di_prof_t prof = NULL; 14443448Sdh155122 char zone_name[ZONENAME_MAX]; 14453448Sdh155122 dladm_status_t status; 14465895Syz147064 int ret; 14473448Sdh155122 14483448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 14493448Sdh155122 return (dladm_errno2status(errno)); 14503448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 14513448Sdh155122 return (dladm_errno2status(errno)); 14523448Sdh155122 if (di_prof_init(path, &prof) != 0) 14533448Sdh155122 return (dladm_errno2status(errno)); 14543448Sdh155122 14558453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 14565895Syz147064 if (status != DLADM_STATUS_OK) 14575895Syz147064 goto cleanup; 14585895Syz147064 14595895Syz147064 if (add) 14605895Syz147064 ret = di_prof_add_dev(prof, name); 14615895Syz147064 else 14625895Syz147064 ret = di_prof_add_exclude(prof, name); 14635895Syz147064 14645895Syz147064 if (ret != 0) { 14653448Sdh155122 status = dladm_errno2status(errno); 14663448Sdh155122 goto cleanup; 14673448Sdh155122 } 14683448Sdh155122 14693448Sdh155122 if (di_prof_commit(prof) != 0) 14703448Sdh155122 status = dladm_errno2status(errno); 14713448Sdh155122 cleanup: 14723448Sdh155122 if (prof) 14733448Sdh155122 di_prof_fini(prof); 14743448Sdh155122 14753448Sdh155122 return (status); 14763448Sdh155122 } 14773448Sdh155122 14785903Ssowmini /* ARGSUSED */ 14793448Sdh155122 static dladm_status_t 1480*11878SVenu.Iyer@Sun.COM set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14818453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 14823448Sdh155122 { 14838275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 14848275SEric Cheng zoneid_t zid_old, zid_new; 14857342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14863448Sdh155122 14873448Sdh155122 if (val_cnt != 1) 14883448Sdh155122 return (DLADM_STATUS_BADVALCNT); 14893448Sdh155122 14907342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 14917342SAruna.Ramakrishna@Sun.COM 1492*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1493*11878SVenu.Iyer@Sun.COM NULL, &zid_old, sizeof (zid_old)); 14948275SEric Cheng if (status != DLADM_STATUS_OK) 14958275SEric Cheng return (status); 14968275SEric Cheng 14977342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 14983448Sdh155122 if (zid_new == zid_old) 149910616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 150010616SSebastien.Roy@Sun.COM 1501*11878SVenu.Iyer@Sun.COM if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 150210616SSebastien.Roy@Sun.COM flags, media)) != DLADM_STATUS_OK) 15035895Syz147064 return (status); 15045895Syz147064 150510616SSebastien.Roy@Sun.COM /* 150610616SSebastien.Roy@Sun.COM * It is okay to fail to update the /dev entry (some vanity-named 150710616SSebastien.Roy@Sun.COM * links do not have a /dev entry). 150810616SSebastien.Roy@Sun.COM */ 15093448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 15108453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 15118453SAnurag.Maskey@Sun.COM B_FALSE); 15125895Syz147064 } 151310616SSebastien.Roy@Sun.COM if (zid_new != GLOBAL_ZONEID) 15148453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 15153448Sdh155122 15163448Sdh155122 return (DLADM_STATUS_OK); 15173448Sdh155122 } 15183448Sdh155122 15193448Sdh155122 /* ARGSUSED */ 15203448Sdh155122 static dladm_status_t 1521*11878SVenu.Iyer@Sun.COM check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1522*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1523*11878SVenu.Iyer@Sun.COM datalink_media_t media) 15243448Sdh155122 { 15257342SAruna.Ramakrishna@Sun.COM char *zone_name; 15267342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 15277342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 15287342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 15293448Sdh155122 15303448Sdh155122 if (val_cnt != 1) 15313448Sdh155122 return (DLADM_STATUS_BADVALCNT); 15323448Sdh155122 15337342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 15347342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 15357342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 15363448Sdh155122 15378275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 15387342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 15397342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 15407342SAruna.Ramakrishna@Sun.COM goto done; 15417342SAruna.Ramakrishna@Sun.COM } 15427342SAruna.Ramakrishna@Sun.COM 15437342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 15443448Sdh155122 ushort_t flags; 15453448Sdh155122 15467342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 15473448Sdh155122 sizeof (flags)) < 0) { 15487342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 15497342SAruna.Ramakrishna@Sun.COM goto done; 15503448Sdh155122 } 15513448Sdh155122 15523448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 15537342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 15547342SAruna.Ramakrishna@Sun.COM goto done; 15553448Sdh155122 } 15563448Sdh155122 } 15573448Sdh155122 15587342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15597342SAruna.Ramakrishna@Sun.COM 15607342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 156110616SSebastien.Roy@Sun.COM dzp->diz_linkid = linkid; 15627342SAruna.Ramakrishna@Sun.COM 15637342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 15645895Syz147064 return (DLADM_STATUS_OK); 15657342SAruna.Ramakrishna@Sun.COM done: 15667342SAruna.Ramakrishna@Sun.COM free(dzp); 15677342SAruna.Ramakrishna@Sun.COM return (status); 15685895Syz147064 } 15695895Syz147064 15705903Ssowmini /* ARGSUSED */ 15715895Syz147064 static dladm_status_t 1572*11878SVenu.Iyer@Sun.COM get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15738275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15748275SEric Cheng uint_t flags, uint_t *perm_flags) 15758275SEric Cheng { 15768275SEric Cheng mac_resource_props_t mrp; 15778275SEric Cheng dladm_status_t status; 15788275SEric Cheng 1579*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 1580*11878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 1581*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 15828275SEric Cheng return (status); 15838275SEric Cheng 15848275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 1585*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 1586*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 15878275SEric Cheng } 1588*11878SVenu.Iyer@Sun.COM 1589*11878SVenu.Iyer@Sun.COM (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 15908275SEric Cheng *val_cnt = 1; 15918275SEric Cheng return (DLADM_STATUS_OK); 15928275SEric Cheng } 15938275SEric Cheng 15948275SEric Cheng /* ARGSUSED */ 15958275SEric Cheng static dladm_status_t 1596*11878SVenu.Iyer@Sun.COM check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1597*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1598*11878SVenu.Iyer@Sun.COM datalink_media_t media) 15998275SEric Cheng { 16008275SEric Cheng uint64_t *maxbw; 16018275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 16028275SEric Cheng 16038275SEric Cheng if (val_cnt != 1) 16048275SEric Cheng return (DLADM_STATUS_BADVALCNT); 16058275SEric Cheng 16068275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 16078275SEric Cheng if (maxbw == NULL) 16088275SEric Cheng return (DLADM_STATUS_NOMEM); 16098275SEric Cheng 16108275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 16118275SEric Cheng if (status != DLADM_STATUS_OK) { 16128275SEric Cheng free(maxbw); 16138275SEric Cheng return (status); 16148275SEric Cheng } 16158275SEric Cheng 16168275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 16178275SEric Cheng free(maxbw); 16188275SEric Cheng return (DLADM_STATUS_MINMAXBW); 16198275SEric Cheng } 16208275SEric Cheng 16218275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 16228275SEric Cheng return (DLADM_STATUS_OK); 16238275SEric Cheng } 16248275SEric Cheng 16258275SEric Cheng /* ARGSUSED */ 16268275SEric Cheng dladm_status_t 1627*11878SVenu.Iyer@Sun.COM extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 16288275SEric Cheng { 162910734SEric Cheng mac_resource_props_t *mrp = arg; 16308275SEric Cheng 1631*11878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) { 1632*11878SVenu.Iyer@Sun.COM mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 1633*11878SVenu.Iyer@Sun.COM } else { 1634*11878SVenu.Iyer@Sun.COM bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 1635*11878SVenu.Iyer@Sun.COM } 16368275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 16378275SEric Cheng 16388275SEric Cheng return (DLADM_STATUS_OK); 16398275SEric Cheng } 16408275SEric Cheng 16418275SEric Cheng /* ARGSUSED */ 16428275SEric Cheng static dladm_status_t 1643*11878SVenu.Iyer@Sun.COM get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16448275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 16458275SEric Cheng uint_t flags, uint_t *perm_flags) 16468275SEric Cheng { 1647*11878SVenu.Iyer@Sun.COM dladm_status_t status; 16488275SEric Cheng mac_resource_props_t mrp; 16498275SEric Cheng int i; 16508275SEric Cheng uint32_t ncpus; 1651*11878SVenu.Iyer@Sun.COM 1652*11878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 1653*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 1654*11878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 1655*11878SVenu.Iyer@Sun.COM sizeof (mrp)); 1656*11878SVenu.Iyer@Sun.COM } else { 1657*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 1658*11878SVenu.Iyer@Sun.COM "resource", flags, perm_flags, &mrp, sizeof (mrp)); 1659*11878SVenu.Iyer@Sun.COM } 1660*11878SVenu.Iyer@Sun.COM 1661*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 16628275SEric Cheng return (status); 16638275SEric Cheng 16648275SEric Cheng ncpus = mrp.mrp_ncpus; 16658275SEric Cheng if (ncpus > *val_cnt) 16668275SEric Cheng return (DLADM_STATUS_TOOSMALL); 16678275SEric Cheng 16688275SEric Cheng if (ncpus == 0) { 1669*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 16708275SEric Cheng return (DLADM_STATUS_OK); 16718275SEric Cheng } 16728275SEric Cheng 16738275SEric Cheng *val_cnt = ncpus; 16748275SEric Cheng for (i = 0; i < ncpus; i++) { 16758275SEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 16768275SEric Cheng "%u", mrp.mrp_cpu[i]); 16778275SEric Cheng } 16788275SEric Cheng return (DLADM_STATUS_OK); 16798275SEric Cheng } 16808275SEric Cheng 16818275SEric Cheng /* ARGSUSED */ 16828275SEric Cheng static dladm_status_t 1683*11878SVenu.Iyer@Sun.COM check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1684*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1685*11878SVenu.Iyer@Sun.COM datalink_media_t media) 16868275SEric Cheng { 1687*11878SVenu.Iyer@Sun.COM uint32_t cpuid; 1688*11878SVenu.Iyer@Sun.COM int i, j, rc; 1689*11878SVenu.Iyer@Sun.COM char *endp; 1690*11878SVenu.Iyer@Sun.COM long nproc = sysconf(_SC_NPROCESSORS_CONF); 16918275SEric Cheng mac_resource_props_t mrp; 1692*11878SVenu.Iyer@Sun.COM dladm_status_t status; 1693*11878SVenu.Iyer@Sun.COM uint_t perm_flags; 1694*11878SVenu.Iyer@Sun.COM 1695*11878SVenu.Iyer@Sun.COM /* Get the current pool property */ 1696*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 1697*11878SVenu.Iyer@Sun.COM &perm_flags, &mrp, sizeof (mrp)); 1698*11878SVenu.Iyer@Sun.COM 1699*11878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) { 1700*11878SVenu.Iyer@Sun.COM /* Can't set cpus if a pool is set */ 1701*11878SVenu.Iyer@Sun.COM if (strlen(mrp.mrp_pool) != 0) 1702*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_POOLCPU); 1703*11878SVenu.Iyer@Sun.COM } 17048275SEric Cheng 17058275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 1706*11878SVenu.Iyer@Sun.COM 1707*11878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 1708*11878SVenu.Iyer@Sun.COM errno = 0; 1709*11878SVenu.Iyer@Sun.COM cpuid = strtol(prop_val[i], &endp, 10); 1710*11878SVenu.Iyer@Sun.COM if (errno != 0 || *endp != '\0') 1711*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 1712*11878SVenu.Iyer@Sun.COM 1713*11878SVenu.Iyer@Sun.COM if (cpuid >= nproc) 1714*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_CPUMAX); 1715*11878SVenu.Iyer@Sun.COM 1716*11878SVenu.Iyer@Sun.COM rc = p_online(cpuid, P_STATUS); 1717*11878SVenu.Iyer@Sun.COM if (rc < 1) 1718*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_CPUERR); 1719*11878SVenu.Iyer@Sun.COM 1720*11878SVenu.Iyer@Sun.COM if (rc != P_ONLINE) 1721*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_CPUNOTONLINE); 1722*11878SVenu.Iyer@Sun.COM 1723*11878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)cpuid; 1724*11878SVenu.Iyer@Sun.COM } 1725*11878SVenu.Iyer@Sun.COM 1726*11878SVenu.Iyer@Sun.COM /* Check for duplicates */ 1727*11878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 1728*11878SVenu.Iyer@Sun.COM for (j = 0; j < val_cnt; j++) { 1729*11878SVenu.Iyer@Sun.COM if (i != j && vdp[i].vd_val == vdp[j].vd_val) 1730*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 17318275SEric Cheng } 17328275SEric Cheng } 1733*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 1734*11878SVenu.Iyer@Sun.COM } 1735*11878SVenu.Iyer@Sun.COM 1736*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 1737*11878SVenu.Iyer@Sun.COM dladm_status_t 1738*11878SVenu.Iyer@Sun.COM extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 1739*11878SVenu.Iyer@Sun.COM { 1740*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 1741*11878SVenu.Iyer@Sun.COM int i; 1742*11878SVenu.Iyer@Sun.COM 1743*11878SVenu.Iyer@Sun.COM if (vdp[0].vd_val == RESET_VAL) { 1744*11878SVenu.Iyer@Sun.COM bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 1745*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_CPUS; 1746*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 1747*11878SVenu.Iyer@Sun.COM } 1748*11878SVenu.Iyer@Sun.COM 1749*11878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) 1750*11878SVenu.Iyer@Sun.COM mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 1751*11878SVenu.Iyer@Sun.COM 1752*11878SVenu.Iyer@Sun.COM mrp->mrp_ncpus = cnt; 1753*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 1754*11878SVenu.Iyer@Sun.COM mrp->mrp_fanout_mode = MCM_CPUS; 1755*11878SVenu.Iyer@Sun.COM mrp->mrp_rx_intr_cpu = -1; 1756*11878SVenu.Iyer@Sun.COM 1757*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 1758*11878SVenu.Iyer@Sun.COM } 1759*11878SVenu.Iyer@Sun.COM 1760*11878SVenu.Iyer@Sun.COM /* 1761*11878SVenu.Iyer@Sun.COM * Get the pool datalink property from the kernel. This is used 1762*11878SVenu.Iyer@Sun.COM * for both the user specified pool and effective pool properties. 1763*11878SVenu.Iyer@Sun.COM */ 1764*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 1765*11878SVenu.Iyer@Sun.COM static dladm_status_t 1766*11878SVenu.Iyer@Sun.COM get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1767*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 1768*11878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 1769*11878SVenu.Iyer@Sun.COM { 1770*11878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 1771*11878SVenu.Iyer@Sun.COM dladm_status_t status; 1772*11878SVenu.Iyer@Sun.COM 1773*11878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "pool-effective") == 0) { 1774*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 1775*11878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 1776*11878SVenu.Iyer@Sun.COM sizeof (mrp)); 1777*11878SVenu.Iyer@Sun.COM } else { 1778*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 1779*11878SVenu.Iyer@Sun.COM "resource", flags, perm_flags, &mrp, sizeof (mrp)); 1780*11878SVenu.Iyer@Sun.COM } 1781*11878SVenu.Iyer@Sun.COM 1782*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 1783*11878SVenu.Iyer@Sun.COM return (status); 1784*11878SVenu.Iyer@Sun.COM 1785*11878SVenu.Iyer@Sun.COM if (strlen(mrp.mrp_pool) == 0) { 1786*11878SVenu.Iyer@Sun.COM (*prop_val)[0] = '\0'; 1787*11878SVenu.Iyer@Sun.COM } else { 1788*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 1789*11878SVenu.Iyer@Sun.COM "%s", mrp.mrp_pool); 1790*11878SVenu.Iyer@Sun.COM } 1791*11878SVenu.Iyer@Sun.COM *val_cnt = 1; 1792*11878SVenu.Iyer@Sun.COM 1793*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 17948275SEric Cheng } 17958275SEric Cheng 17968275SEric Cheng /* ARGSUSED */ 17978275SEric Cheng static dladm_status_t 1798*11878SVenu.Iyer@Sun.COM check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1799*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1800*11878SVenu.Iyer@Sun.COM datalink_media_t media) 18018275SEric Cheng { 1802*11878SVenu.Iyer@Sun.COM pool_conf_t *poolconf; 1803*11878SVenu.Iyer@Sun.COM pool_t *pool; 18048275SEric Cheng mac_resource_props_t mrp; 18058275SEric Cheng dladm_status_t status; 1806*11878SVenu.Iyer@Sun.COM uint_t perm_flags; 1807*11878SVenu.Iyer@Sun.COM char *poolname; 1808*11878SVenu.Iyer@Sun.COM 1809*11878SVenu.Iyer@Sun.COM /* Get the current cpus property */ 1810*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 1811*11878SVenu.Iyer@Sun.COM &perm_flags, &mrp, sizeof (mrp)); 1812*11878SVenu.Iyer@Sun.COM 1813*11878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) { 1814*11878SVenu.Iyer@Sun.COM /* Can't set pool if cpus are set */ 1815*11878SVenu.Iyer@Sun.COM if (mrp.mrp_ncpus != 0) 1816*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_POOLCPU); 18178275SEric Cheng } 18188275SEric Cheng 1819*11878SVenu.Iyer@Sun.COM poolname = malloc(sizeof (mrp.mrp_pool)); 1820*11878SVenu.Iyer@Sun.COM if (poolname == NULL) 18218275SEric Cheng return (DLADM_STATUS_NOMEM); 18228275SEric Cheng 1823*11878SVenu.Iyer@Sun.COM /* Check for pool's availability if not booting */ 1824*11878SVenu.Iyer@Sun.COM if ((flags & DLADM_OPT_BOOT) == 0) { 1825*11878SVenu.Iyer@Sun.COM 1826*11878SVenu.Iyer@Sun.COM /* Allocate and open pool configuration */ 1827*11878SVenu.Iyer@Sun.COM if ((poolconf = pool_conf_alloc()) == NULL) 1828*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 1829*11878SVenu.Iyer@Sun.COM 1830*11878SVenu.Iyer@Sun.COM if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 1831*11878SVenu.Iyer@Sun.COM != PO_SUCCESS) { 1832*11878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 1833*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 18348275SEric Cheng } 1835*11878SVenu.Iyer@Sun.COM 1836*11878SVenu.Iyer@Sun.COM /* Look for pool name */ 1837*11878SVenu.Iyer@Sun.COM if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 1838*11878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 1839*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 18408275SEric Cheng } 1841*11878SVenu.Iyer@Sun.COM 1842*11878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 1843*11878SVenu.Iyer@Sun.COM free(pool); 18448275SEric Cheng } 1845*11878SVenu.Iyer@Sun.COM 1846*11878SVenu.Iyer@Sun.COM (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 1847*11878SVenu.Iyer@Sun.COM vdp->vd_val = (uintptr_t)poolname; 18488275SEric Cheng 18498275SEric Cheng return (DLADM_STATUS_OK); 18508275SEric Cheng } 18518275SEric Cheng 18528275SEric Cheng /* ARGSUSED */ 18538275SEric Cheng dladm_status_t 1854*11878SVenu.Iyer@Sun.COM extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 18558275SEric Cheng { 1856*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1857*11878SVenu.Iyer@Sun.COM 1858*11878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) { 1859*11878SVenu.Iyer@Sun.COM bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 1860*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_POOL; 1861*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 18628275SEric Cheng } 1863*11878SVenu.Iyer@Sun.COM 1864*11878SVenu.Iyer@Sun.COM (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 1865*11878SVenu.Iyer@Sun.COM sizeof (mrp->mrp_pool)); 1866*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_POOL; 1867*11878SVenu.Iyer@Sun.COM /* 1868*11878SVenu.Iyer@Sun.COM * Use MCM_CPUS since the fanout count is not user specified 1869*11878SVenu.Iyer@Sun.COM * and will be determined by the cpu list generated from the 1870*11878SVenu.Iyer@Sun.COM * pool. 1871*11878SVenu.Iyer@Sun.COM */ 18728275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 18738275SEric Cheng 18748275SEric Cheng return (DLADM_STATUS_OK); 18758275SEric Cheng } 18768275SEric Cheng 18778275SEric Cheng /* ARGSUSED */ 18788275SEric Cheng static dladm_status_t 1879*11878SVenu.Iyer@Sun.COM get_priority(dladm_handle_t handle, prop_desc_t *pdp, 18808460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 18818460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 18828275SEric Cheng { 18838275SEric Cheng mac_resource_props_t mrp; 18848275SEric Cheng mac_priority_level_t pri; 18858275SEric Cheng dladm_status_t status; 18868275SEric Cheng 1887*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 1888*11878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 1889*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 18908275SEric Cheng return (status); 18918275SEric Cheng 18928275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 18938275SEric Cheng mrp.mrp_priority; 18948275SEric Cheng 18958275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 18968275SEric Cheng *val_cnt = 1; 18978275SEric Cheng return (DLADM_STATUS_OK); 18988275SEric Cheng } 18998275SEric Cheng 19008275SEric Cheng /* ARGSUSED */ 1901*11878SVenu.Iyer@Sun.COM dladm_status_t 1902*11878SVenu.Iyer@Sun.COM extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 1903*11878SVenu.Iyer@Sun.COM { 1904*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 1905*11878SVenu.Iyer@Sun.COM 1906*11878SVenu.Iyer@Sun.COM if (cnt != 1) 1907*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 1908*11878SVenu.Iyer@Sun.COM 1909*11878SVenu.Iyer@Sun.COM mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 1910*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_PRIORITY; 1911*11878SVenu.Iyer@Sun.COM 1912*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 1913*11878SVenu.Iyer@Sun.COM } 1914*11878SVenu.Iyer@Sun.COM 1915*11878SVenu.Iyer@Sun.COM /* 1916*11878SVenu.Iyer@Sun.COM * Determines the size of the structure that needs to be sent to drivers 1917*11878SVenu.Iyer@Sun.COM * for retrieving the property range values. 1918*11878SVenu.Iyer@Sun.COM */ 1919*11878SVenu.Iyer@Sun.COM static int 1920*11878SVenu.Iyer@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 19218275SEric Cheng { 1922*11878SVenu.Iyer@Sun.COM uint_t count = r->mpr_count; 1923*11878SVenu.Iyer@Sun.COM 1924*11878SVenu.Iyer@Sun.COM *sz = sizeof (mac_propval_range_t); 1925*11878SVenu.Iyer@Sun.COM --count; 1926*11878SVenu.Iyer@Sun.COM 1927*11878SVenu.Iyer@Sun.COM switch (r->mpr_type) { 1928*11878SVenu.Iyer@Sun.COM case MAC_PROPVAL_UINT32: 1929*11878SVenu.Iyer@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 1930*11878SVenu.Iyer@Sun.COM return (0); 1931*11878SVenu.Iyer@Sun.COM default: 1932*11878SVenu.Iyer@Sun.COM break; 1933*11878SVenu.Iyer@Sun.COM } 1934*11878SVenu.Iyer@Sun.COM *sz = 0; 1935*11878SVenu.Iyer@Sun.COM return (EINVAL); 1936*11878SVenu.Iyer@Sun.COM } 1937*11878SVenu.Iyer@Sun.COM 1938*11878SVenu.Iyer@Sun.COM 1939*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 1940*11878SVenu.Iyer@Sun.COM static dladm_status_t 1941*11878SVenu.Iyer@Sun.COM check_rings(dladm_handle_t handle, prop_desc_t *pdp, 1942*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 1943*11878SVenu.Iyer@Sun.COM val_desc_t *v, datalink_media_t media) 1944*11878SVenu.Iyer@Sun.COM { 19458275SEric Cheng if (val_cnt != 1) 1946*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 1947*11878SVenu.Iyer@Sun.COM if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 1948*11878SVenu.Iyer@Sun.COM v->vd_val = UNSPEC_VAL; 1949*11878SVenu.Iyer@Sun.COM } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 1950*11878SVenu.Iyer@Sun.COM v->vd_val = 0; 1951*11878SVenu.Iyer@Sun.COM } else { 1952*11878SVenu.Iyer@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 1953*11878SVenu.Iyer@Sun.COM if (v->vd_val == 0) 1954*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 1955*11878SVenu.Iyer@Sun.COM } 1956*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 1957*11878SVenu.Iyer@Sun.COM } 1958*11878SVenu.Iyer@Sun.COM 1959*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 1960*11878SVenu.Iyer@Sun.COM static dladm_status_t 1961*11878SVenu.Iyer@Sun.COM get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 1962*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 1963*11878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 1964*11878SVenu.Iyer@Sun.COM { 1965*11878SVenu.Iyer@Sun.COM dld_ioc_macprop_t *dip; 1966*11878SVenu.Iyer@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 1967*11878SVenu.Iyer@Sun.COM mac_propval_range_t *rangep; 1968*11878SVenu.Iyer@Sun.COM size_t sz; 1969*11878SVenu.Iyer@Sun.COM mac_propval_uint32_range_t *ur; 1970*11878SVenu.Iyer@Sun.COM 1971*11878SVenu.Iyer@Sun.COM sz = sizeof (mac_propval_range_t); 1972*11878SVenu.Iyer@Sun.COM 1973*11878SVenu.Iyer@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 1974*11878SVenu.Iyer@Sun.COM &status)) == NULL) 1975*11878SVenu.Iyer@Sun.COM return (status); 1976*11878SVenu.Iyer@Sun.COM 1977*11878SVenu.Iyer@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 1978*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 19798275SEric Cheng return (status); 1980*11878SVenu.Iyer@Sun.COM 1981*11878SVenu.Iyer@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 1982*11878SVenu.Iyer@Sun.COM *val_cnt = 1; 1983*11878SVenu.Iyer@Sun.COM ur = &rangep->mpr_range_uint32[0]; 1984*11878SVenu.Iyer@Sun.COM /* This is the case where the dev doesn't have any rings/groups */ 1985*11878SVenu.Iyer@Sun.COM if (rangep->mpr_count == 0) { 1986*11878SVenu.Iyer@Sun.COM (*prop_val)[0] = '\0'; 1987*11878SVenu.Iyer@Sun.COM /* 1988*11878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings, but static 1989*11878SVenu.Iyer@Sun.COM * grouping. 1990*11878SVenu.Iyer@Sun.COM */ 1991*11878SVenu.Iyer@Sun.COM } else if (ur->mpur_min == ur->mpur_max && 1992*11878SVenu.Iyer@Sun.COM ur->mpur_max == 0) { 1993*11878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 1994*11878SVenu.Iyer@Sun.COM /* 1995*11878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings and dynamic 1996*11878SVenu.Iyer@Sun.COM * grouping, but has only one value (say 2 rings and 2 groups). 1997*11878SVenu.Iyer@Sun.COM */ 1998*11878SVenu.Iyer@Sun.COM } else if (ur->mpur_min == ur->mpur_max) { 1999*11878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 2000*11878SVenu.Iyer@Sun.COM ur->mpur_min); 2001*11878SVenu.Iyer@Sun.COM /* 2002*11878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings and dynamic 2003*11878SVenu.Iyer@Sun.COM * grouping and has a range of rings. 2004*11878SVenu.Iyer@Sun.COM */ 2005*11878SVenu.Iyer@Sun.COM } else { 2006*11878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 2007*11878SVenu.Iyer@Sun.COM "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 20088275SEric Cheng } 2009*11878SVenu.Iyer@Sun.COM free(dip); 2010*11878SVenu.Iyer@Sun.COM return (status); 2011*11878SVenu.Iyer@Sun.COM } 2012*11878SVenu.Iyer@Sun.COM 2013*11878SVenu.Iyer@Sun.COM 2014*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2015*11878SVenu.Iyer@Sun.COM static dladm_status_t 2016*11878SVenu.Iyer@Sun.COM get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2017*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 2018*11878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 2019*11878SVenu.Iyer@Sun.COM { 2020*11878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 2021*11878SVenu.Iyer@Sun.COM dladm_status_t status; 2022*11878SVenu.Iyer@Sun.COM uint32_t nrings = 0; 2023*11878SVenu.Iyer@Sun.COM 2024*11878SVenu.Iyer@Sun.COM /* 2025*11878SVenu.Iyer@Sun.COM * Get the number of (effective-)rings from the resource property. 2026*11878SVenu.Iyer@Sun.COM */ 2027*11878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 2028*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 2029*11878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 2030*11878SVenu.Iyer@Sun.COM sizeof (mrp)); 2031*11878SVenu.Iyer@Sun.COM } else { 2032*11878SVenu.Iyer@Sun.COM /* 2033*11878SVenu.Iyer@Sun.COM * Get the permissions from the "rxrings" property. 2034*11878SVenu.Iyer@Sun.COM */ 2035*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "rxrings", 2036*11878SVenu.Iyer@Sun.COM flags, perm_flags, NULL, 0); 2037*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2038*11878SVenu.Iyer@Sun.COM return (status); 2039*11878SVenu.Iyer@Sun.COM 2040*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 2041*11878SVenu.Iyer@Sun.COM "resource", flags, NULL, &mrp, sizeof (mrp)); 20428275SEric Cheng } 20438275SEric Cheng 2044*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2045*11878SVenu.Iyer@Sun.COM return (status); 2046*11878SVenu.Iyer@Sun.COM 2047*11878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 2048*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 2049*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2050*11878SVenu.Iyer@Sun.COM } 2051*11878SVenu.Iyer@Sun.COM nrings = mrp.mrp_nrxrings; 2052*11878SVenu.Iyer@Sun.COM *val_cnt = 1; 2053*11878SVenu.Iyer@Sun.COM if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 2054*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 2055*11878SVenu.Iyer@Sun.COM else if (nrings == 0) 2056*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 2057*11878SVenu.Iyer@Sun.COM else 2058*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 20598275SEric Cheng return (DLADM_STATUS_OK); 20608275SEric Cheng } 20618275SEric Cheng 20628275SEric Cheng /* ARGSUSED */ 20638275SEric Cheng dladm_status_t 2064*11878SVenu.Iyer@Sun.COM extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 20658275SEric Cheng { 2066*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 2067*11878SVenu.Iyer@Sun.COM 2068*11878SVenu.Iyer@Sun.COM mrp->mrp_nrxrings = 0; 2069*11878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) 2070*11878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RINGS_RESET; 2071*11878SVenu.Iyer@Sun.COM else if (vdp->vd_val == UNSPEC_VAL) 2072*11878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 2073*11878SVenu.Iyer@Sun.COM else 2074*11878SVenu.Iyer@Sun.COM mrp->mrp_nrxrings = vdp->vd_val; 2075*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_RX_RINGS; 20768275SEric Cheng 20778275SEric Cheng return (DLADM_STATUS_OK); 20788275SEric Cheng } 20798275SEric Cheng 20808275SEric Cheng /* ARGSUSED */ 20818275SEric Cheng static dladm_status_t 2082*11878SVenu.Iyer@Sun.COM get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2083*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 2084*11878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 2085*11878SVenu.Iyer@Sun.COM { 2086*11878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 2087*11878SVenu.Iyer@Sun.COM dladm_status_t status; 2088*11878SVenu.Iyer@Sun.COM uint32_t nrings = 0; 2089*11878SVenu.Iyer@Sun.COM 2090*11878SVenu.Iyer@Sun.COM 2091*11878SVenu.Iyer@Sun.COM /* 2092*11878SVenu.Iyer@Sun.COM * Get the number of (effective-)rings from the resource property. 2093*11878SVenu.Iyer@Sun.COM */ 2094*11878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 2095*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 2096*11878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 2097*11878SVenu.Iyer@Sun.COM sizeof (mrp)); 2098*11878SVenu.Iyer@Sun.COM } else { 2099*11878SVenu.Iyer@Sun.COM /* 2100*11878SVenu.Iyer@Sun.COM * Get the permissions from the "txrings" property. 2101*11878SVenu.Iyer@Sun.COM */ 2102*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "txrings", 2103*11878SVenu.Iyer@Sun.COM flags, perm_flags, NULL, 0); 2104*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2105*11878SVenu.Iyer@Sun.COM return (status); 2106*11878SVenu.Iyer@Sun.COM 2107*11878SVenu.Iyer@Sun.COM /* 2108*11878SVenu.Iyer@Sun.COM * Get the number of rings from the "resource" property. 2109*11878SVenu.Iyer@Sun.COM */ 2110*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 2111*11878SVenu.Iyer@Sun.COM flags, NULL, &mrp, sizeof (mrp)); 2112*11878SVenu.Iyer@Sun.COM } 2113*11878SVenu.Iyer@Sun.COM 2114*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2115*11878SVenu.Iyer@Sun.COM return (status); 2116*11878SVenu.Iyer@Sun.COM 2117*11878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 2118*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 2119*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2120*11878SVenu.Iyer@Sun.COM } 2121*11878SVenu.Iyer@Sun.COM nrings = mrp.mrp_ntxrings; 2122*11878SVenu.Iyer@Sun.COM *val_cnt = 1; 2123*11878SVenu.Iyer@Sun.COM if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 2124*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 2125*11878SVenu.Iyer@Sun.COM else if (nrings == 0) 2126*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 2127*11878SVenu.Iyer@Sun.COM else 2128*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 2129*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2130*11878SVenu.Iyer@Sun.COM } 2131*11878SVenu.Iyer@Sun.COM 2132*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2133*11878SVenu.Iyer@Sun.COM dladm_status_t 2134*11878SVenu.Iyer@Sun.COM extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 2135*11878SVenu.Iyer@Sun.COM { 2136*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 2137*11878SVenu.Iyer@Sun.COM 2138*11878SVenu.Iyer@Sun.COM mrp->mrp_ntxrings = 0; 2139*11878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) 2140*11878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RINGS_RESET; 2141*11878SVenu.Iyer@Sun.COM else if (vdp->vd_val == UNSPEC_VAL) 2142*11878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 2143*11878SVenu.Iyer@Sun.COM else 2144*11878SVenu.Iyer@Sun.COM mrp->mrp_ntxrings = vdp->vd_val; 2145*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_TX_RINGS; 2146*11878SVenu.Iyer@Sun.COM 2147*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2148*11878SVenu.Iyer@Sun.COM } 2149*11878SVenu.Iyer@Sun.COM 2150*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2151*11878SVenu.Iyer@Sun.COM static dladm_status_t 2152*11878SVenu.Iyer@Sun.COM get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2153*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 2154*11878SVenu.Iyer@Sun.COM uint_t *perm_flags) 2155*11878SVenu.Iyer@Sun.COM { 2156*11878SVenu.Iyer@Sun.COM if (flags & DLD_PROP_DEFAULT) 2157*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTDEFINED); 2158*11878SVenu.Iyer@Sun.COM 2159*11878SVenu.Iyer@Sun.COM return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 2160*11878SVenu.Iyer@Sun.COM flags, perm_flags)); 2161*11878SVenu.Iyer@Sun.COM } 2162*11878SVenu.Iyer@Sun.COM 2163*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2164*11878SVenu.Iyer@Sun.COM static dladm_status_t 2165*11878SVenu.Iyer@Sun.COM set_resource(dladm_handle_t handle, prop_desc_t *pdp, 216610734SEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 216710734SEric Cheng uint_t flags, datalink_media_t media) 216810734SEric Cheng { 216910734SEric Cheng mac_resource_props_t mrp; 217010734SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 217110734SEric Cheng dld_ioc_macprop_t *dip; 2172*11878SVenu.Iyer@Sun.COM int i; 217310734SEric Cheng 217410734SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 2175*11878SVenu.Iyer@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 217610734SEric Cheng flags, &status); 217710734SEric Cheng 217810734SEric Cheng if (dip == NULL) 217910734SEric Cheng return (status); 218010734SEric Cheng 2181*11878SVenu.Iyer@Sun.COM for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 2182*11878SVenu.Iyer@Sun.COM resource_prop_t *rp = &rsrc_prop_table[i]; 2183*11878SVenu.Iyer@Sun.COM 2184*11878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, rp->rp_name) != 0) 2185*11878SVenu.Iyer@Sun.COM continue; 2186*11878SVenu.Iyer@Sun.COM 2187*11878SVenu.Iyer@Sun.COM status = rp->rp_extract(vdp, val_cnt, &mrp); 218810734SEric Cheng if (status != DLADM_STATUS_OK) 218910734SEric Cheng goto done; 219010734SEric Cheng 2191*11878SVenu.Iyer@Sun.COM break; 219210734SEric Cheng } 219310734SEric Cheng 219410734SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 219510734SEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 219610734SEric Cheng 219710734SEric Cheng done: 219810734SEric Cheng free(dip); 219910734SEric Cheng return (status); 220010734SEric Cheng } 220110734SEric Cheng 220210734SEric Cheng /* ARGSUSED */ 220310734SEric Cheng static dladm_status_t 2204*11878SVenu.Iyer@Sun.COM get_protection(dladm_handle_t handle, prop_desc_t *pdp, 220510734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 220610734SEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 220710734SEric Cheng { 2208*11878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 2209*11878SVenu.Iyer@Sun.COM mac_protect_t *p; 2210*11878SVenu.Iyer@Sun.COM dladm_status_t status; 2211*11878SVenu.Iyer@Sun.COM uint32_t i, cnt = 0, setbits[32]; 2212*11878SVenu.Iyer@Sun.COM 2213*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 2214*11878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 2215*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2216*11878SVenu.Iyer@Sun.COM return (status); 2217*11878SVenu.Iyer@Sun.COM 2218*11878SVenu.Iyer@Sun.COM p = &mrp.mrp_protect; 2219*11878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 2220*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 2221*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2222*11878SVenu.Iyer@Sun.COM } 2223*11878SVenu.Iyer@Sun.COM dladm_find_setbits32(p->mp_types, setbits, &cnt); 2224*11878SVenu.Iyer@Sun.COM if (cnt > *val_cnt) 2225*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 2226*11878SVenu.Iyer@Sun.COM 2227*11878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) 2228*11878SVenu.Iyer@Sun.COM (void) dladm_protect2str(setbits[i], prop_val[i]); 2229*11878SVenu.Iyer@Sun.COM 2230*11878SVenu.Iyer@Sun.COM *val_cnt = cnt; 2231*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2232*11878SVenu.Iyer@Sun.COM } 2233*11878SVenu.Iyer@Sun.COM 2234*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2235*11878SVenu.Iyer@Sun.COM static dladm_status_t 2236*11878SVenu.Iyer@Sun.COM get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2237*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2238*11878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 2239*11878SVenu.Iyer@Sun.COM { 224010734SEric Cheng mac_resource_props_t mrp; 224110734SEric Cheng mac_protect_t *p; 224210734SEric Cheng dladm_status_t status; 224310734SEric Cheng int i; 224410734SEric Cheng 2245*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 2246*11878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 2247*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 224810734SEric Cheng return (status); 224910734SEric Cheng 225010734SEric Cheng p = &mrp.mrp_protect; 2251*11878SVenu.Iyer@Sun.COM if (p->mp_ipaddrcnt == 0) { 2252*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 225310734SEric Cheng return (DLADM_STATUS_OK); 225410734SEric Cheng } 2255*11878SVenu.Iyer@Sun.COM if (p->mp_ipaddrcnt > *val_cnt) 2256*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 2257*11878SVenu.Iyer@Sun.COM 2258*11878SVenu.Iyer@Sun.COM for (i = 0; i < p->mp_ipaddrcnt; i++) { 2259*11878SVenu.Iyer@Sun.COM if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 2260*11878SVenu.Iyer@Sun.COM ipaddr_t v4addr; 2261*11878SVenu.Iyer@Sun.COM 2262*11878SVenu.Iyer@Sun.COM v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 2263*11878SVenu.Iyer@Sun.COM (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 2264*11878SVenu.Iyer@Sun.COM } else { 2265*11878SVenu.Iyer@Sun.COM (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 226610734SEric Cheng prop_val[i]); 226710734SEric Cheng } 226810734SEric Cheng } 2269*11878SVenu.Iyer@Sun.COM *val_cnt = p->mp_ipaddrcnt; 227010734SEric Cheng return (DLADM_STATUS_OK); 227110734SEric Cheng } 227210734SEric Cheng 227310734SEric Cheng dladm_status_t 2274*11878SVenu.Iyer@Sun.COM extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 227510734SEric Cheng { 227610734SEric Cheng mac_resource_props_t *mrp = arg; 227710734SEric Cheng uint32_t types = 0; 227810734SEric Cheng int i; 227910734SEric Cheng 228010734SEric Cheng for (i = 0; i < cnt; i++) 228110734SEric Cheng types |= (uint32_t)vdp[i].vd_val; 228210734SEric Cheng 228310734SEric Cheng mrp->mrp_protect.mp_types = types; 228410734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 228510734SEric Cheng return (DLADM_STATUS_OK); 228610734SEric Cheng } 228710734SEric Cheng 228810734SEric Cheng dladm_status_t 2289*11878SVenu.Iyer@Sun.COM extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 229010734SEric Cheng { 229110734SEric Cheng mac_resource_props_t *mrp = arg; 229210734SEric Cheng mac_protect_t *p = &mrp->mrp_protect; 229310734SEric Cheng int i; 229410734SEric Cheng 229510734SEric Cheng if (vdp->vd_val == 0) { 229610734SEric Cheng cnt = (uint_t)-1; 229710734SEric Cheng } else { 2298*11878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) { 2299*11878SVenu.Iyer@Sun.COM bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 2300*11878SVenu.Iyer@Sun.COM sizeof (mac_ipaddr_t)); 2301*11878SVenu.Iyer@Sun.COM } 230210734SEric Cheng } 230310734SEric Cheng p->mp_ipaddrcnt = cnt; 230410734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 230510734SEric Cheng return (DLADM_STATUS_OK); 230610734SEric Cheng } 230710734SEric Cheng 2308*11878SVenu.Iyer@Sun.COM static dladm_status_t 2309*11878SVenu.Iyer@Sun.COM check_single_ip(char *buf, mac_ipaddr_t *addr) 2310*11878SVenu.Iyer@Sun.COM { 2311*11878SVenu.Iyer@Sun.COM dladm_status_t status; 2312*11878SVenu.Iyer@Sun.COM ipaddr_t v4addr; 2313*11878SVenu.Iyer@Sun.COM in6_addr_t v6addr; 2314*11878SVenu.Iyer@Sun.COM boolean_t isv4 = B_TRUE; 2315*11878SVenu.Iyer@Sun.COM 2316*11878SVenu.Iyer@Sun.COM status = dladm_str2ipv4addr(buf, &v4addr); 2317*11878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_INVALID_IP) { 2318*11878SVenu.Iyer@Sun.COM status = dladm_str2ipv6addr(buf, &v6addr); 2319*11878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) 2320*11878SVenu.Iyer@Sun.COM isv4 = B_FALSE; 2321*11878SVenu.Iyer@Sun.COM } 2322*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2323*11878SVenu.Iyer@Sun.COM return (status); 2324*11878SVenu.Iyer@Sun.COM 2325*11878SVenu.Iyer@Sun.COM if (isv4) { 2326*11878SVenu.Iyer@Sun.COM if (v4addr == INADDR_ANY) 2327*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_INVALID_IP); 2328*11878SVenu.Iyer@Sun.COM 2329*11878SVenu.Iyer@Sun.COM IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 2330*11878SVenu.Iyer@Sun.COM addr->ip_version = IPV4_VERSION; 2331*11878SVenu.Iyer@Sun.COM } else { 2332*11878SVenu.Iyer@Sun.COM if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 2333*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_INVALID_IP); 2334*11878SVenu.Iyer@Sun.COM 2335*11878SVenu.Iyer@Sun.COM addr->ip_addr = v6addr; 2336*11878SVenu.Iyer@Sun.COM addr->ip_version = IPV6_VERSION; 2337*11878SVenu.Iyer@Sun.COM } 2338*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2339*11878SVenu.Iyer@Sun.COM } 2340*11878SVenu.Iyer@Sun.COM 234110734SEric Cheng /* ARGSUSED */ 234210734SEric Cheng static dladm_status_t 2343*11878SVenu.Iyer@Sun.COM check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2344*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 234510734SEric Cheng val_desc_t *vdp, datalink_media_t media) 234610734SEric Cheng { 234710734SEric Cheng dladm_status_t status; 2348*11878SVenu.Iyer@Sun.COM mac_ipaddr_t *addr; 234910734SEric Cheng int i; 235010734SEric Cheng 235110734SEric Cheng if (val_cnt > MPT_MAXIPADDR) 235210734SEric Cheng return (DLADM_STATUS_BADVALCNT); 235310734SEric Cheng 235410734SEric Cheng for (i = 0; i < val_cnt; i++) { 2355*11878SVenu.Iyer@Sun.COM if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 2356*11878SVenu.Iyer@Sun.COM status = DLADM_STATUS_NOMEM; 2357*11878SVenu.Iyer@Sun.COM goto fail; 2358*11878SVenu.Iyer@Sun.COM } 2359*11878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)addr; 2360*11878SVenu.Iyer@Sun.COM 2361*11878SVenu.Iyer@Sun.COM status = check_single_ip(prop_val[i], addr); 236210734SEric Cheng if (status != DLADM_STATUS_OK) 2363*11878SVenu.Iyer@Sun.COM goto fail; 2364*11878SVenu.Iyer@Sun.COM } 2365*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2366*11878SVenu.Iyer@Sun.COM 2367*11878SVenu.Iyer@Sun.COM fail: 2368*11878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 2369*11878SVenu.Iyer@Sun.COM free((void *)vdp[i].vd_val); 2370*11878SVenu.Iyer@Sun.COM vdp[i].vd_val = NULL; 2371*11878SVenu.Iyer@Sun.COM } 2372*11878SVenu.Iyer@Sun.COM return (status); 2373*11878SVenu.Iyer@Sun.COM } 2374*11878SVenu.Iyer@Sun.COM 2375*11878SVenu.Iyer@Sun.COM static void 2376*11878SVenu.Iyer@Sun.COM dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 2377*11878SVenu.Iyer@Sun.COM { 2378*11878SVenu.Iyer@Sun.COM char tmp_buf[DLADM_STRSIZE]; 2379*11878SVenu.Iyer@Sun.COM uint_t hexlen; 2380*11878SVenu.Iyer@Sun.COM 2381*11878SVenu.Iyer@Sun.COM switch (cid->dc_form) { 2382*11878SVenu.Iyer@Sun.COM case CIDFORM_TYPED: { 2383*11878SVenu.Iyer@Sun.COM uint16_t duidtype, hwtype; 2384*11878SVenu.Iyer@Sun.COM uint32_t timestamp, ennum; 2385*11878SVenu.Iyer@Sun.COM char *lladdr; 2386*11878SVenu.Iyer@Sun.COM 2387*11878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (duidtype)) 2388*11878SVenu.Iyer@Sun.COM goto fail; 2389*11878SVenu.Iyer@Sun.COM 2390*11878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 2391*11878SVenu.Iyer@Sun.COM duidtype = ntohs(duidtype); 2392*11878SVenu.Iyer@Sun.COM switch (duidtype) { 2393*11878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LLT: { 2394*11878SVenu.Iyer@Sun.COM duid_llt_t llt; 2395*11878SVenu.Iyer@Sun.COM 2396*11878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (llt)) 2397*11878SVenu.Iyer@Sun.COM goto fail; 2398*11878SVenu.Iyer@Sun.COM 2399*11878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &llt, sizeof (llt)); 2400*11878SVenu.Iyer@Sun.COM hwtype = ntohs(llt.dllt_hwtype); 2401*11878SVenu.Iyer@Sun.COM timestamp = ntohl(llt.dllt_time); 2402*11878SVenu.Iyer@Sun.COM lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 2403*11878SVenu.Iyer@Sun.COM NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 2404*11878SVenu.Iyer@Sun.COM if (lladdr == NULL) 2405*11878SVenu.Iyer@Sun.COM goto fail; 2406*11878SVenu.Iyer@Sun.COM 2407*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 2408*11878SVenu.Iyer@Sun.COM duidtype, hwtype, timestamp, lladdr); 2409*11878SVenu.Iyer@Sun.COM free(lladdr); 2410*11878SVenu.Iyer@Sun.COM break; 2411*11878SVenu.Iyer@Sun.COM } 2412*11878SVenu.Iyer@Sun.COM case DHCPV6_DUID_EN: { 2413*11878SVenu.Iyer@Sun.COM duid_en_t en; 2414*11878SVenu.Iyer@Sun.COM 2415*11878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (en)) 2416*11878SVenu.Iyer@Sun.COM goto fail; 2417*11878SVenu.Iyer@Sun.COM 2418*11878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &en, sizeof (en)); 2419*11878SVenu.Iyer@Sun.COM ennum = DHCPV6_GET_ENTNUM(&en); 2420*11878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 2421*11878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id + sizeof (en), 2422*11878SVenu.Iyer@Sun.COM cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 2423*11878SVenu.Iyer@Sun.COM goto fail; 2424*11878SVenu.Iyer@Sun.COM 2425*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 2426*11878SVenu.Iyer@Sun.COM duidtype, ennum, tmp_buf); 2427*11878SVenu.Iyer@Sun.COM break; 2428*11878SVenu.Iyer@Sun.COM } 2429*11878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LL: { 2430*11878SVenu.Iyer@Sun.COM duid_ll_t ll; 2431*11878SVenu.Iyer@Sun.COM 2432*11878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (ll)) 2433*11878SVenu.Iyer@Sun.COM goto fail; 2434*11878SVenu.Iyer@Sun.COM 2435*11878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &ll, sizeof (ll)); 2436*11878SVenu.Iyer@Sun.COM hwtype = ntohs(ll.dll_hwtype); 2437*11878SVenu.Iyer@Sun.COM lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 2438*11878SVenu.Iyer@Sun.COM NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 2439*11878SVenu.Iyer@Sun.COM if (lladdr == NULL) 2440*11878SVenu.Iyer@Sun.COM goto fail; 2441*11878SVenu.Iyer@Sun.COM 2442*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 2443*11878SVenu.Iyer@Sun.COM duidtype, hwtype, lladdr); 2444*11878SVenu.Iyer@Sun.COM free(lladdr); 2445*11878SVenu.Iyer@Sun.COM break; 2446*11878SVenu.Iyer@Sun.COM } 2447*11878SVenu.Iyer@Sun.COM default: { 2448*11878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 2449*11878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 2450*11878SVenu.Iyer@Sun.COM cid->dc_len - sizeof (duidtype), 2451*11878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 2452*11878SVenu.Iyer@Sun.COM goto fail; 2453*11878SVenu.Iyer@Sun.COM 2454*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 2455*11878SVenu.Iyer@Sun.COM duidtype, tmp_buf); 2456*11878SVenu.Iyer@Sun.COM } 2457*11878SVenu.Iyer@Sun.COM } 2458*11878SVenu.Iyer@Sun.COM break; 2459*11878SVenu.Iyer@Sun.COM } 2460*11878SVenu.Iyer@Sun.COM case CIDFORM_HEX: { 2461*11878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 2462*11878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id, cid->dc_len, 2463*11878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 2464*11878SVenu.Iyer@Sun.COM goto fail; 2465*11878SVenu.Iyer@Sun.COM 2466*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 2467*11878SVenu.Iyer@Sun.COM break; 2468*11878SVenu.Iyer@Sun.COM } 2469*11878SVenu.Iyer@Sun.COM case CIDFORM_STR: { 2470*11878SVenu.Iyer@Sun.COM int i; 2471*11878SVenu.Iyer@Sun.COM 2472*11878SVenu.Iyer@Sun.COM for (i = 0; i < cid->dc_len; i++) { 2473*11878SVenu.Iyer@Sun.COM if (!isprint(cid->dc_id[i])) 2474*11878SVenu.Iyer@Sun.COM goto fail; 2475*11878SVenu.Iyer@Sun.COM } 2476*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 2477*11878SVenu.Iyer@Sun.COM break; 2478*11878SVenu.Iyer@Sun.COM } 2479*11878SVenu.Iyer@Sun.COM default: 2480*11878SVenu.Iyer@Sun.COM goto fail; 248110734SEric Cheng } 2482*11878SVenu.Iyer@Sun.COM return; 2483*11878SVenu.Iyer@Sun.COM 2484*11878SVenu.Iyer@Sun.COM fail: 2485*11878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 2486*11878SVenu.Iyer@Sun.COM } 2487*11878SVenu.Iyer@Sun.COM 2488*11878SVenu.Iyer@Sun.COM static dladm_status_t 2489*11878SVenu.Iyer@Sun.COM dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 2490*11878SVenu.Iyer@Sun.COM { 2491*11878SVenu.Iyer@Sun.COM char *ptr = buf; 2492*11878SVenu.Iyer@Sun.COM char tmp_buf[DLADM_STRSIZE]; 2493*11878SVenu.Iyer@Sun.COM uint_t hexlen, cidlen; 2494*11878SVenu.Iyer@Sun.COM 2495*11878SVenu.Iyer@Sun.COM bzero(cid, sizeof (*cid)); 2496*11878SVenu.Iyer@Sun.COM if (isdigit(*ptr) && 2497*11878SVenu.Iyer@Sun.COM ptr[strspn(ptr, "0123456789")] == '.') { 2498*11878SVenu.Iyer@Sun.COM char *cp; 2499*11878SVenu.Iyer@Sun.COM ulong_t duidtype; 2500*11878SVenu.Iyer@Sun.COM ulong_t subtype; 2501*11878SVenu.Iyer@Sun.COM ulong_t timestamp; 2502*11878SVenu.Iyer@Sun.COM uchar_t *lladdr; 2503*11878SVenu.Iyer@Sun.COM int addrlen; 2504*11878SVenu.Iyer@Sun.COM 2505*11878SVenu.Iyer@Sun.COM errno = 0; 2506*11878SVenu.Iyer@Sun.COM duidtype = strtoul(ptr, &cp, 0); 2507*11878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.' || 2508*11878SVenu.Iyer@Sun.COM duidtype > USHRT_MAX) 2509*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2510*11878SVenu.Iyer@Sun.COM ptr = cp + 1; 2511*11878SVenu.Iyer@Sun.COM 2512*11878SVenu.Iyer@Sun.COM if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 2513*11878SVenu.Iyer@Sun.COM errno = 0; 2514*11878SVenu.Iyer@Sun.COM subtype = strtoul(ptr, &cp, 0); 2515*11878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.') 2516*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2517*11878SVenu.Iyer@Sun.COM ptr = cp + 1; 2518*11878SVenu.Iyer@Sun.COM } 2519*11878SVenu.Iyer@Sun.COM switch (duidtype) { 2520*11878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LLT: { 2521*11878SVenu.Iyer@Sun.COM duid_llt_t llt; 2522*11878SVenu.Iyer@Sun.COM 2523*11878SVenu.Iyer@Sun.COM errno = 0; 2524*11878SVenu.Iyer@Sun.COM timestamp = strtoul(ptr, &cp, 0); 2525*11878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.') 2526*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2527*11878SVenu.Iyer@Sun.COM 2528*11878SVenu.Iyer@Sun.COM ptr = cp + 1; 2529*11878SVenu.Iyer@Sun.COM lladdr = _link_aton(ptr, &addrlen); 2530*11878SVenu.Iyer@Sun.COM if (lladdr == NULL) 2531*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2532*11878SVenu.Iyer@Sun.COM 2533*11878SVenu.Iyer@Sun.COM cidlen = sizeof (llt) + addrlen; 2534*11878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) { 2535*11878SVenu.Iyer@Sun.COM free(lladdr); 2536*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 2537*11878SVenu.Iyer@Sun.COM } 2538*11878SVenu.Iyer@Sun.COM llt.dllt_dutype = htons(duidtype); 2539*11878SVenu.Iyer@Sun.COM llt.dllt_hwtype = htons(subtype); 2540*11878SVenu.Iyer@Sun.COM llt.dllt_time = htonl(timestamp); 2541*11878SVenu.Iyer@Sun.COM bcopy(&llt, cid->dc_id, sizeof (llt)); 2542*11878SVenu.Iyer@Sun.COM bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 2543*11878SVenu.Iyer@Sun.COM free(lladdr); 2544*11878SVenu.Iyer@Sun.COM break; 2545*11878SVenu.Iyer@Sun.COM } 2546*11878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LL: { 2547*11878SVenu.Iyer@Sun.COM duid_ll_t ll; 2548*11878SVenu.Iyer@Sun.COM 2549*11878SVenu.Iyer@Sun.COM lladdr = _link_aton(ptr, &addrlen); 2550*11878SVenu.Iyer@Sun.COM if (lladdr == NULL) 2551*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2552*11878SVenu.Iyer@Sun.COM 2553*11878SVenu.Iyer@Sun.COM cidlen = sizeof (ll) + addrlen; 2554*11878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) { 2555*11878SVenu.Iyer@Sun.COM free(lladdr); 2556*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 2557*11878SVenu.Iyer@Sun.COM } 2558*11878SVenu.Iyer@Sun.COM ll.dll_dutype = htons(duidtype); 2559*11878SVenu.Iyer@Sun.COM ll.dll_hwtype = htons(subtype); 2560*11878SVenu.Iyer@Sun.COM bcopy(&ll, cid->dc_id, sizeof (ll)); 2561*11878SVenu.Iyer@Sun.COM bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 2562*11878SVenu.Iyer@Sun.COM free(lladdr); 2563*11878SVenu.Iyer@Sun.COM break; 2564*11878SVenu.Iyer@Sun.COM } 2565*11878SVenu.Iyer@Sun.COM default: { 2566*11878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 2567*11878SVenu.Iyer@Sun.COM if (hexascii_to_octet(ptr, strlen(ptr), 2568*11878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 2569*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2570*11878SVenu.Iyer@Sun.COM 2571*11878SVenu.Iyer@Sun.COM if (duidtype == DHCPV6_DUID_EN) { 2572*11878SVenu.Iyer@Sun.COM duid_en_t en; 2573*11878SVenu.Iyer@Sun.COM 2574*11878SVenu.Iyer@Sun.COM en.den_dutype = htons(duidtype); 2575*11878SVenu.Iyer@Sun.COM DHCPV6_SET_ENTNUM(&en, subtype); 2576*11878SVenu.Iyer@Sun.COM 2577*11878SVenu.Iyer@Sun.COM cidlen = sizeof (en) + hexlen; 2578*11878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 2579*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 2580*11878SVenu.Iyer@Sun.COM 2581*11878SVenu.Iyer@Sun.COM bcopy(&en, cid->dc_id, sizeof (en)); 2582*11878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id + sizeof (en), 2583*11878SVenu.Iyer@Sun.COM hexlen); 2584*11878SVenu.Iyer@Sun.COM } else { 2585*11878SVenu.Iyer@Sun.COM uint16_t dutype = htons(duidtype); 2586*11878SVenu.Iyer@Sun.COM 2587*11878SVenu.Iyer@Sun.COM cidlen = sizeof (dutype) + hexlen; 2588*11878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 2589*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 2590*11878SVenu.Iyer@Sun.COM 2591*11878SVenu.Iyer@Sun.COM bcopy(&dutype, cid->dc_id, sizeof (dutype)); 2592*11878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 2593*11878SVenu.Iyer@Sun.COM hexlen); 2594*11878SVenu.Iyer@Sun.COM } 2595*11878SVenu.Iyer@Sun.COM break; 2596*11878SVenu.Iyer@Sun.COM } 2597*11878SVenu.Iyer@Sun.COM } 2598*11878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_TYPED; 2599*11878SVenu.Iyer@Sun.COM } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 2600*11878SVenu.Iyer@Sun.COM ptr += 2; 2601*11878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 2602*11878SVenu.Iyer@Sun.COM if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 2603*11878SVenu.Iyer@Sun.COM &hexlen) != 0) { 2604*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 2605*11878SVenu.Iyer@Sun.COM } 2606*11878SVenu.Iyer@Sun.COM cidlen = hexlen; 2607*11878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 2608*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 2609*11878SVenu.Iyer@Sun.COM 2610*11878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id, cidlen); 2611*11878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_HEX; 2612*11878SVenu.Iyer@Sun.COM } else { 2613*11878SVenu.Iyer@Sun.COM cidlen = strlen(ptr); 2614*11878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 2615*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 2616*11878SVenu.Iyer@Sun.COM 2617*11878SVenu.Iyer@Sun.COM bcopy(ptr, cid->dc_id, cidlen); 2618*11878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_STR; 2619*11878SVenu.Iyer@Sun.COM } 2620*11878SVenu.Iyer@Sun.COM cid->dc_len = cidlen; 262110734SEric Cheng return (DLADM_STATUS_OK); 262210734SEric Cheng } 262310734SEric Cheng 262410734SEric Cheng /* ARGSUSED */ 262510734SEric Cheng static dladm_status_t 2626*11878SVenu.Iyer@Sun.COM get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2627*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2628*11878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 2629*11878SVenu.Iyer@Sun.COM { 2630*11878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 2631*11878SVenu.Iyer@Sun.COM mac_protect_t *p; 2632*11878SVenu.Iyer@Sun.COM dladm_status_t status; 2633*11878SVenu.Iyer@Sun.COM int i; 2634*11878SVenu.Iyer@Sun.COM 2635*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 2636*11878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 2637*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2638*11878SVenu.Iyer@Sun.COM return (status); 2639*11878SVenu.Iyer@Sun.COM 2640*11878SVenu.Iyer@Sun.COM p = &mrp.mrp_protect; 2641*11878SVenu.Iyer@Sun.COM if (p->mp_cidcnt == 0) { 2642*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 2643*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2644*11878SVenu.Iyer@Sun.COM } 2645*11878SVenu.Iyer@Sun.COM if (p->mp_cidcnt > *val_cnt) 2646*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 2647*11878SVenu.Iyer@Sun.COM 2648*11878SVenu.Iyer@Sun.COM for (i = 0; i < p->mp_cidcnt; i++) { 2649*11878SVenu.Iyer@Sun.COM mac_dhcpcid_t *cid = &p->mp_cids[i]; 2650*11878SVenu.Iyer@Sun.COM 2651*11878SVenu.Iyer@Sun.COM dladm_cid2str(cid, prop_val[i]); 2652*11878SVenu.Iyer@Sun.COM } 2653*11878SVenu.Iyer@Sun.COM *val_cnt = p->mp_cidcnt; 2654*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2655*11878SVenu.Iyer@Sun.COM } 2656*11878SVenu.Iyer@Sun.COM 2657*11878SVenu.Iyer@Sun.COM dladm_status_t 2658*11878SVenu.Iyer@Sun.COM extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 2659*11878SVenu.Iyer@Sun.COM { 2660*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 2661*11878SVenu.Iyer@Sun.COM mac_protect_t *p = &mrp->mrp_protect; 2662*11878SVenu.Iyer@Sun.COM int i; 2663*11878SVenu.Iyer@Sun.COM 2664*11878SVenu.Iyer@Sun.COM if (vdp->vd_val == 0) { 2665*11878SVenu.Iyer@Sun.COM cnt = (uint_t)-1; 2666*11878SVenu.Iyer@Sun.COM } else { 2667*11878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) { 2668*11878SVenu.Iyer@Sun.COM bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 2669*11878SVenu.Iyer@Sun.COM sizeof (mac_dhcpcid_t)); 2670*11878SVenu.Iyer@Sun.COM } 2671*11878SVenu.Iyer@Sun.COM } 2672*11878SVenu.Iyer@Sun.COM p->mp_cidcnt = cnt; 2673*11878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_PROTECT; 2674*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2675*11878SVenu.Iyer@Sun.COM } 2676*11878SVenu.Iyer@Sun.COM 2677*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2678*11878SVenu.Iyer@Sun.COM static dladm_status_t 2679*11878SVenu.Iyer@Sun.COM check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2680*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, 2681*11878SVenu.Iyer@Sun.COM uint_t flags, val_desc_t *vdp, datalink_media_t media) 2682*11878SVenu.Iyer@Sun.COM { 2683*11878SVenu.Iyer@Sun.COM dladm_status_t status; 2684*11878SVenu.Iyer@Sun.COM mac_dhcpcid_t *cid; 2685*11878SVenu.Iyer@Sun.COM int i; 2686*11878SVenu.Iyer@Sun.COM 2687*11878SVenu.Iyer@Sun.COM if (val_cnt > MPT_MAXCID) 2688*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 2689*11878SVenu.Iyer@Sun.COM 2690*11878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 2691*11878SVenu.Iyer@Sun.COM if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 2692*11878SVenu.Iyer@Sun.COM status = DLADM_STATUS_NOMEM; 2693*11878SVenu.Iyer@Sun.COM goto fail; 2694*11878SVenu.Iyer@Sun.COM } 2695*11878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)cid; 2696*11878SVenu.Iyer@Sun.COM 2697*11878SVenu.Iyer@Sun.COM status = dladm_str2cid(prop_val[i], cid); 2698*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2699*11878SVenu.Iyer@Sun.COM goto fail; 2700*11878SVenu.Iyer@Sun.COM } 2701*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 2702*11878SVenu.Iyer@Sun.COM 2703*11878SVenu.Iyer@Sun.COM fail: 2704*11878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 2705*11878SVenu.Iyer@Sun.COM free((void *)vdp[i].vd_val); 2706*11878SVenu.Iyer@Sun.COM vdp[i].vd_val = NULL; 2707*11878SVenu.Iyer@Sun.COM } 2708*11878SVenu.Iyer@Sun.COM return (status); 2709*11878SVenu.Iyer@Sun.COM } 2710*11878SVenu.Iyer@Sun.COM 2711*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 2712*11878SVenu.Iyer@Sun.COM static dladm_status_t 2713*11878SVenu.Iyer@Sun.COM get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 27148275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 27158275SEric Cheng uint_t flags, uint_t *perm_flags) 27165895Syz147064 { 27177342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 27187342SAruna.Ramakrishna@Sun.COM int i, len; 27197342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 2720*11878SVenu.Iyer@Sun.COM 2721*11878SVenu.Iyer@Sun.COM if (flags & DLD_PROP_DEFAULT) 27227776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 27236512Ssowmini 2724*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 2725*11878SVenu.Iyer@Sun.COM perm_flags, &dlap, sizeof (dlap)); 2726*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 2727*11878SVenu.Iyer@Sun.COM return (status); 2728*11878SVenu.Iyer@Sun.COM 2729*11878SVenu.Iyer@Sun.COM if (dlap.dap_npush == 0) { 2730*11878SVenu.Iyer@Sun.COM *val_cnt = 0; 27318275SEric Cheng return (DLADM_STATUS_OK); 27325895Syz147064 } 27337342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 27345895Syz147064 if (i != 0) { 27355895Syz147064 (void) snprintf(*prop_val + len, 27365895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 27375895Syz147064 len += 1; 27385895Syz147064 } 27395895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 27407342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 27417342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 27427342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 27435895Syz147064 (void) snprintf(*prop_val + len, 27445895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 27455895Syz147064 AP_ANCHOR); 27465895Syz147064 len += (strlen(AP_ANCHOR) + 1); 27475895Syz147064 } 27485895Syz147064 } 2749*11878SVenu.Iyer@Sun.COM *val_cnt = 1; 27505895Syz147064 return (DLADM_STATUS_OK); 27515895Syz147064 } 27525895Syz147064 27535895Syz147064 /* 27545895Syz147064 * Add the specified module to the dlautopush structure; returns a 27555895Syz147064 * DLADM_STATUS_* code. 27565895Syz147064 */ 27575895Syz147064 dladm_status_t 27585895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 27595895Syz147064 { 27605895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 27615895Syz147064 return (DLADM_STATUS_BADVAL); 27625895Syz147064 27635895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 27645895Syz147064 /* 27655895Syz147064 * We don't allow multiple anchors, and the anchor must 27665895Syz147064 * be after at least one module. 27675895Syz147064 */ 27685895Syz147064 if (dlap->dap_anchor != 0) 27695895Syz147064 return (DLADM_STATUS_BADVAL); 27705895Syz147064 if (dlap->dap_npush == 0) 27715895Syz147064 return (DLADM_STATUS_BADVAL); 27725895Syz147064 27735895Syz147064 dlap->dap_anchor = dlap->dap_npush; 27745895Syz147064 return (DLADM_STATUS_OK); 27755895Syz147064 } 27768957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 27775895Syz147064 return (DLADM_STATUS_BADVALCNT); 27785895Syz147064 27795895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 27805895Syz147064 FMNAMESZ + 1); 27815895Syz147064 27825895Syz147064 return (DLADM_STATUS_OK); 27835895Syz147064 } 27845895Syz147064 27855895Syz147064 /* 27865895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 27875895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 27885895Syz147064 * latter is used in the autopush(1M) file. 27895895Syz147064 */ 27905895Syz147064 /* ARGSUSED */ 27915895Syz147064 static dladm_status_t 2792*11878SVenu.Iyer@Sun.COM check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2793*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 2794*11878SVenu.Iyer@Sun.COM datalink_media_t media) 27955895Syz147064 { 27965895Syz147064 char *module; 27975895Syz147064 struct dlautopush *dlap; 27985895Syz147064 dladm_status_t status; 27995895Syz147064 char val[DLADM_PROP_VAL_MAX]; 28005895Syz147064 char delimiters[4]; 28015895Syz147064 28025895Syz147064 if (val_cnt != 1) 28035895Syz147064 return (DLADM_STATUS_BADVALCNT); 28045895Syz147064 28057342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 28067342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 28077342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 28087342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 28093448Sdh155122 28107342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 28117342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 28127342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 28137342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 28147342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 28157342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 28167342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 28177342SAruna.Ramakrishna@Sun.COM return (status); 28187342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 28197342SAruna.Ramakrishna@Sun.COM } 28207342SAruna.Ramakrishna@Sun.COM 28217342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 28227342SAruna.Ramakrishna@Sun.COM } else { 28237342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 28245895Syz147064 } 28253448Sdh155122 return (DLADM_STATUS_OK); 28263448Sdh155122 } 28273448Sdh155122 28287663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 28297663SSowmini.Varadhan@Sun.COM 28305903Ssowmini /* ARGSUSED */ 28313448Sdh155122 static dladm_status_t 2832*11878SVenu.Iyer@Sun.COM get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 28338453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 28348453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 28353448Sdh155122 { 28365895Syz147064 wl_rates_t *wrp; 28375895Syz147064 uint_t i; 28385895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 28395895Syz147064 28407663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 28417663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 28427663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 28435895Syz147064 28448453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 28458453SAnurag.Maskey@Sun.COM B_FALSE); 28465895Syz147064 if (status != DLADM_STATUS_OK) 28475895Syz147064 goto done; 28485895Syz147064 28495895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 28505895Syz147064 status = DLADM_STATUS_TOOSMALL; 28515895Syz147064 goto done; 28525895Syz147064 } 28535895Syz147064 28545895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 28555895Syz147064 prop_val[0][0] = '\0'; 28565895Syz147064 *val_cnt = 1; 28575895Syz147064 goto done; 28585895Syz147064 } 28595895Syz147064 28605895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 28615895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 28625895Syz147064 wrp->wl_rates_rates[i] % 2, 28635895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 28645895Syz147064 } 28655895Syz147064 *val_cnt = wrp->wl_rates_num; 28668275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 28673448Sdh155122 28685895Syz147064 done: 28697663SSowmini.Varadhan@Sun.COM free(wrp); 28705895Syz147064 return (status); 28715895Syz147064 } 28725895Syz147064 28735895Syz147064 static dladm_status_t 2874*11878SVenu.Iyer@Sun.COM get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 28758275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 28768275SEric Cheng uint_t flags, uint_t *perm_flags) 28775895Syz147064 { 28788118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 2879*11878SVenu.Iyer@Sun.COM return (get_speed(handle, pdp, linkid, prop_val, 2880*11878SVenu.Iyer@Sun.COM val_cnt, media, flags, perm_flags)); 28818118SVasumathi.Sundaram@Sun.COM } 28825960Ssowmini 2883*11878SVenu.Iyer@Sun.COM return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 28848275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 28855895Syz147064 } 28865895Syz147064 28876512Ssowmini /* ARGSUSED */ 28885895Syz147064 static dladm_status_t 2889*11878SVenu.Iyer@Sun.COM get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 28908275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 28918275SEric Cheng uint_t flags, uint_t *perm_flags) 28925895Syz147064 { 28935960Ssowmini switch (media) { 28945960Ssowmini case DL_ETHER: 28956512Ssowmini /* 28966512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 28976512Ssowmini * links can have a speed of 5.5 Gbps. 28986512Ssowmini */ 28996512Ssowmini return (DLADM_STATUS_NOTSUP); 29005960Ssowmini 29015960Ssowmini case DL_WIFI: 2902*11878SVenu.Iyer@Sun.COM return (get_rate_common(handle, pdp, linkid, prop_val, 29038453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 29045960Ssowmini default: 29055960Ssowmini return (DLADM_STATUS_BADARG); 29065960Ssowmini } 29075895Syz147064 } 29085895Syz147064 29095895Syz147064 static dladm_status_t 2910*11878SVenu.Iyer@Sun.COM set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 29118453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 29125895Syz147064 { 29135895Syz147064 int i; 29145895Syz147064 uint_t len; 29155895Syz147064 wl_rates_t *wrp; 29165895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 29175895Syz147064 29187663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 29197663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 29205895Syz147064 return (DLADM_STATUS_NOMEM); 29215895Syz147064 29227663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 29235895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 29245895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 29255895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 29265895Syz147064 29275895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 29285895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 29298453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 29308453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 29315895Syz147064 29327663SSowmini.Varadhan@Sun.COM free(wrp); 29335895Syz147064 return (status); 29345895Syz147064 } 29353448Sdh155122 29365903Ssowmini /* ARGSUSED */ 29375895Syz147064 static dladm_status_t 2938*11878SVenu.Iyer@Sun.COM set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 29395960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 29405895Syz147064 { 29415895Syz147064 dladm_wlan_rates_t rates; 29425895Syz147064 dladm_status_t status; 29435895Syz147064 29445960Ssowmini /* 29455960Ssowmini * can currently set rate on WIFI links only. 29465960Ssowmini */ 29475960Ssowmini if (media != DL_WIFI) 29485960Ssowmini return (DLADM_STATUS_PROPRDONLY); 29495960Ssowmini 29505895Syz147064 if (val_cnt != 1) 29515895Syz147064 return (DLADM_STATUS_BADVALCNT); 29525895Syz147064 29535895Syz147064 rates.wr_cnt = 1; 29545895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 29555895Syz147064 2956*11878SVenu.Iyer@Sun.COM status = set_wlan_rate(handle, linkid, &rates); 2957*11878SVenu.Iyer@Sun.COM 29585895Syz147064 return (status); 29595895Syz147064 } 29603448Sdh155122 29615895Syz147064 /* ARGSUSED */ 29625895Syz147064 static dladm_status_t 2963*11878SVenu.Iyer@Sun.COM check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2964*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 2965*11878SVenu.Iyer@Sun.COM datalink_media_t media) 29665895Syz147064 { 29675895Syz147064 int i; 29685895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 29695895Syz147064 char *buf, **modval; 29705895Syz147064 dladm_status_t status; 29718118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 29725895Syz147064 29735895Syz147064 if (val_cnt != 1) 29745895Syz147064 return (DLADM_STATUS_BADVALCNT); 29755895Syz147064 29765895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 29775895Syz147064 MAX_SUPPORT_RATES); 29785895Syz147064 if (buf == NULL) { 29795895Syz147064 status = DLADM_STATUS_NOMEM; 29805895Syz147064 goto done; 29815895Syz147064 } 29823448Sdh155122 29835895Syz147064 modval = (char **)(void *)buf; 29845895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 29855895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 29865895Syz147064 i * DLADM_STRSIZE; 29875895Syz147064 } 29885895Syz147064 2989*11878SVenu.Iyer@Sun.COM status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 29908453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 29915895Syz147064 if (status != DLADM_STATUS_OK) 29925895Syz147064 goto done; 29935895Syz147064 29945895Syz147064 for (i = 0; i < modval_cnt; i++) { 29955895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 29965903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 29975903Ssowmini (atof(*prop_val) * 2); 29985895Syz147064 status = DLADM_STATUS_OK; 29993448Sdh155122 break; 30003448Sdh155122 } 30015895Syz147064 } 30025895Syz147064 if (i == modval_cnt) 30035895Syz147064 status = DLADM_STATUS_BADVAL; 30045895Syz147064 done: 30055895Syz147064 free(buf); 30065895Syz147064 return (status); 30075895Syz147064 } 30085895Syz147064 30095895Syz147064 static dladm_status_t 3010*11878SVenu.Iyer@Sun.COM get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 30118453SAnurag.Maskey@Sun.COM int buflen) 30125895Syz147064 { 30138453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 30147663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 30155895Syz147064 } 30165895Syz147064 30175903Ssowmini /* ARGSUSED */ 30185895Syz147064 static dladm_status_t 3019*11878SVenu.Iyer@Sun.COM get_channel(dladm_handle_t handle, prop_desc_t *pdp, 30208453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30218453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30225895Syz147064 { 30235895Syz147064 uint32_t channel; 30247663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 3025*11878SVenu.Iyer@Sun.COM dladm_status_t status; 30267663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 30275895Syz147064 3028*11878SVenu.Iyer@Sun.COM if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 30297663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 3030*11878SVenu.Iyer@Sun.COM return (status); 30315895Syz147064 30327663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 3033*11878SVenu.Iyer@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 3034*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 30355895Syz147064 30365895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 30375895Syz147064 *val_cnt = 1; 30388275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 3039*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 30405895Syz147064 } 30415895Syz147064 30425903Ssowmini /* ARGSUSED */ 30435895Syz147064 static dladm_status_t 3044*11878SVenu.Iyer@Sun.COM get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 30458453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30468453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30475895Syz147064 { 30487663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 30495895Syz147064 const char *s; 30507663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 3051*11878SVenu.Iyer@Sun.COM dladm_status_t status; 3052*11878SVenu.Iyer@Sun.COM 3053*11878SVenu.Iyer@Sun.COM if ((status = i_dladm_wlan_param(handle, linkid, buf, 3054*11878SVenu.Iyer@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 3055*11878SVenu.Iyer@Sun.COM return (status); 30565895Syz147064 30577663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 30587663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 30595895Syz147064 case WL_PM_AM: 30605895Syz147064 s = "off"; 30615895Syz147064 break; 30625895Syz147064 case WL_PM_MPS: 30635895Syz147064 s = "max"; 30645895Syz147064 break; 30655895Syz147064 case WL_PM_FAST: 30665895Syz147064 s = "fast"; 30673448Sdh155122 break; 30683448Sdh155122 default: 3069*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 30705895Syz147064 } 30715895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 30725895Syz147064 *val_cnt = 1; 30738275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 3074*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 30755895Syz147064 } 30765895Syz147064 3077*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 30785895Syz147064 static dladm_status_t 3079*11878SVenu.Iyer@Sun.COM set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 3080*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 3081*11878SVenu.Iyer@Sun.COM datalink_media_t media) 30825895Syz147064 { 3083*11878SVenu.Iyer@Sun.COM dladm_wlan_powermode_t powermode = vdp->vd_val; 3084*11878SVenu.Iyer@Sun.COM wl_ps_mode_t ps_mode; 3085*11878SVenu.Iyer@Sun.COM 3086*11878SVenu.Iyer@Sun.COM if (val_cnt != 1) 3087*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 30885895Syz147064 30895895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 30905895Syz147064 3091*11878SVenu.Iyer@Sun.COM switch (powermode) { 30925895Syz147064 case DLADM_WLAN_PM_OFF: 30935895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 30943448Sdh155122 break; 30955895Syz147064 case DLADM_WLAN_PM_MAX: 30965895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 30975895Syz147064 break; 30985895Syz147064 case DLADM_WLAN_PM_FAST: 30995895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 31005895Syz147064 break; 31015895Syz147064 default: 31025895Syz147064 return (DLADM_STATUS_NOTSUP); 31033448Sdh155122 } 31048453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 31058453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 31065895Syz147064 } 31075895Syz147064 31085895Syz147064 /* ARGSUSED */ 31095895Syz147064 static dladm_status_t 3110*11878SVenu.Iyer@Sun.COM get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 31118275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 31128275SEric Cheng uint_t flags, uint_t *perm_flags) 31135895Syz147064 { 31145895Syz147064 wl_radio_t radio; 31155895Syz147064 const char *s; 31167663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 3117*11878SVenu.Iyer@Sun.COM dladm_status_t status; 3118*11878SVenu.Iyer@Sun.COM 3119*11878SVenu.Iyer@Sun.COM if ((status = i_dladm_wlan_param(handle, linkid, buf, 3120*11878SVenu.Iyer@Sun.COM MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 3121*11878SVenu.Iyer@Sun.COM return (status); 31223448Sdh155122 31237663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 31245895Syz147064 switch (radio) { 31255895Syz147064 case B_TRUE: 31265895Syz147064 s = "on"; 31275895Syz147064 break; 31285895Syz147064 case B_FALSE: 31295895Syz147064 s = "off"; 31305895Syz147064 break; 31315895Syz147064 default: 3132*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 31335895Syz147064 } 31345895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 31355895Syz147064 *val_cnt = 1; 31368275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 3137*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 31383448Sdh155122 } 31393448Sdh155122 3140*11878SVenu.Iyer@Sun.COM /* ARGSUSED */ 31413448Sdh155122 static dladm_status_t 3142*11878SVenu.Iyer@Sun.COM set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3143*11878SVenu.Iyer@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 31443448Sdh155122 { 3145*11878SVenu.Iyer@Sun.COM dladm_wlan_radio_t radio = vdp->vd_val; 3146*11878SVenu.Iyer@Sun.COM wl_radio_t r; 3147*11878SVenu.Iyer@Sun.COM 3148*11878SVenu.Iyer@Sun.COM if (val_cnt != 1) 3149*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 3150*11878SVenu.Iyer@Sun.COM 3151*11878SVenu.Iyer@Sun.COM switch (radio) { 31525895Syz147064 case DLADM_WLAN_RADIO_ON: 31535895Syz147064 r = B_TRUE; 31545895Syz147064 break; 31555895Syz147064 case DLADM_WLAN_RADIO_OFF: 31565895Syz147064 r = B_FALSE; 31575895Syz147064 break; 31585895Syz147064 default: 31595895Syz147064 return (DLADM_STATUS_NOTSUP); 31605895Syz147064 } 31618453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 31627663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 31635895Syz147064 } 31643448Sdh155122 31655895Syz147064 /* ARGSUSED */ 31665895Syz147064 static dladm_status_t 3167*11878SVenu.Iyer@Sun.COM check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 3168*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 3169*11878SVenu.Iyer@Sun.COM val_desc_t *vdp, datalink_media_t media) 317010616SSebastien.Roy@Sun.COM { 317110616SSebastien.Roy@Sun.COM int32_t hlim; 317210616SSebastien.Roy@Sun.COM char *ep; 317310616SSebastien.Roy@Sun.COM 317410616SSebastien.Roy@Sun.COM if (val_cnt != 1) 317510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 317610616SSebastien.Roy@Sun.COM 317710616SSebastien.Roy@Sun.COM errno = 0; 317810616SSebastien.Roy@Sun.COM hlim = strtol(*prop_val, &ep, 10); 317910616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || hlim < 1 || 318010616SSebastien.Roy@Sun.COM hlim > (int32_t)UINT8_MAX) 318110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 318210616SSebastien.Roy@Sun.COM vdp->vd_val = hlim; 318310616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 318410616SSebastien.Roy@Sun.COM } 318510616SSebastien.Roy@Sun.COM 318610616SSebastien.Roy@Sun.COM /* ARGSUSED */ 318710616SSebastien.Roy@Sun.COM static dladm_status_t 3188*11878SVenu.Iyer@Sun.COM check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3189*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 3190*11878SVenu.Iyer@Sun.COM datalink_media_t media) 319110616SSebastien.Roy@Sun.COM { 319210616SSebastien.Roy@Sun.COM int32_t elim; 319310616SSebastien.Roy@Sun.COM char *ep; 319410616SSebastien.Roy@Sun.COM 319510616SSebastien.Roy@Sun.COM if (media != DL_IPV6) 319610616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG); 319710616SSebastien.Roy@Sun.COM 319810616SSebastien.Roy@Sun.COM if (val_cnt != 1) 319910616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 320010616SSebastien.Roy@Sun.COM 320110616SSebastien.Roy@Sun.COM errno = 0; 320210616SSebastien.Roy@Sun.COM elim = strtol(*prop_val, &ep, 10); 320310616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || elim < 0 || 320410616SSebastien.Roy@Sun.COM elim > (int32_t)UINT8_MAX) 320510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 320610616SSebastien.Roy@Sun.COM vdp->vd_val = elim; 320710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 320810616SSebastien.Roy@Sun.COM } 320910616SSebastien.Roy@Sun.COM 32105895Syz147064 static dladm_status_t 32118453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 32128453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 32133448Sdh155122 { 32145895Syz147064 char buf[MAXLINELEN]; 32155895Syz147064 int i; 32165895Syz147064 dladm_conf_t conf; 32175895Syz147064 dladm_status_t status; 32183448Sdh155122 32198453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 32205895Syz147064 if (status != DLADM_STATUS_OK) 32215895Syz147064 return (status); 32223448Sdh155122 32235895Syz147064 /* 32245895Syz147064 * reset case. 32255895Syz147064 */ 32265895Syz147064 if (val_cnt == 0) { 32278453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 32285895Syz147064 if (status == DLADM_STATUS_OK) 32298453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 32305895Syz147064 goto done; 32315895Syz147064 } 32323448Sdh155122 32335895Syz147064 buf[0] = '\0'; 32345895Syz147064 for (i = 0; i < val_cnt; i++) { 32355895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 32365895Syz147064 if (i != val_cnt - 1) 32375895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 32383448Sdh155122 } 32393448Sdh155122 32408453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 32418453SAnurag.Maskey@Sun.COM buf); 32425895Syz147064 if (status == DLADM_STATUS_OK) 32438453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 32445895Syz147064 32455895Syz147064 done: 32468453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 32475895Syz147064 return (status); 32483448Sdh155122 } 32495895Syz147064 32505895Syz147064 static dladm_status_t 32518453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 32528453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 32535895Syz147064 { 32545895Syz147064 char buf[MAXLINELEN], *str; 32555895Syz147064 uint_t cnt = 0; 32565895Syz147064 dladm_conf_t conf; 32575895Syz147064 dladm_status_t status; 32585895Syz147064 32598453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 32605895Syz147064 if (status != DLADM_STATUS_OK) 32615895Syz147064 return (status); 32625895Syz147064 32638453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 32645895Syz147064 if (status != DLADM_STATUS_OK) 32655895Syz147064 goto done; 32665895Syz147064 32675895Syz147064 str = strtok(buf, ","); 32685895Syz147064 while (str != NULL) { 32695895Syz147064 if (cnt == *val_cntp) { 32705895Syz147064 status = DLADM_STATUS_TOOSMALL; 32715895Syz147064 goto done; 32725895Syz147064 } 32735895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 32745895Syz147064 str = strtok(NULL, ","); 32755895Syz147064 } 32765895Syz147064 32775895Syz147064 *val_cntp = cnt; 32785895Syz147064 32795895Syz147064 done: 32808453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 32815895Syz147064 return (status); 32825895Syz147064 } 32835903Ssowmini 32848460SArtem.Kachitchkin@Sun.COM /* 32858460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 32868460SArtem.Kachitchkin@Sun.COM */ 32878460SArtem.Kachitchkin@Sun.COM static dladm_status_t 32888460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 32898460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 32908460SArtem.Kachitchkin@Sun.COM { 32918460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 32928460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 32938460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 32948460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 32958460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 32968460SArtem.Kachitchkin@Sun.COM size_t attrsz; 32978460SArtem.Kachitchkin@Sun.COM 32988460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 32998460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 33008460SArtem.Kachitchkin@Sun.COM 33018460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 33028460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 33038460SArtem.Kachitchkin@Sun.COM return (status); 33048460SArtem.Kachitchkin@Sun.COM 33058460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 33068460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 33078460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 33088460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 33098460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 33108460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 33118460SArtem.Kachitchkin@Sun.COM break; 33128460SArtem.Kachitchkin@Sun.COM } 33138460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 33148460SArtem.Kachitchkin@Sun.COM } 33158460SArtem.Kachitchkin@Sun.COM 33168460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 33178460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 33188460SArtem.Kachitchkin@Sun.COM } 33198460SArtem.Kachitchkin@Sun.COM 33207663SSowmini.Varadhan@Sun.COM static link_attr_t * 33215903Ssowmini dladm_name2prop(const char *prop_name) 33225903Ssowmini { 33237663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33245903Ssowmini 33257663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 33265903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 33275903Ssowmini break; 33285903Ssowmini } 33295903Ssowmini return (p); 33305903Ssowmini } 33315903Ssowmini 33327663SSowmini.Varadhan@Sun.COM static link_attr_t * 33337663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 33347663SSowmini.Varadhan@Sun.COM { 33357663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33367663SSowmini.Varadhan@Sun.COM 33377663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 33387663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 33397663SSowmini.Varadhan@Sun.COM break; 33407663SSowmini.Varadhan@Sun.COM } 33417663SSowmini.Varadhan@Sun.COM return (p); 33427663SSowmini.Varadhan@Sun.COM } 33435903Ssowmini 33446789Sam223141 static dld_ioc_macprop_t * 33457663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 33467663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 33477663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 33485903Ssowmini { 33495903Ssowmini int dsize; 33506789Sam223141 dld_ioc_macprop_t *dip; 33515903Ssowmini 33525903Ssowmini *status = DLADM_STATUS_OK; 33536789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 33545903Ssowmini dip = malloc(dsize); 33555903Ssowmini if (dip == NULL) { 33565903Ssowmini *status = DLADM_STATUS_NOMEM; 33575903Ssowmini return (NULL); 33585903Ssowmini } 33595903Ssowmini bzero(dip, dsize); 33605903Ssowmini dip->pr_valsize = valsize; 33616512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 33625960Ssowmini dip->pr_linkid = linkid; 33637663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 33646512Ssowmini dip->pr_flags = flags; 33655903Ssowmini return (dip); 33665903Ssowmini } 33675903Ssowmini 33687663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 33697663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 33707663SSowmini.Varadhan@Sun.COM const char *prop_name, uint_t flags, dladm_status_t *status) 33717663SSowmini.Varadhan@Sun.COM { 33727663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33737663SSowmini.Varadhan@Sun.COM 33747663SSowmini.Varadhan@Sun.COM p = dladm_name2prop(prop_name); 33757663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 33767663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 33777663SSowmini.Varadhan@Sun.COM flags, status)); 33787663SSowmini.Varadhan@Sun.COM } 33797663SSowmini.Varadhan@Sun.COM 33807663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 33817663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 33827663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 33837663SSowmini.Varadhan@Sun.COM { 33847663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33857663SSowmini.Varadhan@Sun.COM 33867663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 33877663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 33887663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 33897663SSowmini.Varadhan@Sun.COM flags, status)); 33907663SSowmini.Varadhan@Sun.COM } 33917663SSowmini.Varadhan@Sun.COM 33925903Ssowmini /* ARGSUSED */ 33935903Ssowmini static dladm_status_t 3394*11878SVenu.Iyer@Sun.COM set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 33958453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 33968453SAnurag.Maskey@Sun.COM datalink_media_t media) 33975903Ssowmini { 33986789Sam223141 dld_ioc_macprop_t *dip; 33995903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 34005903Ssowmini uint8_t u8; 34015903Ssowmini uint16_t u16; 34025903Ssowmini uint32_t u32; 34035903Ssowmini void *val; 34045903Ssowmini 34058275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 34065903Ssowmini if (dip == NULL) 34075903Ssowmini return (status); 34085903Ssowmini 34098275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 34105903Ssowmini val = (void *)vdp->vd_val; 34115903Ssowmini else { 34125903Ssowmini /* 34135903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 34145903Ssowmini * No need (yet) to distinguish these from arrays of same size. 34155903Ssowmini */ 34165903Ssowmini switch (dip->pr_valsize) { 34175903Ssowmini case 1: 34185903Ssowmini u8 = vdp->vd_val; 34195903Ssowmini val = &u8; 34205903Ssowmini break; 34215903Ssowmini case 2: 34225903Ssowmini u16 = vdp->vd_val; 34235903Ssowmini val = &u16; 34245903Ssowmini break; 34255903Ssowmini case 4: 34265903Ssowmini u32 = vdp->vd_val; 34275903Ssowmini val = &u32; 34285903Ssowmini break; 34295903Ssowmini default: 34305903Ssowmini val = &vdp->vd_val; 34315903Ssowmini break; 34325903Ssowmini } 34335903Ssowmini } 34345903Ssowmini 34357342SAruna.Ramakrishna@Sun.COM if (val != NULL) 34367342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 34377342SAruna.Ramakrishna@Sun.COM else 34387342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 34397342SAruna.Ramakrishna@Sun.COM 34408453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 34417663SSowmini.Varadhan@Sun.COM 34427663SSowmini.Varadhan@Sun.COM done: 34437663SSowmini.Varadhan@Sun.COM free(dip); 34447663SSowmini.Varadhan@Sun.COM return (status); 34457663SSowmini.Varadhan@Sun.COM } 34467663SSowmini.Varadhan@Sun.COM 34477663SSowmini.Varadhan@Sun.COM dladm_status_t 34488453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 34497663SSowmini.Varadhan@Sun.COM { 34507663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 34517663SSowmini.Varadhan@Sun.COM 34528453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 34538453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 34545903Ssowmini status = dladm_errno2status(errno); 34558453SAnurag.Maskey@Sun.COM 34565903Ssowmini return (status); 34575903Ssowmini } 34585903Ssowmini 3459*11878SVenu.Iyer@Sun.COM static dladm_status_t 34608453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 3461*11878SVenu.Iyer@Sun.COM char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 34625903Ssowmini { 3463*11878SVenu.Iyer@Sun.COM dld_ioc_macprop_t *dip; 3464*11878SVenu.Iyer@Sun.COM dladm_status_t status; 3465*11878SVenu.Iyer@Sun.COM 3466*11878SVenu.Iyer@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 34676512Ssowmini if (dip == NULL) 3468*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 3469*11878SVenu.Iyer@Sun.COM 3470*11878SVenu.Iyer@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 3471*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) { 34726512Ssowmini free(dip); 3473*11878SVenu.Iyer@Sun.COM return (status); 34746512Ssowmini } 3475*11878SVenu.Iyer@Sun.COM 34768275SEric Cheng if (perm_flags != NULL) 34778275SEric Cheng *perm_flags = dip->pr_perm_flags; 34788275SEric Cheng 3479*11878SVenu.Iyer@Sun.COM if (arg != NULL) 3480*11878SVenu.Iyer@Sun.COM (void) memcpy(arg, dip->pr_val, size); 3481*11878SVenu.Iyer@Sun.COM free(dip); 3482*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 34835903Ssowmini } 34845903Ssowmini 34855903Ssowmini /* ARGSUSED */ 34865903Ssowmini static dladm_status_t 3487*11878SVenu.Iyer@Sun.COM check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 3488*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 3489*11878SVenu.Iyer@Sun.COM val_desc_t *v, datalink_media_t media) 34905903Ssowmini { 34915903Ssowmini if (val_cnt != 1) 34925903Ssowmini return (DLADM_STATUS_BADVAL); 349310491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 34945903Ssowmini return (DLADM_STATUS_OK); 34955903Ssowmini } 34965903Ssowmini 34975903Ssowmini /* ARGSUSED */ 34985903Ssowmini static dladm_status_t 3499*11878SVenu.Iyer@Sun.COM get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 35008453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35018453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35025903Ssowmini { 35035903Ssowmini link_duplex_t link_duplex; 35045903Ssowmini dladm_status_t status; 35055903Ssowmini 35068453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 35075903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 35085903Ssowmini return (status); 35095903Ssowmini 35105903Ssowmini switch (link_duplex) { 35115903Ssowmini case LINK_DUPLEX_FULL: 35125903Ssowmini (void) strcpy(*prop_val, "full"); 35135903Ssowmini break; 35145903Ssowmini case LINK_DUPLEX_HALF: 35155903Ssowmini (void) strcpy(*prop_val, "half"); 35165903Ssowmini break; 35175903Ssowmini default: 35185903Ssowmini (void) strcpy(*prop_val, "unknown"); 35195903Ssowmini break; 35205903Ssowmini } 35215903Ssowmini *val_cnt = 1; 35225903Ssowmini return (DLADM_STATUS_OK); 35235903Ssowmini } 35245903Ssowmini 35255903Ssowmini /* ARGSUSED */ 35265903Ssowmini static dladm_status_t 3527*11878SVenu.Iyer@Sun.COM get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3528*11878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 3529*11878SVenu.Iyer@Sun.COM uint_t *perm_flags) 35305903Ssowmini { 35315903Ssowmini uint64_t ifspeed = 0; 35325903Ssowmini dladm_status_t status; 35335903Ssowmini 35348453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 35355903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 35365903Ssowmini return (status); 35376512Ssowmini 35385960Ssowmini if ((ifspeed % 1000000) != 0) { 35395960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 35405960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 35415960Ssowmini } else { 35425960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 35435960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 35445960Ssowmini } 35455903Ssowmini *val_cnt = 1; 35468275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 35475903Ssowmini return (DLADM_STATUS_OK); 35485903Ssowmini } 35495903Ssowmini 35505903Ssowmini /* ARGSUSED */ 35515903Ssowmini static dladm_status_t 3552*11878SVenu.Iyer@Sun.COM get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 35538453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35548453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35555903Ssowmini { 35568275SEric Cheng link_state_t link_state; 35578275SEric Cheng dladm_status_t status; 35588306SSowmini.Varadhan@Sun.COM 3559*11878SVenu.Iyer@Sun.COM status = dladm_get_state(handle, linkid, &link_state); 35606512Ssowmini if (status != DLADM_STATUS_OK) 35615903Ssowmini return (status); 35628275SEric Cheng 35635903Ssowmini switch (link_state) { 35645903Ssowmini case LINK_STATE_UP: 35655903Ssowmini (void) strcpy(*prop_val, "up"); 35665903Ssowmini break; 35675903Ssowmini case LINK_STATE_DOWN: 35685903Ssowmini (void) strcpy(*prop_val, "down"); 35695903Ssowmini break; 35705903Ssowmini default: 35715903Ssowmini (void) strcpy(*prop_val, "unknown"); 35725903Ssowmini break; 35735903Ssowmini } 35745903Ssowmini *val_cnt = 1; 35758306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 35765903Ssowmini return (DLADM_STATUS_OK); 35775903Ssowmini } 35785903Ssowmini 35795903Ssowmini /* ARGSUSED */ 35805903Ssowmini static dladm_status_t 3581*11878SVenu.Iyer@Sun.COM get_binary(dladm_handle_t handle, prop_desc_t *pdp, 35828453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35838453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35845903Ssowmini { 3585*11878SVenu.Iyer@Sun.COM dladm_status_t status; 3586*11878SVenu.Iyer@Sun.COM uint_t v = 0; 3587*11878SVenu.Iyer@Sun.COM 3588*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3589*11878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 3590*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 35915903Ssowmini return (status); 35928275SEric Cheng 3593*11878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 35945903Ssowmini *val_cnt = 1; 35955903Ssowmini return (DLADM_STATUS_OK); 35965903Ssowmini } 35975903Ssowmini 35985960Ssowmini /* ARGSUSED */ 35995903Ssowmini static dladm_status_t 3600*11878SVenu.Iyer@Sun.COM get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 36018453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36028453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36035903Ssowmini { 3604*11878SVenu.Iyer@Sun.COM dladm_status_t status; 3605*11878SVenu.Iyer@Sun.COM uint32_t v = 0; 3606*11878SVenu.Iyer@Sun.COM 3607*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3608*11878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 3609*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 36105903Ssowmini return (status); 36118275SEric Cheng 36126512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 36135903Ssowmini *val_cnt = 1; 36145903Ssowmini return (DLADM_STATUS_OK); 36155903Ssowmini } 36165903Ssowmini 36179514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 36189514SGirish.Moodalbail@Sun.COM static dladm_status_t 3619*11878SVenu.Iyer@Sun.COM get_range(dladm_handle_t handle, prop_desc_t *pdp, 36209514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36219514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36229514SGirish.Moodalbail@Sun.COM { 36239514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 36249514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 36259514SGirish.Moodalbail@Sun.COM size_t sz; 36269514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 36279514SGirish.Moodalbail@Sun.COM 36289514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 36299514SGirish.Moodalbail@Sun.COM 36309514SGirish.Moodalbail@Sun.COM /* 36319514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 36329514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 36339514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 36349514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 36359514SGirish.Moodalbail@Sun.COM */ 36369514SGirish.Moodalbail@Sun.COM retry: 36379514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 36389514SGirish.Moodalbail@Sun.COM &status)) == NULL) 36399514SGirish.Moodalbail@Sun.COM return (status); 36409514SGirish.Moodalbail@Sun.COM 36419514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 36429514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 36439514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 36449514SGirish.Moodalbail@Sun.COM int err; 36459514SGirish.Moodalbail@Sun.COM 36469514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 36479514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 36489514SGirish.Moodalbail@Sun.COM free(dip); 36499514SGirish.Moodalbail@Sun.COM goto retry; 36509514SGirish.Moodalbail@Sun.COM } else { 36519514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 36529514SGirish.Moodalbail@Sun.COM } 36539514SGirish.Moodalbail@Sun.COM } 36549514SGirish.Moodalbail@Sun.COM free(dip); 36559514SGirish.Moodalbail@Sun.COM return (status); 36569514SGirish.Moodalbail@Sun.COM } 3657*11878SVenu.Iyer@Sun.COM 36589514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 3659*11878SVenu.Iyer@Sun.COM if (rangep->mpr_count == 0) { 3660*11878SVenu.Iyer@Sun.COM *val_cnt = 1; 3661*11878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 3662*11878SVenu.Iyer@Sun.COM goto done; 3663*11878SVenu.Iyer@Sun.COM } 36649514SGirish.Moodalbail@Sun.COM 36659514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 36669514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 36679514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 36689514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 36699514SGirish.Moodalbail@Sun.COM 3670*11878SVenu.Iyer@Sun.COM ur = &rangep->mpr_range_uint32[0]; 36719514SGirish.Moodalbail@Sun.COM 36729514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 36739514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 36749514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 36759514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 36769514SGirish.Moodalbail@Sun.COM } else { 36779514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 36789514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 36799514SGirish.Moodalbail@Sun.COM } 36809514SGirish.Moodalbail@Sun.COM } 36819514SGirish.Moodalbail@Sun.COM *val_cnt = count; 36829514SGirish.Moodalbail@Sun.COM break; 36839514SGirish.Moodalbail@Sun.COM } 36849514SGirish.Moodalbail@Sun.COM default: 36859514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 36869514SGirish.Moodalbail@Sun.COM break; 36879514SGirish.Moodalbail@Sun.COM } 3688*11878SVenu.Iyer@Sun.COM done: 36899514SGirish.Moodalbail@Sun.COM free(dip); 36909514SGirish.Moodalbail@Sun.COM return (status); 36919514SGirish.Moodalbail@Sun.COM } 36929514SGirish.Moodalbail@Sun.COM 36935960Ssowmini /* ARGSUSED */ 36945903Ssowmini static dladm_status_t 3695*11878SVenu.Iyer@Sun.COM get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 36968874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36978874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36988874SSebastien.Roy@Sun.COM { 36998874SSebastien.Roy@Sun.COM link_tagmode_t mode; 37008874SSebastien.Roy@Sun.COM dladm_status_t status; 37018874SSebastien.Roy@Sun.COM 3702*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3703*11878SVenu.Iyer@Sun.COM perm_flags, &mode, sizeof (mode)); 3704*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 37058874SSebastien.Roy@Sun.COM return (status); 37068874SSebastien.Roy@Sun.COM 37078874SSebastien.Roy@Sun.COM switch (mode) { 37088874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 37098874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 37108874SSebastien.Roy@Sun.COM break; 37118874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 37128874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 37138874SSebastien.Roy@Sun.COM break; 37148874SSebastien.Roy@Sun.COM default: 37158874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 37168874SSebastien.Roy@Sun.COM } 37178874SSebastien.Roy@Sun.COM *val_cnt = 1; 37188874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 37198874SSebastien.Roy@Sun.COM } 37208874SSebastien.Roy@Sun.COM 37218874SSebastien.Roy@Sun.COM /* ARGSUSED */ 37228874SSebastien.Roy@Sun.COM static dladm_status_t 3723*11878SVenu.Iyer@Sun.COM get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 37248453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37258453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 37265903Ssowmini { 3727*11878SVenu.Iyer@Sun.COM link_flowctrl_t v; 3728*11878SVenu.Iyer@Sun.COM dladm_status_t status; 3729*11878SVenu.Iyer@Sun.COM 3730*11878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3731*11878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 3732*11878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 37335903Ssowmini return (status); 37348275SEric Cheng 37355903Ssowmini switch (v) { 37365903Ssowmini case LINK_FLOWCTRL_NONE: 37375903Ssowmini (void) sprintf(*prop_val, "no"); 37385903Ssowmini break; 37395903Ssowmini case LINK_FLOWCTRL_RX: 37405903Ssowmini (void) sprintf(*prop_val, "rx"); 37415903Ssowmini break; 37425903Ssowmini case LINK_FLOWCTRL_TX: 37435903Ssowmini (void) sprintf(*prop_val, "tx"); 37445903Ssowmini break; 37455903Ssowmini case LINK_FLOWCTRL_BI: 37465903Ssowmini (void) sprintf(*prop_val, "bi"); 37475903Ssowmini break; 37485903Ssowmini } 37495903Ssowmini *val_cnt = 1; 37505903Ssowmini return (DLADM_STATUS_OK); 37515903Ssowmini } 37525903Ssowmini 37535903Ssowmini 37545903Ssowmini /* ARGSUSED */ 37555903Ssowmini static dladm_status_t 37569692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 37578453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 37588453SAnurag.Maskey@Sun.COM 37595903Ssowmini { 37607663SSowmini.Varadhan@Sun.COM int i, slen; 37617408SSebastien.Roy@Sun.COM int bufsize = 0; 37626789Sam223141 dld_ioc_macprop_t *dip = NULL; 37635903Ssowmini uchar_t *dp; 37647663SSowmini.Varadhan@Sun.COM link_attr_t *p; 37656512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 37665903Ssowmini 37675903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 37685903Ssowmini (prop_val != NULL && val_cnt == 0)) 37695903Ssowmini return (DLADM_STATUS_BADARG); 37705903Ssowmini p = dladm_name2prop(prop_name); 37716789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 37725903Ssowmini return (DLADM_STATUS_BADARG); 37735903Ssowmini 37749692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 37759692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 37769692SRishi.Srivatsavai@Sun.COM 37775903Ssowmini /* 37785903Ssowmini * private properties: all parsing is done in the kernel. 37795903Ssowmini * allocate a enough space for each property + its separator (','). 37805903Ssowmini */ 37815903Ssowmini for (i = 0; i < val_cnt; i++) { 37825903Ssowmini bufsize += strlen(prop_val[i]) + 1; 37835903Ssowmini } 37846512Ssowmini 37856512Ssowmini if (prop_val == NULL) { 37866512Ssowmini /* 37876512Ssowmini * getting default value. so use more buffer space. 37886512Ssowmini */ 37897663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 37906512Ssowmini } 37916512Ssowmini 37927663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 3793*11878SVenu.Iyer@Sun.COM (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 37945903Ssowmini if (dip == NULL) 37955903Ssowmini return (status); 37965903Ssowmini 37975903Ssowmini dp = (uchar_t *)dip->pr_val; 37985903Ssowmini slen = 0; 37997663SSowmini.Varadhan@Sun.COM 38006512Ssowmini if (prop_val == NULL) { 38018453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 38028460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 38036512Ssowmini } else { 38046512Ssowmini for (i = 0; i < val_cnt; i++) { 38056512Ssowmini int plen = 0; 38065903Ssowmini 38076512Ssowmini plen = strlen(prop_val[i]); 38086512Ssowmini bcopy(prop_val[i], dp, plen); 38096512Ssowmini slen += plen; 38106512Ssowmini /* 38116512Ssowmini * add a "," separator and update dp. 38126512Ssowmini */ 38136512Ssowmini if (i != (val_cnt -1)) 38146512Ssowmini dp[slen++] = ','; 38156512Ssowmini dp += (plen + 1); 38166512Ssowmini } 38178460SArtem.Kachitchkin@Sun.COM } 38188460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 38198453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 38206512Ssowmini 38215903Ssowmini free(dip); 38226512Ssowmini return (status); 38235903Ssowmini } 38245903Ssowmini 38255903Ssowmini static dladm_status_t 38268460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 38278453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 38288453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 38295903Ssowmini { 38307663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 38316789Sam223141 dld_ioc_macprop_t *dip = NULL; 38327663SSowmini.Varadhan@Sun.COM link_attr_t *p; 38335903Ssowmini 38345903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 38355903Ssowmini (prop_val != NULL && val_cnt == 0)) 38365903Ssowmini return (DLADM_STATUS_BADARG); 38375903Ssowmini 38385903Ssowmini p = dladm_name2prop(prop_name); 38396789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 38405903Ssowmini return (DLADM_STATUS_BADARG); 38415903Ssowmini 38425903Ssowmini /* 38435903Ssowmini * private properties: all parsing is done in the kernel. 38445903Ssowmini */ 38457663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 38467663SSowmini.Varadhan@Sun.COM dld_flags, &status); 38475903Ssowmini if (dip == NULL) 38485903Ssowmini return (status); 38495903Ssowmini 38508453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 38518453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 38528118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 38538275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 38548460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 38558460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 38568118SVasumathi.Sundaram@Sun.COM } else { 38578118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 38588118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 38598118SVasumathi.Sundaram@Sun.COM } 38605903Ssowmini *val_cnt = 1; 38618460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 38628460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 38638460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 38645903Ssowmini } 38656512Ssowmini free(dip); 38665903Ssowmini return (status); 38675903Ssowmini } 38686512Ssowmini 38696512Ssowmini 38706512Ssowmini static dladm_status_t 38718453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 38728453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 38736512Ssowmini { 38746512Ssowmini dladm_status_t status; 38756512Ssowmini char **prop_vals = NULL, *buf; 38766512Ssowmini size_t bufsize; 38776512Ssowmini uint_t cnt; 38786512Ssowmini int i; 38798118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 38806512Ssowmini 38816512Ssowmini /* 38826512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 38836512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 38846512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 38856512Ssowmini */ 38866512Ssowmini bufsize = 38876512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 38886512Ssowmini buf = malloc(bufsize); 38896512Ssowmini prop_vals = (char **)(void *)buf; 38906512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 38916512Ssowmini prop_vals[i] = buf + 38926512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 38936512Ssowmini i * DLADM_PROP_VAL_MAX; 38946512Ssowmini } 38956768Sar224390 38966768Sar224390 /* 38977342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 38987342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 38997342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 39007342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 39017342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 39027342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 39037342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 39047342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 39056768Sar224390 */ 39068453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 3907*11878SVenu.Iyer@Sun.COM DLD_PROP_DEFAULT, &perm_flags); 39086512Ssowmini if (status == DLADM_STATUS_OK) { 39098118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 39108453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 39118453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 39128118SVasumathi.Sundaram@Sun.COM } 39138118SVasumathi.Sundaram@Sun.COM else 39148118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 39156512Ssowmini } 39166512Ssowmini free(buf); 39176512Ssowmini return (status); 39186512Ssowmini } 39197663SSowmini.Varadhan@Sun.COM 392010491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 392110491SRishi.Srivatsavai@Sun.COM static dladm_status_t 3922*11878SVenu.Iyer@Sun.COM get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 392310491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 392410491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 392510491SRishi.Srivatsavai@Sun.COM { 392610491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 392710491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 392810491SRishi.Srivatsavai@Sun.COM int val, i; 392910491SRishi.Srivatsavai@Sun.COM 393010491SRishi.Srivatsavai@Sun.COM if (flags != 0) 393110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 393210491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 393310491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 393410491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 393510491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 393610491SRishi.Srivatsavai@Sun.COM break; 393710491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 393810491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 393910491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 394010491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 394110491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 394210491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 394310491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 394410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 394510491SRishi.Srivatsavai@Sun.COM } 394610491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 394710491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 394810491SRishi.Srivatsavai@Sun.COM return (retv); 394910491SRishi.Srivatsavai@Sun.COM } 395010491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 395110491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 395210491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 395310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 395410491SRishi.Srivatsavai@Sun.COM } 395510491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 395610491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 395710491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 395810491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 395910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 396010491SRishi.Srivatsavai@Sun.COM } 396110491SRishi.Srivatsavai@Sun.COM } 396210491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 396310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 396410491SRishi.Srivatsavai@Sun.COM } 396510491SRishi.Srivatsavai@Sun.COM 396610491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 396710491SRishi.Srivatsavai@Sun.COM static dladm_status_t 396810491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 396910491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 397010491SRishi.Srivatsavai@Sun.COM { 397110491SRishi.Srivatsavai@Sun.COM /* 397210491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 397310491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 397410491SRishi.Srivatsavai@Sun.COM */ 397510491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 397610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 397710491SRishi.Srivatsavai@Sun.COM 397810491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 397910491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 398010491SRishi.Srivatsavai@Sun.COM } 398110491SRishi.Srivatsavai@Sun.COM 398210491SRishi.Srivatsavai@Sun.COM /* 398310491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 398410491SRishi.Srivatsavai@Sun.COM */ 398510491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 398610491SRishi.Srivatsavai@Sun.COM static dladm_status_t 398710491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 3988*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 3989*11878SVenu.Iyer@Sun.COM val_desc_t *vdp, datalink_media_t media) 399010491SRishi.Srivatsavai@Sun.COM { 399110491SRishi.Srivatsavai@Sun.COM char *cp; 399210491SRishi.Srivatsavai@Sun.COM boolean_t iscost; 399310491SRishi.Srivatsavai@Sun.COM 399410491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 399510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 399610491SRishi.Srivatsavai@Sun.COM 399710491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 399810491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 399910491SRishi.Srivatsavai@Sun.COM } else { 400010491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 400110491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 400210491SRishi.Srivatsavai@Sun.COM 400310491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 400410491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 400510491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 400610491SRishi.Srivatsavai@Sun.COM } else { 400710491SRishi.Srivatsavai@Sun.COM errno = 0; 400810491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 400910491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 401010491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 401110491SRishi.Srivatsavai@Sun.COM } 401210491SRishi.Srivatsavai@Sun.COM } 401310491SRishi.Srivatsavai@Sun.COM 401410491SRishi.Srivatsavai@Sun.COM if (iscost) { 401510491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 401610491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 401710491SRishi.Srivatsavai@Sun.COM } else { 401810491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 401910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 402010491SRishi.Srivatsavai@Sun.COM /* 402110491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 402210491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 402310491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 402410491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 402510491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 402610491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 402710491SRishi.Srivatsavai@Sun.COM * can't be used now. 402810491SRishi.Srivatsavai@Sun.COM */ 402910491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 403010491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 403110491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 403210491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 403310491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 403410491SRishi.Srivatsavai@Sun.COM 403510491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 403610491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 403710491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 403810491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 403910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 404010491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 404110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 404210491SRishi.Srivatsavai@Sun.COM } 404310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 404410491SRishi.Srivatsavai@Sun.COM } 404510491SRishi.Srivatsavai@Sun.COM } 404610491SRishi.Srivatsavai@Sun.COM 404710491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 404810491SRishi.Srivatsavai@Sun.COM static dladm_status_t 404910491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 405010491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 405110491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 405210491SRishi.Srivatsavai@Sun.COM { 405310491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 405410491SRishi.Srivatsavai@Sun.COM uint_t val; 405510491SRishi.Srivatsavai@Sun.COM 405610491SRishi.Srivatsavai@Sun.COM if (flags != 0) 405710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 405810491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 405910491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 406010491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 406110491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 406210491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 406310491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 406410491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 406510491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 406610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 406710491SRishi.Srivatsavai@Sun.COM } 406810491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 406910491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 407010491SRishi.Srivatsavai@Sun.COM else 407110491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 407210491SRishi.Srivatsavai@Sun.COM return (retv); 407310491SRishi.Srivatsavai@Sun.COM } 407410491SRishi.Srivatsavai@Sun.COM 407510491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 407610491SRishi.Srivatsavai@Sun.COM static dladm_status_t 407710491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 407810491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 407910491SRishi.Srivatsavai@Sun.COM { 408010491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 408110491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 408210491SRishi.Srivatsavai@Sun.COM } 408310491SRishi.Srivatsavai@Sun.COM 408410491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 408510491SRishi.Srivatsavai@Sun.COM static dladm_status_t 408610491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 408710491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 408810491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 408910491SRishi.Srivatsavai@Sun.COM { 409010491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 409110491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 409210491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 409310491SRishi.Srivatsavai@Sun.COM 409410491SRishi.Srivatsavai@Sun.COM if (flags != 0) 409510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 409610491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 409710491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 409810491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 409910491SRishi.Srivatsavai@Sun.COM 0, &status); 410010491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 410110491SRishi.Srivatsavai@Sun.COM return (status); 410210491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 410310491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 410410491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 410510491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 410610491SRishi.Srivatsavai@Sun.COM } else { 410710491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 410810491SRishi.Srivatsavai@Sun.COM } 410910491SRishi.Srivatsavai@Sun.COM free(dip); 411010491SRishi.Srivatsavai@Sun.COM return (status); 411110491SRishi.Srivatsavai@Sun.COM } 411210491SRishi.Srivatsavai@Sun.COM 411310491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 411410491SRishi.Srivatsavai@Sun.COM static dladm_status_t 411510491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 411610491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 411710491SRishi.Srivatsavai@Sun.COM { 411810491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 411910491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 412010491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 412110491SRishi.Srivatsavai@Sun.COM 412210491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 412310491SRishi.Srivatsavai@Sun.COM 0, &status); 412410491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 412510491SRishi.Srivatsavai@Sun.COM return (status); 412610491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 412710491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 412810491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 412910491SRishi.Srivatsavai@Sun.COM free(dip); 413010491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 413110491SRishi.Srivatsavai@Sun.COM return (status); 413210491SRishi.Srivatsavai@Sun.COM 413310491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 413410491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 413510491SRishi.Srivatsavai@Sun.COM } 413610491SRishi.Srivatsavai@Sun.COM 413710491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 413810491SRishi.Srivatsavai@Sun.COM static dladm_status_t 413910491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 4140*11878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 4141*11878SVenu.Iyer@Sun.COM val_desc_t *vdp, datalink_media_t media) 414210491SRishi.Srivatsavai@Sun.COM { 414310491SRishi.Srivatsavai@Sun.COM char *cp; 414410491SRishi.Srivatsavai@Sun.COM 414510491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 414610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 414710491SRishi.Srivatsavai@Sun.COM 414810491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 414910491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 415010491SRishi.Srivatsavai@Sun.COM } else { 415110491SRishi.Srivatsavai@Sun.COM errno = 0; 415210491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 415310491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 415410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 415510491SRishi.Srivatsavai@Sun.COM } 415610491SRishi.Srivatsavai@Sun.COM 415710491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 415810491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 415910491SRishi.Srivatsavai@Sun.COM } 416010491SRishi.Srivatsavai@Sun.COM 41617663SSowmini.Varadhan@Sun.COM dladm_status_t 41628453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 41638453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 41647663SSowmini.Varadhan@Sun.COM { 41657663SSowmini.Varadhan@Sun.COM uint32_t flags; 41667663SSowmini.Varadhan@Sun.COM dladm_status_t status; 41677663SSowmini.Varadhan@Sun.COM uint32_t media; 41687663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 41697663SSowmini.Varadhan@Sun.COM void *dp; 41707663SSowmini.Varadhan@Sun.COM 41718453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 41728453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 41737663SSowmini.Varadhan@Sun.COM return (status); 41747663SSowmini.Varadhan@Sun.COM } 41757663SSowmini.Varadhan@Sun.COM 41767663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 41777663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 41787663SSowmini.Varadhan@Sun.COM 41797663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 41807663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 41817663SSowmini.Varadhan@Sun.COM 41827663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 41837663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 41847663SSowmini.Varadhan@Sun.COM 41857663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 41867663SSowmini.Varadhan@Sun.COM if (dip == NULL) 41877663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 41887663SSowmini.Varadhan@Sun.COM 41897663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 41907663SSowmini.Varadhan@Sun.COM if (set) 41917663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 41927663SSowmini.Varadhan@Sun.COM 41938453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 419410191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 41957663SSowmini.Varadhan@Sun.COM if (!set) 41967663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 41977663SSowmini.Varadhan@Sun.COM } 41987663SSowmini.Varadhan@Sun.COM 41997663SSowmini.Varadhan@Sun.COM free(dip); 42007663SSowmini.Varadhan@Sun.COM return (status); 42017663SSowmini.Varadhan@Sun.COM } 42027663SSowmini.Varadhan@Sun.COM 42038275SEric Cheng dladm_status_t 42048275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 42058275SEric Cheng { 42068460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 42078275SEric Cheng } 42088275SEric Cheng 42098275SEric Cheng /* 42108275SEric Cheng * Retrieve the one link property from the database 42118275SEric Cheng */ 42128275SEric Cheng /*ARGSUSED*/ 42138275SEric Cheng static int 42148453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 42158453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 42168275SEric Cheng { 42178275SEric Cheng dladm_arg_list_t *proplist = arg; 42188275SEric Cheng dladm_arg_info_t *aip = NULL; 42198275SEric Cheng 42208275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 42218275SEric Cheng /* 42228275SEric Cheng * it is fine to point to prop_name since prop_name points to the 42238275SEric Cheng * prop_table[n].pd_name. 42248275SEric Cheng */ 42258275SEric Cheng aip->ai_name = prop_name; 42268275SEric Cheng 42278453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 42288453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 42298275SEric Cheng 42308275SEric Cheng if (aip->ai_count != 0) 42318275SEric Cheng proplist->al_count++; 42328275SEric Cheng 42338275SEric Cheng return (DLADM_WALK_CONTINUE); 42348275SEric Cheng } 42358275SEric Cheng 42368275SEric Cheng 42378275SEric Cheng /* 42388275SEric Cheng * Retrieve all link properties for a link from the database and 42398275SEric Cheng * return a property list. 42408275SEric Cheng */ 42418275SEric Cheng dladm_status_t 42428453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 42438453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 42448275SEric Cheng { 42458275SEric Cheng dladm_arg_list_t *list; 42468275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 42478275SEric Cheng 42488275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 42498275SEric Cheng if (list == NULL) 42508275SEric Cheng return (dladm_errno2status(errno)); 42518275SEric Cheng 42528453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 42538453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 42548275SEric Cheng 42558275SEric Cheng *listp = list; 42568275SEric Cheng return (status); 42578275SEric Cheng } 42588275SEric Cheng 42598275SEric Cheng /* 42608275SEric Cheng * Retrieve the named property from a proplist, check the value and 42618275SEric Cheng * convert to a kernel structure. 42628275SEric Cheng */ 42638275SEric Cheng static dladm_status_t 42648453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 4265*11878SVenu.Iyer@Sun.COM dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 42668275SEric Cheng { 42678275SEric Cheng dladm_status_t status; 42688275SEric Cheng dladm_arg_info_t *aip = NULL; 42698275SEric Cheng int i, j; 42708275SEric Cheng 42718275SEric Cheng /* Find named property in proplist */ 42728275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 42738275SEric Cheng aip = &proplist->al_info[i]; 42748275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 42758275SEric Cheng break; 42768275SEric Cheng } 42778275SEric Cheng 42788275SEric Cheng /* Property not in list */ 42798275SEric Cheng if (i == proplist->al_count) 42808275SEric Cheng return (DLADM_STATUS_OK); 42818275SEric Cheng 42828275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 42838275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 42848275SEric Cheng val_desc_t *vdp; 42858275SEric Cheng 42868275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 42878275SEric Cheng if (vdp == NULL) 42888275SEric Cheng return (DLADM_STATUS_NOMEM); 42898275SEric Cheng 42908275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 42918275SEric Cheng continue; 42928275SEric Cheng 42938275SEric Cheng if (aip->ai_val == NULL) 42948275SEric Cheng return (DLADM_STATUS_BADARG); 42958275SEric Cheng 42968275SEric Cheng /* Check property value */ 42978275SEric Cheng if (pdp->pd_check != NULL) { 42988453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 4299*11878SVenu.Iyer@Sun.COM aip->ai_count, flags, vdp, 0); 43008275SEric Cheng } else { 43018275SEric Cheng status = DLADM_STATUS_BADARG; 43028275SEric Cheng } 43038275SEric Cheng 43048275SEric Cheng if (status != DLADM_STATUS_OK) 43058275SEric Cheng return (status); 43068275SEric Cheng 43078275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 43088275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 43098275SEric Cheng 43108275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 43118275SEric Cheng continue; 43128275SEric Cheng 43138275SEric Cheng /* Extract kernel structure */ 43148275SEric Cheng if (rpp->rp_extract != NULL) { 431510734SEric Cheng status = rpp->rp_extract(vdp, 431610734SEric Cheng aip->ai_count, arg); 43178275SEric Cheng } else { 43188275SEric Cheng status = DLADM_STATUS_BADARG; 43198275SEric Cheng } 43208275SEric Cheng break; 43218275SEric Cheng } 43228275SEric Cheng 43238275SEric Cheng if (status != DLADM_STATUS_OK) 43248275SEric Cheng return (status); 43258275SEric Cheng 43268275SEric Cheng break; 43278275SEric Cheng } 43288275SEric Cheng return (status); 43298275SEric Cheng } 43308275SEric Cheng 43318275SEric Cheng /* 43328275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 43338275SEric Cheng */ 43348275SEric Cheng dladm_status_t 43358453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 4336*11878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp, uint_t flags) 43378275SEric Cheng { 433810734SEric Cheng dladm_status_t status; 433910734SEric Cheng int i; 434010734SEric Cheng 434110734SEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 434210734SEric Cheng status = i_dladm_link_proplist_extract_one(handle, 4343*11878SVenu.Iyer@Sun.COM proplist, rsrc_prop_table[i].rp_name, flags, mrp); 434410734SEric Cheng if (status != DLADM_STATUS_OK) 434510734SEric Cheng return (status); 434610734SEric Cheng } 43478275SEric Cheng return (status); 43488275SEric Cheng } 43498275SEric Cheng 43508275SEric Cheng static const char * 43518275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 43528275SEric Cheng { 43538275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 43548275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 43558275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 43568275SEric Cheng return (buf); 43578275SEric Cheng } 43588306SSowmini.Varadhan@Sun.COM 43598306SSowmini.Varadhan@Sun.COM dladm_status_t 4360*11878SVenu.Iyer@Sun.COM dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 43618453SAnurag.Maskey@Sun.COM link_state_t *state) 43628306SSowmini.Varadhan@Sun.COM { 43638306SSowmini.Varadhan@Sun.COM uint_t perms; 43648306SSowmini.Varadhan@Sun.COM 4365*11878SVenu.Iyer@Sun.COM return (i_dladm_get_public_prop(handle, linkid, "state", 0, 4366*11878SVenu.Iyer@Sun.COM &perms, state, sizeof (*state))); 43678306SSowmini.Varadhan@Sun.COM } 43688460SArtem.Kachitchkin@Sun.COM 43698460SArtem.Kachitchkin@Sun.COM boolean_t 43708460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 43718460SArtem.Kachitchkin@Sun.COM { 43728460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 43738460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 43748460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 43758460SArtem.Kachitchkin@Sun.COM "name", 43768460SArtem.Kachitchkin@Sun.COM "class", 43778460SArtem.Kachitchkin@Sun.COM "media", 43788460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 43798460SArtem.Kachitchkin@Sun.COM FPHYINST, 43808460SArtem.Kachitchkin@Sun.COM FDEVNAME, 43818460SArtem.Kachitchkin@Sun.COM 43828460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 43838460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 43848460SArtem.Kachitchkin@Sun.COM }; 43858460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 43868460SArtem.Kachitchkin@Sun.COM int i; 43878460SArtem.Kachitchkin@Sun.COM 43888460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 43898460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 43908460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 43918460SArtem.Kachitchkin@Sun.COM break; 43928460SArtem.Kachitchkin@Sun.COM } 43938460SArtem.Kachitchkin@Sun.COM } 43948460SArtem.Kachitchkin@Sun.COM 43958460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 43968460SArtem.Kachitchkin@Sun.COM } 4397*11878SVenu.Iyer@Sun.COM 4398*11878SVenu.Iyer@Sun.COM dladm_status_t 4399*11878SVenu.Iyer@Sun.COM dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 4400*11878SVenu.Iyer@Sun.COM dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 4401*11878SVenu.Iyer@Sun.COM { 4402*11878SVenu.Iyer@Sun.COM char *buf, **propvals; 4403*11878SVenu.Iyer@Sun.COM uint_t valcnt = DLADM_MAX_PROP_VALCNT; 4404*11878SVenu.Iyer@Sun.COM int i; 4405*11878SVenu.Iyer@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 4406*11878SVenu.Iyer@Sun.COM 4407*11878SVenu.Iyer@Sun.COM *is_set = B_FALSE; 4408*11878SVenu.Iyer@Sun.COM 4409*11878SVenu.Iyer@Sun.COM if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 4410*11878SVenu.Iyer@Sun.COM DLADM_MAX_PROP_VALCNT)) == NULL) 4411*11878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 4412*11878SVenu.Iyer@Sun.COM 4413*11878SVenu.Iyer@Sun.COM propvals = (char **)(void *)buf; 4414*11878SVenu.Iyer@Sun.COM for (i = 0; i < valcnt; i++) { 4415*11878SVenu.Iyer@Sun.COM propvals[i] = buf + 4416*11878SVenu.Iyer@Sun.COM sizeof (char *) * DLADM_MAX_PROP_VALCNT + 4417*11878SVenu.Iyer@Sun.COM i * DLADM_PROP_VAL_MAX; 4418*11878SVenu.Iyer@Sun.COM } 4419*11878SVenu.Iyer@Sun.COM 4420*11878SVenu.Iyer@Sun.COM if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 4421*11878SVenu.Iyer@Sun.COM &valcnt) != DLADM_STATUS_OK) { 4422*11878SVenu.Iyer@Sun.COM goto done; 4423*11878SVenu.Iyer@Sun.COM } 4424*11878SVenu.Iyer@Sun.COM 4425*11878SVenu.Iyer@Sun.COM if ((strcmp(prop_name, "pool") == 0) && (strlen(*propvals) != 0)) { 4426*11878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 4427*11878SVenu.Iyer@Sun.COM } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 4428*11878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 4429*11878SVenu.Iyer@Sun.COM } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 4430*11878SVenu.Iyer@Sun.COM (strcmp(propvals[0], "true") == 0)) { 4431*11878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 4432*11878SVenu.Iyer@Sun.COM } 4433*11878SVenu.Iyer@Sun.COM 4434*11878SVenu.Iyer@Sun.COM done: 4435*11878SVenu.Iyer@Sun.COM if (buf != NULL) 4436*11878SVenu.Iyer@Sun.COM free(buf); 4437*11878SVenu.Iyer@Sun.COM return (status); 4438*11878SVenu.Iyer@Sun.COM } 4439