13147Sxc151355 /* 23147Sxc151355 * CDDL HEADER START 33147Sxc151355 * 43147Sxc151355 * The contents of this file are subject to the terms of the 53147Sxc151355 * Common Development and Distribution License (the "License"). 63147Sxc151355 * You may not use this file except in compliance with the License. 73147Sxc151355 * 83147Sxc151355 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93147Sxc151355 * or http://www.opensolaris.org/os/licensing. 103147Sxc151355 * See the License for the specific language governing permissions 113147Sxc151355 * and limitations under the License. 123147Sxc151355 * 133147Sxc151355 * When distributing Covered Code, include this CDDL HEADER in each 143147Sxc151355 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153147Sxc151355 * If applicable, add the following below this CDDL HEADER, with the 163147Sxc151355 * fields enclosed by brackets "[]" replaced with your own identifying 173147Sxc151355 * information: Portions Copyright [yyyy] [name of copyright owner] 183147Sxc151355 * 193147Sxc151355 * CDDL HEADER END 203147Sxc151355 */ 213147Sxc151355 /* 2212163SRamaswamy.Tummala@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 233147Sxc151355 */ 243147Sxc151355 253147Sxc151355 #include <stdlib.h> 263147Sxc151355 #include <strings.h> 273147Sxc151355 #include <errno.h> 283147Sxc151355 #include <ctype.h> 295895Syz147064 #include <stddef.h> 303448Sdh155122 #include <sys/types.h> 313147Sxc151355 #include <sys/stat.h> 323448Sdh155122 #include <sys/dld.h> 333448Sdh155122 #include <sys/zone.h> 343448Sdh155122 #include <fcntl.h> 353448Sdh155122 #include <unistd.h> 363448Sdh155122 #include <libdevinfo.h> 373448Sdh155122 #include <zone.h> 383871Syz147064 #include <libdllink.h> 393147Sxc151355 #include <libdladm_impl.h> 405895Syz147064 #include <libdlwlan_impl.h> 413871Syz147064 #include <libdlwlan.h> 425895Syz147064 #include <libdlvlan.h> 438275SEric Cheng #include <libdlvnic.h> 4412163SRamaswamy.Tummala@Sun.COM #include <libdlib.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> 6211878SVenu.Iyer@Sun.COM #include <netinet/dhcp.h> 6311878SVenu.Iyer@Sun.COM #include <netinet/dhcp6.h> 6411878SVenu.Iyer@Sun.COM #include <net/if_types.h> 6511878SVenu.Iyer@Sun.COM #include <libinetutil.h> 6611878SVenu.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, 11411878SVenu.Iyer@Sun.COM uint_t flags, val_desc_t *propval, 11511878SVenu.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 12311878SVenu.Iyer@Sun.COM typedef struct dladm_linkprop_args_s { 12411878SVenu.Iyer@Sun.COM dladm_status_t dla_status; 12511878SVenu.Iyer@Sun.COM uint_t dla_flags; 12611878SVenu.Iyer@Sun.COM } dladm_linkprop_args_t; 12711878SVenu.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 *); 13211878SVenu.Iyer@Sun.COM static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 13311878SVenu.Iyer@Sun.COM char *, uint_t, uint_t *, void *, size_t); 13411878SVenu.Iyer@Sun.COM 13511878SVenu.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); 13711878SVenu.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 *); 14211878SVenu.Iyer@Sun.COM static link_attr_t *dladm_name2prop(const char *); 14311878SVenu.Iyer@Sun.COM static link_attr_t *dladm_id2prop(mac_prop_id_t); 14411878SVenu.Iyer@Sun.COM 14511878SVenu.Iyer@Sun.COM static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 14611878SVenu.Iyer@Sun.COM get_speed, get_channel, get_powermode, get_radio, 14711878SVenu.Iyer@Sun.COM get_duplex, get_link_state, get_binary, get_uint32, 14811878SVenu.Iyer@Sun.COM get_flowctl, get_maxbw, get_cpus, get_priority, 14911878SVenu.Iyer@Sun.COM get_tagmode, get_range, get_stp, get_bridge_forward, 15011878SVenu.Iyer@Sun.COM get_bridge_pvid, get_protection, get_rxrings, 15111878SVenu.Iyer@Sun.COM get_txrings, get_cntavail, 15211878SVenu.Iyer@Sun.COM get_allowedips, get_allowedcids, get_pool, 15312163SRamaswamy.Tummala@Sun.COM get_rings_range, get_linkmode_prop; 15411878SVenu.Iyer@Sun.COM 15511878SVenu.Iyer@Sun.COM static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 15611878SVenu.Iyer@Sun.COM set_public_prop, set_resource, set_stp_prop, 15711878SVenu.Iyer@Sun.COM set_bridge_forward, set_bridge_pvid; 15811878SVenu.Iyer@Sun.COM 15911878SVenu.Iyer@Sun.COM static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 16011878SVenu.Iyer@Sun.COM check_encaplim, check_uint32, check_maxbw, check_cpus, 16111878SVenu.Iyer@Sun.COM check_stp_prop, check_bridge_pvid, check_allowedips, 16211878SVenu.Iyer@Sun.COM check_allowedcids, check_rings, 16311878SVenu.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 34411878SVenu.Iyer@Sun.COM { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 34511878SVenu.Iyer@Sun.COM 34611878SVenu.Iyer@Sun.COM { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 34711878SVenu.Iyer@Sun.COM "resource-effective"}, 34811878SVenu.Iyer@Sun.COM 34911878SVenu.Iyer@Sun.COM { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 35011878SVenu.Iyer@Sun.COM 35111878SVenu.Iyer@Sun.COM { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 35211878SVenu.Iyer@Sun.COM 35311878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 35411878SVenu.Iyer@Sun.COM "txrings-available"}, 35511878SVenu.Iyer@Sun.COM 35611878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 35711878SVenu.Iyer@Sun.COM "rxrings-available"}, 35811878SVenu.Iyer@Sun.COM 35911878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 36011878SVenu.Iyer@Sun.COM 36111878SVenu.Iyer@Sun.COM { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 36210734SEric Cheng 36312163SRamaswamy.Tummala@Sun.COM { MAC_PROP_IB_LINKMODE, sizeof (uint32_t), "linkmode"}, 36412163SRamaswamy.Tummala@Sun.COM 3657663SSowmini.Varadhan@Sun.COM { MAC_PROP_PRIVATE, 0, "driver-private"} 3665903Ssowmini }; 3675903Ssowmini 36810491SRishi.Srivatsavai@Sun.COM typedef struct bridge_public_prop_s { 36910491SRishi.Srivatsavai@Sun.COM const char *bpp_name; 37010491SRishi.Srivatsavai@Sun.COM int bpp_code; 37110491SRishi.Srivatsavai@Sun.COM } bridge_public_prop_t; 37210491SRishi.Srivatsavai@Sun.COM 37310491SRishi.Srivatsavai@Sun.COM static const bridge_public_prop_t bridge_prop[] = { 37410491SRishi.Srivatsavai@Sun.COM { "stp", PT_CFG_NON_STP }, 37510491SRishi.Srivatsavai@Sun.COM { "stp_priority", PT_CFG_PRIO }, 37610491SRishi.Srivatsavai@Sun.COM { "stp_cost", PT_CFG_COST }, 37710491SRishi.Srivatsavai@Sun.COM { "stp_edge", PT_CFG_EDGE }, 37810491SRishi.Srivatsavai@Sun.COM { "stp_p2p", PT_CFG_P2P }, 37910491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", PT_CFG_MCHECK }, 38010491SRishi.Srivatsavai@Sun.COM { NULL, 0 } 38110491SRishi.Srivatsavai@Sun.COM }; 38210491SRishi.Srivatsavai@Sun.COM 3835903Ssowmini static val_desc_t link_duplex_vals[] = { 3845903Ssowmini { "half", LINK_DUPLEX_HALF }, 3855903Ssowmini { "full", LINK_DUPLEX_HALF } 3865903Ssowmini }; 3875903Ssowmini static val_desc_t link_status_vals[] = { 3885903Ssowmini { "up", LINK_STATE_UP }, 3895903Ssowmini { "down", LINK_STATE_DOWN } 3905903Ssowmini }; 3915903Ssowmini static val_desc_t link_01_vals[] = { 3925903Ssowmini { "1", 1 }, 3935903Ssowmini { "0", 0 } 3945903Ssowmini }; 3955903Ssowmini static val_desc_t link_flow_vals[] = { 3965903Ssowmini { "no", LINK_FLOWCTRL_NONE }, 3975903Ssowmini { "tx", LINK_FLOWCTRL_TX }, 3985903Ssowmini { "rx", LINK_FLOWCTRL_RX }, 3995903Ssowmini { "bi", LINK_FLOWCTRL_BI } 4005903Ssowmini }; 4018275SEric Cheng static val_desc_t link_priority_vals[] = { 4028275SEric Cheng { "low", MPL_LOW }, 4038275SEric Cheng { "medium", MPL_MEDIUM }, 4048275SEric Cheng { "high", MPL_HIGH } 4058275SEric Cheng }; 4065903Ssowmini 4078874SSebastien.Roy@Sun.COM static val_desc_t link_tagmode_vals[] = { 4088874SSebastien.Roy@Sun.COM { "normal", LINK_TAGMODE_NORMAL }, 4098874SSebastien.Roy@Sun.COM { "vlanonly", LINK_TAGMODE_VLANONLY } 4108874SSebastien.Roy@Sun.COM }; 4118874SSebastien.Roy@Sun.COM 41210734SEric Cheng static val_desc_t link_protect_vals[] = { 41310734SEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 41411878SVenu.Iyer@Sun.COM { "restricted", MPT_RESTRICTED }, 41510734SEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 41611878SVenu.Iyer@Sun.COM { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 41710734SEric Cheng }; 41810734SEric Cheng 4195895Syz147064 static val_desc_t dladm_wlan_radio_vals[] = { 4205895Syz147064 { "on", DLADM_WLAN_RADIO_ON }, 4215895Syz147064 { "off", DLADM_WLAN_RADIO_OFF } 4225895Syz147064 }; 4235895Syz147064 4245895Syz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 4255895Syz147064 { "off", DLADM_WLAN_PM_OFF }, 4265895Syz147064 { "fast", DLADM_WLAN_PM_FAST }, 4275895Syz147064 { "max", DLADM_WLAN_PM_MAX } 4285895Syz147064 }; 4295895Syz147064 43010491SRishi.Srivatsavai@Sun.COM static val_desc_t stp_p2p_vals[] = { 43110491SRishi.Srivatsavai@Sun.COM { "true", P2P_FORCE_TRUE }, 43210491SRishi.Srivatsavai@Sun.COM { "false", P2P_FORCE_FALSE }, 43310491SRishi.Srivatsavai@Sun.COM { "auto", P2P_AUTO } 43410491SRishi.Srivatsavai@Sun.COM }; 43510491SRishi.Srivatsavai@Sun.COM 436*12303SRajkumar.Sivaprakasam@Sun.COM static val_desc_t dladm_part_linkmode_vals[] = { 437*12303SRajkumar.Sivaprakasam@Sun.COM { "cm", DLADM_PART_CM_MODE }, 438*12303SRajkumar.Sivaprakasam@Sun.COM { "ud", DLADM_PART_UD_MODE }, 43912163SRamaswamy.Tummala@Sun.COM }; 44012163SRamaswamy.Tummala@Sun.COM 4418275SEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 4428275SEric Cheng #define RESET_VAL ((uintptr_t)-1) 44311878SVenu.Iyer@Sun.COM #define UNSPEC_VAL ((uintptr_t)-2) 4448275SEric Cheng 4453448Sdh155122 static prop_desc_t prop_table[] = { 4465903Ssowmini { "channel", { NULL, 0 }, 4475903Ssowmini NULL, 0, NULL, NULL, 44811878SVenu.Iyer@Sun.COM get_channel, NULL, 0, 4495903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4505895Syz147064 4515895Syz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 4525895Syz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 45311878SVenu.Iyer@Sun.COM set_powermode, NULL, 45411878SVenu.Iyer@Sun.COM get_powermode, NULL, 0, 4555903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4565895Syz147064 4575895Syz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 4585895Syz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 45911878SVenu.Iyer@Sun.COM set_radio, NULL, 46011878SVenu.Iyer@Sun.COM get_radio, NULL, 0, 4615903Ssowmini DATALINK_CLASS_PHYS, DL_WIFI }, 4625895Syz147064 463*12303SRajkumar.Sivaprakasam@Sun.COM { "linkmode", { "cm", DLADM_PART_CM_MODE }, 464*12303SRajkumar.Sivaprakasam@Sun.COM dladm_part_linkmode_vals, VALCNT(dladm_part_linkmode_vals), 46512163SRamaswamy.Tummala@Sun.COM set_public_prop, NULL, get_linkmode_prop, NULL, 0, 46612163SRamaswamy.Tummala@Sun.COM DATALINK_CLASS_PART, DL_IB }, 46712163SRamaswamy.Tummala@Sun.COM 4685895Syz147064 { "speed", { "", 0 }, NULL, 0, 46911878SVenu.Iyer@Sun.COM set_rate, get_rate_mod, 47011878SVenu.Iyer@Sun.COM get_rate, check_rate, 0, 4715960Ssowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 4725895Syz147064 4736512Ssowmini { "autopush", { "", 0 }, NULL, 0, 47411878SVenu.Iyer@Sun.COM set_public_prop, NULL, 47511878SVenu.Iyer@Sun.COM get_autopush, check_autopush, PD_CHECK_ALLOC, 4765903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4775895Syz147064 4786512Ssowmini { "zone", { "", 0 }, NULL, 0, 47911878SVenu.Iyer@Sun.COM set_zone, NULL, 48011878SVenu.Iyer@Sun.COM get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 4815903Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4825903Ssowmini 4838275SEric Cheng { "duplex", { "", 0 }, 4845903Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 48511878SVenu.Iyer@Sun.COM NULL, NULL, get_duplex, NULL, 4865903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4875903Ssowmini 4888275SEric Cheng { "state", { "up", LINK_STATE_UP }, 4895903Ssowmini link_status_vals, VALCNT(link_status_vals), 49011878SVenu.Iyer@Sun.COM NULL, NULL, get_link_state, NULL, 4916512Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 4925903Ssowmini 49310191SSowmini.Varadhan@Sun.COM { "adv_autoneg_cap", { "", 0 }, 4945903Ssowmini link_01_vals, VALCNT(link_01_vals), 49511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 4965903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 4975903Ssowmini 4986512Ssowmini { "mtu", { "", 0 }, NULL, 0, 49911878SVenu.Iyer@Sun.COM set_public_prop, get_range, 50011878SVenu.Iyer@Sun.COM get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 5017342SAruna.Ramakrishna@Sun.COM DATALINK_ANY_MEDIATYPE }, 5025903Ssowmini 5036512Ssowmini { "flowctrl", { "", 0 }, 5045903Ssowmini link_flow_vals, VALCNT(link_flow_vals), 50511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_flowctl, NULL, 5065903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5075903Ssowmini 5089449Sxiuyan.wang@Sun.COM { "adv_10gfdx_cap", { "", 0 }, 5099449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 51011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5119449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5129449Sxiuyan.wang@Sun.COM 5139449Sxiuyan.wang@Sun.COM { "en_10gfdx_cap", { "", 0 }, 5149449Sxiuyan.wang@Sun.COM link_01_vals, VALCNT(link_01_vals), 51511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5169449Sxiuyan.wang@Sun.COM 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5179449Sxiuyan.wang@Sun.COM 5186512Ssowmini { "adv_1000fdx_cap", { "", 0 }, 5196512Ssowmini link_01_vals, VALCNT(link_01_vals), 52011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5215903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5225903Ssowmini 5236512Ssowmini { "en_1000fdx_cap", { "", 0 }, 5245903Ssowmini link_01_vals, VALCNT(link_01_vals), 52511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5265903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5275903Ssowmini 5286512Ssowmini { "adv_1000hdx_cap", { "", 0 }, 5295903Ssowmini link_01_vals, VALCNT(link_01_vals), 53011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5315903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5325903Ssowmini 5336512Ssowmini { "en_1000hdx_cap", { "", 0 }, 5345903Ssowmini link_01_vals, VALCNT(link_01_vals), 53511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5365903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5375903Ssowmini 5386512Ssowmini { "adv_100fdx_cap", { "", 0 }, 5395903Ssowmini link_01_vals, VALCNT(link_01_vals), 54011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5415903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5425903Ssowmini 5436512Ssowmini { "en_100fdx_cap", { "", 0 }, 5445903Ssowmini link_01_vals, VALCNT(link_01_vals), 54511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5465903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5475903Ssowmini 5486512Ssowmini { "adv_100hdx_cap", { "", 0 }, 5495903Ssowmini link_01_vals, VALCNT(link_01_vals), 55011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5515903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5525903Ssowmini 5536512Ssowmini { "en_100hdx_cap", { "", 0 }, 5545903Ssowmini link_01_vals, VALCNT(link_01_vals), 55511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5565903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5575903Ssowmini 5586512Ssowmini { "adv_10fdx_cap", { "", 0 }, 5595903Ssowmini link_01_vals, VALCNT(link_01_vals), 56011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5615903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5625903Ssowmini 5636512Ssowmini { "en_10fdx_cap", { "", 0 }, 5645903Ssowmini link_01_vals, VALCNT(link_01_vals), 56511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5665903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5675903Ssowmini 5686512Ssowmini { "adv_10hdx_cap", { "", 0 }, 5695903Ssowmini link_01_vals, VALCNT(link_01_vals), 57011878SVenu.Iyer@Sun.COM NULL, NULL, get_binary, NULL, 5715903Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5725903Ssowmini 5736512Ssowmini { "en_10hdx_cap", { "", 0 }, 5745903Ssowmini link_01_vals, VALCNT(link_01_vals), 57511878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_binary, NULL, 5768275SEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5778275SEric Cheng 5788275SEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 57911878SVenu.Iyer@Sun.COM set_resource, NULL, 58011878SVenu.Iyer@Sun.COM get_maxbw, check_maxbw, PD_CHECK_ALLOC, 5818275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5828275SEric Cheng 5838275SEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 58411878SVenu.Iyer@Sun.COM set_resource, NULL, 58511878SVenu.Iyer@Sun.COM get_cpus, check_cpus, 0, 58611878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 58711878SVenu.Iyer@Sun.COM 58811878SVenu.Iyer@Sun.COM { "cpus-effective", { "--", 0 }, 58911878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 59011878SVenu.Iyer@Sun.COM get_cpus, 0, 0, 5918275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5928275SEric Cheng 59311878SVenu.Iyer@Sun.COM { "pool", { "--", RESET_VAL }, NULL, 0, 59411878SVenu.Iyer@Sun.COM set_resource, NULL, 59511878SVenu.Iyer@Sun.COM get_pool, check_pool, 0, 59611878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 59711878SVenu.Iyer@Sun.COM 59811878SVenu.Iyer@Sun.COM { "pool-effective", { "--", 0 }, 59911878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 60011878SVenu.Iyer@Sun.COM get_pool, 0, 0, 60111878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 60211878SVenu.Iyer@Sun.COM 60311878SVenu.Iyer@Sun.COM { "priority", { "high", MPL_RESET }, 60411878SVenu.Iyer@Sun.COM link_priority_vals, VALCNT(link_priority_vals), set_resource, 60511878SVenu.Iyer@Sun.COM NULL, get_priority, check_prop, 0, 6068275SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6078874SSebastien.Roy@Sun.COM 6088874SSebastien.Roy@Sun.COM { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 6098874SSebastien.Roy@Sun.COM link_tagmode_vals, VALCNT(link_tagmode_vals), 61011878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_tagmode, 6118874SSebastien.Roy@Sun.COM NULL, 0, 6128874SSebastien.Roy@Sun.COM DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 61310491SRishi.Srivatsavai@Sun.COM DL_ETHER }, 61410491SRishi.Srivatsavai@Sun.COM 61510616SSebastien.Roy@Sun.COM { "hoplimit", { "", 0 }, NULL, 0, 61611878SVenu.Iyer@Sun.COM set_public_prop, get_range, get_uint32, 61711878SVenu.Iyer@Sun.COM check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 61810616SSebastien.Roy@Sun.COM 61910616SSebastien.Roy@Sun.COM { "encaplimit", { "", 0 }, NULL, 0, 62011878SVenu.Iyer@Sun.COM set_public_prop, get_range, get_uint32, 62111878SVenu.Iyer@Sun.COM check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 62210616SSebastien.Roy@Sun.COM 62310491SRishi.Srivatsavai@Sun.COM { "forward", { "1", 1 }, 62410491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 62510491SRishi.Srivatsavai@Sun.COM set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 62610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 62710491SRishi.Srivatsavai@Sun.COM 62810491SRishi.Srivatsavai@Sun.COM { "default_tag", { "1", 1 }, NULL, 0, 62910491SRishi.Srivatsavai@Sun.COM set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 63010491SRishi.Srivatsavai@Sun.COM 0, 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 { "learn_limit", { "1000", 1000 }, NULL, 0, 63411878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_uint32, 63511878SVenu.Iyer@Sun.COM check_uint32, 0, 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 { "learn_decay", { "200", 200 }, NULL, 0, 64011878SVenu.Iyer@Sun.COM set_public_prop, NULL, get_uint32, 64111878SVenu.Iyer@Sun.COM check_uint32, 0, 64210491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 64310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 64410491SRishi.Srivatsavai@Sun.COM 64510491SRishi.Srivatsavai@Sun.COM { "stp", { "1", 1 }, 64610491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 64711878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 64810491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 64910491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 65010491SRishi.Srivatsavai@Sun.COM 65110491SRishi.Srivatsavai@Sun.COM { "stp_priority", { "128", 128 }, NULL, 0, 65211878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 65310491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 65410491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 65510491SRishi.Srivatsavai@Sun.COM 65610491SRishi.Srivatsavai@Sun.COM { "stp_cost", { "auto", 0 }, NULL, 0, 65711878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, 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_edge", { "1", 1 }, 66210491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 66311878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, 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 }, 66610491SRishi.Srivatsavai@Sun.COM 66710491SRishi.Srivatsavai@Sun.COM { "stp_p2p", { "auto", P2P_AUTO }, 66810491SRishi.Srivatsavai@Sun.COM stp_p2p_vals, VALCNT(stp_p2p_vals), 66911878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 67010491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 67110491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 67210491SRishi.Srivatsavai@Sun.COM 67310491SRishi.Srivatsavai@Sun.COM { "stp_mcheck", { "0", 0 }, 67410491SRishi.Srivatsavai@Sun.COM link_01_vals, VALCNT(link_01_vals), 67511878SVenu.Iyer@Sun.COM set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 67610491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 67710491SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 67810734SEric Cheng 67910734SEric Cheng { "protection", { "--", RESET_VAL }, 68010734SEric Cheng link_protect_vals, VALCNT(link_protect_vals), 68111878SVenu.Iyer@Sun.COM set_resource, NULL, get_protection, check_prop, 0, 68210734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 68310734SEric Cheng 68410734SEric Cheng { "allowed-ips", { "--", 0 }, 68511878SVenu.Iyer@Sun.COM NULL, 0, set_resource, NULL, 68611878SVenu.Iyer@Sun.COM get_allowedips, check_allowedips, PD_CHECK_ALLOC, 68711878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 68811878SVenu.Iyer@Sun.COM 68911878SVenu.Iyer@Sun.COM { "allowed-dhcp-cids", { "--", 0 }, 69011878SVenu.Iyer@Sun.COM NULL, 0, set_resource, NULL, 69111878SVenu.Iyer@Sun.COM get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 69211878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 69311878SVenu.Iyer@Sun.COM 69411878SVenu.Iyer@Sun.COM { "rxrings", { "--", RESET_VAL }, NULL, 0, 69511878SVenu.Iyer@Sun.COM set_resource, get_rings_range, get_rxrings, check_rings, 0, 69611878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 69711878SVenu.Iyer@Sun.COM 69811878SVenu.Iyer@Sun.COM { "rxrings-effective", { "--", 0 }, 69911878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 70011878SVenu.Iyer@Sun.COM get_rxrings, NULL, 0, 70111878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 70211878SVenu.Iyer@Sun.COM 70311878SVenu.Iyer@Sun.COM { "txrings", { "--", RESET_VAL }, NULL, 0, 70411878SVenu.Iyer@Sun.COM set_resource, get_rings_range, get_txrings, check_rings, 0, 70510734SEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 70611878SVenu.Iyer@Sun.COM 70711878SVenu.Iyer@Sun.COM { "txrings-effective", { "--", 0 }, 70811878SVenu.Iyer@Sun.COM NULL, 0, NULL, NULL, 70911878SVenu.Iyer@Sun.COM get_txrings, NULL, 0, 71011878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 71111878SVenu.Iyer@Sun.COM 71211878SVenu.Iyer@Sun.COM { "txrings-available", { "", 0 }, NULL, 0, 71311878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 71411878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 71511878SVenu.Iyer@Sun.COM 71611878SVenu.Iyer@Sun.COM { "rxrings-available", { "", 0 }, NULL, 0, 71711878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 71811878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 71911878SVenu.Iyer@Sun.COM 72011878SVenu.Iyer@Sun.COM { "rxhwclnt-available", { "", 0 }, NULL, 0, 72111878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 72211878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 72311878SVenu.Iyer@Sun.COM 72411878SVenu.Iyer@Sun.COM { "txhwclnt-available", { "", 0 }, NULL, 0, 72511878SVenu.Iyer@Sun.COM NULL, NULL, get_cntavail, NULL, 0, 72611878SVenu.Iyer@Sun.COM DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 72711878SVenu.Iyer@Sun.COM 7283448Sdh155122 }; 7293448Sdh155122 7305895Syz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 7315895Syz147064 7328275SEric Cheng static resource_prop_t rsrc_prop_table[] = { 73311878SVenu.Iyer@Sun.COM {"maxbw", extract_maxbw}, 73411878SVenu.Iyer@Sun.COM {"priority", extract_priority}, 73511878SVenu.Iyer@Sun.COM {"cpus", extract_cpus}, 73611878SVenu.Iyer@Sun.COM {"cpus-effective", extract_cpus}, 73711878SVenu.Iyer@Sun.COM {"pool", extract_pool}, 73811878SVenu.Iyer@Sun.COM {"pool-effective", extract_pool}, 73911878SVenu.Iyer@Sun.COM {"protection", extract_protection}, 74011878SVenu.Iyer@Sun.COM {"allowed-ips", extract_allowedips}, 74111878SVenu.Iyer@Sun.COM {"allowed-dhcp-cids", extract_allowedcids}, 74211878SVenu.Iyer@Sun.COM {"rxrings", extract_rxrings}, 74311878SVenu.Iyer@Sun.COM {"rxrings-effective", extract_rxrings}, 74411878SVenu.Iyer@Sun.COM {"txrings", extract_txrings}, 74511878SVenu.Iyer@Sun.COM {"txrings-effective", extract_txrings} 7468275SEric Cheng }; 7478275SEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 7488275SEric Cheng sizeof (resource_prop_t)) 7498275SEric Cheng 7507663SSowmini.Varadhan@Sun.COM /* 7517663SSowmini.Varadhan@Sun.COM * when retrieving private properties, we pass down a buffer with 7527663SSowmini.Varadhan@Sun.COM * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 7537663SSowmini.Varadhan@Sun.COM */ 7547663SSowmini.Varadhan@Sun.COM #define DLADM_PROP_BUF_CHUNK 1024 7557663SSowmini.Varadhan@Sun.COM 7568453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 7578453SAnurag.Maskey@Sun.COM const char *, char **, uint_t); 7588453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 7598453SAnurag.Maskey@Sun.COM const char *, char **, uint_t *); 7608460SArtem.Kachitchkin@Sun.COM static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 7618460SArtem.Kachitchkin@Sun.COM datalink_id_t, void *, int (*)(dladm_handle_t, 7628460SArtem.Kachitchkin@Sun.COM datalink_id_t, const char *, void *)); 7638453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 7648453SAnurag.Maskey@Sun.COM datalink_class_t, uint32_t, prop_desc_t *, char **, 7658453SAnurag.Maskey@Sun.COM uint_t, uint_t); 7668453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 7678453SAnurag.Maskey@Sun.COM const char *, char **, uint_t, uint_t); 7688453SAnurag.Maskey@Sun.COM static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 7698453SAnurag.Maskey@Sun.COM datalink_id_t, datalink_media_t, uint_t); 7708275SEric Cheng 7715895Syz147064 /* 7725895Syz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 7735895Syz147064 * rates to be retrieved. However, we cannot increase it at this 7745895Syz147064 * time because it will break binary compatibility with unbundled 7755895Syz147064 * WiFi drivers and utilities. So for now we define an additional 7765895Syz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 7775895Syz147064 */ 7785895Syz147064 #define MAX_SUPPORT_RATES 64 7795895Syz147064 7805895Syz147064 #define AP_ANCHOR "[anchor]" 7815895Syz147064 #define AP_DELIMITER '.' 7825895Syz147064 78310734SEric Cheng /* ARGSUSED */ 7845895Syz147064 static dladm_status_t 78511878SVenu.Iyer@Sun.COM check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 78611878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 78711878SVenu.Iyer@Sun.COM datalink_media_t media) 7885895Syz147064 { 7895895Syz147064 int i, j; 7903147Sxc151355 7915895Syz147064 for (j = 0; j < val_cnt; j++) { 7925895Syz147064 for (i = 0; i < pdp->pd_noptval; i++) { 79310734SEric Cheng if (strcasecmp(prop_val[j], 7945895Syz147064 pdp->pd_optval[i].vd_name) == 0) { 7955895Syz147064 break; 7965895Syz147064 } 7975895Syz147064 } 79810734SEric Cheng if (i == pdp->pd_noptval) 79910734SEric Cheng return (DLADM_STATUS_BADVAL); 80010734SEric Cheng 80110734SEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 8025895Syz147064 } 80310734SEric Cheng return (DLADM_STATUS_OK); 8045895Syz147064 } 8055895Syz147064 8065895Syz147064 static dladm_status_t 8078453SAnurag.Maskey@Sun.COM i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 8088453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 8098453SAnurag.Maskey@Sun.COM uint_t val_cnt, uint_t flags) 8103147Sxc151355 { 8115895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 8125895Syz147064 val_desc_t *vdp = NULL; 8135895Syz147064 boolean_t needfree = B_FALSE; 8145895Syz147064 uint_t cnt, i; 8153147Sxc151355 8165895Syz147064 if (!(pdp->pd_class & class)) 8175895Syz147064 return (DLADM_STATUS_BADARG); 8185895Syz147064 8195895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 8203147Sxc151355 return (DLADM_STATUS_BADARG); 8213147Sxc151355 8225895Syz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 8235895Syz147064 return (DLADM_STATUS_TEMPONLY); 8245895Syz147064 8255895Syz147064 if (!(flags & DLADM_OPT_ACTIVE)) 8265895Syz147064 return (DLADM_STATUS_OK); 8275895Syz147064 8285895Syz147064 if (pdp->pd_set == NULL) 8295895Syz147064 return (DLADM_STATUS_PROPRDONLY); 8303448Sdh155122 8315895Syz147064 if (prop_val != NULL) { 83211878SVenu.Iyer@Sun.COM vdp = calloc(val_cnt, sizeof (val_desc_t)); 8335895Syz147064 if (vdp == NULL) 8345895Syz147064 return (DLADM_STATUS_NOMEM); 8355895Syz147064 8365895Syz147064 if (pdp->pd_check != NULL) { 8378275SEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 8388453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, prop_val, 83911878SVenu.Iyer@Sun.COM val_cnt, flags, vdp, media); 8405895Syz147064 } else if (pdp->pd_optval != NULL) { 84111878SVenu.Iyer@Sun.COM status = check_prop(handle, pdp, linkid, prop_val, 84211878SVenu.Iyer@Sun.COM val_cnt, flags, vdp, media); 8435895Syz147064 } else { 8443448Sdh155122 status = DLADM_STATUS_BADARG; 8453147Sxc151355 } 8465895Syz147064 8473147Sxc151355 if (status != DLADM_STATUS_OK) 8485895Syz147064 goto done; 8495895Syz147064 8505895Syz147064 cnt = val_cnt; 8515895Syz147064 } else { 8528275SEric Cheng boolean_t defval = B_FALSE; 8538275SEric Cheng 8545895Syz147064 if (pdp->pd_defval.vd_name == NULL) 8555895Syz147064 return (DLADM_STATUS_NOTSUP); 8565895Syz147064 8577342SAruna.Ramakrishna@Sun.COM cnt = 1; 8588275SEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 8598275SEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 86011878SVenu.Iyer@Sun.COM if ((vdp = calloc(1, sizeof (val_desc_t))) == NULL) 8616512Ssowmini return (DLADM_STATUS_NOMEM); 8627342SAruna.Ramakrishna@Sun.COM 8638275SEric Cheng if (defval) { 8648275SEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 8658275SEric Cheng sizeof (val_desc_t)); 8668275SEric Cheng } else if (pdp->pd_check != NULL) { 8678453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 86811878SVenu.Iyer@Sun.COM prop_val, cnt, flags, vdp, media); 8697342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 8707342SAruna.Ramakrishna@Sun.COM goto done; 8717342SAruna.Ramakrishna@Sun.COM } 8726512Ssowmini } else { 8738453SAnurag.Maskey@Sun.COM status = i_dladm_getset_defval(handle, pdp, linkid, 8746512Ssowmini media, flags); 8756512Ssowmini return (status); 8766512Ssowmini } 8775895Syz147064 } 87810491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_AFTER_PERM) 87910491SRishi.Srivatsavai@Sun.COM status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 88010491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_PERMONLY; 88110491SRishi.Srivatsavai@Sun.COM else 88210491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 88310491SRishi.Srivatsavai@Sun.COM media); 8845895Syz147064 if (needfree) { 8855895Syz147064 for (i = 0; i < cnt; i++) 8865903Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 8873147Sxc151355 } 8885895Syz147064 done: 8895895Syz147064 free(vdp); 8905895Syz147064 return (status); 8915895Syz147064 } 8925895Syz147064 8935895Syz147064 static dladm_status_t 8948453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8958453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 8965895Syz147064 { 8975895Syz147064 int i; 8985895Syz147064 boolean_t found = B_FALSE; 8995895Syz147064 datalink_class_t class; 9005895Syz147064 uint32_t media; 9015895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9025895Syz147064 9038453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9048453SAnurag.Maskey@Sun.COM NULL, 0); 9055895Syz147064 if (status != DLADM_STATUS_OK) 9065895Syz147064 return (status); 9075895Syz147064 9085895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 9095895Syz147064 prop_desc_t *pdp = &prop_table[i]; 9105895Syz147064 dladm_status_t s; 9115895Syz147064 9125895Syz147064 if (prop_name != NULL && 9135895Syz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 9145895Syz147064 continue; 9155895Syz147064 found = B_TRUE; 9168453SAnurag.Maskey@Sun.COM s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 9178453SAnurag.Maskey@Sun.COM prop_val, val_cnt, flags); 9183448Sdh155122 9195895Syz147064 if (prop_name != NULL) { 9205895Syz147064 status = s; 9215895Syz147064 break; 9225895Syz147064 } else { 9235895Syz147064 if (s != DLADM_STATUS_OK && 9245895Syz147064 s != DLADM_STATUS_NOTSUP) 9255895Syz147064 status = s; 9265895Syz147064 } 9275895Syz147064 } 9285903Ssowmini if (!found) { 9295903Ssowmini if (prop_name[0] == '_') { 9305903Ssowmini /* other private properties */ 9319692SRishi.Srivatsavai@Sun.COM status = i_dladm_set_private_prop(handle, linkid, 9329692SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cnt, flags); 9335903Ssowmini } else { 9345903Ssowmini status = DLADM_STATUS_NOTFOUND; 9355903Ssowmini } 9365903Ssowmini } 9375895Syz147064 return (status); 9385895Syz147064 } 9395895Syz147064 9405895Syz147064 /* 9415895Syz147064 * Set/reset link property for specific link 9425895Syz147064 */ 9435895Syz147064 dladm_status_t 9448453SAnurag.Maskey@Sun.COM dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9458453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 9465895Syz147064 { 9475895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 9485895Syz147064 9495895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 9505895Syz147064 (prop_val == NULL && val_cnt > 0) || 9515895Syz147064 (prop_val != NULL && val_cnt == 0) || 9525895Syz147064 (prop_name == NULL && prop_val != NULL)) { 9535895Syz147064 return (DLADM_STATUS_BADARG); 9545895Syz147064 } 9555895Syz147064 9569692SRishi.Srivatsavai@Sun.COM /* 9579692SRishi.Srivatsavai@Sun.COM * Check for valid link property against the flags passed 9589692SRishi.Srivatsavai@Sun.COM * and set the link property when active flag is passed. 9599692SRishi.Srivatsavai@Sun.COM */ 9608453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 9615895Syz147064 val_cnt, flags); 9625895Syz147064 if (status != DLADM_STATUS_OK) 9635895Syz147064 return (status); 9645895Syz147064 9655895Syz147064 if (flags & DLADM_OPT_PERSIST) { 9668453SAnurag.Maskey@Sun.COM status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 9673147Sxc151355 prop_val, val_cnt); 96810491SRishi.Srivatsavai@Sun.COM 96910491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 97010491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp = prop_table; 97110491SRishi.Srivatsavai@Sun.COM int i; 97210491SRishi.Srivatsavai@Sun.COM 97310491SRishi.Srivatsavai@Sun.COM for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 97410491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_flags & PD_AFTER_PERM)) 97510491SRishi.Srivatsavai@Sun.COM continue; 97610491SRishi.Srivatsavai@Sun.COM if (prop_name != NULL && 97710491SRishi.Srivatsavai@Sun.COM strcasecmp(prop_name, pdp->pd_name) != 0) 97810491SRishi.Srivatsavai@Sun.COM continue; 97910491SRishi.Srivatsavai@Sun.COM status = pdp->pd_set(handle, pdp, linkid, NULL, 98010491SRishi.Srivatsavai@Sun.COM 0, flags, 0); 98110491SRishi.Srivatsavai@Sun.COM } 98210491SRishi.Srivatsavai@Sun.COM } 9833147Sxc151355 } 9843147Sxc151355 return (status); 9853147Sxc151355 } 9863147Sxc151355 9875895Syz147064 /* 9888460SArtem.Kachitchkin@Sun.COM * Walk all link properties of the given specific link. 9898460SArtem.Kachitchkin@Sun.COM * 9908460SArtem.Kachitchkin@Sun.COM * Note: this function currently lacks the ability to walk _all_ private 9918460SArtem.Kachitchkin@Sun.COM * properties if the link, because there is no kernel interface to 9928460SArtem.Kachitchkin@Sun.COM * retrieve all known private property names. Once such an interface 9938460SArtem.Kachitchkin@Sun.COM * is added, this function should be fixed accordingly. 9945895Syz147064 */ 9953147Sxc151355 dladm_status_t 9968453SAnurag.Maskey@Sun.COM dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 9978453SAnurag.Maskey@Sun.COM int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 9983147Sxc151355 { 9995895Syz147064 dladm_status_t status; 10005895Syz147064 datalink_class_t class; 10015895Syz147064 uint_t media; 10025895Syz147064 int i; 10035895Syz147064 10045895Syz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 10055895Syz147064 return (DLADM_STATUS_BADARG); 10065895Syz147064 10078453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10088453SAnurag.Maskey@Sun.COM NULL, 0); 10095895Syz147064 if (status != DLADM_STATUS_OK) 10105895Syz147064 return (status); 10115895Syz147064 10128460SArtem.Kachitchkin@Sun.COM /* public */ 10135895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 10145895Syz147064 if (!(prop_table[i].pd_class & class)) 10155895Syz147064 continue; 10165895Syz147064 10175895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 10185895Syz147064 continue; 10195895Syz147064 10208453SAnurag.Maskey@Sun.COM if (func(handle, linkid, prop_table[i].pd_name, arg) == 10215895Syz147064 DLADM_WALK_TERMINATE) { 10225895Syz147064 break; 10235895Syz147064 } 10245895Syz147064 } 10255895Syz147064 10268460SArtem.Kachitchkin@Sun.COM /* private */ 10278460SArtem.Kachitchkin@Sun.COM status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 10288460SArtem.Kachitchkin@Sun.COM 10298460SArtem.Kachitchkin@Sun.COM return (status); 10305895Syz147064 } 10313448Sdh155122 10325895Syz147064 /* 10335895Syz147064 * Get linkprop of the given specific link. 10345895Syz147064 */ 10355895Syz147064 dladm_status_t 10368453SAnurag.Maskey@Sun.COM dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10378453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, const char *prop_name, char **prop_val, 10388453SAnurag.Maskey@Sun.COM uint_t *val_cntp) 10395895Syz147064 { 10405895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 10415895Syz147064 datalink_class_t class; 10425895Syz147064 uint_t media; 10435895Syz147064 prop_desc_t *pdp; 10446512Ssowmini uint_t cnt, dld_flags = 0; 10455895Syz147064 int i; 10468118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 10475895Syz147064 10486512Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 104911878SVenu.Iyer@Sun.COM dld_flags |= DLD_PROP_DEFAULT; 10509514SGirish.Moodalbail@Sun.COM else if (type == DLADM_PROP_VAL_MODIFIABLE) 105111878SVenu.Iyer@Sun.COM dld_flags |= DLD_PROP_POSSIBLE; 10526512Ssowmini 10535895Syz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 10545895Syz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 10555895Syz147064 return (DLADM_STATUS_BADARG); 10565895Syz147064 10575895Syz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 10585895Syz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 10595895Syz147064 break; 10605895Syz147064 10615903Ssowmini if (i == DLADM_MAX_PROPS) { 10625903Ssowmini if (prop_name[0] == '_') { 10635903Ssowmini /* 10645903Ssowmini * private property. 10655903Ssowmini */ 10668460SArtem.Kachitchkin@Sun.COM if (type == DLADM_PROP_VAL_PERSISTENT) 10678460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_linkprop_db(handle, linkid, 10688460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp)); 10698460SArtem.Kachitchkin@Sun.COM else 10708460SArtem.Kachitchkin@Sun.COM return (i_dladm_get_priv_prop(handle, linkid, 10718460SArtem.Kachitchkin@Sun.COM prop_name, prop_val, val_cntp, type, 10728460SArtem.Kachitchkin@Sun.COM dld_flags)); 10735903Ssowmini } else { 10745903Ssowmini return (DLADM_STATUS_NOTFOUND); 10755903Ssowmini } 10765903Ssowmini } 10775895Syz147064 10785895Syz147064 pdp = &prop_table[i]; 10795895Syz147064 10808453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10818453SAnurag.Maskey@Sun.COM NULL, 0); 10825895Syz147064 if (status != DLADM_STATUS_OK) 10835895Syz147064 return (status); 10845895Syz147064 10855895Syz147064 if (!(pdp->pd_class & class)) 10865895Syz147064 return (DLADM_STATUS_BADARG); 10875895Syz147064 10885895Syz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 10893147Sxc151355 return (DLADM_STATUS_BADARG); 10903147Sxc151355 10915895Syz147064 switch (type) { 10925895Syz147064 case DLADM_PROP_VAL_CURRENT: 10938453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 10948453SAnurag.Maskey@Sun.COM media, dld_flags, &perm_flags); 10958118SVasumathi.Sundaram@Sun.COM break; 10968118SVasumathi.Sundaram@Sun.COM 10978118SVasumathi.Sundaram@Sun.COM case DLADM_PROP_VAL_PERM: 10988118SVasumathi.Sundaram@Sun.COM if (pdp->pd_set == NULL) { 10998118SVasumathi.Sundaram@Sun.COM perm_flags = MAC_PROP_PERM_READ; 11008118SVasumathi.Sundaram@Sun.COM } else { 11018453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 11028453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11038118SVasumathi.Sundaram@Sun.COM } 11048118SVasumathi.Sundaram@Sun.COM 11058118SVasumathi.Sundaram@Sun.COM *prop_val[0] = '\0'; 11069055SMichael.Lim@Sun.COM *val_cntp = 1; 11078275SEric Cheng if (status == DLADM_STATUS_OK) 11088275SEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 11095895Syz147064 break; 11105895Syz147064 11115895Syz147064 case DLADM_PROP_VAL_DEFAULT: 11126768Sar224390 /* 11136768Sar224390 * If defaults are not defined for the property, 11146768Sar224390 * pd_defval.vd_name should be null. If the driver 11156768Sar224390 * has to be contacted for the value, vd_name should 11166768Sar224390 * be the empty string (""). Otherwise, dladm will 11176768Sar224390 * just print whatever is in the table. 11186768Sar224390 */ 11195895Syz147064 if (pdp->pd_defval.vd_name == NULL) { 11205895Syz147064 status = DLADM_STATUS_NOTSUP; 11215895Syz147064 break; 11225895Syz147064 } 11236512Ssowmini 11246512Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 11258453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, 11268453SAnurag.Maskey@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11276512Ssowmini } else { 11286512Ssowmini (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 11296512Ssowmini } 11305895Syz147064 *val_cntp = 1; 11315895Syz147064 break; 11323448Sdh155122 11335895Syz147064 case DLADM_PROP_VAL_MODIFIABLE: 11345895Syz147064 if (pdp->pd_getmod != NULL) { 11358453SAnurag.Maskey@Sun.COM status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 11368118SVasumathi.Sundaram@Sun.COM val_cntp, media, dld_flags, &perm_flags); 11375895Syz147064 break; 11385895Syz147064 } 11395895Syz147064 cnt = pdp->pd_noptval; 11405895Syz147064 if (cnt == 0) { 11415895Syz147064 status = DLADM_STATUS_NOTSUP; 11425895Syz147064 } else if (cnt > *val_cntp) { 11435895Syz147064 status = DLADM_STATUS_TOOSMALL; 11445895Syz147064 } else { 11455895Syz147064 for (i = 0; i < cnt; i++) { 11465895Syz147064 (void) strcpy(prop_val[i], 11475895Syz147064 pdp->pd_optval[i].vd_name); 11485895Syz147064 } 11495895Syz147064 *val_cntp = cnt; 11505895Syz147064 } 11515895Syz147064 break; 11525895Syz147064 case DLADM_PROP_VAL_PERSISTENT: 11535895Syz147064 if (pdp->pd_flags & PD_TEMPONLY) 11545895Syz147064 return (DLADM_STATUS_TEMPONLY); 11558453SAnurag.Maskey@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 11565895Syz147064 prop_val, val_cntp); 11575895Syz147064 break; 11585895Syz147064 default: 11595895Syz147064 status = DLADM_STATUS_BADARG; 11605895Syz147064 break; 11613147Sxc151355 } 11623448Sdh155122 11635895Syz147064 return (status); 11645895Syz147064 } 11655895Syz147064 116610491SRishi.Srivatsavai@Sun.COM /* 116710491SRishi.Srivatsavai@Sun.COM * Get linkprop of the given specific link and run any possible conversion 116810491SRishi.Srivatsavai@Sun.COM * of the values using the check function for the property. Fails if the 116910491SRishi.Srivatsavai@Sun.COM * check function doesn't succeed for the property value. 117010491SRishi.Srivatsavai@Sun.COM */ 117110491SRishi.Srivatsavai@Sun.COM dladm_status_t 117210491SRishi.Srivatsavai@Sun.COM dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 117310491SRishi.Srivatsavai@Sun.COM dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 117410491SRishi.Srivatsavai@Sun.COM uint_t *val_cntp) 117510491SRishi.Srivatsavai@Sun.COM { 117610491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 117710491SRishi.Srivatsavai@Sun.COM datalink_class_t class; 117810491SRishi.Srivatsavai@Sun.COM uint_t media; 117910491SRishi.Srivatsavai@Sun.COM prop_desc_t *pdp; 118010491SRishi.Srivatsavai@Sun.COM uint_t dld_flags; 118110491SRishi.Srivatsavai@Sun.COM int valc, i; 118210491SRishi.Srivatsavai@Sun.COM char **prop_val; 118310491SRishi.Srivatsavai@Sun.COM uint_t perm_flags; 118410491SRishi.Srivatsavai@Sun.COM 118510491SRishi.Srivatsavai@Sun.COM if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 118610491SRishi.Srivatsavai@Sun.COM ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 118710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 118810491SRishi.Srivatsavai@Sun.COM 118910491SRishi.Srivatsavai@Sun.COM for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 119010491SRishi.Srivatsavai@Sun.COM if (strcasecmp(prop_name, pdp->pd_name) == 0) 119110491SRishi.Srivatsavai@Sun.COM break; 119210491SRishi.Srivatsavai@Sun.COM 119310491SRishi.Srivatsavai@Sun.COM if (pdp == prop_table + DLADM_MAX_PROPS) 119410491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTFOUND); 119510491SRishi.Srivatsavai@Sun.COM 119610491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_CHECK_ALLOC) 119710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 119810491SRishi.Srivatsavai@Sun.COM 119910491SRishi.Srivatsavai@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 120010491SRishi.Srivatsavai@Sun.COM NULL, 0); 120110491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 120210491SRishi.Srivatsavai@Sun.COM return (status); 120310491SRishi.Srivatsavai@Sun.COM 120410491SRishi.Srivatsavai@Sun.COM if (!(pdp->pd_class & class)) 120510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 120610491SRishi.Srivatsavai@Sun.COM 120710491SRishi.Srivatsavai@Sun.COM if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 120810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 120910491SRishi.Srivatsavai@Sun.COM 121010491SRishi.Srivatsavai@Sun.COM prop_val = malloc(*val_cntp * sizeof (*prop_val) + 121110491SRishi.Srivatsavai@Sun.COM *val_cntp * DLADM_PROP_VAL_MAX); 121210491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) 121310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOMEM); 121410491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 121510491SRishi.Srivatsavai@Sun.COM prop_val[valc] = (char *)(prop_val + *val_cntp) + 121610491SRishi.Srivatsavai@Sun.COM valc * DLADM_PROP_VAL_MAX; 121710491SRishi.Srivatsavai@Sun.COM 121811878SVenu.Iyer@Sun.COM dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 121910491SRishi.Srivatsavai@Sun.COM 122010491SRishi.Srivatsavai@Sun.COM switch (type) { 122110491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_CURRENT: 122210491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 122310491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 122410491SRishi.Srivatsavai@Sun.COM break; 122510491SRishi.Srivatsavai@Sun.COM 122610491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_DEFAULT: 122710491SRishi.Srivatsavai@Sun.COM /* 122810491SRishi.Srivatsavai@Sun.COM * If defaults are not defined for the property, 122910491SRishi.Srivatsavai@Sun.COM * pd_defval.vd_name should be null. If the driver 123010491SRishi.Srivatsavai@Sun.COM * has to be contacted for the value, vd_name should 123110491SRishi.Srivatsavai@Sun.COM * be the empty string (""). Otherwise, dladm will 123210491SRishi.Srivatsavai@Sun.COM * just print whatever is in the table. 123310491SRishi.Srivatsavai@Sun.COM */ 123410491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name == NULL) { 123510491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOTSUP; 123610491SRishi.Srivatsavai@Sun.COM break; 123710491SRishi.Srivatsavai@Sun.COM } 123810491SRishi.Srivatsavai@Sun.COM 123910491SRishi.Srivatsavai@Sun.COM if (pdp->pd_defval.vd_name[0] != '\0') { 124010491SRishi.Srivatsavai@Sun.COM *val_cntp = 1; 124110491SRishi.Srivatsavai@Sun.COM *ret_val = pdp->pd_defval.vd_val; 124210491SRishi.Srivatsavai@Sun.COM free(prop_val); 124310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 124410491SRishi.Srivatsavai@Sun.COM } 124510491SRishi.Srivatsavai@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 124610491SRishi.Srivatsavai@Sun.COM media, dld_flags, &perm_flags); 124710491SRishi.Srivatsavai@Sun.COM break; 124810491SRishi.Srivatsavai@Sun.COM 124910491SRishi.Srivatsavai@Sun.COM case DLADM_PROP_VAL_PERSISTENT: 125010491SRishi.Srivatsavai@Sun.COM if (pdp->pd_flags & PD_TEMPONLY) 125110491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_TEMPONLY; 125210491SRishi.Srivatsavai@Sun.COM else 125310491SRishi.Srivatsavai@Sun.COM status = i_dladm_get_linkprop_db(handle, linkid, 125410491SRishi.Srivatsavai@Sun.COM prop_name, prop_val, val_cntp); 125510491SRishi.Srivatsavai@Sun.COM break; 125610491SRishi.Srivatsavai@Sun.COM 125710491SRishi.Srivatsavai@Sun.COM default: 125810491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_BADARG; 125910491SRishi.Srivatsavai@Sun.COM break; 126010491SRishi.Srivatsavai@Sun.COM } 126110491SRishi.Srivatsavai@Sun.COM 126210491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 126310491SRishi.Srivatsavai@Sun.COM if (pdp->pd_check != NULL) { 126410491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp; 126510491SRishi.Srivatsavai@Sun.COM 126610491SRishi.Srivatsavai@Sun.COM vdp = malloc(sizeof (val_desc_t) * *val_cntp); 126710491SRishi.Srivatsavai@Sun.COM if (vdp == NULL) 126810491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_NOMEM; 126910491SRishi.Srivatsavai@Sun.COM else 127010491SRishi.Srivatsavai@Sun.COM status = pdp->pd_check(handle, pdp, linkid, 127111878SVenu.Iyer@Sun.COM prop_val, *val_cntp, 0, vdp, media); 127210491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 127310491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) 127410491SRishi.Srivatsavai@Sun.COM ret_val[valc] = vdp[valc].vd_val; 127510491SRishi.Srivatsavai@Sun.COM } 127610491SRishi.Srivatsavai@Sun.COM free(vdp); 127710491SRishi.Srivatsavai@Sun.COM } else { 127810491SRishi.Srivatsavai@Sun.COM for (valc = 0; valc < *val_cntp; valc++) { 127910491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pdp->pd_noptval; i++) { 128010491SRishi.Srivatsavai@Sun.COM if (strcmp(pdp->pd_optval[i].vd_name, 128110491SRishi.Srivatsavai@Sun.COM prop_val[valc]) == 0) { 128210491SRishi.Srivatsavai@Sun.COM ret_val[valc] = 128310491SRishi.Srivatsavai@Sun.COM pdp->pd_optval[i].vd_val; 128410491SRishi.Srivatsavai@Sun.COM break; 128510491SRishi.Srivatsavai@Sun.COM } 128610491SRishi.Srivatsavai@Sun.COM } 128710491SRishi.Srivatsavai@Sun.COM if (i == pdp->pd_noptval) { 128810491SRishi.Srivatsavai@Sun.COM status = DLADM_STATUS_FAILED; 128910491SRishi.Srivatsavai@Sun.COM break; 129010491SRishi.Srivatsavai@Sun.COM } 129110491SRishi.Srivatsavai@Sun.COM } 129210491SRishi.Srivatsavai@Sun.COM } 129310491SRishi.Srivatsavai@Sun.COM } 129410491SRishi.Srivatsavai@Sun.COM 129510491SRishi.Srivatsavai@Sun.COM free(prop_val); 129610491SRishi.Srivatsavai@Sun.COM 129710491SRishi.Srivatsavai@Sun.COM return (status); 129810491SRishi.Srivatsavai@Sun.COM } 129910491SRishi.Srivatsavai@Sun.COM 13005895Syz147064 /*ARGSUSED*/ 13015895Syz147064 static int 13028453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 13038453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 13045895Syz147064 { 130511878SVenu.Iyer@Sun.COM char *buf, **propvals; 130611878SVenu.Iyer@Sun.COM uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 130711878SVenu.Iyer@Sun.COM dladm_status_t status; 130811878SVenu.Iyer@Sun.COM dladm_linkprop_args_t *dla = arg; 13095895Syz147064 13105895Syz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 13115895Syz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 13125895Syz147064 return (DLADM_WALK_CONTINUE); 13135895Syz147064 } 13145895Syz147064 13155895Syz147064 propvals = (char **)(void *)buf; 13165895Syz147064 for (i = 0; i < valcnt; i++) { 13175895Syz147064 propvals[i] = buf + 13185895Syz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 13195895Syz147064 i * DLADM_PROP_VAL_MAX; 13205895Syz147064 } 13215895Syz147064 13228453SAnurag.Maskey@Sun.COM if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 13238453SAnurag.Maskey@Sun.COM prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 13245895Syz147064 goto done; 13255895Syz147064 } 13265895Syz147064 132711021SEric.Cheng@Sun.COM status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 132811878SVenu.Iyer@Sun.COM valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 132911878SVenu.Iyer@Sun.COM 133011021SEric.Cheng@Sun.COM if (status != DLADM_STATUS_OK) 133111878SVenu.Iyer@Sun.COM dla->dla_status = status; 13325895Syz147064 13335895Syz147064 done: 13345895Syz147064 if (buf != NULL) 13355895Syz147064 free(buf); 13365895Syz147064 13375895Syz147064 return (DLADM_WALK_CONTINUE); 13385895Syz147064 } 13395895Syz147064 13405895Syz147064 /*ARGSUSED*/ 13415895Syz147064 static int 13428453SAnurag.Maskey@Sun.COM i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 13435895Syz147064 { 13448275SEric Cheng datalink_class_t class; 13458275SEric Cheng dladm_status_t status; 13468275SEric Cheng 13478453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 13488453SAnurag.Maskey@Sun.COM NULL, 0); 13498275SEric Cheng if (status != DLADM_STATUS_OK) 13508275SEric Cheng return (DLADM_WALK_TERMINATE); 13518275SEric Cheng 13528275SEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 13538453SAnurag.Maskey@Sun.COM (void) dladm_init_linkprop(handle, linkid, B_TRUE); 13548275SEric Cheng 13555895Syz147064 return (DLADM_WALK_CONTINUE); 13565895Syz147064 } 13575895Syz147064 13585895Syz147064 dladm_status_t 13598453SAnurag.Maskey@Sun.COM dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 13608453SAnurag.Maskey@Sun.COM boolean_t any_media) 13615895Syz147064 { 136211021SEric.Cheng@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 13636916Sartem datalink_media_t dmedia; 13646916Sartem uint32_t media; 136511878SVenu.Iyer@Sun.COM dladm_linkprop_args_t *dla; 13666916Sartem 13676916Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 13686916Sartem 136911878SVenu.Iyer@Sun.COM dla = malloc(sizeof (dladm_linkprop_args_t)); 137011878SVenu.Iyer@Sun.COM if (dla == NULL) 137111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 137211878SVenu.Iyer@Sun.COM dla->dla_flags = DLADM_OPT_BOOT; 137311878SVenu.Iyer@Sun.COM dla->dla_status = DLADM_STATUS_OK; 137411878SVenu.Iyer@Sun.COM 13755895Syz147064 if (linkid == DATALINK_ALL_LINKID) { 13768453SAnurag.Maskey@Sun.COM (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 13778453SAnurag.Maskey@Sun.COM NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 13788453SAnurag.Maskey@Sun.COM } else if (any_media || 13798453SAnurag.Maskey@Sun.COM ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 13808453SAnurag.Maskey@Sun.COM 0) == DLADM_STATUS_OK) && 13816916Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 138211878SVenu.Iyer@Sun.COM (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 13838453SAnurag.Maskey@Sun.COM i_dladm_init_one_prop); 138411878SVenu.Iyer@Sun.COM status = dla->dla_status; 13853448Sdh155122 } 138611878SVenu.Iyer@Sun.COM free(dla); 138711021SEric.Cheng@Sun.COM return (status); 13883147Sxc151355 } 13893147Sxc151355 13905903Ssowmini /* ARGSUSED */ 13915895Syz147064 static dladm_status_t 139211878SVenu.Iyer@Sun.COM get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 13938275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 13948275SEric Cheng uint_t flags, uint_t *perm_flags) 13953147Sxc151355 { 13968275SEric Cheng char zone_name[ZONENAME_MAX]; 13978275SEric Cheng zoneid_t zid; 13988275SEric Cheng dladm_status_t status; 13993147Sxc151355 14006512Ssowmini if (flags != 0) 14016512Ssowmini return (DLADM_STATUS_NOTSUP); 14026512Ssowmini 140311878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 140411878SVenu.Iyer@Sun.COM perm_flags, &zid, sizeof (zid)); 14055895Syz147064 if (status != DLADM_STATUS_OK) 14063448Sdh155122 return (status); 14073448Sdh155122 14085895Syz147064 *val_cnt = 1; 14095895Syz147064 if (zid != GLOBAL_ZONEID) { 14108118SVasumathi.Sundaram@Sun.COM if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 14115895Syz147064 return (dladm_errno2status(errno)); 14128118SVasumathi.Sundaram@Sun.COM } 14133147Sxc151355 14145895Syz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 14153147Sxc151355 } else { 14165895Syz147064 *prop_val[0] = '\0'; 14173147Sxc151355 } 14183147Sxc151355 14193448Sdh155122 return (DLADM_STATUS_OK); 14203448Sdh155122 } 14213448Sdh155122 14223448Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 14233448Sdh155122 14243448Sdh155122 static int 14253448Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 14263448Sdh155122 { 14273448Sdh155122 char root[MAXPATHLEN]; 14283448Sdh155122 zone_get_devroot_t real_zone_get_devroot; 14293448Sdh155122 void *dlhandle; 14303448Sdh155122 void *sym; 14313448Sdh155122 int ret; 14323448Sdh155122 14333448Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 14343448Sdh155122 return (-1); 14353448Sdh155122 14363448Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 14373448Sdh155122 (void) dlclose(dlhandle); 14383448Sdh155122 return (-1); 14393448Sdh155122 } 14403448Sdh155122 14413448Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 14423448Sdh155122 14433448Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 14443448Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 14453448Sdh155122 (void) dlclose(dlhandle); 14463448Sdh155122 return (ret); 14473448Sdh155122 } 14483448Sdh155122 14493448Sdh155122 static dladm_status_t 14508453SAnurag.Maskey@Sun.COM i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 14518453SAnurag.Maskey@Sun.COM datalink_id_t linkid, boolean_t add) 14523448Sdh155122 { 14533448Sdh155122 char path[MAXPATHLEN]; 14545895Syz147064 char name[MAXLINKNAMELEN]; 14553448Sdh155122 di_prof_t prof = NULL; 14563448Sdh155122 char zone_name[ZONENAME_MAX]; 14573448Sdh155122 dladm_status_t status; 14585895Syz147064 int ret; 14593448Sdh155122 14603448Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 14613448Sdh155122 return (dladm_errno2status(errno)); 14623448Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 14633448Sdh155122 return (dladm_errno2status(errno)); 14643448Sdh155122 if (di_prof_init(path, &prof) != 0) 14653448Sdh155122 return (dladm_errno2status(errno)); 14663448Sdh155122 14678453SAnurag.Maskey@Sun.COM status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 14685895Syz147064 if (status != DLADM_STATUS_OK) 14695895Syz147064 goto cleanup; 14705895Syz147064 14715895Syz147064 if (add) 14725895Syz147064 ret = di_prof_add_dev(prof, name); 14735895Syz147064 else 14745895Syz147064 ret = di_prof_add_exclude(prof, name); 14755895Syz147064 14765895Syz147064 if (ret != 0) { 14773448Sdh155122 status = dladm_errno2status(errno); 14783448Sdh155122 goto cleanup; 14793448Sdh155122 } 14803448Sdh155122 14813448Sdh155122 if (di_prof_commit(prof) != 0) 14823448Sdh155122 status = dladm_errno2status(errno); 14833448Sdh155122 cleanup: 14843448Sdh155122 if (prof) 14853448Sdh155122 di_prof_fini(prof); 14863448Sdh155122 14873448Sdh155122 return (status); 14883448Sdh155122 } 14893448Sdh155122 14905903Ssowmini /* ARGSUSED */ 14913448Sdh155122 static dladm_status_t 149211878SVenu.Iyer@Sun.COM set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14938453SAnurag.Maskey@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 14943448Sdh155122 { 14958275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 14968275SEric Cheng zoneid_t zid_old, zid_new; 14977342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 14983448Sdh155122 14993448Sdh155122 if (val_cnt != 1) 15003448Sdh155122 return (DLADM_STATUS_BADVALCNT); 15013448Sdh155122 15027342SAruna.Ramakrishna@Sun.COM dzp = (dld_ioc_zid_t *)vdp->vd_val; 15037342SAruna.Ramakrishna@Sun.COM 150411878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 150511878SVenu.Iyer@Sun.COM NULL, &zid_old, sizeof (zid_old)); 15068275SEric Cheng if (status != DLADM_STATUS_OK) 15078275SEric Cheng return (status); 15088275SEric Cheng 15097342SAruna.Ramakrishna@Sun.COM zid_new = dzp->diz_zid; 15103448Sdh155122 if (zid_new == zid_old) 151110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 151210616SSebastien.Roy@Sun.COM 151311878SVenu.Iyer@Sun.COM if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 151410616SSebastien.Roy@Sun.COM flags, media)) != DLADM_STATUS_OK) 15155895Syz147064 return (status); 15165895Syz147064 151710616SSebastien.Roy@Sun.COM /* 151810616SSebastien.Roy@Sun.COM * It is okay to fail to update the /dev entry (some vanity-named 151910616SSebastien.Roy@Sun.COM * links do not have a /dev entry). 152010616SSebastien.Roy@Sun.COM */ 15213448Sdh155122 if (zid_old != GLOBAL_ZONEID) { 15228453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_old, linkid, 15238453SAnurag.Maskey@Sun.COM B_FALSE); 15245895Syz147064 } 152510616SSebastien.Roy@Sun.COM if (zid_new != GLOBAL_ZONEID) 15268453SAnurag.Maskey@Sun.COM (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 15273448Sdh155122 15283448Sdh155122 return (DLADM_STATUS_OK); 15293448Sdh155122 } 15303448Sdh155122 15313448Sdh155122 /* ARGSUSED */ 15323448Sdh155122 static dladm_status_t 153311878SVenu.Iyer@Sun.COM check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 153411878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 153511878SVenu.Iyer@Sun.COM datalink_media_t media) 15363448Sdh155122 { 15377342SAruna.Ramakrishna@Sun.COM char *zone_name; 15387342SAruna.Ramakrishna@Sun.COM zoneid_t zoneid; 15397342SAruna.Ramakrishna@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 15407342SAruna.Ramakrishna@Sun.COM dld_ioc_zid_t *dzp; 15413448Sdh155122 15423448Sdh155122 if (val_cnt != 1) 15433448Sdh155122 return (DLADM_STATUS_BADVALCNT); 15443448Sdh155122 15457342SAruna.Ramakrishna@Sun.COM dzp = malloc(sizeof (dld_ioc_zid_t)); 15467342SAruna.Ramakrishna@Sun.COM if (dzp == NULL) 15477342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 15483448Sdh155122 15498275SEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 15507342SAruna.Ramakrishna@Sun.COM if ((zoneid = getzoneidbyname(zone_name)) == -1) { 15517342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 15527342SAruna.Ramakrishna@Sun.COM goto done; 15537342SAruna.Ramakrishna@Sun.COM } 15547342SAruna.Ramakrishna@Sun.COM 15557342SAruna.Ramakrishna@Sun.COM if (zoneid != GLOBAL_ZONEID) { 15563448Sdh155122 ushort_t flags; 15573448Sdh155122 15587342SAruna.Ramakrishna@Sun.COM if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 15593448Sdh155122 sizeof (flags)) < 0) { 15607342SAruna.Ramakrishna@Sun.COM status = dladm_errno2status(errno); 15617342SAruna.Ramakrishna@Sun.COM goto done; 15623448Sdh155122 } 15633448Sdh155122 15643448Sdh155122 if (!(flags & ZF_NET_EXCL)) { 15657342SAruna.Ramakrishna@Sun.COM status = DLADM_STATUS_BADVAL; 15667342SAruna.Ramakrishna@Sun.COM goto done; 15673448Sdh155122 } 15683448Sdh155122 } 15693448Sdh155122 15707342SAruna.Ramakrishna@Sun.COM (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15717342SAruna.Ramakrishna@Sun.COM 15727342SAruna.Ramakrishna@Sun.COM dzp->diz_zid = zoneid; 157310616SSebastien.Roy@Sun.COM dzp->diz_linkid = linkid; 15747342SAruna.Ramakrishna@Sun.COM 15757342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dzp; 15765895Syz147064 return (DLADM_STATUS_OK); 15777342SAruna.Ramakrishna@Sun.COM done: 15787342SAruna.Ramakrishna@Sun.COM free(dzp); 15797342SAruna.Ramakrishna@Sun.COM return (status); 15805895Syz147064 } 15815895Syz147064 15825903Ssowmini /* ARGSUSED */ 15835895Syz147064 static dladm_status_t 158411878SVenu.Iyer@Sun.COM get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15858275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 15868275SEric Cheng uint_t flags, uint_t *perm_flags) 15878275SEric Cheng { 15888275SEric Cheng mac_resource_props_t mrp; 15898275SEric Cheng dladm_status_t status; 15908275SEric Cheng 159111878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 159211878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 159311878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 15948275SEric Cheng return (status); 15958275SEric Cheng 15968275SEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 159711878SVenu.Iyer@Sun.COM *val_cnt = 0; 159811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 15998275SEric Cheng } 160011878SVenu.Iyer@Sun.COM 160111878SVenu.Iyer@Sun.COM (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 16028275SEric Cheng *val_cnt = 1; 16038275SEric Cheng return (DLADM_STATUS_OK); 16048275SEric Cheng } 16058275SEric Cheng 16068275SEric Cheng /* ARGSUSED */ 16078275SEric Cheng static dladm_status_t 160811878SVenu.Iyer@Sun.COM check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 160911878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 161011878SVenu.Iyer@Sun.COM datalink_media_t media) 16118275SEric Cheng { 16128275SEric Cheng uint64_t *maxbw; 16138275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 16148275SEric Cheng 16158275SEric Cheng if (val_cnt != 1) 16168275SEric Cheng return (DLADM_STATUS_BADVALCNT); 16178275SEric Cheng 16188275SEric Cheng maxbw = malloc(sizeof (uint64_t)); 16198275SEric Cheng if (maxbw == NULL) 16208275SEric Cheng return (DLADM_STATUS_NOMEM); 16218275SEric Cheng 16228275SEric Cheng status = dladm_str2bw(*prop_val, maxbw); 16238275SEric Cheng if (status != DLADM_STATUS_OK) { 16248275SEric Cheng free(maxbw); 16258275SEric Cheng return (status); 16268275SEric Cheng } 16278275SEric Cheng 16288275SEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 16298275SEric Cheng free(maxbw); 16308275SEric Cheng return (DLADM_STATUS_MINMAXBW); 16318275SEric Cheng } 16328275SEric Cheng 16338275SEric Cheng vdp->vd_val = (uintptr_t)maxbw; 16348275SEric Cheng return (DLADM_STATUS_OK); 16358275SEric Cheng } 16368275SEric Cheng 16378275SEric Cheng /* ARGSUSED */ 16388275SEric Cheng dladm_status_t 163911878SVenu.Iyer@Sun.COM extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 16408275SEric Cheng { 164110734SEric Cheng mac_resource_props_t *mrp = arg; 16428275SEric Cheng 164311878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) { 164411878SVenu.Iyer@Sun.COM mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 164511878SVenu.Iyer@Sun.COM } else { 164611878SVenu.Iyer@Sun.COM bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 164711878SVenu.Iyer@Sun.COM } 16488275SEric Cheng mrp->mrp_mask |= MRP_MAXBW; 16498275SEric Cheng 16508275SEric Cheng return (DLADM_STATUS_OK); 16518275SEric Cheng } 16528275SEric Cheng 16538275SEric Cheng /* ARGSUSED */ 16548275SEric Cheng static dladm_status_t 165511878SVenu.Iyer@Sun.COM get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16568275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 16578275SEric Cheng uint_t flags, uint_t *perm_flags) 16588275SEric Cheng { 165911878SVenu.Iyer@Sun.COM dladm_status_t status; 16608275SEric Cheng mac_resource_props_t mrp; 16618275SEric Cheng int i; 16628275SEric Cheng uint32_t ncpus; 166311878SVenu.Iyer@Sun.COM 166411878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 166511878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 166611878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 166711878SVenu.Iyer@Sun.COM sizeof (mrp)); 166811878SVenu.Iyer@Sun.COM } else { 166911878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 167011878SVenu.Iyer@Sun.COM "resource", flags, perm_flags, &mrp, sizeof (mrp)); 167111878SVenu.Iyer@Sun.COM } 167211878SVenu.Iyer@Sun.COM 167311878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 16748275SEric Cheng return (status); 16758275SEric Cheng 16768275SEric Cheng ncpus = mrp.mrp_ncpus; 16778275SEric Cheng if (ncpus > *val_cnt) 16788275SEric Cheng return (DLADM_STATUS_TOOSMALL); 16798275SEric Cheng 16808275SEric Cheng if (ncpus == 0) { 168111878SVenu.Iyer@Sun.COM *val_cnt = 0; 16828275SEric Cheng return (DLADM_STATUS_OK); 16838275SEric Cheng } 16848275SEric Cheng 16858275SEric Cheng *val_cnt = ncpus; 16868275SEric Cheng for (i = 0; i < ncpus; i++) { 16878275SEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 16888275SEric Cheng "%u", mrp.mrp_cpu[i]); 16898275SEric Cheng } 16908275SEric Cheng return (DLADM_STATUS_OK); 16918275SEric Cheng } 16928275SEric Cheng 16938275SEric Cheng /* ARGSUSED */ 16948275SEric Cheng static dladm_status_t 169511878SVenu.Iyer@Sun.COM check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 169611878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 169711878SVenu.Iyer@Sun.COM datalink_media_t media) 16988275SEric Cheng { 169911878SVenu.Iyer@Sun.COM uint32_t cpuid; 170011878SVenu.Iyer@Sun.COM int i, j, rc; 170111878SVenu.Iyer@Sun.COM char *endp; 170211878SVenu.Iyer@Sun.COM long nproc = sysconf(_SC_NPROCESSORS_CONF); 17038275SEric Cheng mac_resource_props_t mrp; 170411878SVenu.Iyer@Sun.COM dladm_status_t status; 170511878SVenu.Iyer@Sun.COM uint_t perm_flags; 170611878SVenu.Iyer@Sun.COM 170711878SVenu.Iyer@Sun.COM /* Get the current pool property */ 170811878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 170911878SVenu.Iyer@Sun.COM &perm_flags, &mrp, sizeof (mrp)); 171011878SVenu.Iyer@Sun.COM 171111878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) { 171211878SVenu.Iyer@Sun.COM /* Can't set cpus if a pool is set */ 171311878SVenu.Iyer@Sun.COM if (strlen(mrp.mrp_pool) != 0) 171411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_POOLCPU); 171511878SVenu.Iyer@Sun.COM } 17168275SEric Cheng 17178275SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 171811878SVenu.Iyer@Sun.COM 171911878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 172011878SVenu.Iyer@Sun.COM errno = 0; 172111878SVenu.Iyer@Sun.COM cpuid = strtol(prop_val[i], &endp, 10); 172211878SVenu.Iyer@Sun.COM if (errno != 0 || *endp != '\0') 172311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 172411878SVenu.Iyer@Sun.COM 172511878SVenu.Iyer@Sun.COM if (cpuid >= nproc) 172611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_CPUMAX); 172711878SVenu.Iyer@Sun.COM 172811878SVenu.Iyer@Sun.COM rc = p_online(cpuid, P_STATUS); 172911878SVenu.Iyer@Sun.COM if (rc < 1) 173011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_CPUERR); 173111878SVenu.Iyer@Sun.COM 173211878SVenu.Iyer@Sun.COM if (rc != P_ONLINE) 173311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_CPUNOTONLINE); 173411878SVenu.Iyer@Sun.COM 173511878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)cpuid; 173611878SVenu.Iyer@Sun.COM } 173711878SVenu.Iyer@Sun.COM 173811878SVenu.Iyer@Sun.COM /* Check for duplicates */ 173911878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 174011878SVenu.Iyer@Sun.COM for (j = 0; j < val_cnt; j++) { 174111878SVenu.Iyer@Sun.COM if (i != j && vdp[i].vd_val == vdp[j].vd_val) 174211878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 17438275SEric Cheng } 17448275SEric Cheng } 174511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 174611878SVenu.Iyer@Sun.COM } 174711878SVenu.Iyer@Sun.COM 174811878SVenu.Iyer@Sun.COM /* ARGSUSED */ 174911878SVenu.Iyer@Sun.COM dladm_status_t 175011878SVenu.Iyer@Sun.COM extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 175111878SVenu.Iyer@Sun.COM { 175211878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 175311878SVenu.Iyer@Sun.COM int i; 175411878SVenu.Iyer@Sun.COM 175511878SVenu.Iyer@Sun.COM if (vdp[0].vd_val == RESET_VAL) { 175611878SVenu.Iyer@Sun.COM bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 175711878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_CPUS; 175811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 175911878SVenu.Iyer@Sun.COM } 176011878SVenu.Iyer@Sun.COM 176111878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) 176211878SVenu.Iyer@Sun.COM mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 176311878SVenu.Iyer@Sun.COM 176411878SVenu.Iyer@Sun.COM mrp->mrp_ncpus = cnt; 176511878SVenu.Iyer@Sun.COM mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 176611878SVenu.Iyer@Sun.COM mrp->mrp_fanout_mode = MCM_CPUS; 176711878SVenu.Iyer@Sun.COM mrp->mrp_rx_intr_cpu = -1; 176811878SVenu.Iyer@Sun.COM 176911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 177011878SVenu.Iyer@Sun.COM } 177111878SVenu.Iyer@Sun.COM 177211878SVenu.Iyer@Sun.COM /* 177311878SVenu.Iyer@Sun.COM * Get the pool datalink property from the kernel. This is used 177411878SVenu.Iyer@Sun.COM * for both the user specified pool and effective pool properties. 177511878SVenu.Iyer@Sun.COM */ 177611878SVenu.Iyer@Sun.COM /* ARGSUSED */ 177711878SVenu.Iyer@Sun.COM static dladm_status_t 177811878SVenu.Iyer@Sun.COM get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 177911878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 178011878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 178111878SVenu.Iyer@Sun.COM { 178211878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 178311878SVenu.Iyer@Sun.COM dladm_status_t status; 178411878SVenu.Iyer@Sun.COM 178511878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "pool-effective") == 0) { 178611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 178711878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 178811878SVenu.Iyer@Sun.COM sizeof (mrp)); 178911878SVenu.Iyer@Sun.COM } else { 179011878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 179111878SVenu.Iyer@Sun.COM "resource", flags, perm_flags, &mrp, sizeof (mrp)); 179211878SVenu.Iyer@Sun.COM } 179311878SVenu.Iyer@Sun.COM 179411878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 179511878SVenu.Iyer@Sun.COM return (status); 179611878SVenu.Iyer@Sun.COM 179711878SVenu.Iyer@Sun.COM if (strlen(mrp.mrp_pool) == 0) { 179811878SVenu.Iyer@Sun.COM (*prop_val)[0] = '\0'; 179911878SVenu.Iyer@Sun.COM } else { 180011878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 180111878SVenu.Iyer@Sun.COM "%s", mrp.mrp_pool); 180211878SVenu.Iyer@Sun.COM } 180311878SVenu.Iyer@Sun.COM *val_cnt = 1; 180411878SVenu.Iyer@Sun.COM 180511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 18068275SEric Cheng } 18078275SEric Cheng 18088275SEric Cheng /* ARGSUSED */ 18098275SEric Cheng static dladm_status_t 181011878SVenu.Iyer@Sun.COM check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 181111878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 181211878SVenu.Iyer@Sun.COM datalink_media_t media) 18138275SEric Cheng { 181411878SVenu.Iyer@Sun.COM pool_conf_t *poolconf; 181511878SVenu.Iyer@Sun.COM pool_t *pool; 18168275SEric Cheng mac_resource_props_t mrp; 18178275SEric Cheng dladm_status_t status; 181811878SVenu.Iyer@Sun.COM uint_t perm_flags; 181911878SVenu.Iyer@Sun.COM char *poolname; 182011878SVenu.Iyer@Sun.COM 182111878SVenu.Iyer@Sun.COM /* Get the current cpus property */ 182211878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 182311878SVenu.Iyer@Sun.COM &perm_flags, &mrp, sizeof (mrp)); 182411878SVenu.Iyer@Sun.COM 182511878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) { 182611878SVenu.Iyer@Sun.COM /* Can't set pool if cpus are set */ 182711878SVenu.Iyer@Sun.COM if (mrp.mrp_ncpus != 0) 182811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_POOLCPU); 18298275SEric Cheng } 18308275SEric Cheng 183111878SVenu.Iyer@Sun.COM poolname = malloc(sizeof (mrp.mrp_pool)); 183211878SVenu.Iyer@Sun.COM if (poolname == NULL) 18338275SEric Cheng return (DLADM_STATUS_NOMEM); 18348275SEric Cheng 183511878SVenu.Iyer@Sun.COM /* Check for pool's availability if not booting */ 183611878SVenu.Iyer@Sun.COM if ((flags & DLADM_OPT_BOOT) == 0) { 183711878SVenu.Iyer@Sun.COM 183811878SVenu.Iyer@Sun.COM /* Allocate and open pool configuration */ 183911878SVenu.Iyer@Sun.COM if ((poolconf = pool_conf_alloc()) == NULL) 184011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 184111878SVenu.Iyer@Sun.COM 184211878SVenu.Iyer@Sun.COM if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 184311878SVenu.Iyer@Sun.COM != PO_SUCCESS) { 184411878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 184511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 18468275SEric Cheng } 184711878SVenu.Iyer@Sun.COM 184811878SVenu.Iyer@Sun.COM /* Look for pool name */ 184911878SVenu.Iyer@Sun.COM if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 185011878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 185111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 18528275SEric Cheng } 185311878SVenu.Iyer@Sun.COM 185411878SVenu.Iyer@Sun.COM pool_conf_free(poolconf); 185511878SVenu.Iyer@Sun.COM free(pool); 18568275SEric Cheng } 185711878SVenu.Iyer@Sun.COM 185811878SVenu.Iyer@Sun.COM (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 185911878SVenu.Iyer@Sun.COM vdp->vd_val = (uintptr_t)poolname; 18608275SEric Cheng 18618275SEric Cheng return (DLADM_STATUS_OK); 18628275SEric Cheng } 18638275SEric Cheng 18648275SEric Cheng /* ARGSUSED */ 18658275SEric Cheng dladm_status_t 186611878SVenu.Iyer@Sun.COM extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 18678275SEric Cheng { 186811878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 186911878SVenu.Iyer@Sun.COM 187011878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) { 187111878SVenu.Iyer@Sun.COM bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 187211878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_POOL; 187311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 18748275SEric Cheng } 187511878SVenu.Iyer@Sun.COM 187611878SVenu.Iyer@Sun.COM (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 187711878SVenu.Iyer@Sun.COM sizeof (mrp->mrp_pool)); 187811878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_POOL; 187911878SVenu.Iyer@Sun.COM /* 188011878SVenu.Iyer@Sun.COM * Use MCM_CPUS since the fanout count is not user specified 188111878SVenu.Iyer@Sun.COM * and will be determined by the cpu list generated from the 188211878SVenu.Iyer@Sun.COM * pool. 188311878SVenu.Iyer@Sun.COM */ 18848275SEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 18858275SEric Cheng 18868275SEric Cheng return (DLADM_STATUS_OK); 18878275SEric Cheng } 18888275SEric Cheng 18898275SEric Cheng /* ARGSUSED */ 18908275SEric Cheng static dladm_status_t 189111878SVenu.Iyer@Sun.COM get_priority(dladm_handle_t handle, prop_desc_t *pdp, 18928460SArtem.Kachitchkin@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 18938460SArtem.Kachitchkin@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 18948275SEric Cheng { 18958275SEric Cheng mac_resource_props_t mrp; 18968275SEric Cheng mac_priority_level_t pri; 18978275SEric Cheng dladm_status_t status; 18988275SEric Cheng 189911878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 190011878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 190111878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 19028275SEric Cheng return (status); 19038275SEric Cheng 19048275SEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 19058275SEric Cheng mrp.mrp_priority; 19068275SEric Cheng 19078275SEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 19088275SEric Cheng *val_cnt = 1; 19098275SEric Cheng return (DLADM_STATUS_OK); 19108275SEric Cheng } 19118275SEric Cheng 19128275SEric Cheng /* ARGSUSED */ 191311878SVenu.Iyer@Sun.COM dladm_status_t 191411878SVenu.Iyer@Sun.COM extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 191511878SVenu.Iyer@Sun.COM { 191611878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 191711878SVenu.Iyer@Sun.COM 191811878SVenu.Iyer@Sun.COM if (cnt != 1) 191911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 192011878SVenu.Iyer@Sun.COM 192111878SVenu.Iyer@Sun.COM mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 192211878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_PRIORITY; 192311878SVenu.Iyer@Sun.COM 192411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 192511878SVenu.Iyer@Sun.COM } 192611878SVenu.Iyer@Sun.COM 192711878SVenu.Iyer@Sun.COM /* 192811878SVenu.Iyer@Sun.COM * Determines the size of the structure that needs to be sent to drivers 192911878SVenu.Iyer@Sun.COM * for retrieving the property range values. 193011878SVenu.Iyer@Sun.COM */ 193111878SVenu.Iyer@Sun.COM static int 193211878SVenu.Iyer@Sun.COM i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 19338275SEric Cheng { 193411878SVenu.Iyer@Sun.COM uint_t count = r->mpr_count; 193511878SVenu.Iyer@Sun.COM 193611878SVenu.Iyer@Sun.COM *sz = sizeof (mac_propval_range_t); 193711878SVenu.Iyer@Sun.COM --count; 193811878SVenu.Iyer@Sun.COM 193911878SVenu.Iyer@Sun.COM switch (r->mpr_type) { 194011878SVenu.Iyer@Sun.COM case MAC_PROPVAL_UINT32: 194111878SVenu.Iyer@Sun.COM *sz += (count * sizeof (mac_propval_uint32_range_t)); 194211878SVenu.Iyer@Sun.COM return (0); 194311878SVenu.Iyer@Sun.COM default: 194411878SVenu.Iyer@Sun.COM break; 194511878SVenu.Iyer@Sun.COM } 194611878SVenu.Iyer@Sun.COM *sz = 0; 194711878SVenu.Iyer@Sun.COM return (EINVAL); 194811878SVenu.Iyer@Sun.COM } 194911878SVenu.Iyer@Sun.COM 195011878SVenu.Iyer@Sun.COM 195111878SVenu.Iyer@Sun.COM /* ARGSUSED */ 195211878SVenu.Iyer@Sun.COM static dladm_status_t 195311878SVenu.Iyer@Sun.COM check_rings(dladm_handle_t handle, prop_desc_t *pdp, 195411878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 195511878SVenu.Iyer@Sun.COM val_desc_t *v, datalink_media_t media) 195611878SVenu.Iyer@Sun.COM { 19578275SEric Cheng if (val_cnt != 1) 195811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 195911878SVenu.Iyer@Sun.COM if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 196011878SVenu.Iyer@Sun.COM v->vd_val = UNSPEC_VAL; 196111878SVenu.Iyer@Sun.COM } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 196211878SVenu.Iyer@Sun.COM v->vd_val = 0; 196311878SVenu.Iyer@Sun.COM } else { 196411878SVenu.Iyer@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 196511878SVenu.Iyer@Sun.COM if (v->vd_val == 0) 196611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVAL); 196711878SVenu.Iyer@Sun.COM } 196811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 196911878SVenu.Iyer@Sun.COM } 197011878SVenu.Iyer@Sun.COM 197111878SVenu.Iyer@Sun.COM /* ARGSUSED */ 197211878SVenu.Iyer@Sun.COM static dladm_status_t 197311878SVenu.Iyer@Sun.COM get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 197411878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 197511878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 197611878SVenu.Iyer@Sun.COM { 197711878SVenu.Iyer@Sun.COM dld_ioc_macprop_t *dip; 197811878SVenu.Iyer@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 197911878SVenu.Iyer@Sun.COM mac_propval_range_t *rangep; 198011878SVenu.Iyer@Sun.COM size_t sz; 198111878SVenu.Iyer@Sun.COM mac_propval_uint32_range_t *ur; 198211878SVenu.Iyer@Sun.COM 198311878SVenu.Iyer@Sun.COM sz = sizeof (mac_propval_range_t); 198411878SVenu.Iyer@Sun.COM 198511878SVenu.Iyer@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 198611878SVenu.Iyer@Sun.COM &status)) == NULL) 198711878SVenu.Iyer@Sun.COM return (status); 198811878SVenu.Iyer@Sun.COM 198911878SVenu.Iyer@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 199011878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 19918275SEric Cheng return (status); 199211878SVenu.Iyer@Sun.COM 199311878SVenu.Iyer@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 199411878SVenu.Iyer@Sun.COM *val_cnt = 1; 199511878SVenu.Iyer@Sun.COM ur = &rangep->mpr_range_uint32[0]; 199611878SVenu.Iyer@Sun.COM /* This is the case where the dev doesn't have any rings/groups */ 199711878SVenu.Iyer@Sun.COM if (rangep->mpr_count == 0) { 199811878SVenu.Iyer@Sun.COM (*prop_val)[0] = '\0'; 199911878SVenu.Iyer@Sun.COM /* 200011878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings, but static 200111878SVenu.Iyer@Sun.COM * grouping. 200211878SVenu.Iyer@Sun.COM */ 200311878SVenu.Iyer@Sun.COM } else if (ur->mpur_min == ur->mpur_max && 200411878SVenu.Iyer@Sun.COM ur->mpur_max == 0) { 200511878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 200611878SVenu.Iyer@Sun.COM /* 200711878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings and dynamic 200811878SVenu.Iyer@Sun.COM * grouping, but has only one value (say 2 rings and 2 groups). 200911878SVenu.Iyer@Sun.COM */ 201011878SVenu.Iyer@Sun.COM } else if (ur->mpur_min == ur->mpur_max) { 201111878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 201211878SVenu.Iyer@Sun.COM ur->mpur_min); 201311878SVenu.Iyer@Sun.COM /* 201411878SVenu.Iyer@Sun.COM * This is the case where the dev supports rings and dynamic 201511878SVenu.Iyer@Sun.COM * grouping and has a range of rings. 201611878SVenu.Iyer@Sun.COM */ 201711878SVenu.Iyer@Sun.COM } else { 201811878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 201911878SVenu.Iyer@Sun.COM "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 20208275SEric Cheng } 202111878SVenu.Iyer@Sun.COM free(dip); 202211878SVenu.Iyer@Sun.COM return (status); 202311878SVenu.Iyer@Sun.COM } 202411878SVenu.Iyer@Sun.COM 202511878SVenu.Iyer@Sun.COM 202611878SVenu.Iyer@Sun.COM /* ARGSUSED */ 202711878SVenu.Iyer@Sun.COM static dladm_status_t 202811878SVenu.Iyer@Sun.COM get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 202911878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 203011878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 203111878SVenu.Iyer@Sun.COM { 203211878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 203311878SVenu.Iyer@Sun.COM dladm_status_t status; 203411878SVenu.Iyer@Sun.COM uint32_t nrings = 0; 203511878SVenu.Iyer@Sun.COM 203611878SVenu.Iyer@Sun.COM /* 203711878SVenu.Iyer@Sun.COM * Get the number of (effective-)rings from the resource property. 203811878SVenu.Iyer@Sun.COM */ 203911878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 204011878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 204111878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 204211878SVenu.Iyer@Sun.COM sizeof (mrp)); 204311878SVenu.Iyer@Sun.COM } else { 204411878SVenu.Iyer@Sun.COM /* 204511878SVenu.Iyer@Sun.COM * Get the permissions from the "rxrings" property. 204611878SVenu.Iyer@Sun.COM */ 204711878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "rxrings", 204811878SVenu.Iyer@Sun.COM flags, perm_flags, NULL, 0); 204911878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 205011878SVenu.Iyer@Sun.COM return (status); 205111878SVenu.Iyer@Sun.COM 205211878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 205311878SVenu.Iyer@Sun.COM "resource", flags, NULL, &mrp, sizeof (mrp)); 20548275SEric Cheng } 20558275SEric Cheng 205611878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 205711878SVenu.Iyer@Sun.COM return (status); 205811878SVenu.Iyer@Sun.COM 205911878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 206011878SVenu.Iyer@Sun.COM *val_cnt = 0; 206111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 206211878SVenu.Iyer@Sun.COM } 206311878SVenu.Iyer@Sun.COM nrings = mrp.mrp_nrxrings; 206411878SVenu.Iyer@Sun.COM *val_cnt = 1; 206511878SVenu.Iyer@Sun.COM if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 206611878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 206711878SVenu.Iyer@Sun.COM else if (nrings == 0) 206811878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 206911878SVenu.Iyer@Sun.COM else 207011878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 20718275SEric Cheng return (DLADM_STATUS_OK); 20728275SEric Cheng } 20738275SEric Cheng 20748275SEric Cheng /* ARGSUSED */ 20758275SEric Cheng dladm_status_t 207611878SVenu.Iyer@Sun.COM extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 20778275SEric Cheng { 207811878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 207911878SVenu.Iyer@Sun.COM 208011878SVenu.Iyer@Sun.COM mrp->mrp_nrxrings = 0; 208111878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) 208211878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RINGS_RESET; 208311878SVenu.Iyer@Sun.COM else if (vdp->vd_val == UNSPEC_VAL) 208411878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 208511878SVenu.Iyer@Sun.COM else 208611878SVenu.Iyer@Sun.COM mrp->mrp_nrxrings = vdp->vd_val; 208711878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_RX_RINGS; 20888275SEric Cheng 20898275SEric Cheng return (DLADM_STATUS_OK); 20908275SEric Cheng } 20918275SEric Cheng 20928275SEric Cheng /* ARGSUSED */ 20938275SEric Cheng static dladm_status_t 209411878SVenu.Iyer@Sun.COM get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 209511878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, 209611878SVenu.Iyer@Sun.COM uint_t flags, uint_t *perm_flags) 209711878SVenu.Iyer@Sun.COM { 209811878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 209911878SVenu.Iyer@Sun.COM dladm_status_t status; 210011878SVenu.Iyer@Sun.COM uint32_t nrings = 0; 210111878SVenu.Iyer@Sun.COM 210211878SVenu.Iyer@Sun.COM 210311878SVenu.Iyer@Sun.COM /* 210411878SVenu.Iyer@Sun.COM * Get the number of (effective-)rings from the resource property. 210511878SVenu.Iyer@Sun.COM */ 210611878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 210711878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, 210811878SVenu.Iyer@Sun.COM "resource-effective", flags, perm_flags, &mrp, 210911878SVenu.Iyer@Sun.COM sizeof (mrp)); 211011878SVenu.Iyer@Sun.COM } else { 211111878SVenu.Iyer@Sun.COM /* 211211878SVenu.Iyer@Sun.COM * Get the permissions from the "txrings" property. 211311878SVenu.Iyer@Sun.COM */ 211411878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "txrings", 211511878SVenu.Iyer@Sun.COM flags, perm_flags, NULL, 0); 211611878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 211711878SVenu.Iyer@Sun.COM return (status); 211811878SVenu.Iyer@Sun.COM 211911878SVenu.Iyer@Sun.COM /* 212011878SVenu.Iyer@Sun.COM * Get the number of rings from the "resource" property. 212111878SVenu.Iyer@Sun.COM */ 212211878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", 212311878SVenu.Iyer@Sun.COM flags, NULL, &mrp, sizeof (mrp)); 212411878SVenu.Iyer@Sun.COM } 212511878SVenu.Iyer@Sun.COM 212611878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 212711878SVenu.Iyer@Sun.COM return (status); 212811878SVenu.Iyer@Sun.COM 212911878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 213011878SVenu.Iyer@Sun.COM *val_cnt = 0; 213111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 213211878SVenu.Iyer@Sun.COM } 213311878SVenu.Iyer@Sun.COM nrings = mrp.mrp_ntxrings; 213411878SVenu.Iyer@Sun.COM *val_cnt = 1; 213511878SVenu.Iyer@Sun.COM if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 213611878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 213711878SVenu.Iyer@Sun.COM else if (nrings == 0) 213811878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 213911878SVenu.Iyer@Sun.COM else 214011878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 214111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 214211878SVenu.Iyer@Sun.COM } 214311878SVenu.Iyer@Sun.COM 214411878SVenu.Iyer@Sun.COM /* ARGSUSED */ 214511878SVenu.Iyer@Sun.COM dladm_status_t 214611878SVenu.Iyer@Sun.COM extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 214711878SVenu.Iyer@Sun.COM { 214811878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 214911878SVenu.Iyer@Sun.COM 215011878SVenu.Iyer@Sun.COM mrp->mrp_ntxrings = 0; 215111878SVenu.Iyer@Sun.COM if (vdp->vd_val == RESET_VAL) 215211878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_RINGS_RESET; 215311878SVenu.Iyer@Sun.COM else if (vdp->vd_val == UNSPEC_VAL) 215411878SVenu.Iyer@Sun.COM mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 215511878SVenu.Iyer@Sun.COM else 215611878SVenu.Iyer@Sun.COM mrp->mrp_ntxrings = vdp->vd_val; 215711878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_TX_RINGS; 215811878SVenu.Iyer@Sun.COM 215911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 216011878SVenu.Iyer@Sun.COM } 216111878SVenu.Iyer@Sun.COM 216211878SVenu.Iyer@Sun.COM /* ARGSUSED */ 216311878SVenu.Iyer@Sun.COM static dladm_status_t 216411878SVenu.Iyer@Sun.COM get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 216511878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 216611878SVenu.Iyer@Sun.COM uint_t *perm_flags) 216711878SVenu.Iyer@Sun.COM { 216811878SVenu.Iyer@Sun.COM if (flags & DLD_PROP_DEFAULT) 216911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTDEFINED); 217011878SVenu.Iyer@Sun.COM 217111878SVenu.Iyer@Sun.COM return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 217211878SVenu.Iyer@Sun.COM flags, perm_flags)); 217311878SVenu.Iyer@Sun.COM } 217411878SVenu.Iyer@Sun.COM 217511878SVenu.Iyer@Sun.COM /* ARGSUSED */ 217611878SVenu.Iyer@Sun.COM static dladm_status_t 217711878SVenu.Iyer@Sun.COM set_resource(dladm_handle_t handle, prop_desc_t *pdp, 217810734SEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 217910734SEric Cheng uint_t flags, datalink_media_t media) 218010734SEric Cheng { 218110734SEric Cheng mac_resource_props_t mrp; 218210734SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 218310734SEric Cheng dld_ioc_macprop_t *dip; 218411878SVenu.Iyer@Sun.COM int i; 218510734SEric Cheng 218610734SEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 218711878SVenu.Iyer@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 218810734SEric Cheng flags, &status); 218910734SEric Cheng 219010734SEric Cheng if (dip == NULL) 219110734SEric Cheng return (status); 219210734SEric Cheng 219311878SVenu.Iyer@Sun.COM for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 219411878SVenu.Iyer@Sun.COM resource_prop_t *rp = &rsrc_prop_table[i]; 219511878SVenu.Iyer@Sun.COM 219611878SVenu.Iyer@Sun.COM if (strcmp(pdp->pd_name, rp->rp_name) != 0) 219711878SVenu.Iyer@Sun.COM continue; 219811878SVenu.Iyer@Sun.COM 219911878SVenu.Iyer@Sun.COM status = rp->rp_extract(vdp, val_cnt, &mrp); 220010734SEric Cheng if (status != DLADM_STATUS_OK) 220110734SEric Cheng goto done; 220210734SEric Cheng 220311878SVenu.Iyer@Sun.COM break; 220410734SEric Cheng } 220510734SEric Cheng 220610734SEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 220710734SEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 220810734SEric Cheng 220910734SEric Cheng done: 221010734SEric Cheng free(dip); 221110734SEric Cheng return (status); 221210734SEric Cheng } 221310734SEric Cheng 221410734SEric Cheng /* ARGSUSED */ 221510734SEric Cheng static dladm_status_t 221611878SVenu.Iyer@Sun.COM get_protection(dladm_handle_t handle, prop_desc_t *pdp, 221710734SEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 221810734SEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 221910734SEric Cheng { 222011878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 222111878SVenu.Iyer@Sun.COM mac_protect_t *p; 222211878SVenu.Iyer@Sun.COM dladm_status_t status; 222311878SVenu.Iyer@Sun.COM uint32_t i, cnt = 0, setbits[32]; 222411878SVenu.Iyer@Sun.COM 222511878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 222611878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 222711878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 222811878SVenu.Iyer@Sun.COM return (status); 222911878SVenu.Iyer@Sun.COM 223011878SVenu.Iyer@Sun.COM p = &mrp.mrp_protect; 223111878SVenu.Iyer@Sun.COM if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 223211878SVenu.Iyer@Sun.COM *val_cnt = 0; 223311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 223411878SVenu.Iyer@Sun.COM } 223511878SVenu.Iyer@Sun.COM dladm_find_setbits32(p->mp_types, setbits, &cnt); 223611878SVenu.Iyer@Sun.COM if (cnt > *val_cnt) 223711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 223811878SVenu.Iyer@Sun.COM 223911878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) 224011878SVenu.Iyer@Sun.COM (void) dladm_protect2str(setbits[i], prop_val[i]); 224111878SVenu.Iyer@Sun.COM 224211878SVenu.Iyer@Sun.COM *val_cnt = cnt; 224311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 224411878SVenu.Iyer@Sun.COM } 224511878SVenu.Iyer@Sun.COM 224611878SVenu.Iyer@Sun.COM /* ARGSUSED */ 224711878SVenu.Iyer@Sun.COM static dladm_status_t 224811878SVenu.Iyer@Sun.COM get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 224911878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 225011878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 225111878SVenu.Iyer@Sun.COM { 225210734SEric Cheng mac_resource_props_t mrp; 225310734SEric Cheng mac_protect_t *p; 225410734SEric Cheng dladm_status_t status; 225510734SEric Cheng int i; 225610734SEric Cheng 225711878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 225811878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 225911878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 226010734SEric Cheng return (status); 226110734SEric Cheng 226210734SEric Cheng p = &mrp.mrp_protect; 226311878SVenu.Iyer@Sun.COM if (p->mp_ipaddrcnt == 0) { 226411878SVenu.Iyer@Sun.COM *val_cnt = 0; 226510734SEric Cheng return (DLADM_STATUS_OK); 226610734SEric Cheng } 226711878SVenu.Iyer@Sun.COM if (p->mp_ipaddrcnt > *val_cnt) 226811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 226911878SVenu.Iyer@Sun.COM 227011878SVenu.Iyer@Sun.COM for (i = 0; i < p->mp_ipaddrcnt; i++) { 227111878SVenu.Iyer@Sun.COM if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 227211878SVenu.Iyer@Sun.COM ipaddr_t v4addr; 227311878SVenu.Iyer@Sun.COM 227411878SVenu.Iyer@Sun.COM v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 227511878SVenu.Iyer@Sun.COM (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 227611878SVenu.Iyer@Sun.COM } else { 227711878SVenu.Iyer@Sun.COM (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 227810734SEric Cheng prop_val[i]); 227910734SEric Cheng } 228010734SEric Cheng } 228111878SVenu.Iyer@Sun.COM *val_cnt = p->mp_ipaddrcnt; 228210734SEric Cheng return (DLADM_STATUS_OK); 228310734SEric Cheng } 228410734SEric Cheng 228510734SEric Cheng dladm_status_t 228611878SVenu.Iyer@Sun.COM extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 228710734SEric Cheng { 228810734SEric Cheng mac_resource_props_t *mrp = arg; 228910734SEric Cheng uint32_t types = 0; 229010734SEric Cheng int i; 229110734SEric Cheng 229210734SEric Cheng for (i = 0; i < cnt; i++) 229310734SEric Cheng types |= (uint32_t)vdp[i].vd_val; 229410734SEric Cheng 229510734SEric Cheng mrp->mrp_protect.mp_types = types; 229610734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 229710734SEric Cheng return (DLADM_STATUS_OK); 229810734SEric Cheng } 229910734SEric Cheng 230010734SEric Cheng dladm_status_t 230111878SVenu.Iyer@Sun.COM extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 230210734SEric Cheng { 230310734SEric Cheng mac_resource_props_t *mrp = arg; 230410734SEric Cheng mac_protect_t *p = &mrp->mrp_protect; 230510734SEric Cheng int i; 230610734SEric Cheng 230710734SEric Cheng if (vdp->vd_val == 0) { 230810734SEric Cheng cnt = (uint_t)-1; 230910734SEric Cheng } else { 231011878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) { 231111878SVenu.Iyer@Sun.COM bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 231211878SVenu.Iyer@Sun.COM sizeof (mac_ipaddr_t)); 231311878SVenu.Iyer@Sun.COM } 231410734SEric Cheng } 231510734SEric Cheng p->mp_ipaddrcnt = cnt; 231610734SEric Cheng mrp->mrp_mask |= MRP_PROTECT; 231710734SEric Cheng return (DLADM_STATUS_OK); 231810734SEric Cheng } 231910734SEric Cheng 232011878SVenu.Iyer@Sun.COM static dladm_status_t 232111878SVenu.Iyer@Sun.COM check_single_ip(char *buf, mac_ipaddr_t *addr) 232211878SVenu.Iyer@Sun.COM { 232311878SVenu.Iyer@Sun.COM dladm_status_t status; 232411878SVenu.Iyer@Sun.COM ipaddr_t v4addr; 232511878SVenu.Iyer@Sun.COM in6_addr_t v6addr; 232611878SVenu.Iyer@Sun.COM boolean_t isv4 = B_TRUE; 232711878SVenu.Iyer@Sun.COM 232811878SVenu.Iyer@Sun.COM status = dladm_str2ipv4addr(buf, &v4addr); 232911878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_INVALID_IP) { 233011878SVenu.Iyer@Sun.COM status = dladm_str2ipv6addr(buf, &v6addr); 233111878SVenu.Iyer@Sun.COM if (status == DLADM_STATUS_OK) 233211878SVenu.Iyer@Sun.COM isv4 = B_FALSE; 233311878SVenu.Iyer@Sun.COM } 233411878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 233511878SVenu.Iyer@Sun.COM return (status); 233611878SVenu.Iyer@Sun.COM 233711878SVenu.Iyer@Sun.COM if (isv4) { 233811878SVenu.Iyer@Sun.COM if (v4addr == INADDR_ANY) 233911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_INVALID_IP); 234011878SVenu.Iyer@Sun.COM 234111878SVenu.Iyer@Sun.COM IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 234211878SVenu.Iyer@Sun.COM addr->ip_version = IPV4_VERSION; 234311878SVenu.Iyer@Sun.COM } else { 234411878SVenu.Iyer@Sun.COM if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 234511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_INVALID_IP); 234611878SVenu.Iyer@Sun.COM 234711878SVenu.Iyer@Sun.COM addr->ip_addr = v6addr; 234811878SVenu.Iyer@Sun.COM addr->ip_version = IPV6_VERSION; 234911878SVenu.Iyer@Sun.COM } 235011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 235111878SVenu.Iyer@Sun.COM } 235211878SVenu.Iyer@Sun.COM 235310734SEric Cheng /* ARGSUSED */ 235410734SEric Cheng static dladm_status_t 235511878SVenu.Iyer@Sun.COM check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 235611878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 235710734SEric Cheng val_desc_t *vdp, datalink_media_t media) 235810734SEric Cheng { 235910734SEric Cheng dladm_status_t status; 236011878SVenu.Iyer@Sun.COM mac_ipaddr_t *addr; 236110734SEric Cheng int i; 236210734SEric Cheng 236310734SEric Cheng if (val_cnt > MPT_MAXIPADDR) 236410734SEric Cheng return (DLADM_STATUS_BADVALCNT); 236510734SEric Cheng 236610734SEric Cheng for (i = 0; i < val_cnt; i++) { 236711878SVenu.Iyer@Sun.COM if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 236811878SVenu.Iyer@Sun.COM status = DLADM_STATUS_NOMEM; 236911878SVenu.Iyer@Sun.COM goto fail; 237011878SVenu.Iyer@Sun.COM } 237111878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)addr; 237211878SVenu.Iyer@Sun.COM 237311878SVenu.Iyer@Sun.COM status = check_single_ip(prop_val[i], addr); 237410734SEric Cheng if (status != DLADM_STATUS_OK) 237511878SVenu.Iyer@Sun.COM goto fail; 237611878SVenu.Iyer@Sun.COM } 237711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 237811878SVenu.Iyer@Sun.COM 237911878SVenu.Iyer@Sun.COM fail: 238011878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 238111878SVenu.Iyer@Sun.COM free((void *)vdp[i].vd_val); 238211878SVenu.Iyer@Sun.COM vdp[i].vd_val = NULL; 238311878SVenu.Iyer@Sun.COM } 238411878SVenu.Iyer@Sun.COM return (status); 238511878SVenu.Iyer@Sun.COM } 238611878SVenu.Iyer@Sun.COM 238711878SVenu.Iyer@Sun.COM static void 238811878SVenu.Iyer@Sun.COM dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 238911878SVenu.Iyer@Sun.COM { 239011878SVenu.Iyer@Sun.COM char tmp_buf[DLADM_STRSIZE]; 239111878SVenu.Iyer@Sun.COM uint_t hexlen; 239211878SVenu.Iyer@Sun.COM 239311878SVenu.Iyer@Sun.COM switch (cid->dc_form) { 239411878SVenu.Iyer@Sun.COM case CIDFORM_TYPED: { 239511878SVenu.Iyer@Sun.COM uint16_t duidtype, hwtype; 239611878SVenu.Iyer@Sun.COM uint32_t timestamp, ennum; 239711878SVenu.Iyer@Sun.COM char *lladdr; 239811878SVenu.Iyer@Sun.COM 239911878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (duidtype)) 240011878SVenu.Iyer@Sun.COM goto fail; 240111878SVenu.Iyer@Sun.COM 240211878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 240311878SVenu.Iyer@Sun.COM duidtype = ntohs(duidtype); 240411878SVenu.Iyer@Sun.COM switch (duidtype) { 240511878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LLT: { 240611878SVenu.Iyer@Sun.COM duid_llt_t llt; 240711878SVenu.Iyer@Sun.COM 240811878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (llt)) 240911878SVenu.Iyer@Sun.COM goto fail; 241011878SVenu.Iyer@Sun.COM 241111878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &llt, sizeof (llt)); 241211878SVenu.Iyer@Sun.COM hwtype = ntohs(llt.dllt_hwtype); 241311878SVenu.Iyer@Sun.COM timestamp = ntohl(llt.dllt_time); 241411878SVenu.Iyer@Sun.COM lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 241511878SVenu.Iyer@Sun.COM NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 241611878SVenu.Iyer@Sun.COM if (lladdr == NULL) 241711878SVenu.Iyer@Sun.COM goto fail; 241811878SVenu.Iyer@Sun.COM 241911878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 242011878SVenu.Iyer@Sun.COM duidtype, hwtype, timestamp, lladdr); 242111878SVenu.Iyer@Sun.COM free(lladdr); 242211878SVenu.Iyer@Sun.COM break; 242311878SVenu.Iyer@Sun.COM } 242411878SVenu.Iyer@Sun.COM case DHCPV6_DUID_EN: { 242511878SVenu.Iyer@Sun.COM duid_en_t en; 242611878SVenu.Iyer@Sun.COM 242711878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (en)) 242811878SVenu.Iyer@Sun.COM goto fail; 242911878SVenu.Iyer@Sun.COM 243011878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &en, sizeof (en)); 243111878SVenu.Iyer@Sun.COM ennum = DHCPV6_GET_ENTNUM(&en); 243211878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 243311878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id + sizeof (en), 243411878SVenu.Iyer@Sun.COM cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 243511878SVenu.Iyer@Sun.COM goto fail; 243611878SVenu.Iyer@Sun.COM 243711878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 243811878SVenu.Iyer@Sun.COM duidtype, ennum, tmp_buf); 243911878SVenu.Iyer@Sun.COM break; 244011878SVenu.Iyer@Sun.COM } 244111878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LL: { 244211878SVenu.Iyer@Sun.COM duid_ll_t ll; 244311878SVenu.Iyer@Sun.COM 244411878SVenu.Iyer@Sun.COM if (cid->dc_len < sizeof (ll)) 244511878SVenu.Iyer@Sun.COM goto fail; 244611878SVenu.Iyer@Sun.COM 244711878SVenu.Iyer@Sun.COM bcopy(cid->dc_id, &ll, sizeof (ll)); 244811878SVenu.Iyer@Sun.COM hwtype = ntohs(ll.dll_hwtype); 244911878SVenu.Iyer@Sun.COM lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 245011878SVenu.Iyer@Sun.COM NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 245111878SVenu.Iyer@Sun.COM if (lladdr == NULL) 245211878SVenu.Iyer@Sun.COM goto fail; 245311878SVenu.Iyer@Sun.COM 245411878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 245511878SVenu.Iyer@Sun.COM duidtype, hwtype, lladdr); 245611878SVenu.Iyer@Sun.COM free(lladdr); 245711878SVenu.Iyer@Sun.COM break; 245811878SVenu.Iyer@Sun.COM } 245911878SVenu.Iyer@Sun.COM default: { 246011878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 246111878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 246211878SVenu.Iyer@Sun.COM cid->dc_len - sizeof (duidtype), 246311878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 246411878SVenu.Iyer@Sun.COM goto fail; 246511878SVenu.Iyer@Sun.COM 246611878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 246711878SVenu.Iyer@Sun.COM duidtype, tmp_buf); 246811878SVenu.Iyer@Sun.COM } 246911878SVenu.Iyer@Sun.COM } 247011878SVenu.Iyer@Sun.COM break; 247111878SVenu.Iyer@Sun.COM } 247211878SVenu.Iyer@Sun.COM case CIDFORM_HEX: { 247311878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 247411878SVenu.Iyer@Sun.COM if (octet_to_hexascii(cid->dc_id, cid->dc_len, 247511878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 247611878SVenu.Iyer@Sun.COM goto fail; 247711878SVenu.Iyer@Sun.COM 247811878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 247911878SVenu.Iyer@Sun.COM break; 248011878SVenu.Iyer@Sun.COM } 248111878SVenu.Iyer@Sun.COM case CIDFORM_STR: { 248211878SVenu.Iyer@Sun.COM int i; 248311878SVenu.Iyer@Sun.COM 248411878SVenu.Iyer@Sun.COM for (i = 0; i < cid->dc_len; i++) { 248511878SVenu.Iyer@Sun.COM if (!isprint(cid->dc_id[i])) 248611878SVenu.Iyer@Sun.COM goto fail; 248711878SVenu.Iyer@Sun.COM } 248811878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 248911878SVenu.Iyer@Sun.COM break; 249011878SVenu.Iyer@Sun.COM } 249111878SVenu.Iyer@Sun.COM default: 249211878SVenu.Iyer@Sun.COM goto fail; 249310734SEric Cheng } 249411878SVenu.Iyer@Sun.COM return; 249511878SVenu.Iyer@Sun.COM 249611878SVenu.Iyer@Sun.COM fail: 249711878SVenu.Iyer@Sun.COM (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 249811878SVenu.Iyer@Sun.COM } 249911878SVenu.Iyer@Sun.COM 250011878SVenu.Iyer@Sun.COM static dladm_status_t 250111878SVenu.Iyer@Sun.COM dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 250211878SVenu.Iyer@Sun.COM { 250311878SVenu.Iyer@Sun.COM char *ptr = buf; 250411878SVenu.Iyer@Sun.COM char tmp_buf[DLADM_STRSIZE]; 250511878SVenu.Iyer@Sun.COM uint_t hexlen, cidlen; 250611878SVenu.Iyer@Sun.COM 250711878SVenu.Iyer@Sun.COM bzero(cid, sizeof (*cid)); 250811878SVenu.Iyer@Sun.COM if (isdigit(*ptr) && 250911878SVenu.Iyer@Sun.COM ptr[strspn(ptr, "0123456789")] == '.') { 251011878SVenu.Iyer@Sun.COM char *cp; 251111878SVenu.Iyer@Sun.COM ulong_t duidtype; 251211878SVenu.Iyer@Sun.COM ulong_t subtype; 251311878SVenu.Iyer@Sun.COM ulong_t timestamp; 251411878SVenu.Iyer@Sun.COM uchar_t *lladdr; 251511878SVenu.Iyer@Sun.COM int addrlen; 251611878SVenu.Iyer@Sun.COM 251711878SVenu.Iyer@Sun.COM errno = 0; 251811878SVenu.Iyer@Sun.COM duidtype = strtoul(ptr, &cp, 0); 251911878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.' || 252011878SVenu.Iyer@Sun.COM duidtype > USHRT_MAX) 252111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 252211878SVenu.Iyer@Sun.COM ptr = cp + 1; 252311878SVenu.Iyer@Sun.COM 252411878SVenu.Iyer@Sun.COM if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 252511878SVenu.Iyer@Sun.COM errno = 0; 252611878SVenu.Iyer@Sun.COM subtype = strtoul(ptr, &cp, 0); 252711878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.') 252811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 252911878SVenu.Iyer@Sun.COM ptr = cp + 1; 253011878SVenu.Iyer@Sun.COM } 253111878SVenu.Iyer@Sun.COM switch (duidtype) { 253211878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LLT: { 253311878SVenu.Iyer@Sun.COM duid_llt_t llt; 253411878SVenu.Iyer@Sun.COM 253511878SVenu.Iyer@Sun.COM errno = 0; 253611878SVenu.Iyer@Sun.COM timestamp = strtoul(ptr, &cp, 0); 253711878SVenu.Iyer@Sun.COM if (ptr == cp || errno != 0 || *cp != '.') 253811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 253911878SVenu.Iyer@Sun.COM 254011878SVenu.Iyer@Sun.COM ptr = cp + 1; 254111878SVenu.Iyer@Sun.COM lladdr = _link_aton(ptr, &addrlen); 254211878SVenu.Iyer@Sun.COM if (lladdr == NULL) 254311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 254411878SVenu.Iyer@Sun.COM 254511878SVenu.Iyer@Sun.COM cidlen = sizeof (llt) + addrlen; 254611878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) { 254711878SVenu.Iyer@Sun.COM free(lladdr); 254811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 254911878SVenu.Iyer@Sun.COM } 255011878SVenu.Iyer@Sun.COM llt.dllt_dutype = htons(duidtype); 255111878SVenu.Iyer@Sun.COM llt.dllt_hwtype = htons(subtype); 255211878SVenu.Iyer@Sun.COM llt.dllt_time = htonl(timestamp); 255311878SVenu.Iyer@Sun.COM bcopy(&llt, cid->dc_id, sizeof (llt)); 255411878SVenu.Iyer@Sun.COM bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 255511878SVenu.Iyer@Sun.COM free(lladdr); 255611878SVenu.Iyer@Sun.COM break; 255711878SVenu.Iyer@Sun.COM } 255811878SVenu.Iyer@Sun.COM case DHCPV6_DUID_LL: { 255911878SVenu.Iyer@Sun.COM duid_ll_t ll; 256011878SVenu.Iyer@Sun.COM 256111878SVenu.Iyer@Sun.COM lladdr = _link_aton(ptr, &addrlen); 256211878SVenu.Iyer@Sun.COM if (lladdr == NULL) 256311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 256411878SVenu.Iyer@Sun.COM 256511878SVenu.Iyer@Sun.COM cidlen = sizeof (ll) + addrlen; 256611878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) { 256711878SVenu.Iyer@Sun.COM free(lladdr); 256811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 256911878SVenu.Iyer@Sun.COM } 257011878SVenu.Iyer@Sun.COM ll.dll_dutype = htons(duidtype); 257111878SVenu.Iyer@Sun.COM ll.dll_hwtype = htons(subtype); 257211878SVenu.Iyer@Sun.COM bcopy(&ll, cid->dc_id, sizeof (ll)); 257311878SVenu.Iyer@Sun.COM bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 257411878SVenu.Iyer@Sun.COM free(lladdr); 257511878SVenu.Iyer@Sun.COM break; 257611878SVenu.Iyer@Sun.COM } 257711878SVenu.Iyer@Sun.COM default: { 257811878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 257911878SVenu.Iyer@Sun.COM if (hexascii_to_octet(ptr, strlen(ptr), 258011878SVenu.Iyer@Sun.COM tmp_buf, &hexlen) != 0) 258111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 258211878SVenu.Iyer@Sun.COM 258311878SVenu.Iyer@Sun.COM if (duidtype == DHCPV6_DUID_EN) { 258411878SVenu.Iyer@Sun.COM duid_en_t en; 258511878SVenu.Iyer@Sun.COM 258611878SVenu.Iyer@Sun.COM en.den_dutype = htons(duidtype); 258711878SVenu.Iyer@Sun.COM DHCPV6_SET_ENTNUM(&en, subtype); 258811878SVenu.Iyer@Sun.COM 258911878SVenu.Iyer@Sun.COM cidlen = sizeof (en) + hexlen; 259011878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 259111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 259211878SVenu.Iyer@Sun.COM 259311878SVenu.Iyer@Sun.COM bcopy(&en, cid->dc_id, sizeof (en)); 259411878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id + sizeof (en), 259511878SVenu.Iyer@Sun.COM hexlen); 259611878SVenu.Iyer@Sun.COM } else { 259711878SVenu.Iyer@Sun.COM uint16_t dutype = htons(duidtype); 259811878SVenu.Iyer@Sun.COM 259911878SVenu.Iyer@Sun.COM cidlen = sizeof (dutype) + hexlen; 260011878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 260111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 260211878SVenu.Iyer@Sun.COM 260311878SVenu.Iyer@Sun.COM bcopy(&dutype, cid->dc_id, sizeof (dutype)); 260411878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 260511878SVenu.Iyer@Sun.COM hexlen); 260611878SVenu.Iyer@Sun.COM } 260711878SVenu.Iyer@Sun.COM break; 260811878SVenu.Iyer@Sun.COM } 260911878SVenu.Iyer@Sun.COM } 261011878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_TYPED; 261111878SVenu.Iyer@Sun.COM } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 261211878SVenu.Iyer@Sun.COM ptr += 2; 261311878SVenu.Iyer@Sun.COM hexlen = sizeof (tmp_buf); 261411878SVenu.Iyer@Sun.COM if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 261511878SVenu.Iyer@Sun.COM &hexlen) != 0) { 261611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADARG); 261711878SVenu.Iyer@Sun.COM } 261811878SVenu.Iyer@Sun.COM cidlen = hexlen; 261911878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 262011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 262111878SVenu.Iyer@Sun.COM 262211878SVenu.Iyer@Sun.COM bcopy(tmp_buf, cid->dc_id, cidlen); 262311878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_HEX; 262411878SVenu.Iyer@Sun.COM } else { 262511878SVenu.Iyer@Sun.COM cidlen = strlen(ptr); 262611878SVenu.Iyer@Sun.COM if (cidlen > sizeof (cid->dc_id)) 262711878SVenu.Iyer@Sun.COM return (DLADM_STATUS_TOOSMALL); 262811878SVenu.Iyer@Sun.COM 262911878SVenu.Iyer@Sun.COM bcopy(ptr, cid->dc_id, cidlen); 263011878SVenu.Iyer@Sun.COM cid->dc_form = CIDFORM_STR; 263111878SVenu.Iyer@Sun.COM } 263211878SVenu.Iyer@Sun.COM cid->dc_len = cidlen; 263310734SEric Cheng return (DLADM_STATUS_OK); 263410734SEric Cheng } 263510734SEric Cheng 263610734SEric Cheng /* ARGSUSED */ 263710734SEric Cheng static dladm_status_t 263811878SVenu.Iyer@Sun.COM get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 263911878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 264011878SVenu.Iyer@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 264111878SVenu.Iyer@Sun.COM { 264211878SVenu.Iyer@Sun.COM mac_resource_props_t mrp; 264311878SVenu.Iyer@Sun.COM mac_protect_t *p; 264411878SVenu.Iyer@Sun.COM dladm_status_t status; 264511878SVenu.Iyer@Sun.COM int i; 264611878SVenu.Iyer@Sun.COM 264711878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 264811878SVenu.Iyer@Sun.COM perm_flags, &mrp, sizeof (mrp)); 264911878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 265011878SVenu.Iyer@Sun.COM return (status); 265111878SVenu.Iyer@Sun.COM 265211878SVenu.Iyer@Sun.COM p = &mrp.mrp_protect; 265311878SVenu.Iyer@Sun.COM if (p->mp_cidcnt == 0) { 265411878SVenu.Iyer@Sun.COM *val_cnt = 0; 265511878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 265611878SVenu.Iyer@Sun.COM } 265711878SVenu.Iyer@Sun.COM if (p->mp_cidcnt > *val_cnt) 265811878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 265911878SVenu.Iyer@Sun.COM 266011878SVenu.Iyer@Sun.COM for (i = 0; i < p->mp_cidcnt; i++) { 266111878SVenu.Iyer@Sun.COM mac_dhcpcid_t *cid = &p->mp_cids[i]; 266211878SVenu.Iyer@Sun.COM 266311878SVenu.Iyer@Sun.COM dladm_cid2str(cid, prop_val[i]); 266411878SVenu.Iyer@Sun.COM } 266511878SVenu.Iyer@Sun.COM *val_cnt = p->mp_cidcnt; 266611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 266711878SVenu.Iyer@Sun.COM } 266811878SVenu.Iyer@Sun.COM 266911878SVenu.Iyer@Sun.COM dladm_status_t 267011878SVenu.Iyer@Sun.COM extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 267111878SVenu.Iyer@Sun.COM { 267211878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp = arg; 267311878SVenu.Iyer@Sun.COM mac_protect_t *p = &mrp->mrp_protect; 267411878SVenu.Iyer@Sun.COM int i; 267511878SVenu.Iyer@Sun.COM 267611878SVenu.Iyer@Sun.COM if (vdp->vd_val == 0) { 267711878SVenu.Iyer@Sun.COM cnt = (uint_t)-1; 267811878SVenu.Iyer@Sun.COM } else { 267911878SVenu.Iyer@Sun.COM for (i = 0; i < cnt; i++) { 268011878SVenu.Iyer@Sun.COM bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 268111878SVenu.Iyer@Sun.COM sizeof (mac_dhcpcid_t)); 268211878SVenu.Iyer@Sun.COM } 268311878SVenu.Iyer@Sun.COM } 268411878SVenu.Iyer@Sun.COM p->mp_cidcnt = cnt; 268511878SVenu.Iyer@Sun.COM mrp->mrp_mask |= MRP_PROTECT; 268611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 268711878SVenu.Iyer@Sun.COM } 268811878SVenu.Iyer@Sun.COM 268911878SVenu.Iyer@Sun.COM /* ARGSUSED */ 269011878SVenu.Iyer@Sun.COM static dladm_status_t 269111878SVenu.Iyer@Sun.COM check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 269211878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, 269311878SVenu.Iyer@Sun.COM uint_t flags, val_desc_t *vdp, datalink_media_t media) 269411878SVenu.Iyer@Sun.COM { 269511878SVenu.Iyer@Sun.COM dladm_status_t status; 269611878SVenu.Iyer@Sun.COM mac_dhcpcid_t *cid; 269711878SVenu.Iyer@Sun.COM int i; 269811878SVenu.Iyer@Sun.COM 269911878SVenu.Iyer@Sun.COM if (val_cnt > MPT_MAXCID) 270011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 270111878SVenu.Iyer@Sun.COM 270211878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 270311878SVenu.Iyer@Sun.COM if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 270411878SVenu.Iyer@Sun.COM status = DLADM_STATUS_NOMEM; 270511878SVenu.Iyer@Sun.COM goto fail; 270611878SVenu.Iyer@Sun.COM } 270711878SVenu.Iyer@Sun.COM vdp[i].vd_val = (uintptr_t)cid; 270811878SVenu.Iyer@Sun.COM 270911878SVenu.Iyer@Sun.COM status = dladm_str2cid(prop_val[i], cid); 271011878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 271111878SVenu.Iyer@Sun.COM goto fail; 271211878SVenu.Iyer@Sun.COM } 271311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 271411878SVenu.Iyer@Sun.COM 271511878SVenu.Iyer@Sun.COM fail: 271611878SVenu.Iyer@Sun.COM for (i = 0; i < val_cnt; i++) { 271711878SVenu.Iyer@Sun.COM free((void *)vdp[i].vd_val); 271811878SVenu.Iyer@Sun.COM vdp[i].vd_val = NULL; 271911878SVenu.Iyer@Sun.COM } 272011878SVenu.Iyer@Sun.COM return (status); 272111878SVenu.Iyer@Sun.COM } 272211878SVenu.Iyer@Sun.COM 272311878SVenu.Iyer@Sun.COM /* ARGSUSED */ 272411878SVenu.Iyer@Sun.COM static dladm_status_t 272511878SVenu.Iyer@Sun.COM get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 27268275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 27278275SEric Cheng uint_t flags, uint_t *perm_flags) 27285895Syz147064 { 27297342SAruna.Ramakrishna@Sun.COM struct dlautopush dlap; 27307342SAruna.Ramakrishna@Sun.COM int i, len; 27317342SAruna.Ramakrishna@Sun.COM dladm_status_t status; 273211878SVenu.Iyer@Sun.COM 273311878SVenu.Iyer@Sun.COM if (flags & DLD_PROP_DEFAULT) 27347776SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOTDEFINED); 27356512Ssowmini 273611878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 273711878SVenu.Iyer@Sun.COM perm_flags, &dlap, sizeof (dlap)); 273811878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 273911878SVenu.Iyer@Sun.COM return (status); 274011878SVenu.Iyer@Sun.COM 274111878SVenu.Iyer@Sun.COM if (dlap.dap_npush == 0) { 274211878SVenu.Iyer@Sun.COM *val_cnt = 0; 27438275SEric Cheng return (DLADM_STATUS_OK); 27445895Syz147064 } 27457342SAruna.Ramakrishna@Sun.COM for (i = 0, len = 0; i < dlap.dap_npush; i++) { 27465895Syz147064 if (i != 0) { 27475895Syz147064 (void) snprintf(*prop_val + len, 27485895Syz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 27495895Syz147064 len += 1; 27505895Syz147064 } 27515895Syz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 27527342SAruna.Ramakrishna@Sun.COM "%s", dlap.dap_aplist[i]); 27537342SAruna.Ramakrishna@Sun.COM len += strlen(dlap.dap_aplist[i]); 27547342SAruna.Ramakrishna@Sun.COM if (dlap.dap_anchor - 1 == i) { 27555895Syz147064 (void) snprintf(*prop_val + len, 27565895Syz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 27575895Syz147064 AP_ANCHOR); 27585895Syz147064 len += (strlen(AP_ANCHOR) + 1); 27595895Syz147064 } 27605895Syz147064 } 276111878SVenu.Iyer@Sun.COM *val_cnt = 1; 27625895Syz147064 return (DLADM_STATUS_OK); 27635895Syz147064 } 27645895Syz147064 27655895Syz147064 /* 27665895Syz147064 * Add the specified module to the dlautopush structure; returns a 27675895Syz147064 * DLADM_STATUS_* code. 27685895Syz147064 */ 27695895Syz147064 dladm_status_t 27705895Syz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 27715895Syz147064 { 27725895Syz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 27735895Syz147064 return (DLADM_STATUS_BADVAL); 27745895Syz147064 27755895Syz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 27765895Syz147064 /* 27775895Syz147064 * We don't allow multiple anchors, and the anchor must 27785895Syz147064 * be after at least one module. 27795895Syz147064 */ 27805895Syz147064 if (dlap->dap_anchor != 0) 27815895Syz147064 return (DLADM_STATUS_BADVAL); 27825895Syz147064 if (dlap->dap_npush == 0) 27835895Syz147064 return (DLADM_STATUS_BADVAL); 27845895Syz147064 27855895Syz147064 dlap->dap_anchor = dlap->dap_npush; 27865895Syz147064 return (DLADM_STATUS_OK); 27875895Syz147064 } 27888957SMichael.Lim@Sun.COM if (dlap->dap_npush >= MAXAPUSH) 27895895Syz147064 return (DLADM_STATUS_BADVALCNT); 27905895Syz147064 27915895Syz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 27925895Syz147064 FMNAMESZ + 1); 27935895Syz147064 27945895Syz147064 return (DLADM_STATUS_OK); 27955895Syz147064 } 27965895Syz147064 27975895Syz147064 /* 27985895Syz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 27995895Syz147064 * autopush modules. The former is used in dladm set-linkprop, and the 28005895Syz147064 * latter is used in the autopush(1M) file. 28015895Syz147064 */ 28025895Syz147064 /* ARGSUSED */ 28035895Syz147064 static dladm_status_t 280411878SVenu.Iyer@Sun.COM check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 280511878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 280611878SVenu.Iyer@Sun.COM datalink_media_t media) 28075895Syz147064 { 28085895Syz147064 char *module; 28095895Syz147064 struct dlautopush *dlap; 28105895Syz147064 dladm_status_t status; 28115895Syz147064 char val[DLADM_PROP_VAL_MAX]; 28125895Syz147064 char delimiters[4]; 28135895Syz147064 28145895Syz147064 if (val_cnt != 1) 28155895Syz147064 return (DLADM_STATUS_BADVALCNT); 28165895Syz147064 28177342SAruna.Ramakrishna@Sun.COM if (prop_val != NULL) { 28187342SAruna.Ramakrishna@Sun.COM dlap = malloc(sizeof (struct dlautopush)); 28197342SAruna.Ramakrishna@Sun.COM if (dlap == NULL) 28207342SAruna.Ramakrishna@Sun.COM return (DLADM_STATUS_NOMEM); 28213448Sdh155122 28227342SAruna.Ramakrishna@Sun.COM (void) memset(dlap, 0, sizeof (struct dlautopush)); 28237342SAruna.Ramakrishna@Sun.COM (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 28247342SAruna.Ramakrishna@Sun.COM bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 28257342SAruna.Ramakrishna@Sun.COM module = strtok(val, delimiters); 28267342SAruna.Ramakrishna@Sun.COM while (module != NULL) { 28277342SAruna.Ramakrishna@Sun.COM status = i_dladm_add_ap_module(module, dlap); 28287342SAruna.Ramakrishna@Sun.COM if (status != DLADM_STATUS_OK) 28297342SAruna.Ramakrishna@Sun.COM return (status); 28307342SAruna.Ramakrishna@Sun.COM module = strtok(NULL, delimiters); 28317342SAruna.Ramakrishna@Sun.COM } 28327342SAruna.Ramakrishna@Sun.COM 28337342SAruna.Ramakrishna@Sun.COM vdp->vd_val = (uintptr_t)dlap; 28347342SAruna.Ramakrishna@Sun.COM } else { 28357342SAruna.Ramakrishna@Sun.COM vdp->vd_val = 0; 28365895Syz147064 } 28373448Sdh155122 return (DLADM_STATUS_OK); 28383448Sdh155122 } 28393448Sdh155122 28407663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 28417663SSowmini.Varadhan@Sun.COM 28425903Ssowmini /* ARGSUSED */ 28433448Sdh155122 static dladm_status_t 284411878SVenu.Iyer@Sun.COM get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 28458453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 28468453SAnurag.Maskey@Sun.COM uint_t *perm_flags) 28473448Sdh155122 { 28485895Syz147064 wl_rates_t *wrp; 28495895Syz147064 uint_t i; 28505895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 28515895Syz147064 28527663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 28537663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 28547663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 28555895Syz147064 28568453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 28578453SAnurag.Maskey@Sun.COM B_FALSE); 28585895Syz147064 if (status != DLADM_STATUS_OK) 28595895Syz147064 goto done; 28605895Syz147064 28615895Syz147064 if (wrp->wl_rates_num > *val_cnt) { 28625895Syz147064 status = DLADM_STATUS_TOOSMALL; 28635895Syz147064 goto done; 28645895Syz147064 } 28655895Syz147064 28665895Syz147064 if (wrp->wl_rates_rates[0] == 0) { 28675895Syz147064 prop_val[0][0] = '\0'; 28685895Syz147064 *val_cnt = 1; 28695895Syz147064 goto done; 28705895Syz147064 } 28715895Syz147064 28725895Syz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 28735895Syz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 28745895Syz147064 wrp->wl_rates_rates[i] % 2, 28755895Syz147064 (float)wrp->wl_rates_rates[i] / 2); 28765895Syz147064 } 28775895Syz147064 *val_cnt = wrp->wl_rates_num; 28788275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 28793448Sdh155122 28805895Syz147064 done: 28817663SSowmini.Varadhan@Sun.COM free(wrp); 28825895Syz147064 return (status); 28835895Syz147064 } 28845895Syz147064 28855895Syz147064 static dladm_status_t 288611878SVenu.Iyer@Sun.COM get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 28878275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 28888275SEric Cheng uint_t flags, uint_t *perm_flags) 28895895Syz147064 { 28908118SVasumathi.Sundaram@Sun.COM if (media != DL_WIFI) { 289111878SVenu.Iyer@Sun.COM return (get_speed(handle, pdp, linkid, prop_val, 289211878SVenu.Iyer@Sun.COM val_cnt, media, flags, perm_flags)); 28938118SVasumathi.Sundaram@Sun.COM } 28945960Ssowmini 289511878SVenu.Iyer@Sun.COM return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 28968275SEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 28975895Syz147064 } 28985895Syz147064 28996512Ssowmini /* ARGSUSED */ 29005895Syz147064 static dladm_status_t 290111878SVenu.Iyer@Sun.COM get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 29028275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 29038275SEric Cheng uint_t flags, uint_t *perm_flags) 29045895Syz147064 { 29055960Ssowmini switch (media) { 29065960Ssowmini case DL_ETHER: 29076512Ssowmini /* 29086512Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 29096512Ssowmini * links can have a speed of 5.5 Gbps. 29106512Ssowmini */ 29116512Ssowmini return (DLADM_STATUS_NOTSUP); 29125960Ssowmini 29135960Ssowmini case DL_WIFI: 291411878SVenu.Iyer@Sun.COM return (get_rate_common(handle, pdp, linkid, prop_val, 29158453SAnurag.Maskey@Sun.COM val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 29165960Ssowmini default: 29175960Ssowmini return (DLADM_STATUS_BADARG); 29185960Ssowmini } 29195895Syz147064 } 29205895Syz147064 29215895Syz147064 static dladm_status_t 292211878SVenu.Iyer@Sun.COM set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 29238453SAnurag.Maskey@Sun.COM dladm_wlan_rates_t *rates) 29245895Syz147064 { 29255895Syz147064 int i; 29265895Syz147064 uint_t len; 29275895Syz147064 wl_rates_t *wrp; 29285895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 29295895Syz147064 29307663SSowmini.Varadhan@Sun.COM wrp = malloc(WLDP_BUFSIZE); 29317663SSowmini.Varadhan@Sun.COM if (wrp == NULL) 29325895Syz147064 return (DLADM_STATUS_NOMEM); 29335895Syz147064 29347663SSowmini.Varadhan@Sun.COM bzero(wrp, WLDP_BUFSIZE); 29355895Syz147064 for (i = 0; i < rates->wr_cnt; i++) 29365895Syz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 29375895Syz147064 wrp->wl_rates_num = rates->wr_cnt; 29385895Syz147064 29395895Syz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 29405895Syz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 29418453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, wrp, 29428453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 29435895Syz147064 29447663SSowmini.Varadhan@Sun.COM free(wrp); 29455895Syz147064 return (status); 29465895Syz147064 } 29473448Sdh155122 29485903Ssowmini /* ARGSUSED */ 29495895Syz147064 static dladm_status_t 295011878SVenu.Iyer@Sun.COM set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 29515960Ssowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 29525895Syz147064 { 29535895Syz147064 dladm_wlan_rates_t rates; 29545895Syz147064 dladm_status_t status; 29555895Syz147064 29565960Ssowmini /* 29575960Ssowmini * can currently set rate on WIFI links only. 29585960Ssowmini */ 29595960Ssowmini if (media != DL_WIFI) 29605960Ssowmini return (DLADM_STATUS_PROPRDONLY); 29615960Ssowmini 29625895Syz147064 if (val_cnt != 1) 29635895Syz147064 return (DLADM_STATUS_BADVALCNT); 29645895Syz147064 29655895Syz147064 rates.wr_cnt = 1; 29665895Syz147064 rates.wr_rates[0] = vdp[0].vd_val; 29675895Syz147064 296811878SVenu.Iyer@Sun.COM status = set_wlan_rate(handle, linkid, &rates); 296911878SVenu.Iyer@Sun.COM 29705895Syz147064 return (status); 29715895Syz147064 } 29723448Sdh155122 29735895Syz147064 /* ARGSUSED */ 29745895Syz147064 static dladm_status_t 297511878SVenu.Iyer@Sun.COM check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 297611878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 297711878SVenu.Iyer@Sun.COM datalink_media_t media) 29785895Syz147064 { 29795895Syz147064 int i; 29805895Syz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 29815895Syz147064 char *buf, **modval; 29825895Syz147064 dladm_status_t status; 29838118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 29845895Syz147064 29855895Syz147064 if (val_cnt != 1) 29865895Syz147064 return (DLADM_STATUS_BADVALCNT); 29875895Syz147064 29885895Syz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 29895895Syz147064 MAX_SUPPORT_RATES); 29905895Syz147064 if (buf == NULL) { 29915895Syz147064 status = DLADM_STATUS_NOMEM; 29925895Syz147064 goto done; 29935895Syz147064 } 29943448Sdh155122 29955895Syz147064 modval = (char **)(void *)buf; 29965895Syz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 29975895Syz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 29985895Syz147064 i * DLADM_STRSIZE; 29995895Syz147064 } 30005895Syz147064 300111878SVenu.Iyer@Sun.COM status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 30028453SAnurag.Maskey@Sun.COM media, 0, &perm_flags); 30035895Syz147064 if (status != DLADM_STATUS_OK) 30045895Syz147064 goto done; 30055895Syz147064 30065895Syz147064 for (i = 0; i < modval_cnt; i++) { 30075895Syz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 30085903Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 30095903Ssowmini (atof(*prop_val) * 2); 30105895Syz147064 status = DLADM_STATUS_OK; 30113448Sdh155122 break; 30123448Sdh155122 } 30135895Syz147064 } 30145895Syz147064 if (i == modval_cnt) 30155895Syz147064 status = DLADM_STATUS_BADVAL; 30165895Syz147064 done: 30175895Syz147064 free(buf); 30185895Syz147064 return (status); 30195895Syz147064 } 30205895Syz147064 30215895Syz147064 static dladm_status_t 302211878SVenu.Iyer@Sun.COM get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 30238453SAnurag.Maskey@Sun.COM int buflen) 30245895Syz147064 { 30258453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 30267663SSowmini.Varadhan@Sun.COM buflen, B_FALSE)); 30275895Syz147064 } 30285895Syz147064 30295903Ssowmini /* ARGSUSED */ 30305895Syz147064 static dladm_status_t 303111878SVenu.Iyer@Sun.COM get_channel(dladm_handle_t handle, prop_desc_t *pdp, 30328453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30338453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30345895Syz147064 { 30355895Syz147064 uint32_t channel; 30367663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 303711878SVenu.Iyer@Sun.COM dladm_status_t status; 30387663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf; 30395895Syz147064 304011878SVenu.Iyer@Sun.COM if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 30417663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK) 304211878SVenu.Iyer@Sun.COM return (status); 30435895Syz147064 30447663SSowmini.Varadhan@Sun.COM (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 304511878SVenu.Iyer@Sun.COM if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 304611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 30475895Syz147064 30485895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 30495895Syz147064 *val_cnt = 1; 30508275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 305111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 30525895Syz147064 } 30535895Syz147064 30545903Ssowmini /* ARGSUSED */ 30555895Syz147064 static dladm_status_t 305611878SVenu.Iyer@Sun.COM get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 30578453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30588453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 30595895Syz147064 { 30607663SSowmini.Varadhan@Sun.COM wl_ps_mode_t mode; 30615895Syz147064 const char *s; 30627663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 306311878SVenu.Iyer@Sun.COM dladm_status_t status; 306411878SVenu.Iyer@Sun.COM 306511878SVenu.Iyer@Sun.COM if ((status = i_dladm_wlan_param(handle, linkid, buf, 306611878SVenu.Iyer@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 306711878SVenu.Iyer@Sun.COM return (status); 30685895Syz147064 30697663SSowmini.Varadhan@Sun.COM (void) memcpy(&mode, buf, sizeof (mode)); 30707663SSowmini.Varadhan@Sun.COM switch (mode.wl_ps_mode) { 30715895Syz147064 case WL_PM_AM: 30725895Syz147064 s = "off"; 30735895Syz147064 break; 30745895Syz147064 case WL_PM_MPS: 30755895Syz147064 s = "max"; 30765895Syz147064 break; 30775895Syz147064 case WL_PM_FAST: 30785895Syz147064 s = "fast"; 30793448Sdh155122 break; 30803448Sdh155122 default: 308111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 30825895Syz147064 } 30835895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 30845895Syz147064 *val_cnt = 1; 30858275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 308611878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 30875895Syz147064 } 30885895Syz147064 308911878SVenu.Iyer@Sun.COM /* ARGSUSED */ 30905895Syz147064 static dladm_status_t 309111878SVenu.Iyer@Sun.COM set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 309211878SVenu.Iyer@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 309311878SVenu.Iyer@Sun.COM datalink_media_t media) 30945895Syz147064 { 309511878SVenu.Iyer@Sun.COM dladm_wlan_powermode_t powermode = vdp->vd_val; 309611878SVenu.Iyer@Sun.COM wl_ps_mode_t ps_mode; 309711878SVenu.Iyer@Sun.COM 309811878SVenu.Iyer@Sun.COM if (val_cnt != 1) 309911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 31005895Syz147064 31015895Syz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 31025895Syz147064 310311878SVenu.Iyer@Sun.COM switch (powermode) { 31045895Syz147064 case DLADM_WLAN_PM_OFF: 31055895Syz147064 ps_mode.wl_ps_mode = WL_PM_AM; 31063448Sdh155122 break; 31075895Syz147064 case DLADM_WLAN_PM_MAX: 31085895Syz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 31095895Syz147064 break; 31105895Syz147064 case DLADM_WLAN_PM_FAST: 31115895Syz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 31125895Syz147064 break; 31135895Syz147064 default: 31145895Syz147064 return (DLADM_STATUS_NOTSUP); 31153448Sdh155122 } 31168453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ps_mode, 31178453SAnurag.Maskey@Sun.COM MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 31185895Syz147064 } 31195895Syz147064 31205895Syz147064 /* ARGSUSED */ 31215895Syz147064 static dladm_status_t 312211878SVenu.Iyer@Sun.COM get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 31238275SEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 31248275SEric Cheng uint_t flags, uint_t *perm_flags) 31255895Syz147064 { 31265895Syz147064 wl_radio_t radio; 31275895Syz147064 const char *s; 31287663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE]; 312911878SVenu.Iyer@Sun.COM dladm_status_t status; 313011878SVenu.Iyer@Sun.COM 313111878SVenu.Iyer@Sun.COM if ((status = i_dladm_wlan_param(handle, linkid, buf, 313211878SVenu.Iyer@Sun.COM MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 313311878SVenu.Iyer@Sun.COM return (status); 31343448Sdh155122 31357663SSowmini.Varadhan@Sun.COM (void) memcpy(&radio, buf, sizeof (radio)); 31365895Syz147064 switch (radio) { 31375895Syz147064 case B_TRUE: 31385895Syz147064 s = "on"; 31395895Syz147064 break; 31405895Syz147064 case B_FALSE: 31415895Syz147064 s = "off"; 31425895Syz147064 break; 31435895Syz147064 default: 314411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOTFOUND); 31455895Syz147064 } 31465895Syz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 31475895Syz147064 *val_cnt = 1; 31488275SEric Cheng *perm_flags = MAC_PROP_PERM_RW; 314911878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 31503448Sdh155122 } 31513448Sdh155122 315211878SVenu.Iyer@Sun.COM /* ARGSUSED */ 31533448Sdh155122 static dladm_status_t 315411878SVenu.Iyer@Sun.COM set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 315511878SVenu.Iyer@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 31563448Sdh155122 { 315711878SVenu.Iyer@Sun.COM dladm_wlan_radio_t radio = vdp->vd_val; 315811878SVenu.Iyer@Sun.COM wl_radio_t r; 315911878SVenu.Iyer@Sun.COM 316011878SVenu.Iyer@Sun.COM if (val_cnt != 1) 316111878SVenu.Iyer@Sun.COM return (DLADM_STATUS_BADVALCNT); 316211878SVenu.Iyer@Sun.COM 316311878SVenu.Iyer@Sun.COM switch (radio) { 31645895Syz147064 case DLADM_WLAN_RADIO_ON: 31655895Syz147064 r = B_TRUE; 31665895Syz147064 break; 31675895Syz147064 case DLADM_WLAN_RADIO_OFF: 31685895Syz147064 r = B_FALSE; 31695895Syz147064 break; 31705895Syz147064 default: 31715895Syz147064 return (DLADM_STATUS_NOTSUP); 31725895Syz147064 } 31738453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 31747663SSowmini.Varadhan@Sun.COM sizeof (r), B_TRUE)); 31755895Syz147064 } 31763448Sdh155122 31775895Syz147064 /* ARGSUSED */ 31785895Syz147064 static dladm_status_t 317911878SVenu.Iyer@Sun.COM check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 318011878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 318111878SVenu.Iyer@Sun.COM val_desc_t *vdp, datalink_media_t media) 318210616SSebastien.Roy@Sun.COM { 318310616SSebastien.Roy@Sun.COM int32_t hlim; 318410616SSebastien.Roy@Sun.COM char *ep; 318510616SSebastien.Roy@Sun.COM 318610616SSebastien.Roy@Sun.COM if (val_cnt != 1) 318710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 318810616SSebastien.Roy@Sun.COM 318910616SSebastien.Roy@Sun.COM errno = 0; 319010616SSebastien.Roy@Sun.COM hlim = strtol(*prop_val, &ep, 10); 319110616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || hlim < 1 || 319210616SSebastien.Roy@Sun.COM hlim > (int32_t)UINT8_MAX) 319310616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 319410616SSebastien.Roy@Sun.COM vdp->vd_val = hlim; 319510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 319610616SSebastien.Roy@Sun.COM } 319710616SSebastien.Roy@Sun.COM 319810616SSebastien.Roy@Sun.COM /* ARGSUSED */ 319910616SSebastien.Roy@Sun.COM static dladm_status_t 320011878SVenu.Iyer@Sun.COM check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 320111878SVenu.Iyer@Sun.COM char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 320211878SVenu.Iyer@Sun.COM datalink_media_t media) 320310616SSebastien.Roy@Sun.COM { 320410616SSebastien.Roy@Sun.COM int32_t elim; 320510616SSebastien.Roy@Sun.COM char *ep; 320610616SSebastien.Roy@Sun.COM 320710616SSebastien.Roy@Sun.COM if (media != DL_IPV6) 320810616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG); 320910616SSebastien.Roy@Sun.COM 321010616SSebastien.Roy@Sun.COM if (val_cnt != 1) 321110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVALCNT); 321210616SSebastien.Roy@Sun.COM 321310616SSebastien.Roy@Sun.COM errno = 0; 321410616SSebastien.Roy@Sun.COM elim = strtol(*prop_val, &ep, 10); 321510616SSebastien.Roy@Sun.COM if (errno != 0 || ep == *prop_val || elim < 0 || 321610616SSebastien.Roy@Sun.COM elim > (int32_t)UINT8_MAX) 321710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADVAL); 321810616SSebastien.Roy@Sun.COM vdp->vd_val = elim; 321910616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 322010616SSebastien.Roy@Sun.COM } 322110616SSebastien.Roy@Sun.COM 32225895Syz147064 static dladm_status_t 32238453SAnurag.Maskey@Sun.COM i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 32248453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt) 32253448Sdh155122 { 32265895Syz147064 char buf[MAXLINELEN]; 32275895Syz147064 int i; 32285895Syz147064 dladm_conf_t conf; 32295895Syz147064 dladm_status_t status; 32303448Sdh155122 32318453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 32325895Syz147064 if (status != DLADM_STATUS_OK) 32335895Syz147064 return (status); 32343448Sdh155122 32355895Syz147064 /* 32365895Syz147064 * reset case. 32375895Syz147064 */ 32385895Syz147064 if (val_cnt == 0) { 32398453SAnurag.Maskey@Sun.COM status = dladm_unset_conf_field(handle, conf, prop_name); 32405895Syz147064 if (status == DLADM_STATUS_OK) 32418453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 32425895Syz147064 goto done; 32435895Syz147064 } 32443448Sdh155122 32455895Syz147064 buf[0] = '\0'; 32465895Syz147064 for (i = 0; i < val_cnt; i++) { 32475895Syz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 32485895Syz147064 if (i != val_cnt - 1) 32495895Syz147064 (void) strlcat(buf, ",", MAXLINELEN); 32503448Sdh155122 } 32513448Sdh155122 32528453SAnurag.Maskey@Sun.COM status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 32538453SAnurag.Maskey@Sun.COM buf); 32545895Syz147064 if (status == DLADM_STATUS_OK) 32558453SAnurag.Maskey@Sun.COM status = dladm_write_conf(handle, conf); 32565895Syz147064 32575895Syz147064 done: 32588453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 32595895Syz147064 return (status); 32603448Sdh155122 } 32615895Syz147064 32625895Syz147064 static dladm_status_t 32638453SAnurag.Maskey@Sun.COM i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 32648453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cntp) 32655895Syz147064 { 32665895Syz147064 char buf[MAXLINELEN], *str; 32675895Syz147064 uint_t cnt = 0; 32685895Syz147064 dladm_conf_t conf; 32695895Syz147064 dladm_status_t status; 32705895Syz147064 32718453SAnurag.Maskey@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 32725895Syz147064 if (status != DLADM_STATUS_OK) 32735895Syz147064 return (status); 32745895Syz147064 32758453SAnurag.Maskey@Sun.COM status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 32765895Syz147064 if (status != DLADM_STATUS_OK) 32775895Syz147064 goto done; 32785895Syz147064 32795895Syz147064 str = strtok(buf, ","); 32805895Syz147064 while (str != NULL) { 32815895Syz147064 if (cnt == *val_cntp) { 32825895Syz147064 status = DLADM_STATUS_TOOSMALL; 32835895Syz147064 goto done; 32845895Syz147064 } 32855895Syz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 32865895Syz147064 str = strtok(NULL, ","); 32875895Syz147064 } 32885895Syz147064 32895895Syz147064 *val_cntp = cnt; 32905895Syz147064 32915895Syz147064 done: 32928453SAnurag.Maskey@Sun.COM dladm_destroy_conf(handle, conf); 32935895Syz147064 return (status); 32945895Syz147064 } 32955903Ssowmini 32968460SArtem.Kachitchkin@Sun.COM /* 32978460SArtem.Kachitchkin@Sun.COM * Walk persistent private link properties of a link. 32988460SArtem.Kachitchkin@Sun.COM */ 32998460SArtem.Kachitchkin@Sun.COM static dladm_status_t 33008460SArtem.Kachitchkin@Sun.COM i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 33018460SArtem.Kachitchkin@Sun.COM void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 33028460SArtem.Kachitchkin@Sun.COM { 33038460SArtem.Kachitchkin@Sun.COM dladm_status_t status; 33048460SArtem.Kachitchkin@Sun.COM dladm_conf_t conf; 33058460SArtem.Kachitchkin@Sun.COM char last_attr[MAXLINKATTRLEN]; 33068460SArtem.Kachitchkin@Sun.COM char attr[MAXLINKATTRLEN]; 33078460SArtem.Kachitchkin@Sun.COM char attrval[MAXLINKATTRVALLEN]; 33088460SArtem.Kachitchkin@Sun.COM size_t attrsz; 33098460SArtem.Kachitchkin@Sun.COM 33108460SArtem.Kachitchkin@Sun.COM if (linkid == DATALINK_INVALID_LINKID || func == NULL) 33118460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 33128460SArtem.Kachitchkin@Sun.COM 33138460SArtem.Kachitchkin@Sun.COM status = dladm_read_conf(handle, linkid, &conf); 33148460SArtem.Kachitchkin@Sun.COM if (status != DLADM_STATUS_OK) 33158460SArtem.Kachitchkin@Sun.COM return (status); 33168460SArtem.Kachitchkin@Sun.COM 33178460SArtem.Kachitchkin@Sun.COM last_attr[0] = '\0'; 33188460SArtem.Kachitchkin@Sun.COM while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 33198460SArtem.Kachitchkin@Sun.COM attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 33208460SArtem.Kachitchkin@Sun.COM if (attr[0] == '_') { 33218460SArtem.Kachitchkin@Sun.COM if (func(handle, linkid, attr, arg) == 33228460SArtem.Kachitchkin@Sun.COM DLADM_WALK_TERMINATE) 33238460SArtem.Kachitchkin@Sun.COM break; 33248460SArtem.Kachitchkin@Sun.COM } 33258460SArtem.Kachitchkin@Sun.COM (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 33268460SArtem.Kachitchkin@Sun.COM } 33278460SArtem.Kachitchkin@Sun.COM 33288460SArtem.Kachitchkin@Sun.COM dladm_destroy_conf(handle, conf); 33298460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 33308460SArtem.Kachitchkin@Sun.COM } 33318460SArtem.Kachitchkin@Sun.COM 33327663SSowmini.Varadhan@Sun.COM static link_attr_t * 33335903Ssowmini dladm_name2prop(const char *prop_name) 33345903Ssowmini { 33357663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33365903Ssowmini 33377663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 33385903Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 33395903Ssowmini break; 33405903Ssowmini } 33415903Ssowmini return (p); 33425903Ssowmini } 33435903Ssowmini 33447663SSowmini.Varadhan@Sun.COM static link_attr_t * 33457663SSowmini.Varadhan@Sun.COM dladm_id2prop(mac_prop_id_t propid) 33467663SSowmini.Varadhan@Sun.COM { 33477663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33487663SSowmini.Varadhan@Sun.COM 33497663SSowmini.Varadhan@Sun.COM for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 33507663SSowmini.Varadhan@Sun.COM if (p->pp_id == propid) 33517663SSowmini.Varadhan@Sun.COM break; 33527663SSowmini.Varadhan@Sun.COM } 33537663SSowmini.Varadhan@Sun.COM return (p); 33547663SSowmini.Varadhan@Sun.COM } 33555903Ssowmini 33566789Sam223141 static dld_ioc_macprop_t * 33577663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 33587663SSowmini.Varadhan@Sun.COM const char *prop_name, mac_prop_id_t propid, uint_t flags, 33597663SSowmini.Varadhan@Sun.COM dladm_status_t *status) 33605903Ssowmini { 33615903Ssowmini int dsize; 33626789Sam223141 dld_ioc_macprop_t *dip; 33635903Ssowmini 33645903Ssowmini *status = DLADM_STATUS_OK; 33656789Sam223141 dsize = MAC_PROP_BUFSIZE(valsize); 33665903Ssowmini dip = malloc(dsize); 33675903Ssowmini if (dip == NULL) { 33685903Ssowmini *status = DLADM_STATUS_NOMEM; 33695903Ssowmini return (NULL); 33705903Ssowmini } 33715903Ssowmini bzero(dip, dsize); 33725903Ssowmini dip->pr_valsize = valsize; 33736512Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 33745960Ssowmini dip->pr_linkid = linkid; 33757663SSowmini.Varadhan@Sun.COM dip->pr_num = propid; 33766512Ssowmini dip->pr_flags = flags; 33775903Ssowmini return (dip); 33785903Ssowmini } 33795903Ssowmini 33807663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 33817663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 33827663SSowmini.Varadhan@Sun.COM const char *prop_name, 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_name2prop(prop_name); 33877663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 33887663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 33897663SSowmini.Varadhan@Sun.COM flags, status)); 33907663SSowmini.Varadhan@Sun.COM } 33917663SSowmini.Varadhan@Sun.COM 33927663SSowmini.Varadhan@Sun.COM static dld_ioc_macprop_t * 33937663SSowmini.Varadhan@Sun.COM i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 33947663SSowmini.Varadhan@Sun.COM mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 33957663SSowmini.Varadhan@Sun.COM { 33967663SSowmini.Varadhan@Sun.COM link_attr_t *p; 33977663SSowmini.Varadhan@Sun.COM 33987663SSowmini.Varadhan@Sun.COM p = dladm_id2prop(propid); 33997663SSowmini.Varadhan@Sun.COM valsize = MAX(p->pp_valsize, valsize); 34007663SSowmini.Varadhan@Sun.COM return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 34017663SSowmini.Varadhan@Sun.COM flags, status)); 34027663SSowmini.Varadhan@Sun.COM } 34037663SSowmini.Varadhan@Sun.COM 34045903Ssowmini /* ARGSUSED */ 34055903Ssowmini static dladm_status_t 340611878SVenu.Iyer@Sun.COM set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 34078453SAnurag.Maskey@Sun.COM datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 34088453SAnurag.Maskey@Sun.COM datalink_media_t media) 34095903Ssowmini { 34106789Sam223141 dld_ioc_macprop_t *dip; 34115903Ssowmini dladm_status_t status = DLADM_STATUS_OK; 34125903Ssowmini uint8_t u8; 34135903Ssowmini uint16_t u16; 34145903Ssowmini uint32_t u32; 34155903Ssowmini void *val; 34165903Ssowmini 34178275SEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 34185903Ssowmini if (dip == NULL) 34195903Ssowmini return (status); 34205903Ssowmini 34218275SEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 34225903Ssowmini val = (void *)vdp->vd_val; 34235903Ssowmini else { 34245903Ssowmini /* 34255903Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 34265903Ssowmini * No need (yet) to distinguish these from arrays of same size. 34275903Ssowmini */ 34285903Ssowmini switch (dip->pr_valsize) { 34295903Ssowmini case 1: 34305903Ssowmini u8 = vdp->vd_val; 34315903Ssowmini val = &u8; 34325903Ssowmini break; 34335903Ssowmini case 2: 34345903Ssowmini u16 = vdp->vd_val; 34355903Ssowmini val = &u16; 34365903Ssowmini break; 34375903Ssowmini case 4: 34385903Ssowmini u32 = vdp->vd_val; 34395903Ssowmini val = &u32; 34405903Ssowmini break; 34415903Ssowmini default: 34425903Ssowmini val = &vdp->vd_val; 34435903Ssowmini break; 34445903Ssowmini } 34455903Ssowmini } 34465903Ssowmini 34477342SAruna.Ramakrishna@Sun.COM if (val != NULL) 34487342SAruna.Ramakrishna@Sun.COM (void) memcpy(dip->pr_val, val, dip->pr_valsize); 34497342SAruna.Ramakrishna@Sun.COM else 34507342SAruna.Ramakrishna@Sun.COM dip->pr_valsize = 0; 34517342SAruna.Ramakrishna@Sun.COM 34528453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 34537663SSowmini.Varadhan@Sun.COM 34547663SSowmini.Varadhan@Sun.COM done: 34557663SSowmini.Varadhan@Sun.COM free(dip); 34567663SSowmini.Varadhan@Sun.COM return (status); 34577663SSowmini.Varadhan@Sun.COM } 34587663SSowmini.Varadhan@Sun.COM 34597663SSowmini.Varadhan@Sun.COM dladm_status_t 34608453SAnurag.Maskey@Sun.COM i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 34617663SSowmini.Varadhan@Sun.COM { 34627663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 34637663SSowmini.Varadhan@Sun.COM 34648453SAnurag.Maskey@Sun.COM if (ioctl(dladm_dld_fd(handle), 34658453SAnurag.Maskey@Sun.COM (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 34665903Ssowmini status = dladm_errno2status(errno); 34678453SAnurag.Maskey@Sun.COM 34685903Ssowmini return (status); 34695903Ssowmini } 34705903Ssowmini 347111878SVenu.Iyer@Sun.COM static dladm_status_t 34728453SAnurag.Maskey@Sun.COM i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 347311878SVenu.Iyer@Sun.COM char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 34745903Ssowmini { 347511878SVenu.Iyer@Sun.COM dld_ioc_macprop_t *dip; 347611878SVenu.Iyer@Sun.COM dladm_status_t status; 347711878SVenu.Iyer@Sun.COM 347811878SVenu.Iyer@Sun.COM dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 34796512Ssowmini if (dip == NULL) 348011878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 348111878SVenu.Iyer@Sun.COM 348211878SVenu.Iyer@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 348311878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) { 34846512Ssowmini free(dip); 348511878SVenu.Iyer@Sun.COM return (status); 34866512Ssowmini } 348711878SVenu.Iyer@Sun.COM 34888275SEric Cheng if (perm_flags != NULL) 34898275SEric Cheng *perm_flags = dip->pr_perm_flags; 34908275SEric Cheng 349111878SVenu.Iyer@Sun.COM if (arg != NULL) 349211878SVenu.Iyer@Sun.COM (void) memcpy(arg, dip->pr_val, size); 349311878SVenu.Iyer@Sun.COM free(dip); 349411878SVenu.Iyer@Sun.COM return (DLADM_STATUS_OK); 34955903Ssowmini } 34965903Ssowmini 34975903Ssowmini /* ARGSUSED */ 34985903Ssowmini static dladm_status_t 349911878SVenu.Iyer@Sun.COM check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 350011878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 350111878SVenu.Iyer@Sun.COM val_desc_t *v, datalink_media_t media) 35025903Ssowmini { 35035903Ssowmini if (val_cnt != 1) 35045903Ssowmini return (DLADM_STATUS_BADVAL); 350510491SRishi.Srivatsavai@Sun.COM v->vd_val = strtoul(prop_val[0], NULL, 0); 35065903Ssowmini return (DLADM_STATUS_OK); 35075903Ssowmini } 35085903Ssowmini 35095903Ssowmini /* ARGSUSED */ 35105903Ssowmini static dladm_status_t 351111878SVenu.Iyer@Sun.COM get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 35128453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35138453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35145903Ssowmini { 35155903Ssowmini link_duplex_t link_duplex; 35165903Ssowmini dladm_status_t status; 35175903Ssowmini 35188453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 35195903Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 35205903Ssowmini return (status); 35215903Ssowmini 35225903Ssowmini switch (link_duplex) { 35235903Ssowmini case LINK_DUPLEX_FULL: 35245903Ssowmini (void) strcpy(*prop_val, "full"); 35255903Ssowmini break; 35265903Ssowmini case LINK_DUPLEX_HALF: 35275903Ssowmini (void) strcpy(*prop_val, "half"); 35285903Ssowmini break; 35295903Ssowmini default: 35305903Ssowmini (void) strcpy(*prop_val, "unknown"); 35315903Ssowmini break; 35325903Ssowmini } 35335903Ssowmini *val_cnt = 1; 35345903Ssowmini return (DLADM_STATUS_OK); 35355903Ssowmini } 35365903Ssowmini 35375903Ssowmini /* ARGSUSED */ 35385903Ssowmini static dladm_status_t 353911878SVenu.Iyer@Sun.COM get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 354011878SVenu.Iyer@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 354111878SVenu.Iyer@Sun.COM uint_t *perm_flags) 35425903Ssowmini { 35435903Ssowmini uint64_t ifspeed = 0; 35445903Ssowmini dladm_status_t status; 35455903Ssowmini 35468453SAnurag.Maskey@Sun.COM if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 35475903Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 35485903Ssowmini return (status); 35496512Ssowmini 35505960Ssowmini if ((ifspeed % 1000000) != 0) { 35515960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 35525960Ssowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 35535960Ssowmini } else { 35545960Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 35555960Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 35565960Ssowmini } 35575903Ssowmini *val_cnt = 1; 35588275SEric Cheng *perm_flags = MAC_PROP_PERM_READ; 35595903Ssowmini return (DLADM_STATUS_OK); 35605903Ssowmini } 35615903Ssowmini 35625903Ssowmini /* ARGSUSED */ 35635903Ssowmini static dladm_status_t 356411878SVenu.Iyer@Sun.COM get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 35658453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35668453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35675903Ssowmini { 35688275SEric Cheng link_state_t link_state; 35698275SEric Cheng dladm_status_t status; 35708306SSowmini.Varadhan@Sun.COM 357111878SVenu.Iyer@Sun.COM status = dladm_get_state(handle, linkid, &link_state); 35726512Ssowmini if (status != DLADM_STATUS_OK) 35735903Ssowmini return (status); 35748275SEric Cheng 35755903Ssowmini switch (link_state) { 35765903Ssowmini case LINK_STATE_UP: 35775903Ssowmini (void) strcpy(*prop_val, "up"); 35785903Ssowmini break; 35795903Ssowmini case LINK_STATE_DOWN: 35805903Ssowmini (void) strcpy(*prop_val, "down"); 35815903Ssowmini break; 35825903Ssowmini default: 35835903Ssowmini (void) strcpy(*prop_val, "unknown"); 35845903Ssowmini break; 35855903Ssowmini } 35865903Ssowmini *val_cnt = 1; 35878306SSowmini.Varadhan@Sun.COM *perm_flags = MAC_PROP_PERM_READ; 35885903Ssowmini return (DLADM_STATUS_OK); 35895903Ssowmini } 35905903Ssowmini 35915903Ssowmini /* ARGSUSED */ 35925903Ssowmini static dladm_status_t 359311878SVenu.Iyer@Sun.COM get_binary(dladm_handle_t handle, prop_desc_t *pdp, 35948453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35958453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 35965903Ssowmini { 359711878SVenu.Iyer@Sun.COM dladm_status_t status; 359811878SVenu.Iyer@Sun.COM uint_t v = 0; 359911878SVenu.Iyer@Sun.COM 360011878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 360111878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 360211878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 36035903Ssowmini return (status); 36048275SEric Cheng 360511878SVenu.Iyer@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 36065903Ssowmini *val_cnt = 1; 36075903Ssowmini return (DLADM_STATUS_OK); 36085903Ssowmini } 36095903Ssowmini 36105960Ssowmini /* ARGSUSED */ 36115903Ssowmini static dladm_status_t 361211878SVenu.Iyer@Sun.COM get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 36138453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36148453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36155903Ssowmini { 361611878SVenu.Iyer@Sun.COM dladm_status_t status; 361711878SVenu.Iyer@Sun.COM uint32_t v = 0; 361811878SVenu.Iyer@Sun.COM 361911878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 362011878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 362111878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 36225903Ssowmini return (status); 36238275SEric Cheng 36246512Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 36255903Ssowmini *val_cnt = 1; 36265903Ssowmini return (DLADM_STATUS_OK); 36275903Ssowmini } 36285903Ssowmini 36299514SGirish.Moodalbail@Sun.COM /* ARGSUSED */ 36309514SGirish.Moodalbail@Sun.COM static dladm_status_t 363111878SVenu.Iyer@Sun.COM get_range(dladm_handle_t handle, prop_desc_t *pdp, 36329514SGirish.Moodalbail@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36339514SGirish.Moodalbail@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 36349514SGirish.Moodalbail@Sun.COM { 36359514SGirish.Moodalbail@Sun.COM dld_ioc_macprop_t *dip; 36369514SGirish.Moodalbail@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 36379514SGirish.Moodalbail@Sun.COM size_t sz; 36389514SGirish.Moodalbail@Sun.COM mac_propval_range_t *rangep; 36399514SGirish.Moodalbail@Sun.COM 36409514SGirish.Moodalbail@Sun.COM sz = sizeof (mac_propval_range_t); 36419514SGirish.Moodalbail@Sun.COM 36429514SGirish.Moodalbail@Sun.COM /* 36439514SGirish.Moodalbail@Sun.COM * As caller we don't know number of value ranges, the driver 36449514SGirish.Moodalbail@Sun.COM * supports. To begin with we assume that number to be 1. If the 36459514SGirish.Moodalbail@Sun.COM * buffer size is insufficient, driver returns back with the 36469514SGirish.Moodalbail@Sun.COM * actual count of value ranges. See mac.h for more details. 36479514SGirish.Moodalbail@Sun.COM */ 36489514SGirish.Moodalbail@Sun.COM retry: 36499514SGirish.Moodalbail@Sun.COM if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 36509514SGirish.Moodalbail@Sun.COM &status)) == NULL) 36519514SGirish.Moodalbail@Sun.COM return (status); 36529514SGirish.Moodalbail@Sun.COM 36539514SGirish.Moodalbail@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 36549514SGirish.Moodalbail@Sun.COM if (status != DLADM_STATUS_OK) { 36559514SGirish.Moodalbail@Sun.COM if (status == DLADM_STATUS_TOOSMALL) { 36569514SGirish.Moodalbail@Sun.COM int err; 36579514SGirish.Moodalbail@Sun.COM 36589514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 36599514SGirish.Moodalbail@Sun.COM if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 36609514SGirish.Moodalbail@Sun.COM free(dip); 36619514SGirish.Moodalbail@Sun.COM goto retry; 36629514SGirish.Moodalbail@Sun.COM } else { 36639514SGirish.Moodalbail@Sun.COM status = dladm_errno2status(err); 36649514SGirish.Moodalbail@Sun.COM } 36659514SGirish.Moodalbail@Sun.COM } 36669514SGirish.Moodalbail@Sun.COM free(dip); 36679514SGirish.Moodalbail@Sun.COM return (status); 36689514SGirish.Moodalbail@Sun.COM } 366911878SVenu.Iyer@Sun.COM 36709514SGirish.Moodalbail@Sun.COM rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 367111878SVenu.Iyer@Sun.COM if (rangep->mpr_count == 0) { 367211878SVenu.Iyer@Sun.COM *val_cnt = 1; 367311878SVenu.Iyer@Sun.COM (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 367411878SVenu.Iyer@Sun.COM goto done; 367511878SVenu.Iyer@Sun.COM } 36769514SGirish.Moodalbail@Sun.COM 36779514SGirish.Moodalbail@Sun.COM switch (rangep->mpr_type) { 36789514SGirish.Moodalbail@Sun.COM case MAC_PROPVAL_UINT32: { 36799514SGirish.Moodalbail@Sun.COM mac_propval_uint32_range_t *ur; 36809514SGirish.Moodalbail@Sun.COM uint_t count = rangep->mpr_count, i; 36819514SGirish.Moodalbail@Sun.COM 368211878SVenu.Iyer@Sun.COM ur = &rangep->mpr_range_uint32[0]; 36839514SGirish.Moodalbail@Sun.COM 36849514SGirish.Moodalbail@Sun.COM for (i = 0; i < count; i++, ur++) { 36859514SGirish.Moodalbail@Sun.COM if (ur->mpur_min == ur->mpur_max) { 36869514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 36879514SGirish.Moodalbail@Sun.COM "%ld", ur->mpur_min); 36889514SGirish.Moodalbail@Sun.COM } else { 36899514SGirish.Moodalbail@Sun.COM (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 36909514SGirish.Moodalbail@Sun.COM "%ld-%ld", ur->mpur_min, ur->mpur_max); 36919514SGirish.Moodalbail@Sun.COM } 36929514SGirish.Moodalbail@Sun.COM } 36939514SGirish.Moodalbail@Sun.COM *val_cnt = count; 36949514SGirish.Moodalbail@Sun.COM break; 36959514SGirish.Moodalbail@Sun.COM } 36969514SGirish.Moodalbail@Sun.COM default: 36979514SGirish.Moodalbail@Sun.COM status = DLADM_STATUS_BADARG; 36989514SGirish.Moodalbail@Sun.COM break; 36999514SGirish.Moodalbail@Sun.COM } 370011878SVenu.Iyer@Sun.COM done: 37019514SGirish.Moodalbail@Sun.COM free(dip); 37029514SGirish.Moodalbail@Sun.COM return (status); 37039514SGirish.Moodalbail@Sun.COM } 37049514SGirish.Moodalbail@Sun.COM 37055960Ssowmini /* ARGSUSED */ 37065903Ssowmini static dladm_status_t 370711878SVenu.Iyer@Sun.COM get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 37088874SSebastien.Roy@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37098874SSebastien.Roy@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 37108874SSebastien.Roy@Sun.COM { 37118874SSebastien.Roy@Sun.COM link_tagmode_t mode; 37128874SSebastien.Roy@Sun.COM dladm_status_t status; 37138874SSebastien.Roy@Sun.COM 371411878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 371511878SVenu.Iyer@Sun.COM perm_flags, &mode, sizeof (mode)); 371611878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 37178874SSebastien.Roy@Sun.COM return (status); 37188874SSebastien.Roy@Sun.COM 37198874SSebastien.Roy@Sun.COM switch (mode) { 37208874SSebastien.Roy@Sun.COM case LINK_TAGMODE_NORMAL: 37218874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 37228874SSebastien.Roy@Sun.COM break; 37238874SSebastien.Roy@Sun.COM case LINK_TAGMODE_VLANONLY: 37248874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 37258874SSebastien.Roy@Sun.COM break; 37268874SSebastien.Roy@Sun.COM default: 37278874SSebastien.Roy@Sun.COM (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 37288874SSebastien.Roy@Sun.COM } 37298874SSebastien.Roy@Sun.COM *val_cnt = 1; 37308874SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK); 37318874SSebastien.Roy@Sun.COM } 37328874SSebastien.Roy@Sun.COM 37338874SSebastien.Roy@Sun.COM /* ARGSUSED */ 37348874SSebastien.Roy@Sun.COM static dladm_status_t 373511878SVenu.Iyer@Sun.COM get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 37368453SAnurag.Maskey@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37378453SAnurag.Maskey@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 37385903Ssowmini { 373911878SVenu.Iyer@Sun.COM link_flowctrl_t v; 374011878SVenu.Iyer@Sun.COM dladm_status_t status; 374111878SVenu.Iyer@Sun.COM 374211878SVenu.Iyer@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 374311878SVenu.Iyer@Sun.COM perm_flags, &v, sizeof (v)); 374411878SVenu.Iyer@Sun.COM if (status != DLADM_STATUS_OK) 37455903Ssowmini return (status); 37468275SEric Cheng 37475903Ssowmini switch (v) { 37485903Ssowmini case LINK_FLOWCTRL_NONE: 37495903Ssowmini (void) sprintf(*prop_val, "no"); 37505903Ssowmini break; 37515903Ssowmini case LINK_FLOWCTRL_RX: 37525903Ssowmini (void) sprintf(*prop_val, "rx"); 37535903Ssowmini break; 37545903Ssowmini case LINK_FLOWCTRL_TX: 37555903Ssowmini (void) sprintf(*prop_val, "tx"); 37565903Ssowmini break; 37575903Ssowmini case LINK_FLOWCTRL_BI: 37585903Ssowmini (void) sprintf(*prop_val, "bi"); 37595903Ssowmini break; 37605903Ssowmini } 37615903Ssowmini *val_cnt = 1; 37625903Ssowmini return (DLADM_STATUS_OK); 37635903Ssowmini } 37645903Ssowmini 37655903Ssowmini 37665903Ssowmini /* ARGSUSED */ 37675903Ssowmini static dladm_status_t 37689692SRishi.Srivatsavai@Sun.COM i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 37698453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 37708453SAnurag.Maskey@Sun.COM 37715903Ssowmini { 37727663SSowmini.Varadhan@Sun.COM int i, slen; 37737408SSebastien.Roy@Sun.COM int bufsize = 0; 37746789Sam223141 dld_ioc_macprop_t *dip = NULL; 37755903Ssowmini uchar_t *dp; 37767663SSowmini.Varadhan@Sun.COM link_attr_t *p; 37776512Ssowmini dladm_status_t status = DLADM_STATUS_OK; 37785903Ssowmini 37795903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 37805903Ssowmini (prop_val != NULL && val_cnt == 0)) 37815903Ssowmini return (DLADM_STATUS_BADARG); 37825903Ssowmini p = dladm_name2prop(prop_name); 37836789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 37845903Ssowmini return (DLADM_STATUS_BADARG); 37855903Ssowmini 37869692SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 37879692SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 37889692SRishi.Srivatsavai@Sun.COM 37895903Ssowmini /* 37905903Ssowmini * private properties: all parsing is done in the kernel. 37915903Ssowmini * allocate a enough space for each property + its separator (','). 37925903Ssowmini */ 37935903Ssowmini for (i = 0; i < val_cnt; i++) { 37945903Ssowmini bufsize += strlen(prop_val[i]) + 1; 37955903Ssowmini } 37966512Ssowmini 37976512Ssowmini if (prop_val == NULL) { 37986512Ssowmini /* 37996512Ssowmini * getting default value. so use more buffer space. 38006512Ssowmini */ 38017663SSowmini.Varadhan@Sun.COM bufsize += DLADM_PROP_BUF_CHUNK; 38026512Ssowmini } 38036512Ssowmini 38047663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 380511878SVenu.Iyer@Sun.COM (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 38065903Ssowmini if (dip == NULL) 38075903Ssowmini return (status); 38085903Ssowmini 38095903Ssowmini dp = (uchar_t *)dip->pr_val; 38105903Ssowmini slen = 0; 38117663SSowmini.Varadhan@Sun.COM 38126512Ssowmini if (prop_val == NULL) { 38138453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 38148460SArtem.Kachitchkin@Sun.COM dip->pr_flags = 0; 38156512Ssowmini } else { 38166512Ssowmini for (i = 0; i < val_cnt; i++) { 38176512Ssowmini int plen = 0; 38185903Ssowmini 38196512Ssowmini plen = strlen(prop_val[i]); 38206512Ssowmini bcopy(prop_val[i], dp, plen); 38216512Ssowmini slen += plen; 38226512Ssowmini /* 38236512Ssowmini * add a "," separator and update dp. 38246512Ssowmini */ 38256512Ssowmini if (i != (val_cnt -1)) 38266512Ssowmini dp[slen++] = ','; 38276512Ssowmini dp += (plen + 1); 38286512Ssowmini } 38298460SArtem.Kachitchkin@Sun.COM } 38308460SArtem.Kachitchkin@Sun.COM if (status == DLADM_STATUS_OK) 38318453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 38326512Ssowmini 38335903Ssowmini free(dip); 38346512Ssowmini return (status); 38355903Ssowmini } 38365903Ssowmini 38375903Ssowmini static dladm_status_t 38388460SArtem.Kachitchkin@Sun.COM i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 38398453SAnurag.Maskey@Sun.COM const char *prop_name, char **prop_val, uint_t *val_cnt, 38408453SAnurag.Maskey@Sun.COM dladm_prop_type_t type, uint_t dld_flags) 38415903Ssowmini { 38427663SSowmini.Varadhan@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 38436789Sam223141 dld_ioc_macprop_t *dip = NULL; 38447663SSowmini.Varadhan@Sun.COM link_attr_t *p; 38455903Ssowmini 38465903Ssowmini if ((prop_name == NULL && prop_val != NULL) || 38475903Ssowmini (prop_val != NULL && val_cnt == 0)) 38485903Ssowmini return (DLADM_STATUS_BADARG); 38495903Ssowmini 38505903Ssowmini p = dladm_name2prop(prop_name); 38516789Sam223141 if (p->pp_id != MAC_PROP_PRIVATE) 38525903Ssowmini return (DLADM_STATUS_BADARG); 38535903Ssowmini 38545903Ssowmini /* 38555903Ssowmini * private properties: all parsing is done in the kernel. 38565903Ssowmini */ 38577663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 38587663SSowmini.Varadhan@Sun.COM dld_flags, &status); 38595903Ssowmini if (dip == NULL) 38605903Ssowmini return (status); 38615903Ssowmini 38628453SAnurag.Maskey@Sun.COM if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 38638453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) { 38648118SVasumathi.Sundaram@Sun.COM if (type == DLADM_PROP_VAL_PERM) { 38658275SEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 38668460SArtem.Kachitchkin@Sun.COM } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 38678460SArtem.Kachitchkin@Sun.COM *prop_val[0] = '\0'; 38688118SVasumathi.Sundaram@Sun.COM } else { 38698118SVasumathi.Sundaram@Sun.COM (void) strncpy(*prop_val, dip->pr_val, 38708118SVasumathi.Sundaram@Sun.COM DLADM_PROP_VAL_MAX); 38718118SVasumathi.Sundaram@Sun.COM } 38725903Ssowmini *val_cnt = 1; 38738460SArtem.Kachitchkin@Sun.COM } else if ((status == DLADM_STATUS_NOTSUP) && 38748460SArtem.Kachitchkin@Sun.COM (type == DLADM_PROP_VAL_CURRENT)) { 38758460SArtem.Kachitchkin@Sun.COM status = DLADM_STATUS_NOTFOUND; 38765903Ssowmini } 38776512Ssowmini free(dip); 38785903Ssowmini return (status); 38795903Ssowmini } 38806512Ssowmini 38816512Ssowmini 38826512Ssowmini static dladm_status_t 38838453SAnurag.Maskey@Sun.COM i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 38848453SAnurag.Maskey@Sun.COM datalink_id_t linkid, datalink_media_t media, uint_t flags) 38856512Ssowmini { 38866512Ssowmini dladm_status_t status; 38876512Ssowmini char **prop_vals = NULL, *buf; 38886512Ssowmini size_t bufsize; 38896512Ssowmini uint_t cnt; 38906512Ssowmini int i; 38918118SVasumathi.Sundaram@Sun.COM uint_t perm_flags; 38926512Ssowmini 38936512Ssowmini /* 38946512Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 38956512Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 38966512Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 38976512Ssowmini */ 38986512Ssowmini bufsize = 38996512Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 39006512Ssowmini buf = malloc(bufsize); 39016512Ssowmini prop_vals = (char **)(void *)buf; 39026512Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 39036512Ssowmini prop_vals[i] = buf + 39046512Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 39056512Ssowmini i * DLADM_PROP_VAL_MAX; 39066512Ssowmini } 39076768Sar224390 39086768Sar224390 /* 39097342SAruna.Ramakrishna@Sun.COM * For properties which have pdp->pd_defval.vd_name as a non-empty 39107342SAruna.Ramakrishna@Sun.COM * string, the "" itself is used to reset the property (exceptions 39117342SAruna.Ramakrishna@Sun.COM * are zone and autopush, which populate vdp->vd_val). So 39127342SAruna.Ramakrishna@Sun.COM * libdladm can copy pdp->pd_defval over to the val_desc_t passed 39137342SAruna.Ramakrishna@Sun.COM * down on the setprop using the global values in the table. For 39147342SAruna.Ramakrishna@Sun.COM * other cases (vd_name is ""), doing reset-linkprop will cause 39157342SAruna.Ramakrishna@Sun.COM * libdladm to do a getprop to find the default value and then do 39167342SAruna.Ramakrishna@Sun.COM * a setprop to reset the value to default. 39176768Sar224390 */ 39188453SAnurag.Maskey@Sun.COM status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 391911878SVenu.Iyer@Sun.COM DLD_PROP_DEFAULT, &perm_flags); 39206512Ssowmini if (status == DLADM_STATUS_OK) { 39218118SVasumathi.Sundaram@Sun.COM if (perm_flags == MAC_PROP_PERM_RW) { 39228453SAnurag.Maskey@Sun.COM status = i_dladm_set_single_prop(handle, linkid, 39238453SAnurag.Maskey@Sun.COM pdp->pd_class, media, pdp, prop_vals, cnt, flags); 39248118SVasumathi.Sundaram@Sun.COM } 39258118SVasumathi.Sundaram@Sun.COM else 39268118SVasumathi.Sundaram@Sun.COM status = DLADM_STATUS_NOTSUP; 39276512Ssowmini } 39286512Ssowmini free(buf); 39296512Ssowmini return (status); 39306512Ssowmini } 39317663SSowmini.Varadhan@Sun.COM 393210491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 393310491SRishi.Srivatsavai@Sun.COM static dladm_status_t 393411878SVenu.Iyer@Sun.COM get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 393510491SRishi.Srivatsavai@Sun.COM char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 393610491SRishi.Srivatsavai@Sun.COM uint_t *perm_flags) 393710491SRishi.Srivatsavai@Sun.COM { 393810491SRishi.Srivatsavai@Sun.COM const bridge_public_prop_t *bpp; 393910491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 394010491SRishi.Srivatsavai@Sun.COM int val, i; 394110491SRishi.Srivatsavai@Sun.COM 394210491SRishi.Srivatsavai@Sun.COM if (flags != 0) 394310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 394410491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 394510491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 394610491SRishi.Srivatsavai@Sun.COM for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 394710491SRishi.Srivatsavai@Sun.COM if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 394810491SRishi.Srivatsavai@Sun.COM break; 394910491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 395010491SRishi.Srivatsavai@Sun.COM /* If the daemon isn't running, then return the persistent value */ 395110491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 395210491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 395310491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 395410491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 395510491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 395610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 395710491SRishi.Srivatsavai@Sun.COM } 395810491SRishi.Srivatsavai@Sun.COM if (retv != DLADM_STATUS_OK) { 395910491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 396010491SRishi.Srivatsavai@Sun.COM return (retv); 396110491SRishi.Srivatsavai@Sun.COM } 396210491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 396310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 396410491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 396510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 396610491SRishi.Srivatsavai@Sun.COM } 396710491SRishi.Srivatsavai@Sun.COM for (i = 0; i < pd->pd_noptval; i++) { 396810491SRishi.Srivatsavai@Sun.COM if (val == pd->pd_optval[i].vd_val) { 396910491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 397010491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 397110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 397210491SRishi.Srivatsavai@Sun.COM } 397310491SRishi.Srivatsavai@Sun.COM } 397410491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 397510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 397610491SRishi.Srivatsavai@Sun.COM } 397710491SRishi.Srivatsavai@Sun.COM 397810491SRishi.Srivatsavai@Sun.COM /* ARGSUSED1 */ 397910491SRishi.Srivatsavai@Sun.COM static dladm_status_t 398010491SRishi.Srivatsavai@Sun.COM set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 398110491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 398210491SRishi.Srivatsavai@Sun.COM { 398310491SRishi.Srivatsavai@Sun.COM /* 398410491SRishi.Srivatsavai@Sun.COM * Special case for mcheck: the daemon resets the value to zero, and we 398510491SRishi.Srivatsavai@Sun.COM * don't want the daemon to refresh itself; it leads to deadlock. 398610491SRishi.Srivatsavai@Sun.COM */ 398710491SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_NOREFRESH) 398810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 398910491SRishi.Srivatsavai@Sun.COM 399010491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 399110491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 399210491SRishi.Srivatsavai@Sun.COM } 399310491SRishi.Srivatsavai@Sun.COM 399410491SRishi.Srivatsavai@Sun.COM /* 399510491SRishi.Srivatsavai@Sun.COM * This is used only for stp_priority, stp_cost, and stp_mcheck. 399610491SRishi.Srivatsavai@Sun.COM */ 399710491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 399810491SRishi.Srivatsavai@Sun.COM static dladm_status_t 399910491SRishi.Srivatsavai@Sun.COM check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 400011878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 400111878SVenu.Iyer@Sun.COM val_desc_t *vdp, datalink_media_t media) 400210491SRishi.Srivatsavai@Sun.COM { 400310491SRishi.Srivatsavai@Sun.COM char *cp; 400410491SRishi.Srivatsavai@Sun.COM boolean_t iscost; 400510491SRishi.Srivatsavai@Sun.COM 400610491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 400710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 400810491SRishi.Srivatsavai@Sun.COM 400910491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 401010491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 401110491SRishi.Srivatsavai@Sun.COM } else { 401210491SRishi.Srivatsavai@Sun.COM /* Only stp_priority and stp_cost use this function */ 401310491SRishi.Srivatsavai@Sun.COM iscost = strcmp(pd->pd_name, "stp_cost") == 0; 401410491SRishi.Srivatsavai@Sun.COM 401510491SRishi.Srivatsavai@Sun.COM if (iscost && strcmp(prop_val[0], "auto") == 0) { 401610491SRishi.Srivatsavai@Sun.COM /* Illegal value 0 is allowed to mean "automatic" */ 401710491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 0; 401810491SRishi.Srivatsavai@Sun.COM } else { 401910491SRishi.Srivatsavai@Sun.COM errno = 0; 402010491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 402110491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 402210491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 402310491SRishi.Srivatsavai@Sun.COM } 402410491SRishi.Srivatsavai@Sun.COM } 402510491SRishi.Srivatsavai@Sun.COM 402610491SRishi.Srivatsavai@Sun.COM if (iscost) { 402710491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 402810491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 402910491SRishi.Srivatsavai@Sun.COM } else { 403010491SRishi.Srivatsavai@Sun.COM if (vdp->vd_val > 255) 403110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 403210491SRishi.Srivatsavai@Sun.COM /* 403310491SRishi.Srivatsavai@Sun.COM * If the user is setting stp_mcheck non-zero, then (per the 403410491SRishi.Srivatsavai@Sun.COM * IEEE management standards and UNH testing) we need to check 403510491SRishi.Srivatsavai@Sun.COM * whether this link is part of a bridge that is running RSTP. 403610491SRishi.Srivatsavai@Sun.COM * If it's not, then setting the flag is an error. Note that 403710491SRishi.Srivatsavai@Sun.COM * errors are intentionally discarded here; it's the value 403810491SRishi.Srivatsavai@Sun.COM * that's the problem -- it's not a bad value, merely one that 403910491SRishi.Srivatsavai@Sun.COM * can't be used now. 404010491SRishi.Srivatsavai@Sun.COM */ 404110491SRishi.Srivatsavai@Sun.COM if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 404210491SRishi.Srivatsavai@Sun.COM vdp->vd_val != 0) { 404310491SRishi.Srivatsavai@Sun.COM char bridge[MAXLINKNAMELEN]; 404410491SRishi.Srivatsavai@Sun.COM UID_STP_CFG_T cfg; 404510491SRishi.Srivatsavai@Sun.COM dladm_bridge_prot_t brprot; 404610491SRishi.Srivatsavai@Sun.COM 404710491SRishi.Srivatsavai@Sun.COM if (dladm_bridge_getlink(handle, linkid, bridge, 404810491SRishi.Srivatsavai@Sun.COM sizeof (bridge)) != DLADM_STATUS_OK || 404910491SRishi.Srivatsavai@Sun.COM dladm_bridge_get_properties(bridge, &cfg, 405010491SRishi.Srivatsavai@Sun.COM &brprot) != DLADM_STATUS_OK) 405110491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 405210491SRishi.Srivatsavai@Sun.COM if (cfg.force_version <= 1) 405310491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_FAILED); 405410491SRishi.Srivatsavai@Sun.COM } 405510491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 405610491SRishi.Srivatsavai@Sun.COM } 405710491SRishi.Srivatsavai@Sun.COM } 405810491SRishi.Srivatsavai@Sun.COM 405910491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 406010491SRishi.Srivatsavai@Sun.COM static dladm_status_t 406110491SRishi.Srivatsavai@Sun.COM get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 406210491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 406310491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 406410491SRishi.Srivatsavai@Sun.COM { 406510491SRishi.Srivatsavai@Sun.COM dladm_status_t retv; 406610491SRishi.Srivatsavai@Sun.COM uint_t val; 406710491SRishi.Srivatsavai@Sun.COM 406810491SRishi.Srivatsavai@Sun.COM if (flags != 0) 406910491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 407010491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 407110491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 407210491SRishi.Srivatsavai@Sun.COM retv = dladm_bridge_get_forwarding(handle, linkid, &val); 407310491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_NOTFOUND) { 407410491SRishi.Srivatsavai@Sun.COM if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 407510491SRishi.Srivatsavai@Sun.COM prop_val, val_cnt) != DLADM_STATUS_OK) 407610491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 407710491SRishi.Srivatsavai@Sun.COM DLADM_PROP_VAL_MAX); 407810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 407910491SRishi.Srivatsavai@Sun.COM } 408010491SRishi.Srivatsavai@Sun.COM if (retv == DLADM_STATUS_OK) 408110491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 408210491SRishi.Srivatsavai@Sun.COM else 408310491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 408410491SRishi.Srivatsavai@Sun.COM return (retv); 408510491SRishi.Srivatsavai@Sun.COM } 408610491SRishi.Srivatsavai@Sun.COM 408710491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 408810491SRishi.Srivatsavai@Sun.COM static dladm_status_t 408910491SRishi.Srivatsavai@Sun.COM set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 409010491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 409110491SRishi.Srivatsavai@Sun.COM { 409210491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 409310491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 409410491SRishi.Srivatsavai@Sun.COM } 409510491SRishi.Srivatsavai@Sun.COM 409610491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 409710491SRishi.Srivatsavai@Sun.COM static dladm_status_t 409810491SRishi.Srivatsavai@Sun.COM get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 409910491SRishi.Srivatsavai@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 410010491SRishi.Srivatsavai@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 410110491SRishi.Srivatsavai@Sun.COM { 410210491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 410310491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 410410491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 410510491SRishi.Srivatsavai@Sun.COM 410610491SRishi.Srivatsavai@Sun.COM if (flags != 0) 410710491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 410810491SRishi.Srivatsavai@Sun.COM *perm_flags = MAC_PROP_PERM_RW; 410910491SRishi.Srivatsavai@Sun.COM *val_cnt = 1; 411010491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 411110491SRishi.Srivatsavai@Sun.COM 0, &status); 411210491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 411310491SRishi.Srivatsavai@Sun.COM return (status); 411410491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_FALSE); 411510491SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 411610491SRishi.Srivatsavai@Sun.COM (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 411710491SRishi.Srivatsavai@Sun.COM (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 411810491SRishi.Srivatsavai@Sun.COM } else { 411910491SRishi.Srivatsavai@Sun.COM (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 412010491SRishi.Srivatsavai@Sun.COM } 412110491SRishi.Srivatsavai@Sun.COM free(dip); 412210491SRishi.Srivatsavai@Sun.COM return (status); 412310491SRishi.Srivatsavai@Sun.COM } 412410491SRishi.Srivatsavai@Sun.COM 412510491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 412610491SRishi.Srivatsavai@Sun.COM static dladm_status_t 412710491SRishi.Srivatsavai@Sun.COM set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 412810491SRishi.Srivatsavai@Sun.COM val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 412910491SRishi.Srivatsavai@Sun.COM { 413010491SRishi.Srivatsavai@Sun.COM dladm_status_t status; 413110491SRishi.Srivatsavai@Sun.COM dld_ioc_macprop_t *dip; 413210491SRishi.Srivatsavai@Sun.COM uint16_t pvid; 413310491SRishi.Srivatsavai@Sun.COM 413410491SRishi.Srivatsavai@Sun.COM dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 413510491SRishi.Srivatsavai@Sun.COM 0, &status); 413610491SRishi.Srivatsavai@Sun.COM if (dip == NULL) 413710491SRishi.Srivatsavai@Sun.COM return (status); 413810491SRishi.Srivatsavai@Sun.COM pvid = vdp->vd_val; 413910491SRishi.Srivatsavai@Sun.COM (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 414010491SRishi.Srivatsavai@Sun.COM status = i_dladm_macprop(handle, dip, B_TRUE); 414110491SRishi.Srivatsavai@Sun.COM free(dip); 414210491SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 414310491SRishi.Srivatsavai@Sun.COM return (status); 414410491SRishi.Srivatsavai@Sun.COM 414510491SRishi.Srivatsavai@Sun.COM /* Tell the running daemon, if any */ 414610491SRishi.Srivatsavai@Sun.COM return (dladm_bridge_refresh(handle, linkid)); 414710491SRishi.Srivatsavai@Sun.COM } 414810491SRishi.Srivatsavai@Sun.COM 414910491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 415010491SRishi.Srivatsavai@Sun.COM static dladm_status_t 415110491SRishi.Srivatsavai@Sun.COM check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 415211878SVenu.Iyer@Sun.COM datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 415311878SVenu.Iyer@Sun.COM val_desc_t *vdp, datalink_media_t media) 415410491SRishi.Srivatsavai@Sun.COM { 415510491SRishi.Srivatsavai@Sun.COM char *cp; 415610491SRishi.Srivatsavai@Sun.COM 415710491SRishi.Srivatsavai@Sun.COM if (val_cnt != 1) 415810491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVALCNT); 415910491SRishi.Srivatsavai@Sun.COM 416010491SRishi.Srivatsavai@Sun.COM if (prop_val == NULL) { 416110491SRishi.Srivatsavai@Sun.COM vdp->vd_val = 1; 416210491SRishi.Srivatsavai@Sun.COM } else { 416310491SRishi.Srivatsavai@Sun.COM errno = 0; 416410491SRishi.Srivatsavai@Sun.COM vdp->vd_val = strtoul(prop_val[0], &cp, 0); 416510491SRishi.Srivatsavai@Sun.COM if (errno != 0 || *cp != '\0') 416610491SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADVAL); 416710491SRishi.Srivatsavai@Sun.COM } 416810491SRishi.Srivatsavai@Sun.COM 416910491SRishi.Srivatsavai@Sun.COM return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 417010491SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK); 417110491SRishi.Srivatsavai@Sun.COM } 417210491SRishi.Srivatsavai@Sun.COM 41737663SSowmini.Varadhan@Sun.COM dladm_status_t 41748453SAnurag.Maskey@Sun.COM i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 41758453SAnurag.Maskey@Sun.COM mac_prop_id_t cmd, size_t len, boolean_t set) 41767663SSowmini.Varadhan@Sun.COM { 41777663SSowmini.Varadhan@Sun.COM uint32_t flags; 41787663SSowmini.Varadhan@Sun.COM dladm_status_t status; 41797663SSowmini.Varadhan@Sun.COM uint32_t media; 41807663SSowmini.Varadhan@Sun.COM dld_ioc_macprop_t *dip; 41817663SSowmini.Varadhan@Sun.COM void *dp; 41827663SSowmini.Varadhan@Sun.COM 41838453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 41848453SAnurag.Maskey@Sun.COM &media, NULL, 0)) != DLADM_STATUS_OK) { 41857663SSowmini.Varadhan@Sun.COM return (status); 41867663SSowmini.Varadhan@Sun.COM } 41877663SSowmini.Varadhan@Sun.COM 41887663SSowmini.Varadhan@Sun.COM if (media != DL_WIFI) 41897663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_BADARG); 41907663SSowmini.Varadhan@Sun.COM 41917663SSowmini.Varadhan@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 41927663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_TEMPONLY); 41937663SSowmini.Varadhan@Sun.COM 41947663SSowmini.Varadhan@Sun.COM if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 41957663SSowmini.Varadhan@Sun.COM len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 41967663SSowmini.Varadhan@Sun.COM 41977663SSowmini.Varadhan@Sun.COM dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 41987663SSowmini.Varadhan@Sun.COM if (dip == NULL) 41997663SSowmini.Varadhan@Sun.COM return (DLADM_STATUS_NOMEM); 42007663SSowmini.Varadhan@Sun.COM 42017663SSowmini.Varadhan@Sun.COM dp = (uchar_t *)dip->pr_val; 42027663SSowmini.Varadhan@Sun.COM if (set) 42037663SSowmini.Varadhan@Sun.COM (void) memcpy(dp, buf, len); 42047663SSowmini.Varadhan@Sun.COM 42058453SAnurag.Maskey@Sun.COM status = i_dladm_macprop(handle, dip, set); 420610191SSowmini.Varadhan@Sun.COM if (status == DLADM_STATUS_OK) { 42077663SSowmini.Varadhan@Sun.COM if (!set) 42087663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, dp, len); 42097663SSowmini.Varadhan@Sun.COM } 42107663SSowmini.Varadhan@Sun.COM 42117663SSowmini.Varadhan@Sun.COM free(dip); 42127663SSowmini.Varadhan@Sun.COM return (status); 42137663SSowmini.Varadhan@Sun.COM } 42147663SSowmini.Varadhan@Sun.COM 42158275SEric Cheng dladm_status_t 42168275SEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 42178275SEric Cheng { 42188460SArtem.Kachitchkin@Sun.COM return (dladm_parse_args(str, listp, novalues)); 42198275SEric Cheng } 42208275SEric Cheng 42218275SEric Cheng /* 42228275SEric Cheng * Retrieve the one link property from the database 42238275SEric Cheng */ 42248275SEric Cheng /*ARGSUSED*/ 42258275SEric Cheng static int 42268453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 42278453SAnurag.Maskey@Sun.COM const char *prop_name, void *arg) 42288275SEric Cheng { 42298275SEric Cheng dladm_arg_list_t *proplist = arg; 42308275SEric Cheng dladm_arg_info_t *aip = NULL; 42318275SEric Cheng 42328275SEric Cheng aip = &proplist->al_info[proplist->al_count]; 42338275SEric Cheng /* 42348275SEric Cheng * it is fine to point to prop_name since prop_name points to the 42358275SEric Cheng * prop_table[n].pd_name. 42368275SEric Cheng */ 42378275SEric Cheng aip->ai_name = prop_name; 42388275SEric Cheng 42398453SAnurag.Maskey@Sun.COM (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 42408453SAnurag.Maskey@Sun.COM prop_name, aip->ai_val, &aip->ai_count); 42418275SEric Cheng 42428275SEric Cheng if (aip->ai_count != 0) 42438275SEric Cheng proplist->al_count++; 42448275SEric Cheng 42458275SEric Cheng return (DLADM_WALK_CONTINUE); 42468275SEric Cheng } 42478275SEric Cheng 42488275SEric Cheng 42498275SEric Cheng /* 42508275SEric Cheng * Retrieve all link properties for a link from the database and 42518275SEric Cheng * return a property list. 42528275SEric Cheng */ 42538275SEric Cheng dladm_status_t 42548453SAnurag.Maskey@Sun.COM dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 42558453SAnurag.Maskey@Sun.COM dladm_arg_list_t **listp) 42568275SEric Cheng { 42578275SEric Cheng dladm_arg_list_t *list; 42588275SEric Cheng dladm_status_t status = DLADM_STATUS_OK; 42598275SEric Cheng 42608275SEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 42618275SEric Cheng if (list == NULL) 42628275SEric Cheng return (dladm_errno2status(errno)); 42638275SEric Cheng 42648453SAnurag.Maskey@Sun.COM status = dladm_walk_linkprop(handle, linkid, list, 42658453SAnurag.Maskey@Sun.COM i_dladm_get_one_prop); 42668275SEric Cheng 42678275SEric Cheng *listp = list; 42688275SEric Cheng return (status); 42698275SEric Cheng } 42708275SEric Cheng 42718275SEric Cheng /* 42728275SEric Cheng * Retrieve the named property from a proplist, check the value and 42738275SEric Cheng * convert to a kernel structure. 42748275SEric Cheng */ 42758275SEric Cheng static dladm_status_t 42768453SAnurag.Maskey@Sun.COM i_dladm_link_proplist_extract_one(dladm_handle_t handle, 427711878SVenu.Iyer@Sun.COM dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 42788275SEric Cheng { 42798275SEric Cheng dladm_status_t status; 42808275SEric Cheng dladm_arg_info_t *aip = NULL; 42818275SEric Cheng int i, j; 42828275SEric Cheng 42838275SEric Cheng /* Find named property in proplist */ 42848275SEric Cheng for (i = 0; i < proplist->al_count; i++) { 42858275SEric Cheng aip = &proplist->al_info[i]; 42868275SEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 42878275SEric Cheng break; 42888275SEric Cheng } 42898275SEric Cheng 42908275SEric Cheng /* Property not in list */ 42918275SEric Cheng if (i == proplist->al_count) 42928275SEric Cheng return (DLADM_STATUS_OK); 42938275SEric Cheng 42948275SEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 42958275SEric Cheng prop_desc_t *pdp = &prop_table[i]; 42968275SEric Cheng val_desc_t *vdp; 42978275SEric Cheng 42988275SEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 42998275SEric Cheng if (vdp == NULL) 43008275SEric Cheng return (DLADM_STATUS_NOMEM); 43018275SEric Cheng 43028275SEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 43038275SEric Cheng continue; 43048275SEric Cheng 43058275SEric Cheng if (aip->ai_val == NULL) 43068275SEric Cheng return (DLADM_STATUS_BADARG); 43078275SEric Cheng 43088275SEric Cheng /* Check property value */ 43098275SEric Cheng if (pdp->pd_check != NULL) { 43108453SAnurag.Maskey@Sun.COM status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 431111878SVenu.Iyer@Sun.COM aip->ai_count, flags, vdp, 0); 43128275SEric Cheng } else { 43138275SEric Cheng status = DLADM_STATUS_BADARG; 43148275SEric Cheng } 43158275SEric Cheng 43168275SEric Cheng if (status != DLADM_STATUS_OK) 43178275SEric Cheng return (status); 43188275SEric Cheng 43198275SEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 43208275SEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 43218275SEric Cheng 43228275SEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 43238275SEric Cheng continue; 43248275SEric Cheng 43258275SEric Cheng /* Extract kernel structure */ 43268275SEric Cheng if (rpp->rp_extract != NULL) { 432710734SEric Cheng status = rpp->rp_extract(vdp, 432810734SEric Cheng aip->ai_count, arg); 43298275SEric Cheng } else { 43308275SEric Cheng status = DLADM_STATUS_BADARG; 43318275SEric Cheng } 43328275SEric Cheng break; 43338275SEric Cheng } 43348275SEric Cheng 43358275SEric Cheng if (status != DLADM_STATUS_OK) 43368275SEric Cheng return (status); 43378275SEric Cheng 43388275SEric Cheng break; 43398275SEric Cheng } 43408275SEric Cheng return (status); 43418275SEric Cheng } 43428275SEric Cheng 43438275SEric Cheng /* 43448275SEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 43458275SEric Cheng */ 43468275SEric Cheng dladm_status_t 43478453SAnurag.Maskey@Sun.COM dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 434811878SVenu.Iyer@Sun.COM mac_resource_props_t *mrp, uint_t flags) 43498275SEric Cheng { 435010734SEric Cheng dladm_status_t status; 435110734SEric Cheng int i; 435210734SEric Cheng 435310734SEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 435410734SEric Cheng status = i_dladm_link_proplist_extract_one(handle, 435511878SVenu.Iyer@Sun.COM proplist, rsrc_prop_table[i].rp_name, flags, mrp); 435610734SEric Cheng if (status != DLADM_STATUS_OK) 435710734SEric Cheng return (status); 435810734SEric Cheng } 43598275SEric Cheng return (status); 43608275SEric Cheng } 43618275SEric Cheng 43628275SEric Cheng static const char * 43638275SEric Cheng dladm_perm2str(uint_t perm, char *buf) 43648275SEric Cheng { 43658275SEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 43668275SEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 43678275SEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 43688275SEric Cheng return (buf); 43698275SEric Cheng } 43708306SSowmini.Varadhan@Sun.COM 43718306SSowmini.Varadhan@Sun.COM dladm_status_t 437211878SVenu.Iyer@Sun.COM dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 43738453SAnurag.Maskey@Sun.COM link_state_t *state) 43748306SSowmini.Varadhan@Sun.COM { 43758306SSowmini.Varadhan@Sun.COM uint_t perms; 43768306SSowmini.Varadhan@Sun.COM 437711878SVenu.Iyer@Sun.COM return (i_dladm_get_public_prop(handle, linkid, "state", 0, 437811878SVenu.Iyer@Sun.COM &perms, state, sizeof (*state))); 43798306SSowmini.Varadhan@Sun.COM } 43808460SArtem.Kachitchkin@Sun.COM 43818460SArtem.Kachitchkin@Sun.COM boolean_t 43828460SArtem.Kachitchkin@Sun.COM dladm_attr_is_linkprop(const char *name) 43838460SArtem.Kachitchkin@Sun.COM { 43848460SArtem.Kachitchkin@Sun.COM /* non-property attribute names */ 43858460SArtem.Kachitchkin@Sun.COM const char *nonprop[] = { 43868460SArtem.Kachitchkin@Sun.COM /* dlmgmtd core attributes */ 43878460SArtem.Kachitchkin@Sun.COM "name", 43888460SArtem.Kachitchkin@Sun.COM "class", 43898460SArtem.Kachitchkin@Sun.COM "media", 43908460SArtem.Kachitchkin@Sun.COM FPHYMAJ, 43918460SArtem.Kachitchkin@Sun.COM FPHYINST, 43928460SArtem.Kachitchkin@Sun.COM FDEVNAME, 43938460SArtem.Kachitchkin@Sun.COM 43948460SArtem.Kachitchkin@Sun.COM /* other attributes for vlan, aggr, etc */ 43958460SArtem.Kachitchkin@Sun.COM DLADM_ATTR_NAMES 43968460SArtem.Kachitchkin@Sun.COM }; 43978460SArtem.Kachitchkin@Sun.COM boolean_t is_nonprop = B_FALSE; 43988460SArtem.Kachitchkin@Sun.COM int i; 43998460SArtem.Kachitchkin@Sun.COM 44008460SArtem.Kachitchkin@Sun.COM for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 44018460SArtem.Kachitchkin@Sun.COM if (strcmp(name, nonprop[i]) == 0) { 44028460SArtem.Kachitchkin@Sun.COM is_nonprop = B_TRUE; 44038460SArtem.Kachitchkin@Sun.COM break; 44048460SArtem.Kachitchkin@Sun.COM } 44058460SArtem.Kachitchkin@Sun.COM } 44068460SArtem.Kachitchkin@Sun.COM 44078460SArtem.Kachitchkin@Sun.COM return (!is_nonprop); 44088460SArtem.Kachitchkin@Sun.COM } 440911878SVenu.Iyer@Sun.COM 441011878SVenu.Iyer@Sun.COM dladm_status_t 441111878SVenu.Iyer@Sun.COM dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 441211878SVenu.Iyer@Sun.COM dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 441311878SVenu.Iyer@Sun.COM { 441411878SVenu.Iyer@Sun.COM char *buf, **propvals; 441511878SVenu.Iyer@Sun.COM uint_t valcnt = DLADM_MAX_PROP_VALCNT; 441611878SVenu.Iyer@Sun.COM int i; 441711878SVenu.Iyer@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 441811878SVenu.Iyer@Sun.COM 441911878SVenu.Iyer@Sun.COM *is_set = B_FALSE; 442011878SVenu.Iyer@Sun.COM 442111878SVenu.Iyer@Sun.COM if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 442211878SVenu.Iyer@Sun.COM DLADM_MAX_PROP_VALCNT)) == NULL) 442311878SVenu.Iyer@Sun.COM return (DLADM_STATUS_NOMEM); 442411878SVenu.Iyer@Sun.COM 442511878SVenu.Iyer@Sun.COM propvals = (char **)(void *)buf; 442611878SVenu.Iyer@Sun.COM for (i = 0; i < valcnt; i++) { 442711878SVenu.Iyer@Sun.COM propvals[i] = buf + 442811878SVenu.Iyer@Sun.COM sizeof (char *) * DLADM_MAX_PROP_VALCNT + 442911878SVenu.Iyer@Sun.COM i * DLADM_PROP_VAL_MAX; 443011878SVenu.Iyer@Sun.COM } 443111878SVenu.Iyer@Sun.COM 443211878SVenu.Iyer@Sun.COM if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 443311878SVenu.Iyer@Sun.COM &valcnt) != DLADM_STATUS_OK) { 443411878SVenu.Iyer@Sun.COM goto done; 443511878SVenu.Iyer@Sun.COM } 443611878SVenu.Iyer@Sun.COM 443711878SVenu.Iyer@Sun.COM if ((strcmp(prop_name, "pool") == 0) && (strlen(*propvals) != 0)) { 443811878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 443911878SVenu.Iyer@Sun.COM } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 444011878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 444111878SVenu.Iyer@Sun.COM } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 444211878SVenu.Iyer@Sun.COM (strcmp(propvals[0], "true") == 0)) { 444311878SVenu.Iyer@Sun.COM *is_set = B_TRUE; 444411878SVenu.Iyer@Sun.COM } 444511878SVenu.Iyer@Sun.COM 444611878SVenu.Iyer@Sun.COM done: 444711878SVenu.Iyer@Sun.COM if (buf != NULL) 444811878SVenu.Iyer@Sun.COM free(buf); 444911878SVenu.Iyer@Sun.COM return (status); 445011878SVenu.Iyer@Sun.COM } 445112163SRamaswamy.Tummala@Sun.COM 445212163SRamaswamy.Tummala@Sun.COM /* ARGSUSED */ 445312163SRamaswamy.Tummala@Sun.COM static dladm_status_t 445412163SRamaswamy.Tummala@Sun.COM get_linkmode_prop(dladm_handle_t handle, prop_desc_t *pdp, 445512163SRamaswamy.Tummala@Sun.COM datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 445612163SRamaswamy.Tummala@Sun.COM datalink_media_t media, uint_t flags, uint_t *perm_flags) 445712163SRamaswamy.Tummala@Sun.COM { 445812163SRamaswamy.Tummala@Sun.COM char *s; 445912163SRamaswamy.Tummala@Sun.COM uint32_t v; 446012163SRamaswamy.Tummala@Sun.COM dladm_status_t status; 446112163SRamaswamy.Tummala@Sun.COM 446212163SRamaswamy.Tummala@Sun.COM status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 446312163SRamaswamy.Tummala@Sun.COM perm_flags, &v, sizeof (v)); 446412163SRamaswamy.Tummala@Sun.COM if (status != DLADM_STATUS_OK) 446512163SRamaswamy.Tummala@Sun.COM return (status); 446612163SRamaswamy.Tummala@Sun.COM 446712163SRamaswamy.Tummala@Sun.COM switch (v) { 4468*12303SRajkumar.Sivaprakasam@Sun.COM case DLADM_PART_CM_MODE: 446912163SRamaswamy.Tummala@Sun.COM s = "cm"; 447012163SRamaswamy.Tummala@Sun.COM break; 4471*12303SRajkumar.Sivaprakasam@Sun.COM case DLADM_PART_UD_MODE: 447212163SRamaswamy.Tummala@Sun.COM s = "ud"; 447312163SRamaswamy.Tummala@Sun.COM break; 447412163SRamaswamy.Tummala@Sun.COM default: 447512163SRamaswamy.Tummala@Sun.COM s = ""; 447612163SRamaswamy.Tummala@Sun.COM break; 447712163SRamaswamy.Tummala@Sun.COM } 447812163SRamaswamy.Tummala@Sun.COM (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); 447912163SRamaswamy.Tummala@Sun.COM 448012163SRamaswamy.Tummala@Sun.COM *val_cnt = 1; 448112163SRamaswamy.Tummala@Sun.COM return (DLADM_STATUS_OK); 448212163SRamaswamy.Tummala@Sun.COM } 4483