10ba2cbe9Sxc151355 /* 20ba2cbe9Sxc151355 * CDDL HEADER START 30ba2cbe9Sxc151355 * 40ba2cbe9Sxc151355 * The contents of this file are subject to the terms of the 50ba2cbe9Sxc151355 * Common Development and Distribution License (the "License"). 60ba2cbe9Sxc151355 * You may not use this file except in compliance with the License. 70ba2cbe9Sxc151355 * 80ba2cbe9Sxc151355 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90ba2cbe9Sxc151355 * or http://www.opensolaris.org/os/licensing. 100ba2cbe9Sxc151355 * See the License for the specific language governing permissions 110ba2cbe9Sxc151355 * and limitations under the License. 120ba2cbe9Sxc151355 * 130ba2cbe9Sxc151355 * When distributing Covered Code, include this CDDL HEADER in each 140ba2cbe9Sxc151355 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150ba2cbe9Sxc151355 * If applicable, add the following below this CDDL HEADER, with the 160ba2cbe9Sxc151355 * fields enclosed by brackets "[]" replaced with your own identifying 170ba2cbe9Sxc151355 * information: Portions Copyright [yyyy] [name of copyright owner] 180ba2cbe9Sxc151355 * 190ba2cbe9Sxc151355 * CDDL HEADER END 200ba2cbe9Sxc151355 */ 210ba2cbe9Sxc151355 /* 22*0dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 230ba2cbe9Sxc151355 * Use is subject to license terms. 240ba2cbe9Sxc151355 */ 250ba2cbe9Sxc151355 260ba2cbe9Sxc151355 #include <stdlib.h> 270ba2cbe9Sxc151355 #include <strings.h> 280ba2cbe9Sxc151355 #include <errno.h> 290ba2cbe9Sxc151355 #include <ctype.h> 30d62bc4baSyz147064 #include <stddef.h> 31f4b3ec61Sdh155122 #include <sys/types.h> 320ba2cbe9Sxc151355 #include <sys/stat.h> 33f4b3ec61Sdh155122 #include <sys/dld.h> 34f4b3ec61Sdh155122 #include <sys/zone.h> 35f4b3ec61Sdh155122 #include <fcntl.h> 36f4b3ec61Sdh155122 #include <unistd.h> 37f4b3ec61Sdh155122 #include <libdevinfo.h> 38f4b3ec61Sdh155122 #include <zone.h> 39f595a68aSyz147064 #include <libdllink.h> 400ba2cbe9Sxc151355 #include <libdladm_impl.h> 41d62bc4baSyz147064 #include <libdlwlan_impl.h> 42f595a68aSyz147064 #include <libdlwlan.h> 43d62bc4baSyz147064 #include <libdlvlan.h> 44da14cebeSEric Cheng #include <libdlvnic.h> 45da14cebeSEric Cheng #include <libintl.h> 46f4b3ec61Sdh155122 #include <dlfcn.h> 47f4b3ec61Sdh155122 #include <link.h> 48d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 49e7801d59Ssowmini #include <libdladm.h> 50da14cebeSEric Cheng #include <libdlstat.h> 51e7801d59Ssowmini #include <sys/param.h> 52da14cebeSEric Cheng #include <sys/debug.h> 53da14cebeSEric Cheng #include <sys/dld.h> 54e7801d59Ssowmini #include <inttypes.h> 55e7801d59Ssowmini #include <sys/ethernet.h> 562b24ab6bSSebastien Roy #include <inet/iptun.h> 57bcb5c89dSSowmini Varadhan #include <net/wpa.h> 58bcb5c89dSSowmini Varadhan #include <sys/sysmacros.h> 594eaa4710SRishi Srivatsavai #include <sys/vlan.h> 604eaa4710SRishi Srivatsavai #include <libdlbridge.h> 614eaa4710SRishi Srivatsavai #include <stp_in.h> 62*0dc2366fSVenugopal Iyer #include <netinet/dhcp.h> 63*0dc2366fSVenugopal Iyer #include <netinet/dhcp6.h> 64*0dc2366fSVenugopal Iyer #include <net/if_types.h> 65*0dc2366fSVenugopal Iyer #include <libinetutil.h> 66*0dc2366fSVenugopal Iyer #include <pool.h> 67f4b3ec61Sdh155122 68d62bc4baSyz147064 /* 69d62bc4baSyz147064 * The linkprop get() callback. 70da14cebeSEric Cheng * - pd: pointer to the prop_desc_t 71d62bc4baSyz147064 * - propstrp: a property string array to keep the returned property. 72d62bc4baSyz147064 * Caller allocated. 73d62bc4baSyz147064 * - cntp: number of returned properties. 74d62bc4baSyz147064 * Caller also uses it to indicate how many it expects. 75d62bc4baSyz147064 */ 76e7801d59Ssowmini struct prop_desc; 77da14cebeSEric Cheng typedef struct prop_desc prop_desc_t; 78e7801d59Ssowmini 794ac67f02SAnurag S. Maskey typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 806b9e797cSsowmini datalink_id_t, char **propstp, uint_t *cntp, 81afdda45fSVasumathi Sundaram - Sun Microsystems datalink_media_t, uint_t, uint_t *); 82f4b3ec61Sdh155122 83d62bc4baSyz147064 /* 84d62bc4baSyz147064 * The linkprop set() callback. 85d62bc4baSyz147064 * - propval: a val_desc_t array which keeps the property values to be set. 86d62bc4baSyz147064 * - cnt: number of properties to be set. 87e7801d59Ssowmini * - flags: additional flags passed down the system call. 88e7801d59Ssowmini * 89e7801d59Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 90e7801d59Ssowmini * a format suitable for kernel consumption. This may require allocation 91e7801d59Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 92e7801d59Ssowmini * by all other pd_sets) which invokes the ioctl. 93d62bc4baSyz147064 */ 944ac67f02SAnurag S. Maskey typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 956b9e797cSsowmini val_desc_t *propval, uint_t cnt, uint_t flags, 966b9e797cSsowmini datalink_media_t); 97f4b3ec61Sdh155122 98d62bc4baSyz147064 /* 99d62bc4baSyz147064 * The linkprop check() callback. 100d62bc4baSyz147064 * - propstrp: property string array which keeps the property to be checked. 101d62bc4baSyz147064 * - cnt: number of properties. 102d62bc4baSyz147064 * - propval: return value; the property values of the given property strings. 103e7801d59Ssowmini * 104e7801d59Ssowmini * pd_check checks that the input values are valid. It does so by 105e7801d59Ssowmini * iteraring through the pd_modval list for the property. If 106e7801d59Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 107e7801d59Ssowmini * specific to this property can be used. If the input values are 108e7801d59Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 109e7801d59Ssowmini * with either a val_desc_t found on the pd_modval list or something 110e7801d59Ssowmini * generated on the fly. 111d62bc4baSyz147064 */ 1124ac67f02SAnurag S. Maskey typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 1134ac67f02SAnurag S. Maskey datalink_id_t, char **propstrp, uint_t cnt, 114*0dc2366fSVenugopal Iyer uint_t flags, val_desc_t *propval, 115*0dc2366fSVenugopal Iyer datalink_media_t); 116f4b3ec61Sdh155122 117bcb5c89dSSowmini Varadhan typedef struct link_attr_s { 1183fd94f8cSam223141 mac_prop_id_t pp_id; 119e7801d59Ssowmini size_t pp_valsize; 120e7801d59Ssowmini char *pp_name; 121bcb5c89dSSowmini Varadhan } link_attr_t; 122e7801d59Ssowmini 123*0dc2366fSVenugopal Iyer typedef struct dladm_linkprop_args_s { 124*0dc2366fSVenugopal Iyer dladm_status_t dla_status; 125*0dc2366fSVenugopal Iyer uint_t dla_flags; 126*0dc2366fSVenugopal Iyer } dladm_linkprop_args_t; 127*0dc2366fSVenugopal Iyer 128bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 129bcb5c89dSSowmini Varadhan const char *, uint_t, dladm_status_t *); 130bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 131da14cebeSEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 132*0dc2366fSVenugopal Iyer static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 133*0dc2366fSVenugopal Iyer char *, uint_t, uint_t *, void *, size_t); 134da14cebeSEric Cheng 1353361618bSRishi Srivatsavai static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1364ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 13762ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1384ac67f02SAnurag S. Maskey const char *, char **, uint_t *, dladm_prop_type_t, 1394ac67f02SAnurag S. Maskey uint_t); 140*0dc2366fSVenugopal Iyer static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 141*0dc2366fSVenugopal Iyer static const char *dladm_perm2str(uint_t, char *); 142bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *); 143bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t); 144da14cebeSEric Cheng 145*0dc2366fSVenugopal Iyer static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 146*0dc2366fSVenugopal Iyer get_speed, get_channel, get_powermode, get_radio, 147*0dc2366fSVenugopal Iyer get_duplex, get_link_state, get_binary, get_uint32, 148*0dc2366fSVenugopal Iyer get_flowctl, get_maxbw, get_cpus, get_priority, 149*0dc2366fSVenugopal Iyer get_tagmode, get_range, get_stp, get_bridge_forward, 150*0dc2366fSVenugopal Iyer get_bridge_pvid, get_protection, get_rxrings, 151*0dc2366fSVenugopal Iyer get_txrings, get_cntavail, 152*0dc2366fSVenugopal Iyer get_allowedips, get_allowedcids, get_pool, 153*0dc2366fSVenugopal Iyer get_rings_range; 154da14cebeSEric Cheng 155*0dc2366fSVenugopal Iyer static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 156*0dc2366fSVenugopal Iyer set_public_prop, set_resource, set_stp_prop, 157*0dc2366fSVenugopal Iyer set_bridge_forward, set_bridge_pvid; 158f4b3ec61Sdh155122 159*0dc2366fSVenugopal Iyer static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 160*0dc2366fSVenugopal Iyer check_encaplim, check_uint32, check_maxbw, check_cpus, 161*0dc2366fSVenugopal Iyer check_stp_prop, check_bridge_pvid, check_allowedips, 162*0dc2366fSVenugopal Iyer check_allowedcids, check_rings, 163*0dc2366fSVenugopal Iyer check_pool, check_prop; 1646b9e797cSsowmini 165da14cebeSEric Cheng struct prop_desc { 166d62bc4baSyz147064 /* 167d62bc4baSyz147064 * link property name 168d62bc4baSyz147064 */ 169f4b3ec61Sdh155122 char *pd_name; 170d62bc4baSyz147064 171d62bc4baSyz147064 /* 172d62bc4baSyz147064 * default property value, can be set to { "", NULL } 173d62bc4baSyz147064 */ 174f4b3ec61Sdh155122 val_desc_t pd_defval; 175d62bc4baSyz147064 176d62bc4baSyz147064 /* 177d62bc4baSyz147064 * list of optional property values, can be NULL. 178d62bc4baSyz147064 * 179d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 180d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 181d62bc4baSyz147064 */ 182d62bc4baSyz147064 val_desc_t *pd_optval; 183d62bc4baSyz147064 184d62bc4baSyz147064 /* 185d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 186d62bc4baSyz147064 */ 187d62bc4baSyz147064 uint_t pd_noptval; 188d62bc4baSyz147064 189d62bc4baSyz147064 /* 1904eaa4710SRishi Srivatsavai * callback to set link property; set to NULL if this property is 1914eaa4710SRishi Srivatsavai * read-only and may be called before or after permanent update; see 1924eaa4710SRishi Srivatsavai * flags. 193d62bc4baSyz147064 */ 194f4b3ec61Sdh155122 pd_setf_t *pd_set; 195d62bc4baSyz147064 196d62bc4baSyz147064 /* 197d62bc4baSyz147064 * callback to get modifiable link property 198d62bc4baSyz147064 */ 199f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 200d62bc4baSyz147064 201d62bc4baSyz147064 /* 202d62bc4baSyz147064 * callback to get current link property 203d62bc4baSyz147064 */ 204f4b3ec61Sdh155122 pd_getf_t *pd_get; 205d62bc4baSyz147064 206d62bc4baSyz147064 /* 207d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 208d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 209d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 210d62bc4baSyz147064 * valid. 211d62bc4baSyz147064 */ 212f4b3ec61Sdh155122 pd_checkf_t *pd_check; 213d62bc4baSyz147064 214d62bc4baSyz147064 uint_t pd_flags; 215e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 216e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 2174eaa4710SRishi Srivatsavai #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 218d62bc4baSyz147064 /* 219d62bc4baSyz147064 * indicate link classes this property applies to. 220d62bc4baSyz147064 */ 221d62bc4baSyz147064 datalink_class_t pd_class; 222d62bc4baSyz147064 223d62bc4baSyz147064 /* 224d62bc4baSyz147064 * indicate link media type this property applies to. 225d62bc4baSyz147064 */ 226d62bc4baSyz147064 datalink_media_t pd_dmedia; 227da14cebeSEric Cheng }; 228f4b3ec61Sdh155122 2293fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 230e7801d59Ssowmini 231bcb5c89dSSowmini Varadhan /* 232bcb5c89dSSowmini Varadhan * Supported link properties enumerated in the prop_table[] array are 233bcb5c89dSSowmini Varadhan * computed using the callback functions in that array. To compute the 234bcb5c89dSSowmini Varadhan * property value, multiple distinct system calls may be needed (e.g., 235bcb5c89dSSowmini Varadhan * for wifi speed, we need to issue system calls to get desired/supported 236bcb5c89dSSowmini Varadhan * rates). The link_attr[] table enumerates the interfaces to the kernel, 237bcb5c89dSSowmini Varadhan * and the type/size of the data passed in the user-kernel interface. 238bcb5c89dSSowmini Varadhan */ 239bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = { 240bcb5c89dSSowmini Varadhan { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 241e7801d59Ssowmini 242bcb5c89dSSowmini Varadhan { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 243e7801d59Ssowmini 244bcb5c89dSSowmini Varadhan { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 245e7801d59Ssowmini 246bcb5c89dSSowmini Varadhan { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 247e7801d59Ssowmini 248bcb5c89dSSowmini Varadhan { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 249e7801d59Ssowmini 250bcb5c89dSSowmini Varadhan { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 251e7801d59Ssowmini 252bcb5c89dSSowmini Varadhan { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 253e7801d59Ssowmini 254bcb5c89dSSowmini Varadhan { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2553bc21d0aSAruna Ramakrishna - Sun Microsystems 256aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 257aca118b7Slucy wang - Sun Microsystems - Beijing China 258aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 259aca118b7Slucy wang - Sun Microsystems - Beijing China 260bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2613bc21d0aSAruna Ramakrishna - Sun Microsystems 262bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 263e7801d59Ssowmini 264bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 265e7801d59Ssowmini 266bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 267e7801d59Ssowmini 268bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 269e7801d59Ssowmini 270bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 271e7801d59Ssowmini 272bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 273e7801d59Ssowmini 274bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 275e7801d59Ssowmini 276bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 277e7801d59Ssowmini 278bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 279e7801d59Ssowmini 280bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 281e7801d59Ssowmini 282bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 283e7801d59Ssowmini 284bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 285e7801d59Ssowmini 286bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 287bcb5c89dSSowmini Varadhan 288bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 289bcb5c89dSSowmini Varadhan 290bcb5c89dSSowmini Varadhan { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 291bcb5c89dSSowmini Varadhan 292bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 293bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 294bcb5c89dSSowmini Varadhan 295bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 296bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 297bcb5c89dSSowmini Varadhan 298bcb5c89dSSowmini Varadhan { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 299bcb5c89dSSowmini Varadhan 300bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 301bcb5c89dSSowmini Varadhan 302bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 303bcb5c89dSSowmini Varadhan 304bcb5c89dSSowmini Varadhan { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 305bcb5c89dSSowmini Varadhan 306bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 307bcb5c89dSSowmini Varadhan 308bcb5c89dSSowmini Varadhan { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 309bcb5c89dSSowmini Varadhan 310bcb5c89dSSowmini Varadhan /* wl_wpa_ess_t has variable length */ 311bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 312bcb5c89dSSowmini Varadhan 313bcb5c89dSSowmini Varadhan { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 314bcb5c89dSSowmini Varadhan 315bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 316bcb5c89dSSowmini Varadhan 317bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 318bcb5c89dSSowmini Varadhan 319bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 320bcb5c89dSSowmini Varadhan 321bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 322bcb5c89dSSowmini Varadhan 323bcb5c89dSSowmini Varadhan /* wl_wpa_ie_t has variable length */ 324bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 325bcb5c89dSSowmini Varadhan 326bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 327bcb5c89dSSowmini Varadhan 328bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 329bcb5c89dSSowmini Varadhan 330bcb5c89dSSowmini Varadhan { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 331bcb5c89dSSowmini Varadhan 332e75f0919SSebastien Roy { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 333e75f0919SSebastien Roy 3342b24ab6bSSebastien Roy { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 3352b24ab6bSSebastien Roy 3362b24ab6bSSebastien Roy { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 3372b24ab6bSSebastien Roy 3384eaa4710SRishi Srivatsavai { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 3394eaa4710SRishi Srivatsavai 3404eaa4710SRishi Srivatsavai { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 3414eaa4710SRishi Srivatsavai 3424eaa4710SRishi Srivatsavai { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 3434eaa4710SRishi Srivatsavai 344*0dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 345*0dc2366fSVenugopal Iyer 346*0dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 347*0dc2366fSVenugopal Iyer "resource-effective"}, 348*0dc2366fSVenugopal Iyer 349*0dc2366fSVenugopal Iyer { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 350*0dc2366fSVenugopal Iyer 351*0dc2366fSVenugopal Iyer { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 352*0dc2366fSVenugopal Iyer 353*0dc2366fSVenugopal Iyer { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 354*0dc2366fSVenugopal Iyer "txrings-available"}, 355*0dc2366fSVenugopal Iyer 356*0dc2366fSVenugopal Iyer { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 357*0dc2366fSVenugopal Iyer "rxrings-available"}, 358*0dc2366fSVenugopal Iyer 359*0dc2366fSVenugopal Iyer { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 360*0dc2366fSVenugopal Iyer 361*0dc2366fSVenugopal Iyer { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 362da14cebeSEric Cheng 36325ec3e3dSEric Cheng { MAC_PROP_PRIVATE, 0, "driver-private"} 364e7801d59Ssowmini }; 365e7801d59Ssowmini 3664eaa4710SRishi Srivatsavai typedef struct bridge_public_prop_s { 3674eaa4710SRishi Srivatsavai const char *bpp_name; 3684eaa4710SRishi Srivatsavai int bpp_code; 3694eaa4710SRishi Srivatsavai } bridge_public_prop_t; 3704eaa4710SRishi Srivatsavai 3714eaa4710SRishi Srivatsavai static const bridge_public_prop_t bridge_prop[] = { 3724eaa4710SRishi Srivatsavai { "stp", PT_CFG_NON_STP }, 3734eaa4710SRishi Srivatsavai { "stp_priority", PT_CFG_PRIO }, 3744eaa4710SRishi Srivatsavai { "stp_cost", PT_CFG_COST }, 3754eaa4710SRishi Srivatsavai { "stp_edge", PT_CFG_EDGE }, 3764eaa4710SRishi Srivatsavai { "stp_p2p", PT_CFG_P2P }, 3774eaa4710SRishi Srivatsavai { "stp_mcheck", PT_CFG_MCHECK }, 3784eaa4710SRishi Srivatsavai { NULL, 0 } 3794eaa4710SRishi Srivatsavai }; 3804eaa4710SRishi Srivatsavai 381e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 382e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 383e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 384e7801d59Ssowmini }; 385e7801d59Ssowmini static val_desc_t link_status_vals[] = { 386e7801d59Ssowmini { "up", LINK_STATE_UP }, 387e7801d59Ssowmini { "down", LINK_STATE_DOWN } 388e7801d59Ssowmini }; 389e7801d59Ssowmini static val_desc_t link_01_vals[] = { 390e7801d59Ssowmini { "1", 1 }, 391e7801d59Ssowmini { "0", 0 } 392e7801d59Ssowmini }; 393e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 394e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 395e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 396e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 397e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 398e7801d59Ssowmini }; 399da14cebeSEric Cheng static val_desc_t link_priority_vals[] = { 400da14cebeSEric Cheng { "low", MPL_LOW }, 401da14cebeSEric Cheng { "medium", MPL_MEDIUM }, 402da14cebeSEric Cheng { "high", MPL_HIGH } 403da14cebeSEric Cheng }; 404e7801d59Ssowmini 405e75f0919SSebastien Roy static val_desc_t link_tagmode_vals[] = { 406e75f0919SSebastien Roy { "normal", LINK_TAGMODE_NORMAL }, 407e75f0919SSebastien Roy { "vlanonly", LINK_TAGMODE_VLANONLY } 408e75f0919SSebastien Roy }; 409e75f0919SSebastien Roy 41025ec3e3dSEric Cheng static val_desc_t link_protect_vals[] = { 41125ec3e3dSEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 412*0dc2366fSVenugopal Iyer { "restricted", MPT_RESTRICTED }, 41325ec3e3dSEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 414*0dc2366fSVenugopal Iyer { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 41525ec3e3dSEric Cheng }; 41625ec3e3dSEric Cheng 417d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 418d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 419d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 420d62bc4baSyz147064 }; 421d62bc4baSyz147064 422d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 423d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 424d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 425d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 426d62bc4baSyz147064 }; 427d62bc4baSyz147064 4284eaa4710SRishi Srivatsavai static val_desc_t stp_p2p_vals[] = { 4294eaa4710SRishi Srivatsavai { "true", P2P_FORCE_TRUE }, 4304eaa4710SRishi Srivatsavai { "false", P2P_FORCE_FALSE }, 4314eaa4710SRishi Srivatsavai { "auto", P2P_AUTO } 4324eaa4710SRishi Srivatsavai }; 4334eaa4710SRishi Srivatsavai 434da14cebeSEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 435da14cebeSEric Cheng #define RESET_VAL ((uintptr_t)-1) 436*0dc2366fSVenugopal Iyer #define UNSPEC_VAL ((uintptr_t)-2) 437d62bc4baSyz147064 438da14cebeSEric Cheng static prop_desc_t prop_table[] = { 439e7801d59Ssowmini { "channel", { NULL, 0 }, 440e7801d59Ssowmini NULL, 0, NULL, NULL, 441*0dc2366fSVenugopal Iyer get_channel, NULL, 0, 442d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 443d62bc4baSyz147064 444d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 445d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 446*0dc2366fSVenugopal Iyer set_powermode, NULL, 447*0dc2366fSVenugopal Iyer get_powermode, NULL, 0, 448d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 449d62bc4baSyz147064 450d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 451d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 452*0dc2366fSVenugopal Iyer set_radio, NULL, 453*0dc2366fSVenugopal Iyer get_radio, NULL, 0, 454d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 455d62bc4baSyz147064 456d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 457*0dc2366fSVenugopal Iyer set_rate, get_rate_mod, 458*0dc2366fSVenugopal Iyer get_rate, check_rate, 0, 4596b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 460d62bc4baSyz147064 4614045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 462*0dc2366fSVenugopal Iyer set_public_prop, NULL, 463*0dc2366fSVenugopal Iyer get_autopush, check_autopush, PD_CHECK_ALLOC, 464d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 465d62bc4baSyz147064 4664045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 467*0dc2366fSVenugopal Iyer set_zone, NULL, 468*0dc2366fSVenugopal Iyer get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 469e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 470e7801d59Ssowmini 4714045d941Ssowmini { "duplex", { "", 0 }, 472e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 473*0dc2366fSVenugopal Iyer NULL, NULL, get_duplex, NULL, 474e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 475e7801d59Ssowmini 4766b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 477e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 478*0dc2366fSVenugopal Iyer NULL, NULL, get_link_state, NULL, 4794045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 480e7801d59Ssowmini 4810b8f0546SSowmini Varadhan { "adv_autoneg_cap", { "", 0 }, 482e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 483*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 484e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 485e7801d59Ssowmini 4864045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 487*0dc2366fSVenugopal Iyer set_public_prop, get_range, 488*0dc2366fSVenugopal Iyer get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 4893bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 490e7801d59Ssowmini 4914045d941Ssowmini { "flowctrl", { "", 0 }, 492e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 493*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_flowctl, NULL, 494e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 495e7801d59Ssowmini 496aca118b7Slucy wang - Sun Microsystems - Beijing China { "adv_10gfdx_cap", { "", 0 }, 497aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 498*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 499aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 500aca118b7Slucy wang - Sun Microsystems - Beijing China 501aca118b7Slucy wang - Sun Microsystems - Beijing China { "en_10gfdx_cap", { "", 0 }, 502aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 503*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 504aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 505aca118b7Slucy wang - Sun Microsystems - Beijing China 5064045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 5074045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 508*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 509e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 510e7801d59Ssowmini 5114045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 512e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 513*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 514e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 515e7801d59Ssowmini 5164045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 517e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 518*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 519e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 520e7801d59Ssowmini 5214045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 522e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 523*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 524e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 525e7801d59Ssowmini 5264045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 527e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 528*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 529e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 530e7801d59Ssowmini 5314045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 532e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 533*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 534e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 535e7801d59Ssowmini 5364045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 537e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 538*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 539e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 540e7801d59Ssowmini 5414045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 542e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 543*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 544e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 545e7801d59Ssowmini 5464045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 547e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 548*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 549e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 550e7801d59Ssowmini 5514045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 552e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 553*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 554e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 555e7801d59Ssowmini 5564045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 557e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 558*0dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 559e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 560e7801d59Ssowmini 5614045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 562e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 563*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 564da14cebeSEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 565e7801d59Ssowmini 566da14cebeSEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 567*0dc2366fSVenugopal Iyer set_resource, NULL, 568*0dc2366fSVenugopal Iyer get_maxbw, check_maxbw, PD_CHECK_ALLOC, 569da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 570da14cebeSEric Cheng 571da14cebeSEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 572*0dc2366fSVenugopal Iyer set_resource, NULL, 573*0dc2366fSVenugopal Iyer get_cpus, check_cpus, 0, 574da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 575da14cebeSEric Cheng 576*0dc2366fSVenugopal Iyer { "cpus-effective", { "--", 0 }, 577*0dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 578*0dc2366fSVenugopal Iyer get_cpus, 0, 0, 579*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 580*0dc2366fSVenugopal Iyer 581*0dc2366fSVenugopal Iyer { "pool", { "--", RESET_VAL }, NULL, 0, 582*0dc2366fSVenugopal Iyer set_resource, NULL, 583*0dc2366fSVenugopal Iyer get_pool, check_pool, 0, 584*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 585*0dc2366fSVenugopal Iyer 586*0dc2366fSVenugopal Iyer { "pool-effective", { "--", 0 }, 587*0dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 588*0dc2366fSVenugopal Iyer get_pool, 0, 0, 589*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 590*0dc2366fSVenugopal Iyer 591*0dc2366fSVenugopal Iyer { "priority", { "high", MPL_RESET }, 592*0dc2366fSVenugopal Iyer link_priority_vals, VALCNT(link_priority_vals), set_resource, 593*0dc2366fSVenugopal Iyer NULL, get_priority, check_prop, 0, 594da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 595e75f0919SSebastien Roy 596e75f0919SSebastien Roy { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 597e75f0919SSebastien Roy link_tagmode_vals, VALCNT(link_tagmode_vals), 598*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_tagmode, 599e75f0919SSebastien Roy NULL, 0, 600e75f0919SSebastien Roy DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 6014eaa4710SRishi Srivatsavai DL_ETHER }, 6024eaa4710SRishi Srivatsavai 6032b24ab6bSSebastien Roy { "hoplimit", { "", 0 }, NULL, 0, 604*0dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 605*0dc2366fSVenugopal Iyer check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 6062b24ab6bSSebastien Roy 6072b24ab6bSSebastien Roy { "encaplimit", { "", 0 }, NULL, 0, 608*0dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 609*0dc2366fSVenugopal Iyer check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 6102b24ab6bSSebastien Roy 6114eaa4710SRishi Srivatsavai { "forward", { "1", 1 }, 6124eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6134eaa4710SRishi Srivatsavai set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 6144eaa4710SRishi Srivatsavai DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 6154eaa4710SRishi Srivatsavai 6164eaa4710SRishi Srivatsavai { "default_tag", { "1", 1 }, NULL, 0, 6174eaa4710SRishi Srivatsavai set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 6184eaa4710SRishi Srivatsavai 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6194eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6204eaa4710SRishi Srivatsavai 6214eaa4710SRishi Srivatsavai { "learn_limit", { "1000", 1000 }, NULL, 0, 622*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 623*0dc2366fSVenugopal Iyer check_uint32, 0, 6244eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6254eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6264eaa4710SRishi Srivatsavai 6274eaa4710SRishi Srivatsavai { "learn_decay", { "200", 200 }, NULL, 0, 628*0dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 629*0dc2366fSVenugopal Iyer check_uint32, 0, 6304eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6314eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6324eaa4710SRishi Srivatsavai 6334eaa4710SRishi Srivatsavai { "stp", { "1", 1 }, 6344eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 635*0dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6364eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6374eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6384eaa4710SRishi Srivatsavai 6394eaa4710SRishi Srivatsavai { "stp_priority", { "128", 128 }, NULL, 0, 640*0dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6414eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6424eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6434eaa4710SRishi Srivatsavai 6444eaa4710SRishi Srivatsavai { "stp_cost", { "auto", 0 }, NULL, 0, 645*0dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6464eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6474eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6484eaa4710SRishi Srivatsavai 6494eaa4710SRishi Srivatsavai { "stp_edge", { "1", 1 }, 6504eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 651*0dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6524eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6534eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6544eaa4710SRishi Srivatsavai 6554eaa4710SRishi Srivatsavai { "stp_p2p", { "auto", P2P_AUTO }, 6564eaa4710SRishi Srivatsavai stp_p2p_vals, VALCNT(stp_p2p_vals), 657*0dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6584eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6594eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6604eaa4710SRishi Srivatsavai 6614eaa4710SRishi Srivatsavai { "stp_mcheck", { "0", 0 }, 6624eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 663*0dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6644eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6654eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 66625ec3e3dSEric Cheng 66725ec3e3dSEric Cheng { "protection", { "--", RESET_VAL }, 66825ec3e3dSEric Cheng link_protect_vals, VALCNT(link_protect_vals), 669*0dc2366fSVenugopal Iyer set_resource, NULL, get_protection, check_prop, 0, 67025ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 67125ec3e3dSEric Cheng 67225ec3e3dSEric Cheng { "allowed-ips", { "--", 0 }, 673*0dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 674*0dc2366fSVenugopal Iyer get_allowedips, check_allowedips, PD_CHECK_ALLOC, 67525ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 676*0dc2366fSVenugopal Iyer 677*0dc2366fSVenugopal Iyer { "allowed-dhcp-cids", { "--", 0 }, 678*0dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 679*0dc2366fSVenugopal Iyer get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 680*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 681*0dc2366fSVenugopal Iyer 682*0dc2366fSVenugopal Iyer { "rxrings", { "--", RESET_VAL }, NULL, 0, 683*0dc2366fSVenugopal Iyer set_resource, get_rings_range, get_rxrings, check_rings, 0, 684*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 685*0dc2366fSVenugopal Iyer 686*0dc2366fSVenugopal Iyer { "rxrings-effective", { "--", 0 }, 687*0dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 688*0dc2366fSVenugopal Iyer get_rxrings, NULL, 0, 689*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 690*0dc2366fSVenugopal Iyer 691*0dc2366fSVenugopal Iyer { "txrings", { "--", RESET_VAL }, NULL, 0, 692*0dc2366fSVenugopal Iyer set_resource, get_rings_range, get_txrings, check_rings, 0, 693*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 694*0dc2366fSVenugopal Iyer 695*0dc2366fSVenugopal Iyer { "txrings-effective", { "--", 0 }, 696*0dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 697*0dc2366fSVenugopal Iyer get_txrings, NULL, 0, 698*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 699*0dc2366fSVenugopal Iyer 700*0dc2366fSVenugopal Iyer { "txrings-available", { "", 0 }, NULL, 0, 701*0dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 702*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 703*0dc2366fSVenugopal Iyer 704*0dc2366fSVenugopal Iyer { "rxrings-available", { "", 0 }, NULL, 0, 705*0dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 706*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 707*0dc2366fSVenugopal Iyer 708*0dc2366fSVenugopal Iyer { "rxhwclnt-available", { "", 0 }, NULL, 0, 709*0dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 710*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 711*0dc2366fSVenugopal Iyer 712*0dc2366fSVenugopal Iyer { "txhwclnt-available", { "", 0 }, NULL, 0, 713*0dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 714*0dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 715*0dc2366fSVenugopal Iyer 716f4b3ec61Sdh155122 }; 717f4b3ec61Sdh155122 718d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 7190ba2cbe9Sxc151355 720da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 721*0dc2366fSVenugopal Iyer {"maxbw", extract_maxbw}, 722*0dc2366fSVenugopal Iyer {"priority", extract_priority}, 723*0dc2366fSVenugopal Iyer {"cpus", extract_cpus}, 724*0dc2366fSVenugopal Iyer {"cpus-effective", extract_cpus}, 725*0dc2366fSVenugopal Iyer {"pool", extract_pool}, 726*0dc2366fSVenugopal Iyer {"pool-effective", extract_pool}, 727*0dc2366fSVenugopal Iyer {"protection", extract_protection}, 728*0dc2366fSVenugopal Iyer {"allowed-ips", extract_allowedips}, 729*0dc2366fSVenugopal Iyer {"allowed-dhcp-cids", extract_allowedcids}, 730*0dc2366fSVenugopal Iyer {"rxrings", extract_rxrings}, 731*0dc2366fSVenugopal Iyer {"rxrings-effective", extract_rxrings}, 732*0dc2366fSVenugopal Iyer {"txrings", extract_txrings}, 733*0dc2366fSVenugopal Iyer {"txrings-effective", extract_txrings} 734da14cebeSEric Cheng }; 735da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 736da14cebeSEric Cheng sizeof (resource_prop_t)) 737da14cebeSEric Cheng 738bcb5c89dSSowmini Varadhan /* 739bcb5c89dSSowmini Varadhan * when retrieving private properties, we pass down a buffer with 740bcb5c89dSSowmini Varadhan * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 741bcb5c89dSSowmini Varadhan */ 742bcb5c89dSSowmini Varadhan #define DLADM_PROP_BUF_CHUNK 1024 743bcb5c89dSSowmini Varadhan 7444ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 7454ac67f02SAnurag S. Maskey const char *, char **, uint_t); 7464ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 7474ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 74862ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 74962ee1d25SArtem Kachitchkine datalink_id_t, void *, int (*)(dladm_handle_t, 75062ee1d25SArtem Kachitchkine datalink_id_t, const char *, void *)); 7514ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 7524ac67f02SAnurag S. Maskey datalink_class_t, uint32_t, prop_desc_t *, char **, 7534ac67f02SAnurag S. Maskey uint_t, uint_t); 7544ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 7554ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 7564ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 7574ac67f02SAnurag S. Maskey datalink_id_t, datalink_media_t, uint_t); 758da14cebeSEric Cheng 759d62bc4baSyz147064 /* 760d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 761d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 762d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 763d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 764d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 765d62bc4baSyz147064 */ 766d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 767d62bc4baSyz147064 768d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 769d62bc4baSyz147064 #define AP_DELIMITER '.' 770d62bc4baSyz147064 77125ec3e3dSEric Cheng /* ARGSUSED */ 772d62bc4baSyz147064 static dladm_status_t 773*0dc2366fSVenugopal Iyer check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 774*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 775*0dc2366fSVenugopal Iyer datalink_media_t media) 7760ba2cbe9Sxc151355 { 777d62bc4baSyz147064 int i, j; 7780ba2cbe9Sxc151355 779d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 780d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 78125ec3e3dSEric Cheng if (strcasecmp(prop_val[j], 782d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 7830ba2cbe9Sxc151355 break; 7840ba2cbe9Sxc151355 } 7850ba2cbe9Sxc151355 } 78625ec3e3dSEric Cheng if (i == pdp->pd_noptval) 78725ec3e3dSEric Cheng return (DLADM_STATUS_BADVAL); 7880ba2cbe9Sxc151355 78925ec3e3dSEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 79025ec3e3dSEric Cheng } 79125ec3e3dSEric Cheng return (DLADM_STATUS_OK); 7920ba2cbe9Sxc151355 } 7930ba2cbe9Sxc151355 7940ba2cbe9Sxc151355 static dladm_status_t 7954ac67f02SAnurag S. Maskey i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 7964ac67f02SAnurag S. Maskey datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 7974ac67f02SAnurag S. Maskey uint_t val_cnt, uint_t flags) 7980ba2cbe9Sxc151355 { 7990ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 800d62bc4baSyz147064 val_desc_t *vdp = NULL; 801d62bc4baSyz147064 boolean_t needfree = B_FALSE; 802d62bc4baSyz147064 uint_t cnt, i; 8030ba2cbe9Sxc151355 804d62bc4baSyz147064 if (!(pdp->pd_class & class)) 805d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 8060ba2cbe9Sxc151355 807d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 808d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 809d62bc4baSyz147064 810d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 811d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 812d62bc4baSyz147064 813d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 814d62bc4baSyz147064 return (DLADM_STATUS_OK); 815d62bc4baSyz147064 816d62bc4baSyz147064 if (pdp->pd_set == NULL) 817d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 818d62bc4baSyz147064 819d62bc4baSyz147064 if (prop_val != NULL) { 820*0dc2366fSVenugopal Iyer vdp = calloc(val_cnt, sizeof (val_desc_t)); 821d62bc4baSyz147064 if (vdp == NULL) 822d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 823d62bc4baSyz147064 824d62bc4baSyz147064 if (pdp->pd_check != NULL) { 825da14cebeSEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 8264ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, prop_val, 827*0dc2366fSVenugopal Iyer val_cnt, flags, vdp, media); 828d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 829*0dc2366fSVenugopal Iyer status = check_prop(handle, pdp, linkid, prop_val, 830*0dc2366fSVenugopal Iyer val_cnt, flags, vdp, media); 831d62bc4baSyz147064 } else { 832d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 8330ba2cbe9Sxc151355 } 8340ba2cbe9Sxc151355 835d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 836d62bc4baSyz147064 goto done; 837d62bc4baSyz147064 838d62bc4baSyz147064 cnt = val_cnt; 839d62bc4baSyz147064 } else { 840da14cebeSEric Cheng boolean_t defval = B_FALSE; 841da14cebeSEric Cheng 842d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 843d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 844d62bc4baSyz147064 8453bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 846da14cebeSEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 847da14cebeSEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 848*0dc2366fSVenugopal Iyer if ((vdp = calloc(1, sizeof (val_desc_t))) == NULL) 849d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 8503bc21d0aSAruna Ramakrishna - Sun Microsystems 851da14cebeSEric Cheng if (defval) { 852da14cebeSEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 853da14cebeSEric Cheng sizeof (val_desc_t)); 854da14cebeSEric Cheng } else if (pdp->pd_check != NULL) { 8554ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, 856*0dc2366fSVenugopal Iyer prop_val, cnt, flags, vdp, media); 8573bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 8583bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 8593bc21d0aSAruna Ramakrishna - Sun Microsystems } 8604045d941Ssowmini } else { 8614ac67f02SAnurag S. Maskey status = i_dladm_getset_defval(handle, pdp, linkid, 8624045d941Ssowmini media, flags); 8634045d941Ssowmini return (status); 8644045d941Ssowmini } 865d62bc4baSyz147064 } 8664eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_AFTER_PERM) 8674eaa4710SRishi Srivatsavai status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 8684eaa4710SRishi Srivatsavai DLADM_STATUS_PERMONLY; 8694eaa4710SRishi Srivatsavai else 8704eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 8714eaa4710SRishi Srivatsavai media); 872d62bc4baSyz147064 if (needfree) { 873d62bc4baSyz147064 for (i = 0; i < cnt; i++) 874e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 875d62bc4baSyz147064 } 876d62bc4baSyz147064 done: 877d62bc4baSyz147064 free(vdp); 878d62bc4baSyz147064 return (status); 879d62bc4baSyz147064 } 880d62bc4baSyz147064 881d62bc4baSyz147064 static dladm_status_t 8824ac67f02SAnurag S. Maskey i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8834ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 884d62bc4baSyz147064 { 885d62bc4baSyz147064 int i; 886d62bc4baSyz147064 boolean_t found = B_FALSE; 887d62bc4baSyz147064 datalink_class_t class; 888d62bc4baSyz147064 uint32_t media; 889d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 890d62bc4baSyz147064 8914ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 8924ac67f02SAnurag S. Maskey NULL, 0); 893d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 8940ba2cbe9Sxc151355 return (status); 8950ba2cbe9Sxc151355 896d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 897d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 898d62bc4baSyz147064 dladm_status_t s; 8990ba2cbe9Sxc151355 900d62bc4baSyz147064 if (prop_name != NULL && 901d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 902d62bc4baSyz147064 continue; 903d62bc4baSyz147064 found = B_TRUE; 9044ac67f02SAnurag S. Maskey s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 9054ac67f02SAnurag S. Maskey prop_val, val_cnt, flags); 906d62bc4baSyz147064 907d62bc4baSyz147064 if (prop_name != NULL) { 908d62bc4baSyz147064 status = s; 909d62bc4baSyz147064 break; 910d62bc4baSyz147064 } else { 911d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 912d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 913d62bc4baSyz147064 status = s; 914d62bc4baSyz147064 } 915d62bc4baSyz147064 } 916e7801d59Ssowmini if (!found) { 917e7801d59Ssowmini if (prop_name[0] == '_') { 918e7801d59Ssowmini /* other private properties */ 9193361618bSRishi Srivatsavai status = i_dladm_set_private_prop(handle, linkid, 9203361618bSRishi Srivatsavai prop_name, prop_val, val_cnt, flags); 921e7801d59Ssowmini } else { 9220ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 923e7801d59Ssowmini } 924e7801d59Ssowmini } 9250ba2cbe9Sxc151355 return (status); 9260ba2cbe9Sxc151355 } 9270ba2cbe9Sxc151355 928d62bc4baSyz147064 /* 929d62bc4baSyz147064 * Set/reset link property for specific link 930d62bc4baSyz147064 */ 931d62bc4baSyz147064 dladm_status_t 9324ac67f02SAnurag S. Maskey dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9334ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 9340ba2cbe9Sxc151355 { 935d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 9360ba2cbe9Sxc151355 937d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 938d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 939d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 940d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 941d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 9420ba2cbe9Sxc151355 } 9430ba2cbe9Sxc151355 9443361618bSRishi Srivatsavai /* 9453361618bSRishi Srivatsavai * Check for valid link property against the flags passed 9463361618bSRishi Srivatsavai * and set the link property when active flag is passed. 9473361618bSRishi Srivatsavai */ 9484ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 949d62bc4baSyz147064 val_cnt, flags); 950d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 951d62bc4baSyz147064 return (status); 952d62bc4baSyz147064 953d62bc4baSyz147064 if (flags & DLADM_OPT_PERSIST) { 9544ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 955d62bc4baSyz147064 prop_val, val_cnt); 9564eaa4710SRishi Srivatsavai 9574eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 9584eaa4710SRishi Srivatsavai prop_desc_t *pdp = prop_table; 9594eaa4710SRishi Srivatsavai int i; 9604eaa4710SRishi Srivatsavai 9614eaa4710SRishi Srivatsavai for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 9624eaa4710SRishi Srivatsavai if (!(pdp->pd_flags & PD_AFTER_PERM)) 9634eaa4710SRishi Srivatsavai continue; 9644eaa4710SRishi Srivatsavai if (prop_name != NULL && 9654eaa4710SRishi Srivatsavai strcasecmp(prop_name, pdp->pd_name) != 0) 9664eaa4710SRishi Srivatsavai continue; 9674eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, NULL, 9684eaa4710SRishi Srivatsavai 0, flags, 0); 9694eaa4710SRishi Srivatsavai } 9704eaa4710SRishi Srivatsavai } 971d62bc4baSyz147064 } 972d62bc4baSyz147064 return (status); 973d62bc4baSyz147064 } 974d62bc4baSyz147064 975d62bc4baSyz147064 /* 97662ee1d25SArtem Kachitchkine * Walk all link properties of the given specific link. 97762ee1d25SArtem Kachitchkine * 97862ee1d25SArtem Kachitchkine * Note: this function currently lacks the ability to walk _all_ private 97962ee1d25SArtem Kachitchkine * properties if the link, because there is no kernel interface to 98062ee1d25SArtem Kachitchkine * retrieve all known private property names. Once such an interface 98162ee1d25SArtem Kachitchkine * is added, this function should be fixed accordingly. 982d62bc4baSyz147064 */ 983d62bc4baSyz147064 dladm_status_t 9844ac67f02SAnurag S. Maskey dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 9854ac67f02SAnurag S. Maskey int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 9860ba2cbe9Sxc151355 { 987d62bc4baSyz147064 dladm_status_t status; 988d62bc4baSyz147064 datalink_class_t class; 989d62bc4baSyz147064 uint_t media; 990d62bc4baSyz147064 int i; 9910ba2cbe9Sxc151355 992d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 993d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 9940ba2cbe9Sxc151355 9954ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9964ac67f02SAnurag S. Maskey NULL, 0); 997d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 998d62bc4baSyz147064 return (status); 999d62bc4baSyz147064 100062ee1d25SArtem Kachitchkine /* public */ 1001d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 1002d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 1003d62bc4baSyz147064 continue; 1004d62bc4baSyz147064 1005d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 1006d62bc4baSyz147064 continue; 1007d62bc4baSyz147064 10084ac67f02SAnurag S. Maskey if (func(handle, linkid, prop_table[i].pd_name, arg) == 1009d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 1010d62bc4baSyz147064 break; 1011d62bc4baSyz147064 } 1012d62bc4baSyz147064 } 1013d62bc4baSyz147064 101462ee1d25SArtem Kachitchkine /* private */ 101562ee1d25SArtem Kachitchkine status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 101662ee1d25SArtem Kachitchkine 101762ee1d25SArtem Kachitchkine return (status); 1018d62bc4baSyz147064 } 1019d62bc4baSyz147064 1020d62bc4baSyz147064 /* 1021d62bc4baSyz147064 * Get linkprop of the given specific link. 1022d62bc4baSyz147064 */ 1023d62bc4baSyz147064 dladm_status_t 10244ac67f02SAnurag S. Maskey dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10254ac67f02SAnurag S. Maskey dladm_prop_type_t type, const char *prop_name, char **prop_val, 10264ac67f02SAnurag S. Maskey uint_t *val_cntp) 1027d62bc4baSyz147064 { 1028d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1029d62bc4baSyz147064 datalink_class_t class; 1030d62bc4baSyz147064 uint_t media; 1031d62bc4baSyz147064 prop_desc_t *pdp; 10324045d941Ssowmini uint_t cnt, dld_flags = 0; 1033d62bc4baSyz147064 int i; 1034afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 1035d62bc4baSyz147064 10364045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 1037*0dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_DEFAULT; 1038f0f2c3a5SGirish Moodalbail else if (type == DLADM_PROP_VAL_MODIFIABLE) 1039*0dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_POSSIBLE; 10404045d941Ssowmini 1041d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 1042d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 1043d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1044d62bc4baSyz147064 1045d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 1046d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 1047d62bc4baSyz147064 break; 1048d62bc4baSyz147064 1049e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 1050e7801d59Ssowmini if (prop_name[0] == '_') { 1051e7801d59Ssowmini /* 1052e7801d59Ssowmini * private property. 1053e7801d59Ssowmini */ 105462ee1d25SArtem Kachitchkine if (type == DLADM_PROP_VAL_PERSISTENT) 105562ee1d25SArtem Kachitchkine return (i_dladm_get_linkprop_db(handle, linkid, 105662ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp)); 105762ee1d25SArtem Kachitchkine else 105862ee1d25SArtem Kachitchkine return (i_dladm_get_priv_prop(handle, linkid, 105962ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp, type, 106062ee1d25SArtem Kachitchkine dld_flags)); 1061e7801d59Ssowmini } else { 1062d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 1063e7801d59Ssowmini } 1064e7801d59Ssowmini } 1065d62bc4baSyz147064 1066d62bc4baSyz147064 pdp = &prop_table[i]; 1067d62bc4baSyz147064 10684ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10694ac67f02SAnurag S. Maskey NULL, 0); 1070d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1071d62bc4baSyz147064 return (status); 1072d62bc4baSyz147064 1073d62bc4baSyz147064 if (!(pdp->pd_class & class)) 1074d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1075d62bc4baSyz147064 1076d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 1077d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1078d62bc4baSyz147064 1079d62bc4baSyz147064 switch (type) { 1080d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 10814ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 10824ac67f02SAnurag S. Maskey media, dld_flags, &perm_flags); 1083afdda45fSVasumathi Sundaram - Sun Microsystems break; 1084afdda45fSVasumathi Sundaram - Sun Microsystems 1085afdda45fSVasumathi Sundaram - Sun Microsystems case DLADM_PROP_VAL_PERM: 1086afdda45fSVasumathi Sundaram - Sun Microsystems if (pdp->pd_set == NULL) { 1087afdda45fSVasumathi Sundaram - Sun Microsystems perm_flags = MAC_PROP_PERM_READ; 1088afdda45fSVasumathi Sundaram - Sun Microsystems } else { 10894ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 10904ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 1091afdda45fSVasumathi Sundaram - Sun Microsystems } 1092afdda45fSVasumathi Sundaram - Sun Microsystems 1093afdda45fSVasumathi Sundaram - Sun Microsystems *prop_val[0] = '\0'; 109463a6526dSMichael Lim *val_cntp = 1; 1095da14cebeSEric Cheng if (status == DLADM_STATUS_OK) 1096da14cebeSEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 1097d62bc4baSyz147064 break; 1098d62bc4baSyz147064 1099d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 110013a55820Sar224390 /* 110113a55820Sar224390 * If defaults are not defined for the property, 110213a55820Sar224390 * pd_defval.vd_name should be null. If the driver 110313a55820Sar224390 * has to be contacted for the value, vd_name should 110413a55820Sar224390 * be the empty string (""). Otherwise, dladm will 110513a55820Sar224390 * just print whatever is in the table. 110613a55820Sar224390 */ 1107d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 1108d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1109d62bc4baSyz147064 break; 1110d62bc4baSyz147064 } 11114045d941Ssowmini 11124045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 11134ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 11144ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 11154045d941Ssowmini } else { 1116d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 11174045d941Ssowmini } 1118d62bc4baSyz147064 *val_cntp = 1; 1119d62bc4baSyz147064 break; 1120d62bc4baSyz147064 1121d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 1122d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 11234ac67f02SAnurag S. Maskey status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 1124afdda45fSVasumathi Sundaram - Sun Microsystems val_cntp, media, dld_flags, &perm_flags); 1125d62bc4baSyz147064 break; 1126d62bc4baSyz147064 } 1127d62bc4baSyz147064 cnt = pdp->pd_noptval; 1128d62bc4baSyz147064 if (cnt == 0) { 1129d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1130d62bc4baSyz147064 } else if (cnt > *val_cntp) { 1131d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1132d62bc4baSyz147064 } else { 1133d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 1134d62bc4baSyz147064 (void) strcpy(prop_val[i], 1135d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 1136d62bc4baSyz147064 } 1137d62bc4baSyz147064 *val_cntp = cnt; 1138d62bc4baSyz147064 } 1139d62bc4baSyz147064 break; 1140d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 1141d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 1142d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 11434ac67f02SAnurag S. Maskey status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 1144d62bc4baSyz147064 prop_val, val_cntp); 1145d62bc4baSyz147064 break; 1146d62bc4baSyz147064 default: 1147d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 1148d62bc4baSyz147064 break; 1149d62bc4baSyz147064 } 1150d62bc4baSyz147064 1151d62bc4baSyz147064 return (status); 1152d62bc4baSyz147064 } 1153d62bc4baSyz147064 11544eaa4710SRishi Srivatsavai /* 11554eaa4710SRishi Srivatsavai * Get linkprop of the given specific link and run any possible conversion 11564eaa4710SRishi Srivatsavai * of the values using the check function for the property. Fails if the 11574eaa4710SRishi Srivatsavai * check function doesn't succeed for the property value. 11584eaa4710SRishi Srivatsavai */ 11594eaa4710SRishi Srivatsavai dladm_status_t 11604eaa4710SRishi Srivatsavai dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 11614eaa4710SRishi Srivatsavai dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 11624eaa4710SRishi Srivatsavai uint_t *val_cntp) 11634eaa4710SRishi Srivatsavai { 11644eaa4710SRishi Srivatsavai dladm_status_t status; 11654eaa4710SRishi Srivatsavai datalink_class_t class; 11664eaa4710SRishi Srivatsavai uint_t media; 11674eaa4710SRishi Srivatsavai prop_desc_t *pdp; 11684eaa4710SRishi Srivatsavai uint_t dld_flags; 11694eaa4710SRishi Srivatsavai int valc, i; 11704eaa4710SRishi Srivatsavai char **prop_val; 11714eaa4710SRishi Srivatsavai uint_t perm_flags; 11724eaa4710SRishi Srivatsavai 11734eaa4710SRishi Srivatsavai if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 11744eaa4710SRishi Srivatsavai ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 11754eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 11764eaa4710SRishi Srivatsavai 11774eaa4710SRishi Srivatsavai for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 11784eaa4710SRishi Srivatsavai if (strcasecmp(prop_name, pdp->pd_name) == 0) 11794eaa4710SRishi Srivatsavai break; 11804eaa4710SRishi Srivatsavai 11814eaa4710SRishi Srivatsavai if (pdp == prop_table + DLADM_MAX_PROPS) 11824eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 11834eaa4710SRishi Srivatsavai 11844eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_CHECK_ALLOC) 11854eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 11864eaa4710SRishi Srivatsavai 11874eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 11884eaa4710SRishi Srivatsavai NULL, 0); 11894eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 11904eaa4710SRishi Srivatsavai return (status); 11914eaa4710SRishi Srivatsavai 11924eaa4710SRishi Srivatsavai if (!(pdp->pd_class & class)) 11934eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 11944eaa4710SRishi Srivatsavai 11954eaa4710SRishi Srivatsavai if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 11964eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 11974eaa4710SRishi Srivatsavai 11984eaa4710SRishi Srivatsavai prop_val = malloc(*val_cntp * sizeof (*prop_val) + 11994eaa4710SRishi Srivatsavai *val_cntp * DLADM_PROP_VAL_MAX); 12004eaa4710SRishi Srivatsavai if (prop_val == NULL) 12014eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOMEM); 12024eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 12034eaa4710SRishi Srivatsavai prop_val[valc] = (char *)(prop_val + *val_cntp) + 12044eaa4710SRishi Srivatsavai valc * DLADM_PROP_VAL_MAX; 12054eaa4710SRishi Srivatsavai 1206*0dc2366fSVenugopal Iyer dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 12074eaa4710SRishi Srivatsavai 12084eaa4710SRishi Srivatsavai switch (type) { 12094eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_CURRENT: 12104eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12114eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 12124eaa4710SRishi Srivatsavai break; 12134eaa4710SRishi Srivatsavai 12144eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_DEFAULT: 12154eaa4710SRishi Srivatsavai /* 12164eaa4710SRishi Srivatsavai * If defaults are not defined for the property, 12174eaa4710SRishi Srivatsavai * pd_defval.vd_name should be null. If the driver 12184eaa4710SRishi Srivatsavai * has to be contacted for the value, vd_name should 12194eaa4710SRishi Srivatsavai * be the empty string (""). Otherwise, dladm will 12204eaa4710SRishi Srivatsavai * just print whatever is in the table. 12214eaa4710SRishi Srivatsavai */ 12224eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name == NULL) { 12234eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOTSUP; 12244eaa4710SRishi Srivatsavai break; 12254eaa4710SRishi Srivatsavai } 12264eaa4710SRishi Srivatsavai 12274eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name[0] != '\0') { 12284eaa4710SRishi Srivatsavai *val_cntp = 1; 12294eaa4710SRishi Srivatsavai *ret_val = pdp->pd_defval.vd_val; 12304eaa4710SRishi Srivatsavai free(prop_val); 12314eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 12324eaa4710SRishi Srivatsavai } 12334eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12344eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 12354eaa4710SRishi Srivatsavai break; 12364eaa4710SRishi Srivatsavai 12374eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_PERSISTENT: 12384eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_TEMPONLY) 12394eaa4710SRishi Srivatsavai status = DLADM_STATUS_TEMPONLY; 12404eaa4710SRishi Srivatsavai else 12414eaa4710SRishi Srivatsavai status = i_dladm_get_linkprop_db(handle, linkid, 12424eaa4710SRishi Srivatsavai prop_name, prop_val, val_cntp); 12434eaa4710SRishi Srivatsavai break; 12444eaa4710SRishi Srivatsavai 12454eaa4710SRishi Srivatsavai default: 12464eaa4710SRishi Srivatsavai status = DLADM_STATUS_BADARG; 12474eaa4710SRishi Srivatsavai break; 12484eaa4710SRishi Srivatsavai } 12494eaa4710SRishi Srivatsavai 12504eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 12514eaa4710SRishi Srivatsavai if (pdp->pd_check != NULL) { 12524eaa4710SRishi Srivatsavai val_desc_t *vdp; 12534eaa4710SRishi Srivatsavai 12544eaa4710SRishi Srivatsavai vdp = malloc(sizeof (val_desc_t) * *val_cntp); 12554eaa4710SRishi Srivatsavai if (vdp == NULL) 12564eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOMEM; 12574eaa4710SRishi Srivatsavai else 12584eaa4710SRishi Srivatsavai status = pdp->pd_check(handle, pdp, linkid, 1259*0dc2366fSVenugopal Iyer prop_val, *val_cntp, 0, vdp, media); 12604eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 12614eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 12624eaa4710SRishi Srivatsavai ret_val[valc] = vdp[valc].vd_val; 12634eaa4710SRishi Srivatsavai } 12644eaa4710SRishi Srivatsavai free(vdp); 12654eaa4710SRishi Srivatsavai } else { 12664eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) { 12674eaa4710SRishi Srivatsavai for (i = 0; i < pdp->pd_noptval; i++) { 12684eaa4710SRishi Srivatsavai if (strcmp(pdp->pd_optval[i].vd_name, 12694eaa4710SRishi Srivatsavai prop_val[valc]) == 0) { 12704eaa4710SRishi Srivatsavai ret_val[valc] = 12714eaa4710SRishi Srivatsavai pdp->pd_optval[i].vd_val; 12724eaa4710SRishi Srivatsavai break; 12734eaa4710SRishi Srivatsavai } 12744eaa4710SRishi Srivatsavai } 12754eaa4710SRishi Srivatsavai if (i == pdp->pd_noptval) { 12764eaa4710SRishi Srivatsavai status = DLADM_STATUS_FAILED; 12774eaa4710SRishi Srivatsavai break; 12784eaa4710SRishi Srivatsavai } 12794eaa4710SRishi Srivatsavai } 12804eaa4710SRishi Srivatsavai } 12814eaa4710SRishi Srivatsavai } 12824eaa4710SRishi Srivatsavai 12834eaa4710SRishi Srivatsavai free(prop_val); 12844eaa4710SRishi Srivatsavai 12854eaa4710SRishi Srivatsavai return (status); 12864eaa4710SRishi Srivatsavai } 12874eaa4710SRishi Srivatsavai 1288d62bc4baSyz147064 /*ARGSUSED*/ 1289d62bc4baSyz147064 static int 12904ac67f02SAnurag S. Maskey i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 12914ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 1292d62bc4baSyz147064 { 1293d62bc4baSyz147064 char *buf, **propvals; 1294d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 1295*0dc2366fSVenugopal Iyer dladm_status_t status; 1296*0dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla = arg; 1297d62bc4baSyz147064 1298d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 1299d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 1300d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1301d62bc4baSyz147064 } 1302d62bc4baSyz147064 1303d62bc4baSyz147064 propvals = (char **)(void *)buf; 1304d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 1305d62bc4baSyz147064 propvals[i] = buf + 1306d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 1307d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 1308d62bc4baSyz147064 } 1309d62bc4baSyz147064 13104ac67f02SAnurag S. Maskey if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 13114ac67f02SAnurag S. Maskey prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 1312d62bc4baSyz147064 goto done; 1313d62bc4baSyz147064 } 1314d62bc4baSyz147064 13158d4cf8d8S status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 1316*0dc2366fSVenugopal Iyer valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 1317*0dc2366fSVenugopal Iyer 13188d4cf8d8S if (status != DLADM_STATUS_OK) 1319*0dc2366fSVenugopal Iyer dla->dla_status = status; 1320d62bc4baSyz147064 1321d62bc4baSyz147064 done: 1322d62bc4baSyz147064 if (buf != NULL) 1323d62bc4baSyz147064 free(buf); 1324d62bc4baSyz147064 1325d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1326d62bc4baSyz147064 } 1327d62bc4baSyz147064 1328d62bc4baSyz147064 /*ARGSUSED*/ 1329d62bc4baSyz147064 static int 13304ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 1331d62bc4baSyz147064 { 1332da14cebeSEric Cheng datalink_class_t class; 1333da14cebeSEric Cheng dladm_status_t status; 1334da14cebeSEric Cheng 13354ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 13364ac67f02SAnurag S. Maskey NULL, 0); 1337da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1338da14cebeSEric Cheng return (DLADM_WALK_TERMINATE); 1339da14cebeSEric Cheng 1340da14cebeSEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 13414ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, B_TRUE); 1342da14cebeSEric Cheng 1343d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 13440ba2cbe9Sxc151355 } 13450ba2cbe9Sxc151355 13460ba2cbe9Sxc151355 dladm_status_t 13474ac67f02SAnurag S. Maskey dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 13484ac67f02SAnurag S. Maskey boolean_t any_media) 13490ba2cbe9Sxc151355 { 13508d4cf8d8S dladm_status_t status = DLADM_STATUS_OK; 135130890389Sartem datalink_media_t dmedia; 135230890389Sartem uint32_t media; 1353*0dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla; 135430890389Sartem 135530890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 135630890389Sartem 1357*0dc2366fSVenugopal Iyer dla = malloc(sizeof (dladm_linkprop_args_t)); 1358*0dc2366fSVenugopal Iyer if (dla == NULL) 1359*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 1360*0dc2366fSVenugopal Iyer dla->dla_flags = DLADM_OPT_BOOT; 1361*0dc2366fSVenugopal Iyer dla->dla_status = DLADM_STATUS_OK; 1362*0dc2366fSVenugopal Iyer 1363d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 13644ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 13654ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 13664ac67f02SAnurag S. Maskey } else if (any_media || 13674ac67f02SAnurag S. Maskey ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 13684ac67f02SAnurag S. Maskey 0) == DLADM_STATUS_OK) && 136930890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 1370*0dc2366fSVenugopal Iyer (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 13714ac67f02SAnurag S. Maskey i_dladm_init_one_prop); 1372*0dc2366fSVenugopal Iyer status = dla->dla_status; 1373d62bc4baSyz147064 } 1374*0dc2366fSVenugopal Iyer free(dla); 13758d4cf8d8S return (status); 13760ba2cbe9Sxc151355 } 1377f4b3ec61Sdh155122 1378e7801d59Ssowmini /* ARGSUSED */ 1379f4b3ec61Sdh155122 static dladm_status_t 1380*0dc2366fSVenugopal Iyer get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1381da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1382da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1383f4b3ec61Sdh155122 { 1384d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 1385d62bc4baSyz147064 zoneid_t zid; 1386d62bc4baSyz147064 dladm_status_t status; 1387f4b3ec61Sdh155122 13884045d941Ssowmini if (flags != 0) 13894045d941Ssowmini return (DLADM_STATUS_NOTSUP); 13904045d941Ssowmini 1391*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1392*0dc2366fSVenugopal Iyer perm_flags, &zid, sizeof (zid)); 1393d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1394d62bc4baSyz147064 return (status); 1395d62bc4baSyz147064 1396d62bc4baSyz147064 *val_cnt = 1; 1397d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 1398afdda45fSVasumathi Sundaram - Sun Microsystems if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 1399f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1400afdda45fSVasumathi Sundaram - Sun Microsystems } 1401f4b3ec61Sdh155122 1402d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 140347a01978Sbw } else { 1404d62bc4baSyz147064 *prop_val[0] = '\0'; 140547a01978Sbw } 1406f4b3ec61Sdh155122 1407f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1408f4b3ec61Sdh155122 } 1409f4b3ec61Sdh155122 1410f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 1411f4b3ec61Sdh155122 1412f4b3ec61Sdh155122 static int 1413f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 1414f4b3ec61Sdh155122 { 1415f4b3ec61Sdh155122 char root[MAXPATHLEN]; 1416f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 1417f4b3ec61Sdh155122 void *dlhandle; 1418f4b3ec61Sdh155122 void *sym; 1419f4b3ec61Sdh155122 int ret; 1420f4b3ec61Sdh155122 1421f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 1422f4b3ec61Sdh155122 return (-1); 1423f4b3ec61Sdh155122 1424f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 1425f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1426f4b3ec61Sdh155122 return (-1); 1427f4b3ec61Sdh155122 } 1428f4b3ec61Sdh155122 1429f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 1430f4b3ec61Sdh155122 1431f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 1432f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 1433f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1434f4b3ec61Sdh155122 return (ret); 1435f4b3ec61Sdh155122 } 1436f4b3ec61Sdh155122 1437f4b3ec61Sdh155122 static dladm_status_t 14384ac67f02SAnurag S. Maskey i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 14394ac67f02SAnurag S. Maskey datalink_id_t linkid, boolean_t add) 1440f4b3ec61Sdh155122 { 1441f4b3ec61Sdh155122 char path[MAXPATHLEN]; 1442d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1443f4b3ec61Sdh155122 di_prof_t prof = NULL; 1444f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 1445f4b3ec61Sdh155122 dladm_status_t status; 1446d62bc4baSyz147064 int ret; 1447f4b3ec61Sdh155122 1448f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 1449f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1450f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 1451f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1452f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 1453f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1454f4b3ec61Sdh155122 14554ac67f02SAnurag S. Maskey status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 1456f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1457d62bc4baSyz147064 goto cleanup; 1458f4b3ec61Sdh155122 1459d62bc4baSyz147064 if (add) 1460d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 1461d62bc4baSyz147064 else 1462d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 1463f4b3ec61Sdh155122 1464d62bc4baSyz147064 if (ret != 0) { 1465d62bc4baSyz147064 status = dladm_errno2status(errno); 1466d62bc4baSyz147064 goto cleanup; 1467f4b3ec61Sdh155122 } 1468f4b3ec61Sdh155122 1469d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 1470d62bc4baSyz147064 status = dladm_errno2status(errno); 1471d62bc4baSyz147064 cleanup: 1472d62bc4baSyz147064 if (prof) 1473d62bc4baSyz147064 di_prof_fini(prof); 1474d62bc4baSyz147064 1475d62bc4baSyz147064 return (status); 1476f4b3ec61Sdh155122 } 1477f4b3ec61Sdh155122 1478e7801d59Ssowmini /* ARGSUSED */ 1479f4b3ec61Sdh155122 static dladm_status_t 1480*0dc2366fSVenugopal Iyer set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14814ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1482f4b3ec61Sdh155122 { 14833bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1484f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 14853bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1486f4b3ec61Sdh155122 1487f4b3ec61Sdh155122 if (val_cnt != 1) 1488f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1489f4b3ec61Sdh155122 14903bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 14913bc21d0aSAruna Ramakrishna - Sun Microsystems 1492*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 1493*0dc2366fSVenugopal Iyer NULL, &zid_old, sizeof (zid_old)); 1494f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1495f4b3ec61Sdh155122 return (status); 1496f4b3ec61Sdh155122 14973bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 14983bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 14992b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 15002b24ab6bSSebastien Roy 1501*0dc2366fSVenugopal Iyer if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 15022b24ab6bSSebastien Roy flags, media)) != DLADM_STATUS_OK) 15033bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 15043bc21d0aSAruna Ramakrishna - Sun Microsystems 1505d62bc4baSyz147064 /* 15062b24ab6bSSebastien Roy * It is okay to fail to update the /dev entry (some vanity-named 15072b24ab6bSSebastien Roy * links do not have a /dev entry). 1508d62bc4baSyz147064 */ 1509d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 15104ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_old, linkid, 15114ac67f02SAnurag S. Maskey B_FALSE); 1512d62bc4baSyz147064 } 15132b24ab6bSSebastien Roy if (zid_new != GLOBAL_ZONEID) 15144ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 1515f4b3ec61Sdh155122 1516f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1517f4b3ec61Sdh155122 } 1518f4b3ec61Sdh155122 1519f4b3ec61Sdh155122 /* ARGSUSED */ 1520f4b3ec61Sdh155122 static dladm_status_t 1521*0dc2366fSVenugopal Iyer check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1522*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1523*0dc2366fSVenugopal Iyer datalink_media_t media) 1524f4b3ec61Sdh155122 { 15253bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 15263bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 15273bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 15283bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1529f4b3ec61Sdh155122 1530f4b3ec61Sdh155122 if (val_cnt != 1) 1531f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1532f4b3ec61Sdh155122 15333bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 15343bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 15353bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1536f4b3ec61Sdh155122 1537da14cebeSEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 15383bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 15393bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 15403bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 15413bc21d0aSAruna Ramakrishna - Sun Microsystems } 15423bc21d0aSAruna Ramakrishna - Sun Microsystems 15433bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1544f4b3ec61Sdh155122 ushort_t flags; 1545f4b3ec61Sdh155122 15463bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1547f4b3ec61Sdh155122 sizeof (flags)) < 0) { 15483bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 15493bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1550f4b3ec61Sdh155122 } 1551f4b3ec61Sdh155122 1552f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 15533bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 15543bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1555f4b3ec61Sdh155122 } 1556f4b3ec61Sdh155122 } 1557f4b3ec61Sdh155122 15583bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15593bc21d0aSAruna Ramakrishna - Sun Microsystems 15603bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 15612b24ab6bSSebastien Roy dzp->diz_linkid = linkid; 15623bc21d0aSAruna Ramakrishna - Sun Microsystems 15633bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1564f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 15653bc21d0aSAruna Ramakrishna - Sun Microsystems done: 15663bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 15673bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1568f4b3ec61Sdh155122 } 1569f4b3ec61Sdh155122 1570e7801d59Ssowmini /* ARGSUSED */ 1571f4b3ec61Sdh155122 static dladm_status_t 1572*0dc2366fSVenugopal Iyer get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1573da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1574da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1575da14cebeSEric Cheng { 1576da14cebeSEric Cheng mac_resource_props_t mrp; 1577da14cebeSEric Cheng dladm_status_t status; 1578da14cebeSEric Cheng 1579*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 1580*0dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 1581*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1582da14cebeSEric Cheng return (status); 1583da14cebeSEric Cheng 1584da14cebeSEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 1585*0dc2366fSVenugopal Iyer *val_cnt = 0; 1586*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1587da14cebeSEric Cheng } 1588*0dc2366fSVenugopal Iyer 1589*0dc2366fSVenugopal Iyer (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 1590da14cebeSEric Cheng *val_cnt = 1; 1591da14cebeSEric Cheng return (DLADM_STATUS_OK); 1592da14cebeSEric Cheng } 1593da14cebeSEric Cheng 1594da14cebeSEric Cheng /* ARGSUSED */ 1595da14cebeSEric Cheng static dladm_status_t 1596*0dc2366fSVenugopal Iyer check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1597*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1598*0dc2366fSVenugopal Iyer datalink_media_t media) 1599da14cebeSEric Cheng { 1600da14cebeSEric Cheng uint64_t *maxbw; 1601da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1602da14cebeSEric Cheng 1603da14cebeSEric Cheng if (val_cnt != 1) 1604da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1605da14cebeSEric Cheng 1606da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 1607da14cebeSEric Cheng if (maxbw == NULL) 1608da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1609da14cebeSEric Cheng 1610da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 1611da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1612da14cebeSEric Cheng free(maxbw); 1613da14cebeSEric Cheng return (status); 1614da14cebeSEric Cheng } 1615da14cebeSEric Cheng 1616da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 1617da14cebeSEric Cheng free(maxbw); 1618da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 1619da14cebeSEric Cheng } 1620da14cebeSEric Cheng 1621da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 1622da14cebeSEric Cheng return (DLADM_STATUS_OK); 1623da14cebeSEric Cheng } 1624da14cebeSEric Cheng 1625da14cebeSEric Cheng /* ARGSUSED */ 1626da14cebeSEric Cheng dladm_status_t 1627*0dc2366fSVenugopal Iyer extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 1628da14cebeSEric Cheng { 162925ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1630da14cebeSEric Cheng 1631*0dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 1632*0dc2366fSVenugopal Iyer mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 1633*0dc2366fSVenugopal Iyer } else { 1634da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 1635*0dc2366fSVenugopal Iyer } 1636da14cebeSEric Cheng mrp->mrp_mask |= MRP_MAXBW; 1637da14cebeSEric Cheng 1638da14cebeSEric Cheng return (DLADM_STATUS_OK); 1639da14cebeSEric Cheng } 1640da14cebeSEric Cheng 1641da14cebeSEric Cheng /* ARGSUSED */ 1642da14cebeSEric Cheng static dladm_status_t 1643*0dc2366fSVenugopal Iyer get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1644da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1645da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1646da14cebeSEric Cheng { 1647*0dc2366fSVenugopal Iyer dladm_status_t status; 1648da14cebeSEric Cheng mac_resource_props_t mrp; 1649da14cebeSEric Cheng int i; 1650da14cebeSEric Cheng uint32_t ncpus; 1651da14cebeSEric Cheng 1652*0dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 1653*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 1654*0dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 1655*0dc2366fSVenugopal Iyer sizeof (mrp)); 1656*0dc2366fSVenugopal Iyer } else { 1657*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 1658*0dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 1659*0dc2366fSVenugopal Iyer } 1660*0dc2366fSVenugopal Iyer 1661*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1662da14cebeSEric Cheng return (status); 1663da14cebeSEric Cheng 1664da14cebeSEric Cheng ncpus = mrp.mrp_ncpus; 1665da14cebeSEric Cheng if (ncpus > *val_cnt) 1666da14cebeSEric Cheng return (DLADM_STATUS_TOOSMALL); 1667da14cebeSEric Cheng 1668da14cebeSEric Cheng if (ncpus == 0) { 1669*0dc2366fSVenugopal Iyer *val_cnt = 0; 1670da14cebeSEric Cheng return (DLADM_STATUS_OK); 1671da14cebeSEric Cheng } 1672da14cebeSEric Cheng 1673da14cebeSEric Cheng *val_cnt = ncpus; 1674da14cebeSEric Cheng for (i = 0; i < ncpus; i++) { 1675da14cebeSEric Cheng (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 1676da14cebeSEric Cheng "%u", mrp.mrp_cpu[i]); 1677da14cebeSEric Cheng } 1678da14cebeSEric Cheng return (DLADM_STATUS_OK); 1679da14cebeSEric Cheng } 1680da14cebeSEric Cheng 1681da14cebeSEric Cheng /* ARGSUSED */ 1682da14cebeSEric Cheng static dladm_status_t 1683*0dc2366fSVenugopal Iyer check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1684*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1685*0dc2366fSVenugopal Iyer datalink_media_t media) 1686da14cebeSEric Cheng { 1687da14cebeSEric Cheng uint32_t cpuid; 1688da14cebeSEric Cheng int i, j, rc; 1689*0dc2366fSVenugopal Iyer char *endp; 1690da14cebeSEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 1691*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 1692*0dc2366fSVenugopal Iyer dladm_status_t status; 1693*0dc2366fSVenugopal Iyer uint_t perm_flags; 1694da14cebeSEric Cheng 1695*0dc2366fSVenugopal Iyer /* Get the current pool property */ 1696*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 1697*0dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 1698*0dc2366fSVenugopal Iyer 1699*0dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 1700*0dc2366fSVenugopal Iyer /* Can't set cpus if a pool is set */ 1701*0dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) != 0) 1702*0dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 1703*0dc2366fSVenugopal Iyer } 1704*0dc2366fSVenugopal Iyer 1705*0dc2366fSVenugopal Iyer bzero(&mrp, sizeof (mac_resource_props_t)); 1706da14cebeSEric Cheng 1707da14cebeSEric Cheng for (i = 0; i < val_cnt; i++) { 1708da14cebeSEric Cheng errno = 0; 1709*0dc2366fSVenugopal Iyer cpuid = strtol(prop_val[i], &endp, 10); 1710*0dc2366fSVenugopal Iyer if (errno != 0 || *endp != '\0') 1711*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1712*0dc2366fSVenugopal Iyer 1713*0dc2366fSVenugopal Iyer if (cpuid >= nproc) 1714da14cebeSEric Cheng return (DLADM_STATUS_CPUMAX); 1715*0dc2366fSVenugopal Iyer 1716da14cebeSEric Cheng rc = p_online(cpuid, P_STATUS); 1717*0dc2366fSVenugopal Iyer if (rc < 1) 1718da14cebeSEric Cheng return (DLADM_STATUS_CPUERR); 1719*0dc2366fSVenugopal Iyer 1720*0dc2366fSVenugopal Iyer if (rc != P_ONLINE) 1721da14cebeSEric Cheng return (DLADM_STATUS_CPUNOTONLINE); 1722*0dc2366fSVenugopal Iyer 1723*0dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)cpuid; 1724da14cebeSEric Cheng } 1725da14cebeSEric Cheng 1726da14cebeSEric Cheng /* Check for duplicates */ 1727da14cebeSEric Cheng for (i = 0; i < val_cnt; i++) { 1728da14cebeSEric Cheng for (j = 0; j < val_cnt; j++) { 1729*0dc2366fSVenugopal Iyer if (i != j && vdp[i].vd_val == vdp[j].vd_val) 1730*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1731da14cebeSEric Cheng } 1732da14cebeSEric Cheng } 1733*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1734da14cebeSEric Cheng } 1735*0dc2366fSVenugopal Iyer 1736*0dc2366fSVenugopal Iyer /* ARGSUSED */ 1737*0dc2366fSVenugopal Iyer dladm_status_t 1738*0dc2366fSVenugopal Iyer extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 1739*0dc2366fSVenugopal Iyer { 1740*0dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 1741*0dc2366fSVenugopal Iyer int i; 1742*0dc2366fSVenugopal Iyer 1743*0dc2366fSVenugopal Iyer if (vdp[0].vd_val == RESET_VAL) { 1744*0dc2366fSVenugopal Iyer bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 1745*0dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_CPUS; 1746*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1747*0dc2366fSVenugopal Iyer } 1748*0dc2366fSVenugopal Iyer 1749*0dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) 1750*0dc2366fSVenugopal Iyer mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 1751*0dc2366fSVenugopal Iyer 1752*0dc2366fSVenugopal Iyer mrp->mrp_ncpus = cnt; 1753*0dc2366fSVenugopal Iyer mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 1754*0dc2366fSVenugopal Iyer mrp->mrp_fanout_mode = MCM_CPUS; 1755*0dc2366fSVenugopal Iyer mrp->mrp_rx_intr_cpu = -1; 1756*0dc2366fSVenugopal Iyer 1757*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1758*0dc2366fSVenugopal Iyer } 1759*0dc2366fSVenugopal Iyer 1760*0dc2366fSVenugopal Iyer /* 1761*0dc2366fSVenugopal Iyer * Get the pool datalink property from the kernel. This is used 1762*0dc2366fSVenugopal Iyer * for both the user specified pool and effective pool properties. 1763*0dc2366fSVenugopal Iyer */ 1764*0dc2366fSVenugopal Iyer /* ARGSUSED */ 1765*0dc2366fSVenugopal Iyer static dladm_status_t 1766*0dc2366fSVenugopal Iyer get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1767*0dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 1768*0dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 1769*0dc2366fSVenugopal Iyer { 1770*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 1771*0dc2366fSVenugopal Iyer dladm_status_t status; 1772*0dc2366fSVenugopal Iyer 1773*0dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "pool-effective") == 0) { 1774*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 1775*0dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 1776*0dc2366fSVenugopal Iyer sizeof (mrp)); 1777*0dc2366fSVenugopal Iyer } else { 1778*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 1779*0dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 1780*0dc2366fSVenugopal Iyer } 1781*0dc2366fSVenugopal Iyer 1782*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1783*0dc2366fSVenugopal Iyer return (status); 1784*0dc2366fSVenugopal Iyer 1785*0dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) == 0) { 1786*0dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 1787*0dc2366fSVenugopal Iyer } else { 1788*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 1789*0dc2366fSVenugopal Iyer "%s", mrp.mrp_pool); 1790*0dc2366fSVenugopal Iyer } 1791*0dc2366fSVenugopal Iyer *val_cnt = 1; 1792*0dc2366fSVenugopal Iyer 1793*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1794*0dc2366fSVenugopal Iyer } 1795*0dc2366fSVenugopal Iyer 1796*0dc2366fSVenugopal Iyer /* ARGSUSED */ 1797*0dc2366fSVenugopal Iyer static dladm_status_t 1798*0dc2366fSVenugopal Iyer check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1799*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 1800*0dc2366fSVenugopal Iyer datalink_media_t media) 1801*0dc2366fSVenugopal Iyer { 1802*0dc2366fSVenugopal Iyer pool_conf_t *poolconf; 1803*0dc2366fSVenugopal Iyer pool_t *pool; 1804*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 1805*0dc2366fSVenugopal Iyer dladm_status_t status; 1806*0dc2366fSVenugopal Iyer uint_t perm_flags; 1807*0dc2366fSVenugopal Iyer char *poolname; 1808*0dc2366fSVenugopal Iyer 1809*0dc2366fSVenugopal Iyer /* Get the current cpus property */ 1810*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 1811*0dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 1812*0dc2366fSVenugopal Iyer 1813*0dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 1814*0dc2366fSVenugopal Iyer /* Can't set pool if cpus are set */ 1815*0dc2366fSVenugopal Iyer if (mrp.mrp_ncpus != 0) 1816*0dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 1817*0dc2366fSVenugopal Iyer } 1818*0dc2366fSVenugopal Iyer 1819*0dc2366fSVenugopal Iyer poolname = malloc(sizeof (mrp.mrp_pool)); 1820*0dc2366fSVenugopal Iyer if (poolname == NULL) 1821*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 1822*0dc2366fSVenugopal Iyer 1823*0dc2366fSVenugopal Iyer /* Check for pool's availability if not booting */ 1824*0dc2366fSVenugopal Iyer if ((flags & DLADM_OPT_BOOT) == 0) { 1825*0dc2366fSVenugopal Iyer 1826*0dc2366fSVenugopal Iyer /* Allocate and open pool configuration */ 1827*0dc2366fSVenugopal Iyer if ((poolconf = pool_conf_alloc()) == NULL) 1828*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1829*0dc2366fSVenugopal Iyer 1830*0dc2366fSVenugopal Iyer if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 1831*0dc2366fSVenugopal Iyer != PO_SUCCESS) { 1832*0dc2366fSVenugopal Iyer pool_conf_free(poolconf); 1833*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1834*0dc2366fSVenugopal Iyer } 1835*0dc2366fSVenugopal Iyer 1836*0dc2366fSVenugopal Iyer /* Look for pool name */ 1837*0dc2366fSVenugopal Iyer if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 1838*0dc2366fSVenugopal Iyer pool_conf_free(poolconf); 1839*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1840*0dc2366fSVenugopal Iyer } 1841*0dc2366fSVenugopal Iyer 1842*0dc2366fSVenugopal Iyer pool_conf_free(poolconf); 1843*0dc2366fSVenugopal Iyer free(pool); 1844*0dc2366fSVenugopal Iyer } 1845*0dc2366fSVenugopal Iyer 1846*0dc2366fSVenugopal Iyer (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 1847*0dc2366fSVenugopal Iyer vdp->vd_val = (uintptr_t)poolname; 1848da14cebeSEric Cheng 1849da14cebeSEric Cheng return (DLADM_STATUS_OK); 1850da14cebeSEric Cheng } 1851da14cebeSEric Cheng 1852da14cebeSEric Cheng /* ARGSUSED */ 1853da14cebeSEric Cheng dladm_status_t 1854*0dc2366fSVenugopal Iyer extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 1855da14cebeSEric Cheng { 1856*0dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1857da14cebeSEric Cheng 1858*0dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 1859*0dc2366fSVenugopal Iyer bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 1860*0dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 1861*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1862da14cebeSEric Cheng } 1863*0dc2366fSVenugopal Iyer 1864*0dc2366fSVenugopal Iyer (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 1865*0dc2366fSVenugopal Iyer sizeof (mrp->mrp_pool)); 1866*0dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 1867*0dc2366fSVenugopal Iyer /* 1868*0dc2366fSVenugopal Iyer * Use MCM_CPUS since the fanout count is not user specified 1869*0dc2366fSVenugopal Iyer * and will be determined by the cpu list generated from the 1870*0dc2366fSVenugopal Iyer * pool. 1871*0dc2366fSVenugopal Iyer */ 1872da14cebeSEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 1873da14cebeSEric Cheng 1874da14cebeSEric Cheng return (DLADM_STATUS_OK); 1875da14cebeSEric Cheng } 1876da14cebeSEric Cheng 1877da14cebeSEric Cheng /* ARGSUSED */ 1878da14cebeSEric Cheng static dladm_status_t 1879*0dc2366fSVenugopal Iyer get_priority(dladm_handle_t handle, prop_desc_t *pdp, 188062ee1d25SArtem Kachitchkine datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 188162ee1d25SArtem Kachitchkine datalink_media_t media, uint_t flags, uint_t *perm_flags) 1882da14cebeSEric Cheng { 1883da14cebeSEric Cheng mac_resource_props_t mrp; 1884da14cebeSEric Cheng mac_priority_level_t pri; 1885da14cebeSEric Cheng dladm_status_t status; 1886da14cebeSEric Cheng 1887*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 1888*0dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 1889*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1890da14cebeSEric Cheng return (status); 1891da14cebeSEric Cheng 1892da14cebeSEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 1893da14cebeSEric Cheng mrp.mrp_priority; 1894da14cebeSEric Cheng 1895da14cebeSEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 1896da14cebeSEric Cheng *val_cnt = 1; 1897da14cebeSEric Cheng return (DLADM_STATUS_OK); 1898da14cebeSEric Cheng } 1899da14cebeSEric Cheng 1900da14cebeSEric Cheng /* ARGSUSED */ 1901da14cebeSEric Cheng dladm_status_t 1902*0dc2366fSVenugopal Iyer extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 1903da14cebeSEric Cheng { 190425ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1905da14cebeSEric Cheng 1906*0dc2366fSVenugopal Iyer if (cnt != 1) 1907*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1908*0dc2366fSVenugopal Iyer 1909*0dc2366fSVenugopal Iyer mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 1910da14cebeSEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 1911da14cebeSEric Cheng 1912da14cebeSEric Cheng return (DLADM_STATUS_OK); 1913da14cebeSEric Cheng } 1914da14cebeSEric Cheng 1915*0dc2366fSVenugopal Iyer /* 1916*0dc2366fSVenugopal Iyer * Determines the size of the structure that needs to be sent to drivers 1917*0dc2366fSVenugopal Iyer * for retrieving the property range values. 1918*0dc2366fSVenugopal Iyer */ 1919*0dc2366fSVenugopal Iyer static int 1920*0dc2366fSVenugopal Iyer i_dladm_range_size(mac_propval_range_t *r, size_t *sz) 1921*0dc2366fSVenugopal Iyer { 1922*0dc2366fSVenugopal Iyer uint_t count = r->mpr_count; 1923*0dc2366fSVenugopal Iyer 1924*0dc2366fSVenugopal Iyer *sz = sizeof (mac_propval_range_t); 1925*0dc2366fSVenugopal Iyer --count; 1926*0dc2366fSVenugopal Iyer 1927*0dc2366fSVenugopal Iyer switch (r->mpr_type) { 1928*0dc2366fSVenugopal Iyer case MAC_PROPVAL_UINT32: 1929*0dc2366fSVenugopal Iyer *sz += (count * sizeof (mac_propval_uint32_range_t)); 1930*0dc2366fSVenugopal Iyer return (0); 1931*0dc2366fSVenugopal Iyer default: 1932*0dc2366fSVenugopal Iyer break; 1933*0dc2366fSVenugopal Iyer } 1934*0dc2366fSVenugopal Iyer *sz = 0; 1935*0dc2366fSVenugopal Iyer return (EINVAL); 1936*0dc2366fSVenugopal Iyer } 1937*0dc2366fSVenugopal Iyer 1938*0dc2366fSVenugopal Iyer 1939da14cebeSEric Cheng /* ARGSUSED */ 1940da14cebeSEric Cheng static dladm_status_t 1941*0dc2366fSVenugopal Iyer check_rings(dladm_handle_t handle, prop_desc_t *pdp, 1942*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 1943*0dc2366fSVenugopal Iyer val_desc_t *v, datalink_media_t media) 1944*0dc2366fSVenugopal Iyer { 1945*0dc2366fSVenugopal Iyer if (val_cnt != 1) 1946*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1947*0dc2366fSVenugopal Iyer if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 1948*0dc2366fSVenugopal Iyer v->vd_val = UNSPEC_VAL; 1949*0dc2366fSVenugopal Iyer } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 1950*0dc2366fSVenugopal Iyer v->vd_val = 0; 1951*0dc2366fSVenugopal Iyer } else { 1952*0dc2366fSVenugopal Iyer v->vd_val = strtoul(prop_val[0], NULL, 0); 1953*0dc2366fSVenugopal Iyer if (v->vd_val == 0) 1954*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 1955*0dc2366fSVenugopal Iyer } 1956*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1957*0dc2366fSVenugopal Iyer } 1958*0dc2366fSVenugopal Iyer 1959*0dc2366fSVenugopal Iyer /* ARGSUSED */ 1960*0dc2366fSVenugopal Iyer static dladm_status_t 1961*0dc2366fSVenugopal Iyer get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 1962*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 1963*0dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 1964*0dc2366fSVenugopal Iyer { 1965*0dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 1966*0dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 1967*0dc2366fSVenugopal Iyer mac_propval_range_t *rangep; 1968*0dc2366fSVenugopal Iyer size_t sz; 1969*0dc2366fSVenugopal Iyer mac_propval_uint32_range_t *ur; 1970*0dc2366fSVenugopal Iyer 1971*0dc2366fSVenugopal Iyer sz = sizeof (mac_propval_range_t); 1972*0dc2366fSVenugopal Iyer 1973*0dc2366fSVenugopal Iyer if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 1974*0dc2366fSVenugopal Iyer &status)) == NULL) 1975*0dc2366fSVenugopal Iyer return (status); 1976*0dc2366fSVenugopal Iyer 1977*0dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 1978*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1979*0dc2366fSVenugopal Iyer return (status); 1980*0dc2366fSVenugopal Iyer 1981*0dc2366fSVenugopal Iyer rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 1982*0dc2366fSVenugopal Iyer *val_cnt = 1; 1983*0dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 1984*0dc2366fSVenugopal Iyer /* This is the case where the dev doesn't have any rings/groups */ 1985*0dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 1986*0dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 1987*0dc2366fSVenugopal Iyer /* 1988*0dc2366fSVenugopal Iyer * This is the case where the dev supports rings, but static 1989*0dc2366fSVenugopal Iyer * grouping. 1990*0dc2366fSVenugopal Iyer */ 1991*0dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max && 1992*0dc2366fSVenugopal Iyer ur->mpur_max == 0) { 1993*0dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 1994*0dc2366fSVenugopal Iyer /* 1995*0dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 1996*0dc2366fSVenugopal Iyer * grouping, but has only one value (say 2 rings and 2 groups). 1997*0dc2366fSVenugopal Iyer */ 1998*0dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max) { 1999*0dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 2000*0dc2366fSVenugopal Iyer ur->mpur_min); 2001*0dc2366fSVenugopal Iyer /* 2002*0dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 2003*0dc2366fSVenugopal Iyer * grouping and has a range of rings. 2004*0dc2366fSVenugopal Iyer */ 2005*0dc2366fSVenugopal Iyer } else { 2006*0dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 2007*0dc2366fSVenugopal Iyer "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 2008*0dc2366fSVenugopal Iyer } 2009*0dc2366fSVenugopal Iyer free(dip); 2010*0dc2366fSVenugopal Iyer return (status); 2011*0dc2366fSVenugopal Iyer } 2012*0dc2366fSVenugopal Iyer 2013*0dc2366fSVenugopal Iyer 2014*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2015*0dc2366fSVenugopal Iyer static dladm_status_t 2016*0dc2366fSVenugopal Iyer get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2017*0dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 2018*0dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 2019*0dc2366fSVenugopal Iyer { 2020*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 2021*0dc2366fSVenugopal Iyer dladm_status_t status; 2022*0dc2366fSVenugopal Iyer uint32_t nrings = 0; 2023*0dc2366fSVenugopal Iyer 2024*0dc2366fSVenugopal Iyer /* 2025*0dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 2026*0dc2366fSVenugopal Iyer */ 2027*0dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 2028*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 2029*0dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 2030*0dc2366fSVenugopal Iyer sizeof (mrp)); 2031*0dc2366fSVenugopal Iyer } else { 2032*0dc2366fSVenugopal Iyer /* 2033*0dc2366fSVenugopal Iyer * Get the permissions from the "rxrings" property. 2034*0dc2366fSVenugopal Iyer */ 2035*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "rxrings", 2036*0dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 2037*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2038*0dc2366fSVenugopal Iyer return (status); 2039*0dc2366fSVenugopal Iyer 2040*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 2041*0dc2366fSVenugopal Iyer "resource", flags, NULL, &mrp, sizeof (mrp)); 2042*0dc2366fSVenugopal Iyer } 2043*0dc2366fSVenugopal Iyer 2044*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2045*0dc2366fSVenugopal Iyer return (status); 2046*0dc2366fSVenugopal Iyer 2047*0dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 2048*0dc2366fSVenugopal Iyer *val_cnt = 0; 2049*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2050*0dc2366fSVenugopal Iyer } 2051*0dc2366fSVenugopal Iyer nrings = mrp.mrp_nrxrings; 2052*0dc2366fSVenugopal Iyer *val_cnt = 1; 2053*0dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 2054*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 2055*0dc2366fSVenugopal Iyer else if (nrings == 0) 2056*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 2057*0dc2366fSVenugopal Iyer else 2058*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 2059*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2060*0dc2366fSVenugopal Iyer } 2061*0dc2366fSVenugopal Iyer 2062*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2063*0dc2366fSVenugopal Iyer dladm_status_t 2064*0dc2366fSVenugopal Iyer extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 2065*0dc2366fSVenugopal Iyer { 2066*0dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 2067*0dc2366fSVenugopal Iyer 2068*0dc2366fSVenugopal Iyer mrp->mrp_nrxrings = 0; 2069*0dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 2070*0dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 2071*0dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 2072*0dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 2073*0dc2366fSVenugopal Iyer else 2074*0dc2366fSVenugopal Iyer mrp->mrp_nrxrings = vdp->vd_val; 2075*0dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_RX_RINGS; 2076*0dc2366fSVenugopal Iyer 2077*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2078*0dc2366fSVenugopal Iyer } 2079*0dc2366fSVenugopal Iyer 2080*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2081*0dc2366fSVenugopal Iyer static dladm_status_t 2082*0dc2366fSVenugopal Iyer get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2083*0dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 2084*0dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 2085*0dc2366fSVenugopal Iyer { 2086*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 2087*0dc2366fSVenugopal Iyer dladm_status_t status; 2088*0dc2366fSVenugopal Iyer uint32_t nrings = 0; 2089*0dc2366fSVenugopal Iyer 2090*0dc2366fSVenugopal Iyer 2091*0dc2366fSVenugopal Iyer /* 2092*0dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 2093*0dc2366fSVenugopal Iyer */ 2094*0dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 2095*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 2096*0dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 2097*0dc2366fSVenugopal Iyer sizeof (mrp)); 2098*0dc2366fSVenugopal Iyer } else { 2099*0dc2366fSVenugopal Iyer /* 2100*0dc2366fSVenugopal Iyer * Get the permissions from the "txrings" property. 2101*0dc2366fSVenugopal Iyer */ 2102*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "txrings", 2103*0dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 2104*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2105*0dc2366fSVenugopal Iyer return (status); 2106*0dc2366fSVenugopal Iyer 2107*0dc2366fSVenugopal Iyer /* 2108*0dc2366fSVenugopal Iyer * Get the number of rings from the "resource" property. 2109*0dc2366fSVenugopal Iyer */ 2110*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 2111*0dc2366fSVenugopal Iyer flags, NULL, &mrp, sizeof (mrp)); 2112*0dc2366fSVenugopal Iyer } 2113*0dc2366fSVenugopal Iyer 2114*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2115*0dc2366fSVenugopal Iyer return (status); 2116*0dc2366fSVenugopal Iyer 2117*0dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 2118*0dc2366fSVenugopal Iyer *val_cnt = 0; 2119*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2120*0dc2366fSVenugopal Iyer } 2121*0dc2366fSVenugopal Iyer nrings = mrp.mrp_ntxrings; 2122*0dc2366fSVenugopal Iyer *val_cnt = 1; 2123*0dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 2124*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 2125*0dc2366fSVenugopal Iyer else if (nrings == 0) 2126*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 2127*0dc2366fSVenugopal Iyer else 2128*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 2129*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2130*0dc2366fSVenugopal Iyer } 2131*0dc2366fSVenugopal Iyer 2132*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2133*0dc2366fSVenugopal Iyer dladm_status_t 2134*0dc2366fSVenugopal Iyer extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 2135*0dc2366fSVenugopal Iyer { 2136*0dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 2137*0dc2366fSVenugopal Iyer 2138*0dc2366fSVenugopal Iyer mrp->mrp_ntxrings = 0; 2139*0dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 2140*0dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 2141*0dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 2142*0dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 2143*0dc2366fSVenugopal Iyer else 2144*0dc2366fSVenugopal Iyer mrp->mrp_ntxrings = vdp->vd_val; 2145*0dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_TX_RINGS; 2146*0dc2366fSVenugopal Iyer 2147*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2148*0dc2366fSVenugopal Iyer } 2149*0dc2366fSVenugopal Iyer 2150*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2151*0dc2366fSVenugopal Iyer static dladm_status_t 2152*0dc2366fSVenugopal Iyer get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2153*0dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 2154*0dc2366fSVenugopal Iyer uint_t *perm_flags) 2155*0dc2366fSVenugopal Iyer { 2156*0dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 2157*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTDEFINED); 2158*0dc2366fSVenugopal Iyer 2159*0dc2366fSVenugopal Iyer return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 2160*0dc2366fSVenugopal Iyer flags, perm_flags)); 2161*0dc2366fSVenugopal Iyer } 2162*0dc2366fSVenugopal Iyer 2163*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2164*0dc2366fSVenugopal Iyer static dladm_status_t 2165*0dc2366fSVenugopal Iyer set_resource(dladm_handle_t handle, prop_desc_t *pdp, 216625ec3e3dSEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 216725ec3e3dSEric Cheng uint_t flags, datalink_media_t media) 216825ec3e3dSEric Cheng { 216925ec3e3dSEric Cheng mac_resource_props_t mrp; 217025ec3e3dSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 217125ec3e3dSEric Cheng dld_ioc_macprop_t *dip; 2172*0dc2366fSVenugopal Iyer int i; 217325ec3e3dSEric Cheng 217425ec3e3dSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 2175*0dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 217625ec3e3dSEric Cheng flags, &status); 217725ec3e3dSEric Cheng 217825ec3e3dSEric Cheng if (dip == NULL) 217925ec3e3dSEric Cheng return (status); 218025ec3e3dSEric Cheng 2181*0dc2366fSVenugopal Iyer for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 2182*0dc2366fSVenugopal Iyer resource_prop_t *rp = &rsrc_prop_table[i]; 2183*0dc2366fSVenugopal Iyer 2184*0dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, rp->rp_name) != 0) 2185*0dc2366fSVenugopal Iyer continue; 2186*0dc2366fSVenugopal Iyer 2187*0dc2366fSVenugopal Iyer status = rp->rp_extract(vdp, val_cnt, &mrp); 218825ec3e3dSEric Cheng if (status != DLADM_STATUS_OK) 218925ec3e3dSEric Cheng goto done; 219025ec3e3dSEric Cheng 2191*0dc2366fSVenugopal Iyer break; 219225ec3e3dSEric Cheng } 219325ec3e3dSEric Cheng 219425ec3e3dSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 219525ec3e3dSEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 219625ec3e3dSEric Cheng 219725ec3e3dSEric Cheng done: 219825ec3e3dSEric Cheng free(dip); 219925ec3e3dSEric Cheng return (status); 220025ec3e3dSEric Cheng } 220125ec3e3dSEric Cheng 220225ec3e3dSEric Cheng /* ARGSUSED */ 220325ec3e3dSEric Cheng static dladm_status_t 2204*0dc2366fSVenugopal Iyer get_protection(dladm_handle_t handle, prop_desc_t *pdp, 220525ec3e3dSEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 220625ec3e3dSEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 220725ec3e3dSEric Cheng { 220825ec3e3dSEric Cheng mac_resource_props_t mrp; 220925ec3e3dSEric Cheng mac_protect_t *p; 221025ec3e3dSEric Cheng dladm_status_t status; 2211*0dc2366fSVenugopal Iyer uint32_t i, cnt = 0, setbits[32]; 221225ec3e3dSEric Cheng 2213*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 2214*0dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 2215*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 221625ec3e3dSEric Cheng return (status); 221725ec3e3dSEric Cheng 221825ec3e3dSEric Cheng p = &mrp.mrp_protect; 2219*0dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 2220*0dc2366fSVenugopal Iyer *val_cnt = 0; 2221*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2222*0dc2366fSVenugopal Iyer } 222325ec3e3dSEric Cheng dladm_find_setbits32(p->mp_types, setbits, &cnt); 222425ec3e3dSEric Cheng if (cnt > *val_cnt) 222525ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 222625ec3e3dSEric Cheng 222725ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 222825ec3e3dSEric Cheng (void) dladm_protect2str(setbits[i], prop_val[i]); 222925ec3e3dSEric Cheng 223025ec3e3dSEric Cheng *val_cnt = cnt; 223125ec3e3dSEric Cheng return (DLADM_STATUS_OK); 223225ec3e3dSEric Cheng } 223325ec3e3dSEric Cheng 2234*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2235*0dc2366fSVenugopal Iyer static dladm_status_t 2236*0dc2366fSVenugopal Iyer get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2237*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2238*0dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 2239*0dc2366fSVenugopal Iyer { 2240*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 2241*0dc2366fSVenugopal Iyer mac_protect_t *p; 2242*0dc2366fSVenugopal Iyer dladm_status_t status; 2243*0dc2366fSVenugopal Iyer int i; 2244*0dc2366fSVenugopal Iyer 2245*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 2246*0dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 2247*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2248*0dc2366fSVenugopal Iyer return (status); 2249*0dc2366fSVenugopal Iyer 2250*0dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 2251*0dc2366fSVenugopal Iyer if (p->mp_ipaddrcnt == 0) { 2252*0dc2366fSVenugopal Iyer *val_cnt = 0; 2253*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2254*0dc2366fSVenugopal Iyer } 225525ec3e3dSEric Cheng if (p->mp_ipaddrcnt > *val_cnt) 225625ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 225725ec3e3dSEric Cheng 225825ec3e3dSEric Cheng for (i = 0; i < p->mp_ipaddrcnt; i++) { 2259*0dc2366fSVenugopal Iyer if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 2260*0dc2366fSVenugopal Iyer ipaddr_t v4addr; 2261*0dc2366fSVenugopal Iyer 2262*0dc2366fSVenugopal Iyer v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 2263*0dc2366fSVenugopal Iyer (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 2264*0dc2366fSVenugopal Iyer } else { 2265*0dc2366fSVenugopal Iyer (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 226625ec3e3dSEric Cheng prop_val[i]); 226725ec3e3dSEric Cheng } 2268*0dc2366fSVenugopal Iyer } 226925ec3e3dSEric Cheng *val_cnt = p->mp_ipaddrcnt; 227025ec3e3dSEric Cheng return (DLADM_STATUS_OK); 227125ec3e3dSEric Cheng } 227225ec3e3dSEric Cheng 227325ec3e3dSEric Cheng dladm_status_t 2274*0dc2366fSVenugopal Iyer extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 227525ec3e3dSEric Cheng { 227625ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 227725ec3e3dSEric Cheng uint32_t types = 0; 227825ec3e3dSEric Cheng int i; 227925ec3e3dSEric Cheng 228025ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 228125ec3e3dSEric Cheng types |= (uint32_t)vdp[i].vd_val; 228225ec3e3dSEric Cheng 228325ec3e3dSEric Cheng mrp->mrp_protect.mp_types = types; 228425ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 228525ec3e3dSEric Cheng return (DLADM_STATUS_OK); 228625ec3e3dSEric Cheng } 228725ec3e3dSEric Cheng 228825ec3e3dSEric Cheng dladm_status_t 2289*0dc2366fSVenugopal Iyer extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 229025ec3e3dSEric Cheng { 229125ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 229225ec3e3dSEric Cheng mac_protect_t *p = &mrp->mrp_protect; 229325ec3e3dSEric Cheng int i; 229425ec3e3dSEric Cheng 229525ec3e3dSEric Cheng if (vdp->vd_val == 0) { 229625ec3e3dSEric Cheng cnt = (uint_t)-1; 229725ec3e3dSEric Cheng } else { 2298*0dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 2299*0dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 2300*0dc2366fSVenugopal Iyer sizeof (mac_ipaddr_t)); 2301*0dc2366fSVenugopal Iyer } 230225ec3e3dSEric Cheng } 230325ec3e3dSEric Cheng p->mp_ipaddrcnt = cnt; 230425ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 230525ec3e3dSEric Cheng return (DLADM_STATUS_OK); 230625ec3e3dSEric Cheng } 230725ec3e3dSEric Cheng 2308*0dc2366fSVenugopal Iyer static dladm_status_t 2309*0dc2366fSVenugopal Iyer check_single_ip(char *buf, mac_ipaddr_t *addr) 2310*0dc2366fSVenugopal Iyer { 2311*0dc2366fSVenugopal Iyer dladm_status_t status; 2312*0dc2366fSVenugopal Iyer ipaddr_t v4addr; 2313*0dc2366fSVenugopal Iyer in6_addr_t v6addr; 2314*0dc2366fSVenugopal Iyer boolean_t isv4 = B_TRUE; 2315*0dc2366fSVenugopal Iyer 2316*0dc2366fSVenugopal Iyer status = dladm_str2ipv4addr(buf, &v4addr); 2317*0dc2366fSVenugopal Iyer if (status == DLADM_STATUS_INVALID_IP) { 2318*0dc2366fSVenugopal Iyer status = dladm_str2ipv6addr(buf, &v6addr); 2319*0dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) 2320*0dc2366fSVenugopal Iyer isv4 = B_FALSE; 2321*0dc2366fSVenugopal Iyer } 2322*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2323*0dc2366fSVenugopal Iyer return (status); 2324*0dc2366fSVenugopal Iyer 2325*0dc2366fSVenugopal Iyer if (isv4) { 2326*0dc2366fSVenugopal Iyer if (v4addr == INADDR_ANY) 2327*0dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 2328*0dc2366fSVenugopal Iyer 2329*0dc2366fSVenugopal Iyer IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 2330*0dc2366fSVenugopal Iyer addr->ip_version = IPV4_VERSION; 2331*0dc2366fSVenugopal Iyer } else { 2332*0dc2366fSVenugopal Iyer if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 2333*0dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 2334*0dc2366fSVenugopal Iyer 2335*0dc2366fSVenugopal Iyer addr->ip_addr = v6addr; 2336*0dc2366fSVenugopal Iyer addr->ip_version = IPV6_VERSION; 2337*0dc2366fSVenugopal Iyer } 2338*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2339*0dc2366fSVenugopal Iyer } 2340*0dc2366fSVenugopal Iyer 234125ec3e3dSEric Cheng /* ARGSUSED */ 234225ec3e3dSEric Cheng static dladm_status_t 2343*0dc2366fSVenugopal Iyer check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2344*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 234525ec3e3dSEric Cheng val_desc_t *vdp, datalink_media_t media) 234625ec3e3dSEric Cheng { 234725ec3e3dSEric Cheng dladm_status_t status; 2348*0dc2366fSVenugopal Iyer mac_ipaddr_t *addr; 234925ec3e3dSEric Cheng int i; 235025ec3e3dSEric Cheng 235125ec3e3dSEric Cheng if (val_cnt > MPT_MAXIPADDR) 235225ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 235325ec3e3dSEric Cheng 235425ec3e3dSEric Cheng for (i = 0; i < val_cnt; i++) { 2355*0dc2366fSVenugopal Iyer if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 2356*0dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 2357*0dc2366fSVenugopal Iyer goto fail; 235825ec3e3dSEric Cheng } 2359*0dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)addr; 2360*0dc2366fSVenugopal Iyer 2361*0dc2366fSVenugopal Iyer status = check_single_ip(prop_val[i], addr); 2362*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2363*0dc2366fSVenugopal Iyer goto fail; 2364*0dc2366fSVenugopal Iyer } 2365*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2366*0dc2366fSVenugopal Iyer 2367*0dc2366fSVenugopal Iyer fail: 2368*0dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 2369*0dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 2370*0dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 2371*0dc2366fSVenugopal Iyer } 2372*0dc2366fSVenugopal Iyer return (status); 2373*0dc2366fSVenugopal Iyer } 2374*0dc2366fSVenugopal Iyer 2375*0dc2366fSVenugopal Iyer static void 2376*0dc2366fSVenugopal Iyer dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 2377*0dc2366fSVenugopal Iyer { 2378*0dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 2379*0dc2366fSVenugopal Iyer uint_t hexlen; 2380*0dc2366fSVenugopal Iyer 2381*0dc2366fSVenugopal Iyer switch (cid->dc_form) { 2382*0dc2366fSVenugopal Iyer case CIDFORM_TYPED: { 2383*0dc2366fSVenugopal Iyer uint16_t duidtype, hwtype; 2384*0dc2366fSVenugopal Iyer uint32_t timestamp, ennum; 2385*0dc2366fSVenugopal Iyer char *lladdr; 2386*0dc2366fSVenugopal Iyer 2387*0dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (duidtype)) 2388*0dc2366fSVenugopal Iyer goto fail; 2389*0dc2366fSVenugopal Iyer 2390*0dc2366fSVenugopal Iyer bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 2391*0dc2366fSVenugopal Iyer duidtype = ntohs(duidtype); 2392*0dc2366fSVenugopal Iyer switch (duidtype) { 2393*0dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 2394*0dc2366fSVenugopal Iyer duid_llt_t llt; 2395*0dc2366fSVenugopal Iyer 2396*0dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (llt)) 2397*0dc2366fSVenugopal Iyer goto fail; 2398*0dc2366fSVenugopal Iyer 2399*0dc2366fSVenugopal Iyer bcopy(cid->dc_id, &llt, sizeof (llt)); 2400*0dc2366fSVenugopal Iyer hwtype = ntohs(llt.dllt_hwtype); 2401*0dc2366fSVenugopal Iyer timestamp = ntohl(llt.dllt_time); 2402*0dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 2403*0dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 2404*0dc2366fSVenugopal Iyer if (lladdr == NULL) 2405*0dc2366fSVenugopal Iyer goto fail; 2406*0dc2366fSVenugopal Iyer 2407*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 2408*0dc2366fSVenugopal Iyer duidtype, hwtype, timestamp, lladdr); 2409*0dc2366fSVenugopal Iyer free(lladdr); 2410*0dc2366fSVenugopal Iyer break; 2411*0dc2366fSVenugopal Iyer } 2412*0dc2366fSVenugopal Iyer case DHCPV6_DUID_EN: { 2413*0dc2366fSVenugopal Iyer duid_en_t en; 2414*0dc2366fSVenugopal Iyer 2415*0dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (en)) 2416*0dc2366fSVenugopal Iyer goto fail; 2417*0dc2366fSVenugopal Iyer 2418*0dc2366fSVenugopal Iyer bcopy(cid->dc_id, &en, sizeof (en)); 2419*0dc2366fSVenugopal Iyer ennum = DHCPV6_GET_ENTNUM(&en); 2420*0dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 2421*0dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (en), 2422*0dc2366fSVenugopal Iyer cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 2423*0dc2366fSVenugopal Iyer goto fail; 2424*0dc2366fSVenugopal Iyer 2425*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 2426*0dc2366fSVenugopal Iyer duidtype, ennum, tmp_buf); 2427*0dc2366fSVenugopal Iyer break; 2428*0dc2366fSVenugopal Iyer } 2429*0dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 2430*0dc2366fSVenugopal Iyer duid_ll_t ll; 2431*0dc2366fSVenugopal Iyer 2432*0dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (ll)) 2433*0dc2366fSVenugopal Iyer goto fail; 2434*0dc2366fSVenugopal Iyer 2435*0dc2366fSVenugopal Iyer bcopy(cid->dc_id, &ll, sizeof (ll)); 2436*0dc2366fSVenugopal Iyer hwtype = ntohs(ll.dll_hwtype); 2437*0dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 2438*0dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 2439*0dc2366fSVenugopal Iyer if (lladdr == NULL) 2440*0dc2366fSVenugopal Iyer goto fail; 2441*0dc2366fSVenugopal Iyer 2442*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 2443*0dc2366fSVenugopal Iyer duidtype, hwtype, lladdr); 2444*0dc2366fSVenugopal Iyer free(lladdr); 2445*0dc2366fSVenugopal Iyer break; 2446*0dc2366fSVenugopal Iyer } 2447*0dc2366fSVenugopal Iyer default: { 2448*0dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 2449*0dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 2450*0dc2366fSVenugopal Iyer cid->dc_len - sizeof (duidtype), 2451*0dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 2452*0dc2366fSVenugopal Iyer goto fail; 2453*0dc2366fSVenugopal Iyer 2454*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 2455*0dc2366fSVenugopal Iyer duidtype, tmp_buf); 2456*0dc2366fSVenugopal Iyer } 2457*0dc2366fSVenugopal Iyer } 2458*0dc2366fSVenugopal Iyer break; 2459*0dc2366fSVenugopal Iyer } 2460*0dc2366fSVenugopal Iyer case CIDFORM_HEX: { 2461*0dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 2462*0dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id, cid->dc_len, 2463*0dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 2464*0dc2366fSVenugopal Iyer goto fail; 2465*0dc2366fSVenugopal Iyer 2466*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 2467*0dc2366fSVenugopal Iyer break; 2468*0dc2366fSVenugopal Iyer } 2469*0dc2366fSVenugopal Iyer case CIDFORM_STR: { 2470*0dc2366fSVenugopal Iyer int i; 2471*0dc2366fSVenugopal Iyer 2472*0dc2366fSVenugopal Iyer for (i = 0; i < cid->dc_len; i++) { 2473*0dc2366fSVenugopal Iyer if (!isprint(cid->dc_id[i])) 2474*0dc2366fSVenugopal Iyer goto fail; 2475*0dc2366fSVenugopal Iyer } 2476*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 2477*0dc2366fSVenugopal Iyer break; 2478*0dc2366fSVenugopal Iyer } 2479*0dc2366fSVenugopal Iyer default: 2480*0dc2366fSVenugopal Iyer goto fail; 2481*0dc2366fSVenugopal Iyer } 2482*0dc2366fSVenugopal Iyer return; 2483*0dc2366fSVenugopal Iyer 2484*0dc2366fSVenugopal Iyer fail: 2485*0dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 2486*0dc2366fSVenugopal Iyer } 2487*0dc2366fSVenugopal Iyer 2488*0dc2366fSVenugopal Iyer static dladm_status_t 2489*0dc2366fSVenugopal Iyer dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 2490*0dc2366fSVenugopal Iyer { 2491*0dc2366fSVenugopal Iyer char *ptr = buf; 2492*0dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 2493*0dc2366fSVenugopal Iyer uint_t hexlen, cidlen; 2494*0dc2366fSVenugopal Iyer 2495*0dc2366fSVenugopal Iyer bzero(cid, sizeof (*cid)); 2496*0dc2366fSVenugopal Iyer if (isdigit(*ptr) && 2497*0dc2366fSVenugopal Iyer ptr[strspn(ptr, "0123456789")] == '.') { 2498*0dc2366fSVenugopal Iyer char *cp; 2499*0dc2366fSVenugopal Iyer ulong_t duidtype; 2500*0dc2366fSVenugopal Iyer ulong_t subtype; 2501*0dc2366fSVenugopal Iyer ulong_t timestamp; 2502*0dc2366fSVenugopal Iyer uchar_t *lladdr; 2503*0dc2366fSVenugopal Iyer int addrlen; 2504*0dc2366fSVenugopal Iyer 2505*0dc2366fSVenugopal Iyer errno = 0; 2506*0dc2366fSVenugopal Iyer duidtype = strtoul(ptr, &cp, 0); 2507*0dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.' || 2508*0dc2366fSVenugopal Iyer duidtype > USHRT_MAX) 2509*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2510*0dc2366fSVenugopal Iyer ptr = cp + 1; 2511*0dc2366fSVenugopal Iyer 2512*0dc2366fSVenugopal Iyer if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 2513*0dc2366fSVenugopal Iyer errno = 0; 2514*0dc2366fSVenugopal Iyer subtype = strtoul(ptr, &cp, 0); 2515*0dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 2516*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2517*0dc2366fSVenugopal Iyer ptr = cp + 1; 2518*0dc2366fSVenugopal Iyer } 2519*0dc2366fSVenugopal Iyer switch (duidtype) { 2520*0dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 2521*0dc2366fSVenugopal Iyer duid_llt_t llt; 2522*0dc2366fSVenugopal Iyer 2523*0dc2366fSVenugopal Iyer errno = 0; 2524*0dc2366fSVenugopal Iyer timestamp = strtoul(ptr, &cp, 0); 2525*0dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 2526*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2527*0dc2366fSVenugopal Iyer 2528*0dc2366fSVenugopal Iyer ptr = cp + 1; 2529*0dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 2530*0dc2366fSVenugopal Iyer if (lladdr == NULL) 2531*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2532*0dc2366fSVenugopal Iyer 2533*0dc2366fSVenugopal Iyer cidlen = sizeof (llt) + addrlen; 2534*0dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 2535*0dc2366fSVenugopal Iyer free(lladdr); 2536*0dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 2537*0dc2366fSVenugopal Iyer } 2538*0dc2366fSVenugopal Iyer llt.dllt_dutype = htons(duidtype); 2539*0dc2366fSVenugopal Iyer llt.dllt_hwtype = htons(subtype); 2540*0dc2366fSVenugopal Iyer llt.dllt_time = htonl(timestamp); 2541*0dc2366fSVenugopal Iyer bcopy(&llt, cid->dc_id, sizeof (llt)); 2542*0dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 2543*0dc2366fSVenugopal Iyer free(lladdr); 2544*0dc2366fSVenugopal Iyer break; 2545*0dc2366fSVenugopal Iyer } 2546*0dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 2547*0dc2366fSVenugopal Iyer duid_ll_t ll; 2548*0dc2366fSVenugopal Iyer 2549*0dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 2550*0dc2366fSVenugopal Iyer if (lladdr == NULL) 2551*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2552*0dc2366fSVenugopal Iyer 2553*0dc2366fSVenugopal Iyer cidlen = sizeof (ll) + addrlen; 2554*0dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 2555*0dc2366fSVenugopal Iyer free(lladdr); 2556*0dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 2557*0dc2366fSVenugopal Iyer } 2558*0dc2366fSVenugopal Iyer ll.dll_dutype = htons(duidtype); 2559*0dc2366fSVenugopal Iyer ll.dll_hwtype = htons(subtype); 2560*0dc2366fSVenugopal Iyer bcopy(&ll, cid->dc_id, sizeof (ll)); 2561*0dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 2562*0dc2366fSVenugopal Iyer free(lladdr); 2563*0dc2366fSVenugopal Iyer break; 2564*0dc2366fSVenugopal Iyer } 2565*0dc2366fSVenugopal Iyer default: { 2566*0dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 2567*0dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), 2568*0dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 2569*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2570*0dc2366fSVenugopal Iyer 2571*0dc2366fSVenugopal Iyer if (duidtype == DHCPV6_DUID_EN) { 2572*0dc2366fSVenugopal Iyer duid_en_t en; 2573*0dc2366fSVenugopal Iyer 2574*0dc2366fSVenugopal Iyer en.den_dutype = htons(duidtype); 2575*0dc2366fSVenugopal Iyer DHCPV6_SET_ENTNUM(&en, subtype); 2576*0dc2366fSVenugopal Iyer 2577*0dc2366fSVenugopal Iyer cidlen = sizeof (en) + hexlen; 2578*0dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 2579*0dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 2580*0dc2366fSVenugopal Iyer 2581*0dc2366fSVenugopal Iyer bcopy(&en, cid->dc_id, sizeof (en)); 2582*0dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (en), 2583*0dc2366fSVenugopal Iyer hexlen); 2584*0dc2366fSVenugopal Iyer } else { 2585*0dc2366fSVenugopal Iyer uint16_t dutype = htons(duidtype); 2586*0dc2366fSVenugopal Iyer 2587*0dc2366fSVenugopal Iyer cidlen = sizeof (dutype) + hexlen; 2588*0dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 2589*0dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 2590*0dc2366fSVenugopal Iyer 2591*0dc2366fSVenugopal Iyer bcopy(&dutype, cid->dc_id, sizeof (dutype)); 2592*0dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 2593*0dc2366fSVenugopal Iyer hexlen); 2594*0dc2366fSVenugopal Iyer } 2595*0dc2366fSVenugopal Iyer break; 2596*0dc2366fSVenugopal Iyer } 2597*0dc2366fSVenugopal Iyer } 2598*0dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_TYPED; 2599*0dc2366fSVenugopal Iyer } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 2600*0dc2366fSVenugopal Iyer ptr += 2; 2601*0dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 2602*0dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 2603*0dc2366fSVenugopal Iyer &hexlen) != 0) { 2604*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 2605*0dc2366fSVenugopal Iyer } 2606*0dc2366fSVenugopal Iyer cidlen = hexlen; 2607*0dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 2608*0dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 2609*0dc2366fSVenugopal Iyer 2610*0dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id, cidlen); 2611*0dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_HEX; 2612*0dc2366fSVenugopal Iyer } else { 2613*0dc2366fSVenugopal Iyer cidlen = strlen(ptr); 2614*0dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 2615*0dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 2616*0dc2366fSVenugopal Iyer 2617*0dc2366fSVenugopal Iyer bcopy(ptr, cid->dc_id, cidlen); 2618*0dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_STR; 2619*0dc2366fSVenugopal Iyer } 2620*0dc2366fSVenugopal Iyer cid->dc_len = cidlen; 262125ec3e3dSEric Cheng return (DLADM_STATUS_OK); 262225ec3e3dSEric Cheng } 262325ec3e3dSEric Cheng 262425ec3e3dSEric Cheng /* ARGSUSED */ 262525ec3e3dSEric Cheng static dladm_status_t 2626*0dc2366fSVenugopal Iyer get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2627*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 2628*0dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 2629*0dc2366fSVenugopal Iyer { 2630*0dc2366fSVenugopal Iyer mac_resource_props_t mrp; 2631*0dc2366fSVenugopal Iyer mac_protect_t *p; 2632*0dc2366fSVenugopal Iyer dladm_status_t status; 2633*0dc2366fSVenugopal Iyer int i; 2634*0dc2366fSVenugopal Iyer 2635*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 2636*0dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 2637*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2638*0dc2366fSVenugopal Iyer return (status); 2639*0dc2366fSVenugopal Iyer 2640*0dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 2641*0dc2366fSVenugopal Iyer if (p->mp_cidcnt == 0) { 2642*0dc2366fSVenugopal Iyer *val_cnt = 0; 2643*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2644*0dc2366fSVenugopal Iyer } 2645*0dc2366fSVenugopal Iyer if (p->mp_cidcnt > *val_cnt) 2646*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 2647*0dc2366fSVenugopal Iyer 2648*0dc2366fSVenugopal Iyer for (i = 0; i < p->mp_cidcnt; i++) { 2649*0dc2366fSVenugopal Iyer mac_dhcpcid_t *cid = &p->mp_cids[i]; 2650*0dc2366fSVenugopal Iyer 2651*0dc2366fSVenugopal Iyer dladm_cid2str(cid, prop_val[i]); 2652*0dc2366fSVenugopal Iyer } 2653*0dc2366fSVenugopal Iyer *val_cnt = p->mp_cidcnt; 2654*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2655*0dc2366fSVenugopal Iyer } 2656*0dc2366fSVenugopal Iyer 2657*0dc2366fSVenugopal Iyer dladm_status_t 2658*0dc2366fSVenugopal Iyer extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 2659*0dc2366fSVenugopal Iyer { 2660*0dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 2661*0dc2366fSVenugopal Iyer mac_protect_t *p = &mrp->mrp_protect; 2662*0dc2366fSVenugopal Iyer int i; 2663*0dc2366fSVenugopal Iyer 2664*0dc2366fSVenugopal Iyer if (vdp->vd_val == 0) { 2665*0dc2366fSVenugopal Iyer cnt = (uint_t)-1; 2666*0dc2366fSVenugopal Iyer } else { 2667*0dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 2668*0dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 2669*0dc2366fSVenugopal Iyer sizeof (mac_dhcpcid_t)); 2670*0dc2366fSVenugopal Iyer } 2671*0dc2366fSVenugopal Iyer } 2672*0dc2366fSVenugopal Iyer p->mp_cidcnt = cnt; 2673*0dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_PROTECT; 2674*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2675*0dc2366fSVenugopal Iyer } 2676*0dc2366fSVenugopal Iyer 2677*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2678*0dc2366fSVenugopal Iyer static dladm_status_t 2679*0dc2366fSVenugopal Iyer check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2680*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, 2681*0dc2366fSVenugopal Iyer uint_t flags, val_desc_t *vdp, datalink_media_t media) 2682*0dc2366fSVenugopal Iyer { 2683*0dc2366fSVenugopal Iyer dladm_status_t status; 2684*0dc2366fSVenugopal Iyer mac_dhcpcid_t *cid; 2685*0dc2366fSVenugopal Iyer int i; 2686*0dc2366fSVenugopal Iyer 2687*0dc2366fSVenugopal Iyer if (val_cnt > MPT_MAXCID) 2688*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 2689*0dc2366fSVenugopal Iyer 2690*0dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 2691*0dc2366fSVenugopal Iyer if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 2692*0dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 2693*0dc2366fSVenugopal Iyer goto fail; 2694*0dc2366fSVenugopal Iyer } 2695*0dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)cid; 2696*0dc2366fSVenugopal Iyer 2697*0dc2366fSVenugopal Iyer status = dladm_str2cid(prop_val[i], cid); 2698*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2699*0dc2366fSVenugopal Iyer goto fail; 2700*0dc2366fSVenugopal Iyer } 2701*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2702*0dc2366fSVenugopal Iyer 2703*0dc2366fSVenugopal Iyer fail: 2704*0dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 2705*0dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 2706*0dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 2707*0dc2366fSVenugopal Iyer } 2708*0dc2366fSVenugopal Iyer return (status); 2709*0dc2366fSVenugopal Iyer } 2710*0dc2366fSVenugopal Iyer 2711*0dc2366fSVenugopal Iyer /* ARGSUSED */ 2712*0dc2366fSVenugopal Iyer static dladm_status_t 2713*0dc2366fSVenugopal Iyer get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2714da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2715da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2716d62bc4baSyz147064 { 27173bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 27183bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 27193bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 2720d62bc4baSyz147064 2721*0dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 2722149b7eb2SSowmini Varadhan return (DLADM_STATUS_NOTDEFINED); 27234045d941Ssowmini 2724*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 2725*0dc2366fSVenugopal Iyer perm_flags, &dlap, sizeof (dlap)); 2726*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2727*0dc2366fSVenugopal Iyer return (status); 2728*0dc2366fSVenugopal Iyer 2729*0dc2366fSVenugopal Iyer if (dlap.dap_npush == 0) { 2730*0dc2366fSVenugopal Iyer *val_cnt = 0; 2731da14cebeSEric Cheng return (DLADM_STATUS_OK); 2732d62bc4baSyz147064 } 27333bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 2734d62bc4baSyz147064 if (i != 0) { 2735d62bc4baSyz147064 (void) snprintf(*prop_val + len, 2736d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 2737d62bc4baSyz147064 len += 1; 2738d62bc4baSyz147064 } 2739d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 27403bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 27413bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 27423bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 2743d62bc4baSyz147064 (void) snprintf(*prop_val + len, 2744d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 2745d62bc4baSyz147064 AP_ANCHOR); 2746d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 2747d62bc4baSyz147064 } 2748d62bc4baSyz147064 } 2749*0dc2366fSVenugopal Iyer *val_cnt = 1; 2750d62bc4baSyz147064 return (DLADM_STATUS_OK); 2751d62bc4baSyz147064 } 2752d62bc4baSyz147064 2753d62bc4baSyz147064 /* 2754d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 2755d62bc4baSyz147064 * DLADM_STATUS_* code. 2756d62bc4baSyz147064 */ 2757d62bc4baSyz147064 dladm_status_t 2758d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 2759d62bc4baSyz147064 { 2760d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 2761d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 2762d62bc4baSyz147064 2763d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 2764d62bc4baSyz147064 /* 2765d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 2766d62bc4baSyz147064 * be after at least one module. 2767d62bc4baSyz147064 */ 2768d62bc4baSyz147064 if (dlap->dap_anchor != 0) 2769d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 2770d62bc4baSyz147064 if (dlap->dap_npush == 0) 2771d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 2772d62bc4baSyz147064 2773d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 2774d62bc4baSyz147064 return (DLADM_STATUS_OK); 2775d62bc4baSyz147064 } 2776285e94f9SMichael Lim if (dlap->dap_npush >= MAXAPUSH) 2777d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2778d62bc4baSyz147064 2779d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 2780d62bc4baSyz147064 FMNAMESZ + 1); 2781d62bc4baSyz147064 2782d62bc4baSyz147064 return (DLADM_STATUS_OK); 2783d62bc4baSyz147064 } 2784d62bc4baSyz147064 2785d62bc4baSyz147064 /* 2786d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 2787d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 2788d62bc4baSyz147064 * latter is used in the autopush(1M) file. 2789d62bc4baSyz147064 */ 2790d62bc4baSyz147064 /* ARGSUSED */ 2791d62bc4baSyz147064 static dladm_status_t 2792*0dc2366fSVenugopal Iyer check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2793*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 2794*0dc2366fSVenugopal Iyer datalink_media_t media) 2795d62bc4baSyz147064 { 2796d62bc4baSyz147064 char *module; 2797d62bc4baSyz147064 struct dlautopush *dlap; 2798d62bc4baSyz147064 dladm_status_t status; 2799d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 2800d62bc4baSyz147064 char delimiters[4]; 2801d62bc4baSyz147064 2802d62bc4baSyz147064 if (val_cnt != 1) 2803d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2804d62bc4baSyz147064 28053bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 2806d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 2807d62bc4baSyz147064 if (dlap == NULL) 2808d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 2809d62bc4baSyz147064 2810d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 2811d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 2812d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 2813d62bc4baSyz147064 module = strtok(val, delimiters); 2814d62bc4baSyz147064 while (module != NULL) { 2815d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 2816d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2817d62bc4baSyz147064 return (status); 2818d62bc4baSyz147064 module = strtok(NULL, delimiters); 2819d62bc4baSyz147064 } 2820d62bc4baSyz147064 2821d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 28223bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 28233bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 28243bc21d0aSAruna Ramakrishna - Sun Microsystems } 2825d62bc4baSyz147064 return (DLADM_STATUS_OK); 2826d62bc4baSyz147064 } 2827d62bc4baSyz147064 2828bcb5c89dSSowmini Varadhan #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 2829bcb5c89dSSowmini Varadhan 2830e7801d59Ssowmini /* ARGSUSED */ 2831d62bc4baSyz147064 static dladm_status_t 2832*0dc2366fSVenugopal Iyer get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 28334ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 28344ac67f02SAnurag S. Maskey uint_t *perm_flags) 2835d62bc4baSyz147064 { 2836d62bc4baSyz147064 wl_rates_t *wrp; 2837d62bc4baSyz147064 uint_t i; 2838d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 2839d62bc4baSyz147064 2840bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 2841bcb5c89dSSowmini Varadhan if (wrp == NULL) 2842bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2843d62bc4baSyz147064 28444ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 28454ac67f02SAnurag S. Maskey B_FALSE); 2846d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2847d62bc4baSyz147064 goto done; 2848d62bc4baSyz147064 2849d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 2850d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 2851d62bc4baSyz147064 goto done; 2852d62bc4baSyz147064 } 2853d62bc4baSyz147064 2854d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 2855d62bc4baSyz147064 prop_val[0][0] = '\0'; 2856d62bc4baSyz147064 *val_cnt = 1; 2857d62bc4baSyz147064 goto done; 2858d62bc4baSyz147064 } 2859d62bc4baSyz147064 2860d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 2861d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 2862d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 2863d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 2864d62bc4baSyz147064 } 2865d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 2866da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_RW; 2867d62bc4baSyz147064 2868d62bc4baSyz147064 done: 2869bcb5c89dSSowmini Varadhan free(wrp); 2870d62bc4baSyz147064 return (status); 2871d62bc4baSyz147064 } 2872d62bc4baSyz147064 2873d62bc4baSyz147064 static dladm_status_t 2874*0dc2366fSVenugopal Iyer get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2875da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2876da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2877d62bc4baSyz147064 { 2878afdda45fSVasumathi Sundaram - Sun Microsystems if (media != DL_WIFI) { 2879*0dc2366fSVenugopal Iyer return (get_speed(handle, pdp, linkid, prop_val, 2880*0dc2366fSVenugopal Iyer val_cnt, media, flags, perm_flags)); 2881afdda45fSVasumathi Sundaram - Sun Microsystems } 28826b9e797cSsowmini 2883*0dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 2884da14cebeSEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 2885d62bc4baSyz147064 } 2886d62bc4baSyz147064 28874045d941Ssowmini /* ARGSUSED */ 2888d62bc4baSyz147064 static dladm_status_t 2889*0dc2366fSVenugopal Iyer get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2890da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2891da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2892d62bc4baSyz147064 { 28936b9e797cSsowmini switch (media) { 28946b9e797cSsowmini case DL_ETHER: 28954045d941Ssowmini /* 28964045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 28974045d941Ssowmini * links can have a speed of 5.5 Gbps. 28984045d941Ssowmini */ 28994045d941Ssowmini return (DLADM_STATUS_NOTSUP); 29006b9e797cSsowmini 29016b9e797cSsowmini case DL_WIFI: 2902*0dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, 29034ac67f02SAnurag S. Maskey val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 29046b9e797cSsowmini default: 29056b9e797cSsowmini return (DLADM_STATUS_BADARG); 29066b9e797cSsowmini } 2907d62bc4baSyz147064 } 2908d62bc4baSyz147064 2909d62bc4baSyz147064 static dladm_status_t 2910*0dc2366fSVenugopal Iyer set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 29114ac67f02SAnurag S. Maskey dladm_wlan_rates_t *rates) 2912f4b3ec61Sdh155122 { 2913f4b3ec61Sdh155122 int i; 2914d62bc4baSyz147064 uint_t len; 2915d62bc4baSyz147064 wl_rates_t *wrp; 2916d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 2917d62bc4baSyz147064 2918bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 2919bcb5c89dSSowmini Varadhan if (wrp == NULL) 2920d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 2921d62bc4baSyz147064 2922bcb5c89dSSowmini Varadhan bzero(wrp, WLDP_BUFSIZE); 2923d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 2924d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 2925d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 2926d62bc4baSyz147064 2927d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 2928d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 29294ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, 29304ac67f02SAnurag S. Maskey MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 2931d62bc4baSyz147064 2932bcb5c89dSSowmini Varadhan free(wrp); 2933d62bc4baSyz147064 return (status); 2934d62bc4baSyz147064 } 2935d62bc4baSyz147064 2936e7801d59Ssowmini /* ARGSUSED */ 2937d62bc4baSyz147064 static dladm_status_t 2938*0dc2366fSVenugopal Iyer set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 29396b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 2940d62bc4baSyz147064 { 2941d62bc4baSyz147064 dladm_wlan_rates_t rates; 2942f4b3ec61Sdh155122 dladm_status_t status; 2943f4b3ec61Sdh155122 29446b9e797cSsowmini /* 29456b9e797cSsowmini * can currently set rate on WIFI links only. 29466b9e797cSsowmini */ 29476b9e797cSsowmini if (media != DL_WIFI) 29486b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 29496b9e797cSsowmini 2950d62bc4baSyz147064 if (val_cnt != 1) 2951d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2952f4b3ec61Sdh155122 2953d62bc4baSyz147064 rates.wr_cnt = 1; 2954d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 2955f4b3ec61Sdh155122 2956*0dc2366fSVenugopal Iyer status = set_wlan_rate(handle, linkid, &rates); 2957f4b3ec61Sdh155122 2958d62bc4baSyz147064 return (status); 2959d62bc4baSyz147064 } 2960d62bc4baSyz147064 2961d62bc4baSyz147064 /* ARGSUSED */ 2962d62bc4baSyz147064 static dladm_status_t 2963*0dc2366fSVenugopal Iyer check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2964*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 2965*0dc2366fSVenugopal Iyer datalink_media_t media) 2966d62bc4baSyz147064 { 2967d62bc4baSyz147064 int i; 2968d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 2969d62bc4baSyz147064 char *buf, **modval; 2970d62bc4baSyz147064 dladm_status_t status; 2971afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 2972d62bc4baSyz147064 2973d62bc4baSyz147064 if (val_cnt != 1) 2974d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2975d62bc4baSyz147064 2976d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 2977d62bc4baSyz147064 MAX_SUPPORT_RATES); 2978d62bc4baSyz147064 if (buf == NULL) { 2979d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 2980d62bc4baSyz147064 goto done; 2981d62bc4baSyz147064 } 2982d62bc4baSyz147064 2983d62bc4baSyz147064 modval = (char **)(void *)buf; 2984d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 2985d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 2986d62bc4baSyz147064 i * DLADM_STRSIZE; 2987d62bc4baSyz147064 } 2988d62bc4baSyz147064 2989*0dc2366fSVenugopal Iyer status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 29904ac67f02SAnurag S. Maskey media, 0, &perm_flags); 2991d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2992d62bc4baSyz147064 goto done; 2993d62bc4baSyz147064 2994d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 2995d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 2996e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 2997e7801d59Ssowmini (atof(*prop_val) * 2); 2998f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 2999f4b3ec61Sdh155122 break; 3000f4b3ec61Sdh155122 } 3001d62bc4baSyz147064 } 3002d62bc4baSyz147064 if (i == modval_cnt) 3003d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 3004d62bc4baSyz147064 done: 3005d62bc4baSyz147064 free(buf); 3006d62bc4baSyz147064 return (status); 3007d62bc4baSyz147064 } 3008f4b3ec61Sdh155122 3009d62bc4baSyz147064 static dladm_status_t 3010*0dc2366fSVenugopal Iyer get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 30114ac67f02SAnurag S. Maskey int buflen) 3012d62bc4baSyz147064 { 30134ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 3014bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 3015d62bc4baSyz147064 } 3016d62bc4baSyz147064 3017e7801d59Ssowmini /* ARGSUSED */ 3018d62bc4baSyz147064 static dladm_status_t 3019*0dc2366fSVenugopal Iyer get_channel(dladm_handle_t handle, prop_desc_t *pdp, 30204ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30214ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3022d62bc4baSyz147064 { 3023d62bc4baSyz147064 uint32_t channel; 3024bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 3025*0dc2366fSVenugopal Iyer dladm_status_t status; 3026bcb5c89dSSowmini Varadhan wl_phy_conf_t wl_phy_conf; 3027d62bc4baSyz147064 3028*0dc2366fSVenugopal Iyer if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 3029bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 3030*0dc2366fSVenugopal Iyer return (status); 3031d62bc4baSyz147064 3032bcb5c89dSSowmini Varadhan (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 3033*0dc2366fSVenugopal Iyer if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 3034*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3035d62bc4baSyz147064 3036d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 3037d62bc4baSyz147064 *val_cnt = 1; 3038da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 3039*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3040d62bc4baSyz147064 } 3041d62bc4baSyz147064 3042e7801d59Ssowmini /* ARGSUSED */ 3043d62bc4baSyz147064 static dladm_status_t 3044*0dc2366fSVenugopal Iyer get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 30454ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30464ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3047d62bc4baSyz147064 { 3048bcb5c89dSSowmini Varadhan wl_ps_mode_t mode; 3049d62bc4baSyz147064 const char *s; 3050bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 3051*0dc2366fSVenugopal Iyer dladm_status_t status; 3052d62bc4baSyz147064 3053*0dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 3054*0dc2366fSVenugopal Iyer MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 3055*0dc2366fSVenugopal Iyer return (status); 3056d62bc4baSyz147064 3057bcb5c89dSSowmini Varadhan (void) memcpy(&mode, buf, sizeof (mode)); 3058bcb5c89dSSowmini Varadhan switch (mode.wl_ps_mode) { 3059d62bc4baSyz147064 case WL_PM_AM: 3060d62bc4baSyz147064 s = "off"; 3061f4b3ec61Sdh155122 break; 3062d62bc4baSyz147064 case WL_PM_MPS: 3063d62bc4baSyz147064 s = "max"; 3064d62bc4baSyz147064 break; 3065d62bc4baSyz147064 case WL_PM_FAST: 3066d62bc4baSyz147064 s = "fast"; 3067f4b3ec61Sdh155122 break; 3068f4b3ec61Sdh155122 default: 3069*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3070f4b3ec61Sdh155122 } 3071d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3072d62bc4baSyz147064 *val_cnt = 1; 3073afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 3074*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3075d62bc4baSyz147064 } 3076d62bc4baSyz147064 3077*0dc2366fSVenugopal Iyer /* ARGSUSED */ 3078d62bc4baSyz147064 static dladm_status_t 3079*0dc2366fSVenugopal Iyer set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 3080*0dc2366fSVenugopal Iyer datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 3081*0dc2366fSVenugopal Iyer datalink_media_t media) 3082d62bc4baSyz147064 { 3083*0dc2366fSVenugopal Iyer dladm_wlan_powermode_t powermode = vdp->vd_val; 3084d62bc4baSyz147064 wl_ps_mode_t ps_mode; 3085d62bc4baSyz147064 3086*0dc2366fSVenugopal Iyer if (val_cnt != 1) 3087*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 3088*0dc2366fSVenugopal Iyer 3089d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 3090d62bc4baSyz147064 3091*0dc2366fSVenugopal Iyer switch (powermode) { 3092d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 3093d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 3094d62bc4baSyz147064 break; 3095d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 3096d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 3097d62bc4baSyz147064 break; 3098d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 3099d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 3100d62bc4baSyz147064 break; 3101d62bc4baSyz147064 default: 3102d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3103d62bc4baSyz147064 } 31044ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &ps_mode, 31054ac67f02SAnurag S. Maskey MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 3106d62bc4baSyz147064 } 3107d62bc4baSyz147064 3108d62bc4baSyz147064 /* ARGSUSED */ 3109d62bc4baSyz147064 static dladm_status_t 3110*0dc2366fSVenugopal Iyer get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3111da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3112da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3113d62bc4baSyz147064 { 3114d62bc4baSyz147064 wl_radio_t radio; 3115d62bc4baSyz147064 const char *s; 3116bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 3117*0dc2366fSVenugopal Iyer dladm_status_t status; 3118d62bc4baSyz147064 3119*0dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 3120*0dc2366fSVenugopal Iyer MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 3121*0dc2366fSVenugopal Iyer return (status); 3122d62bc4baSyz147064 3123bcb5c89dSSowmini Varadhan (void) memcpy(&radio, buf, sizeof (radio)); 3124d62bc4baSyz147064 switch (radio) { 3125d62bc4baSyz147064 case B_TRUE: 3126d62bc4baSyz147064 s = "on"; 3127d62bc4baSyz147064 break; 3128d62bc4baSyz147064 case B_FALSE: 3129d62bc4baSyz147064 s = "off"; 3130d62bc4baSyz147064 break; 3131d62bc4baSyz147064 default: 3132*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3133d62bc4baSyz147064 } 3134d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3135d62bc4baSyz147064 *val_cnt = 1; 3136afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 3137*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3138d62bc4baSyz147064 } 3139d62bc4baSyz147064 3140*0dc2366fSVenugopal Iyer /* ARGSUSED */ 3141d62bc4baSyz147064 static dladm_status_t 3142*0dc2366fSVenugopal Iyer set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3143*0dc2366fSVenugopal Iyer val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3144d62bc4baSyz147064 { 3145*0dc2366fSVenugopal Iyer dladm_wlan_radio_t radio = vdp->vd_val; 3146d62bc4baSyz147064 wl_radio_t r; 3147d62bc4baSyz147064 3148*0dc2366fSVenugopal Iyer if (val_cnt != 1) 3149*0dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 3150*0dc2366fSVenugopal Iyer 3151*0dc2366fSVenugopal Iyer switch (radio) { 3152d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 3153d62bc4baSyz147064 r = B_TRUE; 3154d62bc4baSyz147064 break; 3155d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 3156d62bc4baSyz147064 r = B_FALSE; 3157d62bc4baSyz147064 break; 3158d62bc4baSyz147064 default: 3159d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3160d62bc4baSyz147064 } 31614ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 3162bcb5c89dSSowmini Varadhan sizeof (r), B_TRUE)); 3163d62bc4baSyz147064 } 3164d62bc4baSyz147064 3165d62bc4baSyz147064 /* ARGSUSED */ 3166d62bc4baSyz147064 static dladm_status_t 3167*0dc2366fSVenugopal Iyer check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 3168*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 3169*0dc2366fSVenugopal Iyer val_desc_t *vdp, datalink_media_t media) 31702b24ab6bSSebastien Roy { 31712b24ab6bSSebastien Roy int32_t hlim; 31722b24ab6bSSebastien Roy char *ep; 31732b24ab6bSSebastien Roy 31742b24ab6bSSebastien Roy if (val_cnt != 1) 31752b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 31762b24ab6bSSebastien Roy 31772b24ab6bSSebastien Roy errno = 0; 31782b24ab6bSSebastien Roy hlim = strtol(*prop_val, &ep, 10); 31792b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || hlim < 1 || 31802b24ab6bSSebastien Roy hlim > (int32_t)UINT8_MAX) 31812b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 31822b24ab6bSSebastien Roy vdp->vd_val = hlim; 31832b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 31842b24ab6bSSebastien Roy } 31852b24ab6bSSebastien Roy 31862b24ab6bSSebastien Roy /* ARGSUSED */ 31872b24ab6bSSebastien Roy static dladm_status_t 3188*0dc2366fSVenugopal Iyer check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3189*0dc2366fSVenugopal Iyer char **prop_val, uint_t val_cnt, uint_t flags, val_desc_t *vdp, 3190*0dc2366fSVenugopal Iyer datalink_media_t media) 31912b24ab6bSSebastien Roy { 31922b24ab6bSSebastien Roy int32_t elim; 31932b24ab6bSSebastien Roy char *ep; 31942b24ab6bSSebastien Roy 31952b24ab6bSSebastien Roy if (media != DL_IPV6) 31962b24ab6bSSebastien Roy return (DLADM_STATUS_BADARG); 31972b24ab6bSSebastien Roy 31982b24ab6bSSebastien Roy if (val_cnt != 1) 31992b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 32002b24ab6bSSebastien Roy 32012b24ab6bSSebastien Roy errno = 0; 32022b24ab6bSSebastien Roy elim = strtol(*prop_val, &ep, 10); 32032b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || elim < 0 || 32042b24ab6bSSebastien Roy elim > (int32_t)UINT8_MAX) 32052b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 32062b24ab6bSSebastien Roy vdp->vd_val = elim; 32072b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 32082b24ab6bSSebastien Roy } 32092b24ab6bSSebastien Roy 3210d62bc4baSyz147064 static dladm_status_t 32114ac67f02SAnurag S. Maskey i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 32124ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 3213d62bc4baSyz147064 { 3214d62bc4baSyz147064 char buf[MAXLINELEN]; 3215d62bc4baSyz147064 int i; 3216d62bc4baSyz147064 dladm_conf_t conf; 3217d62bc4baSyz147064 dladm_status_t status; 3218d62bc4baSyz147064 32194ac67f02SAnurag S. Maskey status = dladm_read_conf(handle, linkid, &conf); 3220f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 3221f4b3ec61Sdh155122 return (status); 3222f4b3ec61Sdh155122 3223d62bc4baSyz147064 /* 3224d62bc4baSyz147064 * reset case. 3225d62bc4baSyz147064 */ 3226d62bc4baSyz147064 if (val_cnt == 0) { 32274ac67f02SAnurag S. Maskey status = dladm_unset_conf_field(handle, conf, prop_name); 3228d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 32294ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3230d62bc4baSyz147064 goto done; 3231f4b3ec61Sdh155122 } 3232f4b3ec61Sdh155122 3233d62bc4baSyz147064 buf[0] = '\0'; 3234d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 3235d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 3236d62bc4baSyz147064 if (i != val_cnt - 1) 3237d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 3238d62bc4baSyz147064 } 3239f4b3ec61Sdh155122 32404ac67f02SAnurag S. Maskey status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 32414ac67f02SAnurag S. Maskey buf); 3242d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 32434ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3244d62bc4baSyz147064 3245d62bc4baSyz147064 done: 32464ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3247f4b3ec61Sdh155122 return (status); 3248f4b3ec61Sdh155122 } 3249f4b3ec61Sdh155122 3250f4b3ec61Sdh155122 static dladm_status_t 32514ac67f02SAnurag S. Maskey i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 32524ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 3253f4b3ec61Sdh155122 { 3254d62bc4baSyz147064 char buf[MAXLINELEN], *str; 3255d62bc4baSyz147064 uint_t cnt = 0; 3256d62bc4baSyz147064 dladm_conf_t conf; 3257d62bc4baSyz147064 dladm_status_t status; 3258f4b3ec61Sdh155122 32594ac67f02SAnurag S. Maskey status = dladm_read_conf(handle, linkid, &conf); 3260d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3261f4b3ec61Sdh155122 return (status); 3262d62bc4baSyz147064 32634ac67f02SAnurag S. Maskey status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 3264d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3265d62bc4baSyz147064 goto done; 3266d62bc4baSyz147064 3267d62bc4baSyz147064 str = strtok(buf, ","); 3268d62bc4baSyz147064 while (str != NULL) { 3269d62bc4baSyz147064 if (cnt == *val_cntp) { 3270d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 3271d62bc4baSyz147064 goto done; 3272d62bc4baSyz147064 } 3273d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 3274d62bc4baSyz147064 str = strtok(NULL, ","); 3275f4b3ec61Sdh155122 } 3276f4b3ec61Sdh155122 3277d62bc4baSyz147064 *val_cntp = cnt; 3278f4b3ec61Sdh155122 3279d62bc4baSyz147064 done: 32804ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3281d62bc4baSyz147064 return (status); 3282f4b3ec61Sdh155122 } 3283e7801d59Ssowmini 328462ee1d25SArtem Kachitchkine /* 328562ee1d25SArtem Kachitchkine * Walk persistent private link properties of a link. 328662ee1d25SArtem Kachitchkine */ 328762ee1d25SArtem Kachitchkine static dladm_status_t 328862ee1d25SArtem Kachitchkine i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 328962ee1d25SArtem Kachitchkine void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 329062ee1d25SArtem Kachitchkine { 329162ee1d25SArtem Kachitchkine dladm_status_t status; 329262ee1d25SArtem Kachitchkine dladm_conf_t conf; 329362ee1d25SArtem Kachitchkine char last_attr[MAXLINKATTRLEN]; 329462ee1d25SArtem Kachitchkine char attr[MAXLINKATTRLEN]; 329562ee1d25SArtem Kachitchkine char attrval[MAXLINKATTRVALLEN]; 329662ee1d25SArtem Kachitchkine size_t attrsz; 329762ee1d25SArtem Kachitchkine 329862ee1d25SArtem Kachitchkine if (linkid == DATALINK_INVALID_LINKID || func == NULL) 329962ee1d25SArtem Kachitchkine return (DLADM_STATUS_BADARG); 330062ee1d25SArtem Kachitchkine 330162ee1d25SArtem Kachitchkine status = dladm_read_conf(handle, linkid, &conf); 330262ee1d25SArtem Kachitchkine if (status != DLADM_STATUS_OK) 330362ee1d25SArtem Kachitchkine return (status); 330462ee1d25SArtem Kachitchkine 330562ee1d25SArtem Kachitchkine last_attr[0] = '\0'; 330662ee1d25SArtem Kachitchkine while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 330762ee1d25SArtem Kachitchkine attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 330862ee1d25SArtem Kachitchkine if (attr[0] == '_') { 330962ee1d25SArtem Kachitchkine if (func(handle, linkid, attr, arg) == 331062ee1d25SArtem Kachitchkine DLADM_WALK_TERMINATE) 331162ee1d25SArtem Kachitchkine break; 331262ee1d25SArtem Kachitchkine } 331362ee1d25SArtem Kachitchkine (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 331462ee1d25SArtem Kachitchkine } 331562ee1d25SArtem Kachitchkine 331662ee1d25SArtem Kachitchkine dladm_destroy_conf(handle, conf); 331762ee1d25SArtem Kachitchkine return (DLADM_STATUS_OK); 331862ee1d25SArtem Kachitchkine } 331962ee1d25SArtem Kachitchkine 3320bcb5c89dSSowmini Varadhan static link_attr_t * 3321e7801d59Ssowmini dladm_name2prop(const char *prop_name) 3322e7801d59Ssowmini { 3323bcb5c89dSSowmini Varadhan link_attr_t *p; 3324e7801d59Ssowmini 3325bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3326e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 3327e7801d59Ssowmini break; 3328e7801d59Ssowmini } 3329e7801d59Ssowmini return (p); 3330e7801d59Ssowmini } 3331e7801d59Ssowmini 3332bcb5c89dSSowmini Varadhan static link_attr_t * 3333bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid) 3334bcb5c89dSSowmini Varadhan { 3335bcb5c89dSSowmini Varadhan link_attr_t *p; 3336bcb5c89dSSowmini Varadhan 3337bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3338bcb5c89dSSowmini Varadhan if (p->pp_id == propid) 3339bcb5c89dSSowmini Varadhan break; 3340bcb5c89dSSowmini Varadhan } 3341bcb5c89dSSowmini Varadhan return (p); 3342bcb5c89dSSowmini Varadhan } 3343e7801d59Ssowmini 33443fd94f8cSam223141 static dld_ioc_macprop_t * 3345bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 3346bcb5c89dSSowmini Varadhan const char *prop_name, mac_prop_id_t propid, uint_t flags, 3347bcb5c89dSSowmini Varadhan dladm_status_t *status) 3348e7801d59Ssowmini { 3349e7801d59Ssowmini int dsize; 33503fd94f8cSam223141 dld_ioc_macprop_t *dip; 3351e7801d59Ssowmini 3352e7801d59Ssowmini *status = DLADM_STATUS_OK; 33533fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 3354e7801d59Ssowmini dip = malloc(dsize); 3355e7801d59Ssowmini if (dip == NULL) { 3356e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 3357e7801d59Ssowmini return (NULL); 3358e7801d59Ssowmini } 3359e7801d59Ssowmini bzero(dip, dsize); 3360e7801d59Ssowmini dip->pr_valsize = valsize; 33614045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 33626b9e797cSsowmini dip->pr_linkid = linkid; 3363bcb5c89dSSowmini Varadhan dip->pr_num = propid; 33644045d941Ssowmini dip->pr_flags = flags; 3365e7801d59Ssowmini return (dip); 3366e7801d59Ssowmini } 3367e7801d59Ssowmini 3368bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3369bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 3370bcb5c89dSSowmini Varadhan const char *prop_name, uint_t flags, dladm_status_t *status) 3371bcb5c89dSSowmini Varadhan { 3372bcb5c89dSSowmini Varadhan link_attr_t *p; 3373bcb5c89dSSowmini Varadhan 3374bcb5c89dSSowmini Varadhan p = dladm_name2prop(prop_name); 3375bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3376bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 3377bcb5c89dSSowmini Varadhan flags, status)); 3378bcb5c89dSSowmini Varadhan } 3379bcb5c89dSSowmini Varadhan 3380bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3381bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 3382bcb5c89dSSowmini Varadhan mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 3383bcb5c89dSSowmini Varadhan { 3384bcb5c89dSSowmini Varadhan link_attr_t *p; 3385bcb5c89dSSowmini Varadhan 3386bcb5c89dSSowmini Varadhan p = dladm_id2prop(propid); 3387bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3388bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 3389bcb5c89dSSowmini Varadhan flags, status)); 3390bcb5c89dSSowmini Varadhan } 3391bcb5c89dSSowmini Varadhan 3392e7801d59Ssowmini /* ARGSUSED */ 3393e7801d59Ssowmini static dladm_status_t 3394*0dc2366fSVenugopal Iyer set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 33954ac67f02SAnurag S. Maskey datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 33964ac67f02SAnurag S. Maskey datalink_media_t media) 3397e7801d59Ssowmini { 33983fd94f8cSam223141 dld_ioc_macprop_t *dip; 3399e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 3400e7801d59Ssowmini uint8_t u8; 3401e7801d59Ssowmini uint16_t u16; 3402e7801d59Ssowmini uint32_t u32; 3403e7801d59Ssowmini void *val; 3404e7801d59Ssowmini 3405da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 3406e7801d59Ssowmini if (dip == NULL) 3407e7801d59Ssowmini return (status); 3408e7801d59Ssowmini 3409da14cebeSEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 3410e7801d59Ssowmini val = (void *)vdp->vd_val; 3411e7801d59Ssowmini else { 3412e7801d59Ssowmini /* 3413e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 3414e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 3415e7801d59Ssowmini */ 3416e7801d59Ssowmini switch (dip->pr_valsize) { 3417e7801d59Ssowmini case 1: 3418e7801d59Ssowmini u8 = vdp->vd_val; 3419e7801d59Ssowmini val = &u8; 3420e7801d59Ssowmini break; 3421e7801d59Ssowmini case 2: 3422e7801d59Ssowmini u16 = vdp->vd_val; 3423e7801d59Ssowmini val = &u16; 3424e7801d59Ssowmini break; 3425e7801d59Ssowmini case 4: 3426e7801d59Ssowmini u32 = vdp->vd_val; 3427e7801d59Ssowmini val = &u32; 3428e7801d59Ssowmini break; 3429e7801d59Ssowmini default: 3430e7801d59Ssowmini val = &vdp->vd_val; 3431e7801d59Ssowmini break; 3432e7801d59Ssowmini } 3433e7801d59Ssowmini } 3434e7801d59Ssowmini 34353bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 3436e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 34373bc21d0aSAruna Ramakrishna - Sun Microsystems else 34383bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 34393bc21d0aSAruna Ramakrishna - Sun Microsystems 34404ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 3441bcb5c89dSSowmini Varadhan 3442bcb5c89dSSowmini Varadhan done: 3443bcb5c89dSSowmini Varadhan free(dip); 3444bcb5c89dSSowmini Varadhan return (status); 3445bcb5c89dSSowmini Varadhan } 3446bcb5c89dSSowmini Varadhan 3447bcb5c89dSSowmini Varadhan dladm_status_t 34484ac67f02SAnurag S. Maskey i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 3449bcb5c89dSSowmini Varadhan { 3450bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 3451bcb5c89dSSowmini Varadhan 34524ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), 34534ac67f02SAnurag S. Maskey (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 3454e7801d59Ssowmini status = dladm_errno2status(errno); 3455e7801d59Ssowmini 3456e7801d59Ssowmini return (status); 3457e7801d59Ssowmini } 3458e7801d59Ssowmini 3459*0dc2366fSVenugopal Iyer static dladm_status_t 34604ac67f02SAnurag S. Maskey i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 3461*0dc2366fSVenugopal Iyer char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 3462e7801d59Ssowmini { 3463*0dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 3464*0dc2366fSVenugopal Iyer dladm_status_t status; 34654045d941Ssowmini 3466*0dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 34674045d941Ssowmini if (dip == NULL) 3468*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 3469e7801d59Ssowmini 3470*0dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 3471*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) { 34724045d941Ssowmini free(dip); 3473*0dc2366fSVenugopal Iyer return (status); 34744045d941Ssowmini } 3475*0dc2366fSVenugopal Iyer 3476da14cebeSEric Cheng if (perm_flags != NULL) 3477da14cebeSEric Cheng *perm_flags = dip->pr_perm_flags; 3478da14cebeSEric Cheng 3479*0dc2366fSVenugopal Iyer if (arg != NULL) 3480*0dc2366fSVenugopal Iyer (void) memcpy(arg, dip->pr_val, size); 3481*0dc2366fSVenugopal Iyer free(dip); 3482*0dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3483e7801d59Ssowmini } 3484e7801d59Ssowmini 3485e7801d59Ssowmini /* ARGSUSED */ 3486e7801d59Ssowmini static dladm_status_t 3487*0dc2366fSVenugopal Iyer check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 3488*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 3489*0dc2366fSVenugopal Iyer val_desc_t *v, datalink_media_t media) 3490e7801d59Ssowmini { 3491e7801d59Ssowmini if (val_cnt != 1) 3492e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 34934eaa4710SRishi Srivatsavai v->vd_val = strtoul(prop_val[0], NULL, 0); 3494e7801d59Ssowmini return (DLADM_STATUS_OK); 3495e7801d59Ssowmini } 3496e7801d59Ssowmini 3497e7801d59Ssowmini /* ARGSUSED */ 3498e7801d59Ssowmini static dladm_status_t 3499*0dc2366fSVenugopal Iyer get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 35004ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35014ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3502e7801d59Ssowmini { 3503e7801d59Ssowmini link_duplex_t link_duplex; 3504e7801d59Ssowmini dladm_status_t status; 3505e7801d59Ssowmini 35064ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 3507e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 3508e7801d59Ssowmini return (status); 3509e7801d59Ssowmini 3510e7801d59Ssowmini switch (link_duplex) { 3511e7801d59Ssowmini case LINK_DUPLEX_FULL: 3512e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 3513e7801d59Ssowmini break; 3514e7801d59Ssowmini case LINK_DUPLEX_HALF: 3515e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 3516e7801d59Ssowmini break; 3517e7801d59Ssowmini default: 3518e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3519e7801d59Ssowmini break; 3520e7801d59Ssowmini } 3521e7801d59Ssowmini *val_cnt = 1; 3522e7801d59Ssowmini return (DLADM_STATUS_OK); 3523e7801d59Ssowmini } 3524e7801d59Ssowmini 3525e7801d59Ssowmini /* ARGSUSED */ 3526e7801d59Ssowmini static dladm_status_t 3527*0dc2366fSVenugopal Iyer get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3528*0dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 3529*0dc2366fSVenugopal Iyer uint_t *perm_flags) 3530e7801d59Ssowmini { 3531e7801d59Ssowmini uint64_t ifspeed = 0; 3532e7801d59Ssowmini dladm_status_t status; 3533e7801d59Ssowmini 35344ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 3535e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 3536e7801d59Ssowmini return (status); 35374045d941Ssowmini 35386b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 35396b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 35406b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 35416b9e797cSsowmini } else { 3542e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 3543e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 35446b9e797cSsowmini } 3545e7801d59Ssowmini *val_cnt = 1; 3546da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 3547e7801d59Ssowmini return (DLADM_STATUS_OK); 3548e7801d59Ssowmini } 3549e7801d59Ssowmini 3550e7801d59Ssowmini /* ARGSUSED */ 3551e7801d59Ssowmini static dladm_status_t 3552*0dc2366fSVenugopal Iyer get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 35534ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35544ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3555e7801d59Ssowmini { 3556e7801d59Ssowmini link_state_t link_state; 3557e7801d59Ssowmini dladm_status_t status; 3558e7801d59Ssowmini 3559*0dc2366fSVenugopal Iyer status = dladm_get_state(handle, linkid, &link_state); 35604045d941Ssowmini if (status != DLADM_STATUS_OK) 3561e7801d59Ssowmini return (status); 3562da14cebeSEric Cheng 3563e7801d59Ssowmini switch (link_state) { 3564e7801d59Ssowmini case LINK_STATE_UP: 3565e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 3566e7801d59Ssowmini break; 3567e7801d59Ssowmini case LINK_STATE_DOWN: 3568e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 3569e7801d59Ssowmini break; 3570e7801d59Ssowmini default: 3571e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3572e7801d59Ssowmini break; 3573e7801d59Ssowmini } 3574e7801d59Ssowmini *val_cnt = 1; 35754784fcbdSSowmini Varadhan *perm_flags = MAC_PROP_PERM_READ; 3576e7801d59Ssowmini return (DLADM_STATUS_OK); 3577e7801d59Ssowmini } 3578e7801d59Ssowmini 3579e7801d59Ssowmini /* ARGSUSED */ 3580e7801d59Ssowmini static dladm_status_t 3581*0dc2366fSVenugopal Iyer get_binary(dladm_handle_t handle, prop_desc_t *pdp, 35824ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35834ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3584e7801d59Ssowmini { 3585e7801d59Ssowmini dladm_status_t status; 3586*0dc2366fSVenugopal Iyer uint_t v = 0; 3587e7801d59Ssowmini 3588*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3589*0dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 3590*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3591e7801d59Ssowmini return (status); 3592da14cebeSEric Cheng 3593*0dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 3594e7801d59Ssowmini *val_cnt = 1; 3595e7801d59Ssowmini return (DLADM_STATUS_OK); 3596e7801d59Ssowmini } 3597e7801d59Ssowmini 35986b9e797cSsowmini /* ARGSUSED */ 3599e7801d59Ssowmini static dladm_status_t 3600*0dc2366fSVenugopal Iyer get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 36014ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36024ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3603e7801d59Ssowmini { 3604*0dc2366fSVenugopal Iyer dladm_status_t status; 36054045d941Ssowmini uint32_t v = 0; 3606e7801d59Ssowmini 3607*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3608*0dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 3609*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3610e7801d59Ssowmini return (status); 3611da14cebeSEric Cheng 36124045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 3613e7801d59Ssowmini *val_cnt = 1; 3614e7801d59Ssowmini return (DLADM_STATUS_OK); 3615e7801d59Ssowmini } 3616e7801d59Ssowmini 3617f0f2c3a5SGirish Moodalbail /* ARGSUSED */ 3618f0f2c3a5SGirish Moodalbail static dladm_status_t 3619*0dc2366fSVenugopal Iyer get_range(dladm_handle_t handle, prop_desc_t *pdp, 3620f0f2c3a5SGirish Moodalbail datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3621f0f2c3a5SGirish Moodalbail datalink_media_t media, uint_t flags, uint_t *perm_flags) 3622f0f2c3a5SGirish Moodalbail { 3623f0f2c3a5SGirish Moodalbail dld_ioc_macprop_t *dip; 3624f0f2c3a5SGirish Moodalbail dladm_status_t status = DLADM_STATUS_OK; 3625f0f2c3a5SGirish Moodalbail size_t sz; 3626f0f2c3a5SGirish Moodalbail mac_propval_range_t *rangep; 3627f0f2c3a5SGirish Moodalbail 3628f0f2c3a5SGirish Moodalbail sz = sizeof (mac_propval_range_t); 3629f0f2c3a5SGirish Moodalbail 3630f0f2c3a5SGirish Moodalbail /* 3631f0f2c3a5SGirish Moodalbail * As caller we don't know number of value ranges, the driver 3632f0f2c3a5SGirish Moodalbail * supports. To begin with we assume that number to be 1. If the 3633f0f2c3a5SGirish Moodalbail * buffer size is insufficient, driver returns back with the 3634f0f2c3a5SGirish Moodalbail * actual count of value ranges. See mac.h for more details. 3635f0f2c3a5SGirish Moodalbail */ 3636f0f2c3a5SGirish Moodalbail retry: 3637f0f2c3a5SGirish Moodalbail if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 3638f0f2c3a5SGirish Moodalbail &status)) == NULL) 3639f0f2c3a5SGirish Moodalbail return (status); 3640f0f2c3a5SGirish Moodalbail 3641f0f2c3a5SGirish Moodalbail status = i_dladm_macprop(handle, dip, B_FALSE); 3642f0f2c3a5SGirish Moodalbail if (status != DLADM_STATUS_OK) { 3643f0f2c3a5SGirish Moodalbail if (status == DLADM_STATUS_TOOSMALL) { 3644f0f2c3a5SGirish Moodalbail int err; 3645f0f2c3a5SGirish Moodalbail 3646f0f2c3a5SGirish Moodalbail rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 3647f0f2c3a5SGirish Moodalbail if ((err = i_dladm_range_size(rangep, &sz)) == 0) { 3648f0f2c3a5SGirish Moodalbail free(dip); 3649f0f2c3a5SGirish Moodalbail goto retry; 3650f0f2c3a5SGirish Moodalbail } else { 3651f0f2c3a5SGirish Moodalbail status = dladm_errno2status(err); 3652f0f2c3a5SGirish Moodalbail } 3653f0f2c3a5SGirish Moodalbail } 3654f0f2c3a5SGirish Moodalbail free(dip); 3655f0f2c3a5SGirish Moodalbail return (status); 3656f0f2c3a5SGirish Moodalbail } 3657*0dc2366fSVenugopal Iyer 3658f0f2c3a5SGirish Moodalbail rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 3659*0dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 3660*0dc2366fSVenugopal Iyer *val_cnt = 1; 3661*0dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 3662*0dc2366fSVenugopal Iyer goto done; 3663*0dc2366fSVenugopal Iyer } 3664f0f2c3a5SGirish Moodalbail 3665f0f2c3a5SGirish Moodalbail switch (rangep->mpr_type) { 3666f0f2c3a5SGirish Moodalbail case MAC_PROPVAL_UINT32: { 3667f0f2c3a5SGirish Moodalbail mac_propval_uint32_range_t *ur; 3668f0f2c3a5SGirish Moodalbail uint_t count = rangep->mpr_count, i; 3669f0f2c3a5SGirish Moodalbail 3670*0dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 3671f0f2c3a5SGirish Moodalbail 3672f0f2c3a5SGirish Moodalbail for (i = 0; i < count; i++, ur++) { 3673f0f2c3a5SGirish Moodalbail if (ur->mpur_min == ur->mpur_max) { 3674f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 3675f0f2c3a5SGirish Moodalbail "%ld", ur->mpur_min); 3676f0f2c3a5SGirish Moodalbail } else { 3677f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 3678f0f2c3a5SGirish Moodalbail "%ld-%ld", ur->mpur_min, ur->mpur_max); 3679f0f2c3a5SGirish Moodalbail } 3680f0f2c3a5SGirish Moodalbail } 3681f0f2c3a5SGirish Moodalbail *val_cnt = count; 3682f0f2c3a5SGirish Moodalbail break; 3683f0f2c3a5SGirish Moodalbail } 3684f0f2c3a5SGirish Moodalbail default: 3685f0f2c3a5SGirish Moodalbail status = DLADM_STATUS_BADARG; 3686f0f2c3a5SGirish Moodalbail break; 3687f0f2c3a5SGirish Moodalbail } 3688*0dc2366fSVenugopal Iyer done: 3689f0f2c3a5SGirish Moodalbail free(dip); 3690f0f2c3a5SGirish Moodalbail return (status); 3691f0f2c3a5SGirish Moodalbail } 3692f0f2c3a5SGirish Moodalbail 36936b9e797cSsowmini /* ARGSUSED */ 3694e7801d59Ssowmini static dladm_status_t 3695*0dc2366fSVenugopal Iyer get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 3696e75f0919SSebastien Roy datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3697e75f0919SSebastien Roy datalink_media_t media, uint_t flags, uint_t *perm_flags) 3698e75f0919SSebastien Roy { 3699e75f0919SSebastien Roy link_tagmode_t mode; 3700e75f0919SSebastien Roy dladm_status_t status; 3701e75f0919SSebastien Roy 3702*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3703*0dc2366fSVenugopal Iyer perm_flags, &mode, sizeof (mode)); 3704*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3705e75f0919SSebastien Roy return (status); 3706e75f0919SSebastien Roy 3707e75f0919SSebastien Roy switch (mode) { 3708e75f0919SSebastien Roy case LINK_TAGMODE_NORMAL: 3709e75f0919SSebastien Roy (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 3710e75f0919SSebastien Roy break; 3711e75f0919SSebastien Roy case LINK_TAGMODE_VLANONLY: 3712e75f0919SSebastien Roy (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 3713e75f0919SSebastien Roy break; 3714e75f0919SSebastien Roy default: 3715e75f0919SSebastien Roy (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 3716e75f0919SSebastien Roy } 3717e75f0919SSebastien Roy *val_cnt = 1; 3718e75f0919SSebastien Roy return (DLADM_STATUS_OK); 3719e75f0919SSebastien Roy } 3720e75f0919SSebastien Roy 3721e75f0919SSebastien Roy /* ARGSUSED */ 3722e75f0919SSebastien Roy static dladm_status_t 3723*0dc2366fSVenugopal Iyer get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 37244ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37254ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3726e7801d59Ssowmini { 3727e7801d59Ssowmini link_flowctrl_t v; 3728e7801d59Ssowmini dladm_status_t status; 3729e7801d59Ssowmini 3730*0dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 3731*0dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 3732*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3733e7801d59Ssowmini return (status); 3734da14cebeSEric Cheng 3735e7801d59Ssowmini switch (v) { 3736e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 3737e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 3738e7801d59Ssowmini break; 3739e7801d59Ssowmini case LINK_FLOWCTRL_RX: 3740e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 3741e7801d59Ssowmini break; 3742e7801d59Ssowmini case LINK_FLOWCTRL_TX: 3743e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 3744e7801d59Ssowmini break; 3745e7801d59Ssowmini case LINK_FLOWCTRL_BI: 3746e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 3747e7801d59Ssowmini break; 3748e7801d59Ssowmini } 3749e7801d59Ssowmini *val_cnt = 1; 3750e7801d59Ssowmini return (DLADM_STATUS_OK); 3751e7801d59Ssowmini } 3752e7801d59Ssowmini 3753e7801d59Ssowmini 3754e7801d59Ssowmini /* ARGSUSED */ 3755e7801d59Ssowmini static dladm_status_t 37563361618bSRishi Srivatsavai i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 37574ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 37584ac67f02SAnurag S. Maskey 3759e7801d59Ssowmini { 3760bcb5c89dSSowmini Varadhan int i, slen; 3761eae72b5bSSebastien Roy int bufsize = 0; 37623fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 3763e7801d59Ssowmini uchar_t *dp; 3764bcb5c89dSSowmini Varadhan link_attr_t *p; 37654045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 3766e7801d59Ssowmini 3767e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 3768e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 3769e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3770e7801d59Ssowmini p = dladm_name2prop(prop_name); 37713fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 3772e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3773e7801d59Ssowmini 37743361618bSRishi Srivatsavai if (!(flags & DLADM_OPT_ACTIVE)) 37753361618bSRishi Srivatsavai return (DLADM_STATUS_OK); 37763361618bSRishi Srivatsavai 3777e7801d59Ssowmini /* 3778e7801d59Ssowmini * private properties: all parsing is done in the kernel. 3779e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 3780e7801d59Ssowmini */ 3781e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 3782e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 3783e7801d59Ssowmini } 37844045d941Ssowmini 37854045d941Ssowmini if (prop_val == NULL) { 37864045d941Ssowmini /* 37874045d941Ssowmini * getting default value. so use more buffer space. 37884045d941Ssowmini */ 3789bcb5c89dSSowmini Varadhan bufsize += DLADM_PROP_BUF_CHUNK; 37904045d941Ssowmini } 37914045d941Ssowmini 3792bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 3793*0dc2366fSVenugopal Iyer (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 3794e7801d59Ssowmini if (dip == NULL) 3795e7801d59Ssowmini return (status); 3796e7801d59Ssowmini 3797e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 3798e7801d59Ssowmini slen = 0; 3799bcb5c89dSSowmini Varadhan 38004045d941Ssowmini if (prop_val == NULL) { 38014ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_FALSE); 380262ee1d25SArtem Kachitchkine dip->pr_flags = 0; 38034045d941Ssowmini } else { 3804e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 3805e7801d59Ssowmini int plen = 0; 3806e7801d59Ssowmini 3807e7801d59Ssowmini plen = strlen(prop_val[i]); 3808e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 3809e7801d59Ssowmini slen += plen; 3810e7801d59Ssowmini /* 3811e7801d59Ssowmini * add a "," separator and update dp. 3812e7801d59Ssowmini */ 3813e7801d59Ssowmini if (i != (val_cnt -1)) 3814e7801d59Ssowmini dp[slen++] = ','; 3815e7801d59Ssowmini dp += (plen + 1); 3816e7801d59Ssowmini } 3817e7801d59Ssowmini } 381862ee1d25SArtem Kachitchkine if (status == DLADM_STATUS_OK) 381962ee1d25SArtem Kachitchkine status = i_dladm_macprop(handle, dip, B_TRUE); 38204045d941Ssowmini 3821e7801d59Ssowmini free(dip); 3822e7801d59Ssowmini return (status); 3823e7801d59Ssowmini } 3824e7801d59Ssowmini 3825e7801d59Ssowmini static dladm_status_t 382662ee1d25SArtem Kachitchkine i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 38274ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cnt, 38284ac67f02SAnurag S. Maskey dladm_prop_type_t type, uint_t dld_flags) 3829e7801d59Ssowmini { 3830e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 38313fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 3832bcb5c89dSSowmini Varadhan link_attr_t *p; 3833e7801d59Ssowmini 3834e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 3835e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 3836e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3837e7801d59Ssowmini 3838e7801d59Ssowmini p = dladm_name2prop(prop_name); 38393fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 3840e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3841e7801d59Ssowmini 3842e7801d59Ssowmini /* 3843e7801d59Ssowmini * private properties: all parsing is done in the kernel. 3844e7801d59Ssowmini */ 3845bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 3846bcb5c89dSSowmini Varadhan dld_flags, &status); 3847e7801d59Ssowmini if (dip == NULL) 3848e7801d59Ssowmini return (status); 3849e7801d59Ssowmini 38504ac67f02SAnurag S. Maskey if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 38514ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 3852afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_PERM) { 3853da14cebeSEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 385462ee1d25SArtem Kachitchkine } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 385562ee1d25SArtem Kachitchkine *prop_val[0] = '\0'; 3856afdda45fSVasumathi Sundaram - Sun Microsystems } else { 3857afdda45fSVasumathi Sundaram - Sun Microsystems (void) strncpy(*prop_val, dip->pr_val, 3858afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_MAX); 3859afdda45fSVasumathi Sundaram - Sun Microsystems } 3860e7801d59Ssowmini *val_cnt = 1; 386162ee1d25SArtem Kachitchkine } else if ((status == DLADM_STATUS_NOTSUP) && 386262ee1d25SArtem Kachitchkine (type == DLADM_PROP_VAL_CURRENT)) { 386362ee1d25SArtem Kachitchkine status = DLADM_STATUS_NOTFOUND; 3864e7801d59Ssowmini } 38654045d941Ssowmini free(dip); 38664045d941Ssowmini return (status); 38674045d941Ssowmini } 38684045d941Ssowmini 38694045d941Ssowmini 38704045d941Ssowmini static dladm_status_t 38714ac67f02SAnurag S. Maskey i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 38724ac67f02SAnurag S. Maskey datalink_id_t linkid, datalink_media_t media, uint_t flags) 38734045d941Ssowmini { 38744045d941Ssowmini dladm_status_t status; 38754045d941Ssowmini char **prop_vals = NULL, *buf; 38764045d941Ssowmini size_t bufsize; 38774045d941Ssowmini uint_t cnt; 38784045d941Ssowmini int i; 3879afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 38804045d941Ssowmini 38814045d941Ssowmini /* 38824045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 38834045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 38844045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 38854045d941Ssowmini */ 38864045d941Ssowmini bufsize = 38874045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 38884045d941Ssowmini buf = malloc(bufsize); 38894045d941Ssowmini prop_vals = (char **)(void *)buf; 38904045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 38914045d941Ssowmini prop_vals[i] = buf + 38924045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 38934045d941Ssowmini i * DLADM_PROP_VAL_MAX; 38944045d941Ssowmini } 389513a55820Sar224390 389613a55820Sar224390 /* 38973bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 38983bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 38993bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 39003bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 39013bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 39023bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 39033bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 39043bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 390513a55820Sar224390 */ 39064ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 3907*0dc2366fSVenugopal Iyer DLD_PROP_DEFAULT, &perm_flags); 39084045d941Ssowmini if (status == DLADM_STATUS_OK) { 3909afdda45fSVasumathi Sundaram - Sun Microsystems if (perm_flags == MAC_PROP_PERM_RW) { 39104ac67f02SAnurag S. Maskey status = i_dladm_set_single_prop(handle, linkid, 39114ac67f02SAnurag S. Maskey pdp->pd_class, media, pdp, prop_vals, cnt, flags); 39124045d941Ssowmini } 3913afdda45fSVasumathi Sundaram - Sun Microsystems else 3914afdda45fSVasumathi Sundaram - Sun Microsystems status = DLADM_STATUS_NOTSUP; 3915afdda45fSVasumathi Sundaram - Sun Microsystems } 39164045d941Ssowmini free(buf); 3917e7801d59Ssowmini return (status); 3918e7801d59Ssowmini } 3919bcb5c89dSSowmini Varadhan 39204eaa4710SRishi Srivatsavai /* ARGSUSED */ 39214eaa4710SRishi Srivatsavai static dladm_status_t 3922*0dc2366fSVenugopal Iyer get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 39234eaa4710SRishi Srivatsavai char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 39244eaa4710SRishi Srivatsavai uint_t *perm_flags) 39254eaa4710SRishi Srivatsavai { 39264eaa4710SRishi Srivatsavai const bridge_public_prop_t *bpp; 39274eaa4710SRishi Srivatsavai dladm_status_t retv; 39284eaa4710SRishi Srivatsavai int val, i; 39294eaa4710SRishi Srivatsavai 39304eaa4710SRishi Srivatsavai if (flags != 0) 39314eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 39324eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 39334eaa4710SRishi Srivatsavai *val_cnt = 1; 39344eaa4710SRishi Srivatsavai for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 39354eaa4710SRishi Srivatsavai if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 39364eaa4710SRishi Srivatsavai break; 39374eaa4710SRishi Srivatsavai retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 39384eaa4710SRishi Srivatsavai /* If the daemon isn't running, then return the persistent value */ 39394eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 39404eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 39414eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 39424eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 39434eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 39444eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 39454eaa4710SRishi Srivatsavai } 39464eaa4710SRishi Srivatsavai if (retv != DLADM_STATUS_OK) { 39474eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 39484eaa4710SRishi Srivatsavai return (retv); 39494eaa4710SRishi Srivatsavai } 39504eaa4710SRishi Srivatsavai if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 39514eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 39524eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 39534eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 39544eaa4710SRishi Srivatsavai } 39554eaa4710SRishi Srivatsavai for (i = 0; i < pd->pd_noptval; i++) { 39564eaa4710SRishi Srivatsavai if (val == pd->pd_optval[i].vd_val) { 39574eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 39584eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 39594eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 39604eaa4710SRishi Srivatsavai } 39614eaa4710SRishi Srivatsavai } 39624eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 39634eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 39644eaa4710SRishi Srivatsavai } 39654eaa4710SRishi Srivatsavai 39664eaa4710SRishi Srivatsavai /* ARGSUSED1 */ 39674eaa4710SRishi Srivatsavai static dladm_status_t 39684eaa4710SRishi Srivatsavai set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 39694eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 39704eaa4710SRishi Srivatsavai { 39714eaa4710SRishi Srivatsavai /* 39724eaa4710SRishi Srivatsavai * Special case for mcheck: the daemon resets the value to zero, and we 39734eaa4710SRishi Srivatsavai * don't want the daemon to refresh itself; it leads to deadlock. 39744eaa4710SRishi Srivatsavai */ 39754eaa4710SRishi Srivatsavai if (flags & DLADM_OPT_NOREFRESH) 39764eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 39774eaa4710SRishi Srivatsavai 39784eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 39794eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 39804eaa4710SRishi Srivatsavai } 39814eaa4710SRishi Srivatsavai 39824eaa4710SRishi Srivatsavai /* 39834eaa4710SRishi Srivatsavai * This is used only for stp_priority, stp_cost, and stp_mcheck. 39844eaa4710SRishi Srivatsavai */ 39854eaa4710SRishi Srivatsavai /* ARGSUSED */ 39864eaa4710SRishi Srivatsavai static dladm_status_t 39874eaa4710SRishi Srivatsavai check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 3988*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 3989*0dc2366fSVenugopal Iyer val_desc_t *vdp, datalink_media_t media) 39904eaa4710SRishi Srivatsavai { 39914eaa4710SRishi Srivatsavai char *cp; 39924eaa4710SRishi Srivatsavai boolean_t iscost; 39934eaa4710SRishi Srivatsavai 39944eaa4710SRishi Srivatsavai if (val_cnt != 1) 39954eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 39964eaa4710SRishi Srivatsavai 39974eaa4710SRishi Srivatsavai if (prop_val == NULL) { 39984eaa4710SRishi Srivatsavai vdp->vd_val = 0; 39994eaa4710SRishi Srivatsavai } else { 40004eaa4710SRishi Srivatsavai /* Only stp_priority and stp_cost use this function */ 40014eaa4710SRishi Srivatsavai iscost = strcmp(pd->pd_name, "stp_cost") == 0; 40024eaa4710SRishi Srivatsavai 40034eaa4710SRishi Srivatsavai if (iscost && strcmp(prop_val[0], "auto") == 0) { 40044eaa4710SRishi Srivatsavai /* Illegal value 0 is allowed to mean "automatic" */ 40054eaa4710SRishi Srivatsavai vdp->vd_val = 0; 40064eaa4710SRishi Srivatsavai } else { 40074eaa4710SRishi Srivatsavai errno = 0; 40084eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 40094eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 40104eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 40114eaa4710SRishi Srivatsavai } 40124eaa4710SRishi Srivatsavai } 40134eaa4710SRishi Srivatsavai 40144eaa4710SRishi Srivatsavai if (iscost) { 40154eaa4710SRishi Srivatsavai return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 40164eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 40174eaa4710SRishi Srivatsavai } else { 40184eaa4710SRishi Srivatsavai if (vdp->vd_val > 255) 40194eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 40204eaa4710SRishi Srivatsavai /* 40214eaa4710SRishi Srivatsavai * If the user is setting stp_mcheck non-zero, then (per the 40224eaa4710SRishi Srivatsavai * IEEE management standards and UNH testing) we need to check 40234eaa4710SRishi Srivatsavai * whether this link is part of a bridge that is running RSTP. 40244eaa4710SRishi Srivatsavai * If it's not, then setting the flag is an error. Note that 40254eaa4710SRishi Srivatsavai * errors are intentionally discarded here; it's the value 40264eaa4710SRishi Srivatsavai * that's the problem -- it's not a bad value, merely one that 40274eaa4710SRishi Srivatsavai * can't be used now. 40284eaa4710SRishi Srivatsavai */ 40294eaa4710SRishi Srivatsavai if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 40304eaa4710SRishi Srivatsavai vdp->vd_val != 0) { 40314eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 40324eaa4710SRishi Srivatsavai UID_STP_CFG_T cfg; 40334eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot; 40344eaa4710SRishi Srivatsavai 40354eaa4710SRishi Srivatsavai if (dladm_bridge_getlink(handle, linkid, bridge, 40364eaa4710SRishi Srivatsavai sizeof (bridge)) != DLADM_STATUS_OK || 40374eaa4710SRishi Srivatsavai dladm_bridge_get_properties(bridge, &cfg, 40384eaa4710SRishi Srivatsavai &brprot) != DLADM_STATUS_OK) 40394eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 40404eaa4710SRishi Srivatsavai if (cfg.force_version <= 1) 40414eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 40424eaa4710SRishi Srivatsavai } 40434eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40444eaa4710SRishi Srivatsavai } 40454eaa4710SRishi Srivatsavai } 40464eaa4710SRishi Srivatsavai 40474eaa4710SRishi Srivatsavai /* ARGSUSED */ 40484eaa4710SRishi Srivatsavai static dladm_status_t 40494eaa4710SRishi Srivatsavai get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 40504eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 40514eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 40524eaa4710SRishi Srivatsavai { 40534eaa4710SRishi Srivatsavai dladm_status_t retv; 40544eaa4710SRishi Srivatsavai uint_t val; 40554eaa4710SRishi Srivatsavai 40564eaa4710SRishi Srivatsavai if (flags != 0) 40574eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 40584eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 40594eaa4710SRishi Srivatsavai *val_cnt = 1; 40604eaa4710SRishi Srivatsavai retv = dladm_bridge_get_forwarding(handle, linkid, &val); 40614eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 40624eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 40634eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 40644eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 40654eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 40664eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40674eaa4710SRishi Srivatsavai } 40684eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_OK) 40694eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 40704eaa4710SRishi Srivatsavai else 40714eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 40724eaa4710SRishi Srivatsavai return (retv); 40734eaa4710SRishi Srivatsavai } 40744eaa4710SRishi Srivatsavai 40754eaa4710SRishi Srivatsavai /* ARGSUSED */ 40764eaa4710SRishi Srivatsavai static dladm_status_t 40774eaa4710SRishi Srivatsavai set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 40784eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 40794eaa4710SRishi Srivatsavai { 40804eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 40814eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 40824eaa4710SRishi Srivatsavai } 40834eaa4710SRishi Srivatsavai 40844eaa4710SRishi Srivatsavai /* ARGSUSED */ 40854eaa4710SRishi Srivatsavai static dladm_status_t 40864eaa4710SRishi Srivatsavai get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 40874eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 40884eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 40894eaa4710SRishi Srivatsavai { 40904eaa4710SRishi Srivatsavai dladm_status_t status; 40914eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 40924eaa4710SRishi Srivatsavai uint16_t pvid; 40934eaa4710SRishi Srivatsavai 40944eaa4710SRishi Srivatsavai if (flags != 0) 40954eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 40964eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 40974eaa4710SRishi Srivatsavai *val_cnt = 1; 40984eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 40994eaa4710SRishi Srivatsavai 0, &status); 41004eaa4710SRishi Srivatsavai if (dip == NULL) 41014eaa4710SRishi Srivatsavai return (status); 41024eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_FALSE); 41034eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 41044eaa4710SRishi Srivatsavai (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 41054eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 41064eaa4710SRishi Srivatsavai } else { 41074eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 41084eaa4710SRishi Srivatsavai } 41094eaa4710SRishi Srivatsavai free(dip); 41104eaa4710SRishi Srivatsavai return (status); 41114eaa4710SRishi Srivatsavai } 41124eaa4710SRishi Srivatsavai 41134eaa4710SRishi Srivatsavai /* ARGSUSED */ 41144eaa4710SRishi Srivatsavai static dladm_status_t 41154eaa4710SRishi Srivatsavai set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 41164eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 41174eaa4710SRishi Srivatsavai { 41184eaa4710SRishi Srivatsavai dladm_status_t status; 41194eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 41204eaa4710SRishi Srivatsavai uint16_t pvid; 41214eaa4710SRishi Srivatsavai 41224eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 41234eaa4710SRishi Srivatsavai 0, &status); 41244eaa4710SRishi Srivatsavai if (dip == NULL) 41254eaa4710SRishi Srivatsavai return (status); 41264eaa4710SRishi Srivatsavai pvid = vdp->vd_val; 41274eaa4710SRishi Srivatsavai (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 41284eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_TRUE); 41294eaa4710SRishi Srivatsavai free(dip); 41304eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 41314eaa4710SRishi Srivatsavai return (status); 41324eaa4710SRishi Srivatsavai 41334eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 41344eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 41354eaa4710SRishi Srivatsavai } 41364eaa4710SRishi Srivatsavai 41374eaa4710SRishi Srivatsavai /* ARGSUSED */ 41384eaa4710SRishi Srivatsavai static dladm_status_t 41394eaa4710SRishi Srivatsavai check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 4140*0dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t val_cnt, uint_t flags, 4141*0dc2366fSVenugopal Iyer val_desc_t *vdp, datalink_media_t media) 41424eaa4710SRishi Srivatsavai { 41434eaa4710SRishi Srivatsavai char *cp; 41444eaa4710SRishi Srivatsavai 41454eaa4710SRishi Srivatsavai if (val_cnt != 1) 41464eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 41474eaa4710SRishi Srivatsavai 41484eaa4710SRishi Srivatsavai if (prop_val == NULL) { 41494eaa4710SRishi Srivatsavai vdp->vd_val = 1; 41504eaa4710SRishi Srivatsavai } else { 41514eaa4710SRishi Srivatsavai errno = 0; 41524eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 41534eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 41544eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 41554eaa4710SRishi Srivatsavai } 41564eaa4710SRishi Srivatsavai 41574eaa4710SRishi Srivatsavai return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 41584eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 41594eaa4710SRishi Srivatsavai } 41604eaa4710SRishi Srivatsavai 4161bcb5c89dSSowmini Varadhan dladm_status_t 41624ac67f02SAnurag S. Maskey i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 41634ac67f02SAnurag S. Maskey mac_prop_id_t cmd, size_t len, boolean_t set) 4164bcb5c89dSSowmini Varadhan { 4165bcb5c89dSSowmini Varadhan uint32_t flags; 4166bcb5c89dSSowmini Varadhan dladm_status_t status; 4167bcb5c89dSSowmini Varadhan uint32_t media; 4168bcb5c89dSSowmini Varadhan dld_ioc_macprop_t *dip; 4169bcb5c89dSSowmini Varadhan void *dp; 4170bcb5c89dSSowmini Varadhan 41714ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 41724ac67f02SAnurag S. Maskey &media, NULL, 0)) != DLADM_STATUS_OK) { 4173bcb5c89dSSowmini Varadhan return (status); 4174bcb5c89dSSowmini Varadhan } 4175bcb5c89dSSowmini Varadhan 4176bcb5c89dSSowmini Varadhan if (media != DL_WIFI) 4177bcb5c89dSSowmini Varadhan return (DLADM_STATUS_BADARG); 4178bcb5c89dSSowmini Varadhan 4179bcb5c89dSSowmini Varadhan if (!(flags & DLADM_OPT_ACTIVE)) 4180bcb5c89dSSowmini Varadhan return (DLADM_STATUS_TEMPONLY); 4181bcb5c89dSSowmini Varadhan 4182bcb5c89dSSowmini Varadhan if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 4183bcb5c89dSSowmini Varadhan len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 4184bcb5c89dSSowmini Varadhan 4185bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 4186bcb5c89dSSowmini Varadhan if (dip == NULL) 4187bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 4188bcb5c89dSSowmini Varadhan 4189bcb5c89dSSowmini Varadhan dp = (uchar_t *)dip->pr_val; 4190bcb5c89dSSowmini Varadhan if (set) 4191bcb5c89dSSowmini Varadhan (void) memcpy(dp, buf, len); 4192bcb5c89dSSowmini Varadhan 41934ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, set); 41940b8f0546SSowmini Varadhan if (status == DLADM_STATUS_OK) { 4195bcb5c89dSSowmini Varadhan if (!set) 4196bcb5c89dSSowmini Varadhan (void) memcpy(buf, dp, len); 4197bcb5c89dSSowmini Varadhan } 4198bcb5c89dSSowmini Varadhan 4199bcb5c89dSSowmini Varadhan free(dip); 4200bcb5c89dSSowmini Varadhan return (status); 4201bcb5c89dSSowmini Varadhan } 4202bcb5c89dSSowmini Varadhan 4203da14cebeSEric Cheng dladm_status_t 4204da14cebeSEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 4205da14cebeSEric Cheng { 420662ee1d25SArtem Kachitchkine return (dladm_parse_args(str, listp, novalues)); 4207da14cebeSEric Cheng } 4208da14cebeSEric Cheng 4209da14cebeSEric Cheng /* 4210da14cebeSEric Cheng * Retrieve the one link property from the database 4211da14cebeSEric Cheng */ 4212da14cebeSEric Cheng /*ARGSUSED*/ 4213da14cebeSEric Cheng static int 42144ac67f02SAnurag S. Maskey i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 42154ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 4216da14cebeSEric Cheng { 4217da14cebeSEric Cheng dladm_arg_list_t *proplist = arg; 4218da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4219da14cebeSEric Cheng 4220da14cebeSEric Cheng aip = &proplist->al_info[proplist->al_count]; 4221da14cebeSEric Cheng /* 4222da14cebeSEric Cheng * it is fine to point to prop_name since prop_name points to the 4223da14cebeSEric Cheng * prop_table[n].pd_name. 4224da14cebeSEric Cheng */ 4225da14cebeSEric Cheng aip->ai_name = prop_name; 4226da14cebeSEric Cheng 42274ac67f02SAnurag S. Maskey (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 42284ac67f02SAnurag S. Maskey prop_name, aip->ai_val, &aip->ai_count); 4229da14cebeSEric Cheng 4230da14cebeSEric Cheng if (aip->ai_count != 0) 4231da14cebeSEric Cheng proplist->al_count++; 4232da14cebeSEric Cheng 4233da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 4234da14cebeSEric Cheng } 4235da14cebeSEric Cheng 4236da14cebeSEric Cheng 4237da14cebeSEric Cheng /* 4238da14cebeSEric Cheng * Retrieve all link properties for a link from the database and 4239da14cebeSEric Cheng * return a property list. 4240da14cebeSEric Cheng */ 4241da14cebeSEric Cheng dladm_status_t 42424ac67f02SAnurag S. Maskey dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 42434ac67f02SAnurag S. Maskey dladm_arg_list_t **listp) 4244da14cebeSEric Cheng { 4245da14cebeSEric Cheng dladm_arg_list_t *list; 4246da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 4247da14cebeSEric Cheng 4248da14cebeSEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 4249da14cebeSEric Cheng if (list == NULL) 4250da14cebeSEric Cheng return (dladm_errno2status(errno)); 4251da14cebeSEric Cheng 42524ac67f02SAnurag S. Maskey status = dladm_walk_linkprop(handle, linkid, list, 42534ac67f02SAnurag S. Maskey i_dladm_get_one_prop); 4254da14cebeSEric Cheng 4255da14cebeSEric Cheng *listp = list; 4256da14cebeSEric Cheng return (status); 4257da14cebeSEric Cheng } 4258da14cebeSEric Cheng 4259da14cebeSEric Cheng /* 4260da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 4261da14cebeSEric Cheng * convert to a kernel structure. 4262da14cebeSEric Cheng */ 4263da14cebeSEric Cheng static dladm_status_t 42644ac67f02SAnurag S. Maskey i_dladm_link_proplist_extract_one(dladm_handle_t handle, 4265*0dc2366fSVenugopal Iyer dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 4266da14cebeSEric Cheng { 4267da14cebeSEric Cheng dladm_status_t status; 4268da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4269da14cebeSEric Cheng int i, j; 4270da14cebeSEric Cheng 4271da14cebeSEric Cheng /* Find named property in proplist */ 4272da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 4273da14cebeSEric Cheng aip = &proplist->al_info[i]; 4274da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 4275da14cebeSEric Cheng break; 4276da14cebeSEric Cheng } 4277da14cebeSEric Cheng 4278da14cebeSEric Cheng /* Property not in list */ 4279da14cebeSEric Cheng if (i == proplist->al_count) 4280da14cebeSEric Cheng return (DLADM_STATUS_OK); 4281da14cebeSEric Cheng 4282da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 4283da14cebeSEric Cheng prop_desc_t *pdp = &prop_table[i]; 4284da14cebeSEric Cheng val_desc_t *vdp; 4285da14cebeSEric Cheng 4286da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 4287da14cebeSEric Cheng if (vdp == NULL) 4288da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 4289da14cebeSEric Cheng 4290da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 4291da14cebeSEric Cheng continue; 4292da14cebeSEric Cheng 4293da14cebeSEric Cheng if (aip->ai_val == NULL) 4294da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 4295da14cebeSEric Cheng 4296da14cebeSEric Cheng /* Check property value */ 4297da14cebeSEric Cheng if (pdp->pd_check != NULL) { 42984ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 4299*0dc2366fSVenugopal Iyer aip->ai_count, flags, vdp, 0); 4300da14cebeSEric Cheng } else { 4301da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4302da14cebeSEric Cheng } 4303da14cebeSEric Cheng 4304da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4305da14cebeSEric Cheng return (status); 4306da14cebeSEric Cheng 4307da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 4308da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 4309da14cebeSEric Cheng 4310da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 4311da14cebeSEric Cheng continue; 4312da14cebeSEric Cheng 4313da14cebeSEric Cheng /* Extract kernel structure */ 4314da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 431525ec3e3dSEric Cheng status = rpp->rp_extract(vdp, 431625ec3e3dSEric Cheng aip->ai_count, arg); 4317da14cebeSEric Cheng } else { 4318da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4319da14cebeSEric Cheng } 4320da14cebeSEric Cheng break; 4321da14cebeSEric Cheng } 4322da14cebeSEric Cheng 4323da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4324da14cebeSEric Cheng return (status); 4325da14cebeSEric Cheng 4326da14cebeSEric Cheng break; 4327da14cebeSEric Cheng } 4328da14cebeSEric Cheng return (status); 4329da14cebeSEric Cheng } 4330da14cebeSEric Cheng 4331da14cebeSEric Cheng /* 4332da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 4333da14cebeSEric Cheng */ 4334da14cebeSEric Cheng dladm_status_t 43354ac67f02SAnurag S. Maskey dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 4336*0dc2366fSVenugopal Iyer mac_resource_props_t *mrp, uint_t flags) 4337da14cebeSEric Cheng { 433825ec3e3dSEric Cheng dladm_status_t status; 433925ec3e3dSEric Cheng int i; 4340da14cebeSEric Cheng 434125ec3e3dSEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 434225ec3e3dSEric Cheng status = i_dladm_link_proplist_extract_one(handle, 4343*0dc2366fSVenugopal Iyer proplist, rsrc_prop_table[i].rp_name, flags, mrp); 4344da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4345da14cebeSEric Cheng return (status); 434625ec3e3dSEric Cheng } 4347da14cebeSEric Cheng return (status); 4348da14cebeSEric Cheng } 4349da14cebeSEric Cheng 4350da14cebeSEric Cheng static const char * 4351da14cebeSEric Cheng dladm_perm2str(uint_t perm, char *buf) 4352da14cebeSEric Cheng { 4353da14cebeSEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 4354da14cebeSEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 4355da14cebeSEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 4356da14cebeSEric Cheng return (buf); 4357da14cebeSEric Cheng } 43584784fcbdSSowmini Varadhan 43594784fcbdSSowmini Varadhan dladm_status_t 4360*0dc2366fSVenugopal Iyer dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 43614ac67f02SAnurag S. Maskey link_state_t *state) 43624784fcbdSSowmini Varadhan { 43634784fcbdSSowmini Varadhan uint_t perms; 43644784fcbdSSowmini Varadhan 4365*0dc2366fSVenugopal Iyer return (i_dladm_get_public_prop(handle, linkid, "state", 0, 4366*0dc2366fSVenugopal Iyer &perms, state, sizeof (*state))); 43674784fcbdSSowmini Varadhan } 436862ee1d25SArtem Kachitchkine 436962ee1d25SArtem Kachitchkine boolean_t 437062ee1d25SArtem Kachitchkine dladm_attr_is_linkprop(const char *name) 437162ee1d25SArtem Kachitchkine { 437262ee1d25SArtem Kachitchkine /* non-property attribute names */ 437362ee1d25SArtem Kachitchkine const char *nonprop[] = { 437462ee1d25SArtem Kachitchkine /* dlmgmtd core attributes */ 437562ee1d25SArtem Kachitchkine "name", 437662ee1d25SArtem Kachitchkine "class", 437762ee1d25SArtem Kachitchkine "media", 437862ee1d25SArtem Kachitchkine FPHYMAJ, 437962ee1d25SArtem Kachitchkine FPHYINST, 438062ee1d25SArtem Kachitchkine FDEVNAME, 438162ee1d25SArtem Kachitchkine 438262ee1d25SArtem Kachitchkine /* other attributes for vlan, aggr, etc */ 438362ee1d25SArtem Kachitchkine DLADM_ATTR_NAMES 438462ee1d25SArtem Kachitchkine }; 438562ee1d25SArtem Kachitchkine boolean_t is_nonprop = B_FALSE; 438662ee1d25SArtem Kachitchkine int i; 438762ee1d25SArtem Kachitchkine 438862ee1d25SArtem Kachitchkine for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 438962ee1d25SArtem Kachitchkine if (strcmp(name, nonprop[i]) == 0) { 439062ee1d25SArtem Kachitchkine is_nonprop = B_TRUE; 439162ee1d25SArtem Kachitchkine break; 439262ee1d25SArtem Kachitchkine } 439362ee1d25SArtem Kachitchkine } 439462ee1d25SArtem Kachitchkine 439562ee1d25SArtem Kachitchkine return (!is_nonprop); 439662ee1d25SArtem Kachitchkine } 4397*0dc2366fSVenugopal Iyer 4398*0dc2366fSVenugopal Iyer dladm_status_t 4399*0dc2366fSVenugopal Iyer dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 4400*0dc2366fSVenugopal Iyer dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 4401*0dc2366fSVenugopal Iyer { 4402*0dc2366fSVenugopal Iyer char *buf, **propvals; 4403*0dc2366fSVenugopal Iyer uint_t valcnt = DLADM_MAX_PROP_VALCNT; 4404*0dc2366fSVenugopal Iyer int i; 4405*0dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 4406*0dc2366fSVenugopal Iyer 4407*0dc2366fSVenugopal Iyer *is_set = B_FALSE; 4408*0dc2366fSVenugopal Iyer 4409*0dc2366fSVenugopal Iyer if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 4410*0dc2366fSVenugopal Iyer DLADM_MAX_PROP_VALCNT)) == NULL) 4411*0dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 4412*0dc2366fSVenugopal Iyer 4413*0dc2366fSVenugopal Iyer propvals = (char **)(void *)buf; 4414*0dc2366fSVenugopal Iyer for (i = 0; i < valcnt; i++) { 4415*0dc2366fSVenugopal Iyer propvals[i] = buf + 4416*0dc2366fSVenugopal Iyer sizeof (char *) * DLADM_MAX_PROP_VALCNT + 4417*0dc2366fSVenugopal Iyer i * DLADM_PROP_VAL_MAX; 4418*0dc2366fSVenugopal Iyer } 4419*0dc2366fSVenugopal Iyer 4420*0dc2366fSVenugopal Iyer if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 4421*0dc2366fSVenugopal Iyer &valcnt) != DLADM_STATUS_OK) { 4422*0dc2366fSVenugopal Iyer goto done; 4423*0dc2366fSVenugopal Iyer } 4424*0dc2366fSVenugopal Iyer 4425*0dc2366fSVenugopal Iyer if ((strcmp(prop_name, "pool") == 0) && (strlen(*propvals) != 0)) { 4426*0dc2366fSVenugopal Iyer *is_set = B_TRUE; 4427*0dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 4428*0dc2366fSVenugopal Iyer *is_set = B_TRUE; 4429*0dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 4430*0dc2366fSVenugopal Iyer (strcmp(propvals[0], "true") == 0)) { 4431*0dc2366fSVenugopal Iyer *is_set = B_TRUE; 4432*0dc2366fSVenugopal Iyer } 4433*0dc2366fSVenugopal Iyer 4434*0dc2366fSVenugopal Iyer done: 4435*0dc2366fSVenugopal Iyer if (buf != NULL) 4436*0dc2366fSVenugopal Iyer free(buf); 4437*0dc2366fSVenugopal Iyer return (status); 4438*0dc2366fSVenugopal Iyer } 4439