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 /* 221cfa752fSRamaswamy Tummala * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 230ba2cbe9Sxc151355 */ 240ba2cbe9Sxc151355 250ba2cbe9Sxc151355 #include <stdlib.h> 26c569ef53SMichael Lim #include <string.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> 451cfa752fSRamaswamy Tummala #include <libdlib.h> 46da14cebeSEric Cheng #include <libintl.h> 47f4b3ec61Sdh155122 #include <dlfcn.h> 48f4b3ec61Sdh155122 #include <link.h> 49d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 50e7801d59Ssowmini #include <libdladm.h> 51da14cebeSEric Cheng #include <libdlstat.h> 52e7801d59Ssowmini #include <sys/param.h> 53da14cebeSEric Cheng #include <sys/debug.h> 54da14cebeSEric Cheng #include <sys/dld.h> 55e7801d59Ssowmini #include <inttypes.h> 56e7801d59Ssowmini #include <sys/ethernet.h> 572b24ab6bSSebastien Roy #include <inet/iptun.h> 58bcb5c89dSSowmini Varadhan #include <net/wpa.h> 59bcb5c89dSSowmini Varadhan #include <sys/sysmacros.h> 604eaa4710SRishi Srivatsavai #include <sys/vlan.h> 614eaa4710SRishi Srivatsavai #include <libdlbridge.h> 624eaa4710SRishi Srivatsavai #include <stp_in.h> 630dc2366fSVenugopal Iyer #include <netinet/dhcp.h> 640dc2366fSVenugopal Iyer #include <netinet/dhcp6.h> 650dc2366fSVenugopal Iyer #include <net/if_types.h> 660dc2366fSVenugopal Iyer #include <libinetutil.h> 670dc2366fSVenugopal Iyer #include <pool.h> 68f4b3ec61Sdh155122 69d62bc4baSyz147064 /* 70d62bc4baSyz147064 * The linkprop get() callback. 71da14cebeSEric Cheng * - pd: pointer to the prop_desc_t 72d62bc4baSyz147064 * - propstrp: a property string array to keep the returned property. 73d62bc4baSyz147064 * Caller allocated. 74d62bc4baSyz147064 * - cntp: number of returned properties. 75d62bc4baSyz147064 * Caller also uses it to indicate how many it expects. 76d62bc4baSyz147064 */ 77e7801d59Ssowmini struct prop_desc; 78da14cebeSEric Cheng typedef struct prop_desc prop_desc_t; 79e7801d59Ssowmini 804ac67f02SAnurag S. Maskey typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 816b9e797cSsowmini datalink_id_t, char **propstp, uint_t *cntp, 82afdda45fSVasumathi Sundaram - Sun Microsystems datalink_media_t, uint_t, uint_t *); 83f4b3ec61Sdh155122 84d62bc4baSyz147064 /* 85d62bc4baSyz147064 * The linkprop set() callback. 86d62bc4baSyz147064 * - propval: a val_desc_t array which keeps the property values to be set. 87d62bc4baSyz147064 * - cnt: number of properties to be set. 88e7801d59Ssowmini * - flags: additional flags passed down the system call. 89e7801d59Ssowmini * 90e7801d59Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 91e7801d59Ssowmini * a format suitable for kernel consumption. This may require allocation 92e7801d59Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 93e7801d59Ssowmini * by all other pd_sets) which invokes the ioctl. 94d62bc4baSyz147064 */ 954ac67f02SAnurag S. Maskey typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 966b9e797cSsowmini val_desc_t *propval, uint_t cnt, uint_t flags, 976b9e797cSsowmini datalink_media_t); 98f4b3ec61Sdh155122 99d62bc4baSyz147064 /* 100d62bc4baSyz147064 * The linkprop check() callback. 101d62bc4baSyz147064 * - propstrp: property string array which keeps the property to be checked. 102d62bc4baSyz147064 * - cnt: number of properties. 103d62bc4baSyz147064 * - propval: return value; the property values of the given property strings. 104e7801d59Ssowmini * 105e7801d59Ssowmini * pd_check checks that the input values are valid. It does so by 106e7801d59Ssowmini * iteraring through the pd_modval list for the property. If 107e7801d59Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 108e7801d59Ssowmini * specific to this property can be used. If the input values are 109e7801d59Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 110e7801d59Ssowmini * with either a val_desc_t found on the pd_modval list or something 111e7801d59Ssowmini * generated on the fly. 112d62bc4baSyz147064 */ 1134ac67f02SAnurag S. Maskey typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 114c569ef53SMichael Lim datalink_id_t, char **propstrp, uint_t *cnt, 115c569ef53SMichael Lim uint_t flags, val_desc_t **propval, 1160dc2366fSVenugopal Iyer datalink_media_t); 117f4b3ec61Sdh155122 118bcb5c89dSSowmini Varadhan typedef struct link_attr_s { 1193fd94f8cSam223141 mac_prop_id_t pp_id; 120e7801d59Ssowmini size_t pp_valsize; 121e7801d59Ssowmini char *pp_name; 122bcb5c89dSSowmini Varadhan } link_attr_t; 123e7801d59Ssowmini 1240dc2366fSVenugopal Iyer typedef struct dladm_linkprop_args_s { 1250dc2366fSVenugopal Iyer dladm_status_t dla_status; 1260dc2366fSVenugopal Iyer uint_t dla_flags; 1270dc2366fSVenugopal Iyer } dladm_linkprop_args_t; 1280dc2366fSVenugopal Iyer 129bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 130bcb5c89dSSowmini Varadhan const char *, uint_t, dladm_status_t *); 131bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 132da14cebeSEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 1330dc2366fSVenugopal Iyer static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 1340dc2366fSVenugopal Iyer char *, uint_t, uint_t *, void *, size_t); 135da14cebeSEric Cheng 1363361618bSRishi Srivatsavai static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1374ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 13862ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1394ac67f02SAnurag S. Maskey const char *, char **, uint_t *, dladm_prop_type_t, 1404ac67f02SAnurag S. Maskey uint_t); 1410dc2366fSVenugopal Iyer static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1420dc2366fSVenugopal Iyer static const char *dladm_perm2str(uint_t, char *); 143bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *); 144bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t); 145da14cebeSEric Cheng 1460dc2366fSVenugopal Iyer static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 1470dc2366fSVenugopal Iyer get_speed, get_channel, get_powermode, get_radio, 1480dc2366fSVenugopal Iyer get_duplex, get_link_state, get_binary, get_uint32, 1490dc2366fSVenugopal Iyer get_flowctl, get_maxbw, get_cpus, get_priority, 1500dc2366fSVenugopal Iyer get_tagmode, get_range, get_stp, get_bridge_forward, 1510dc2366fSVenugopal Iyer get_bridge_pvid, get_protection, get_rxrings, 1520dc2366fSVenugopal Iyer get_txrings, get_cntavail, 1530dc2366fSVenugopal Iyer get_allowedips, get_allowedcids, get_pool, 1541cfa752fSRamaswamy Tummala get_rings_range, get_linkmode_prop; 155da14cebeSEric Cheng 1560dc2366fSVenugopal Iyer static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 1570dc2366fSVenugopal Iyer set_public_prop, set_resource, set_stp_prop, 1580dc2366fSVenugopal Iyer set_bridge_forward, set_bridge_pvid; 159f4b3ec61Sdh155122 1600dc2366fSVenugopal Iyer static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 1610dc2366fSVenugopal Iyer check_encaplim, check_uint32, check_maxbw, check_cpus, 1620dc2366fSVenugopal Iyer check_stp_prop, check_bridge_pvid, check_allowedips, 1630dc2366fSVenugopal Iyer check_allowedcids, check_rings, 1640dc2366fSVenugopal Iyer check_pool, check_prop; 1656b9e797cSsowmini 166da14cebeSEric Cheng struct prop_desc { 167d62bc4baSyz147064 /* 168d62bc4baSyz147064 * link property name 169d62bc4baSyz147064 */ 170f4b3ec61Sdh155122 char *pd_name; 171d62bc4baSyz147064 172d62bc4baSyz147064 /* 173d62bc4baSyz147064 * default property value, can be set to { "", NULL } 174d62bc4baSyz147064 */ 175f4b3ec61Sdh155122 val_desc_t pd_defval; 176d62bc4baSyz147064 177d62bc4baSyz147064 /* 178d62bc4baSyz147064 * list of optional property values, can be NULL. 179d62bc4baSyz147064 * 180d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 181d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 182d62bc4baSyz147064 */ 183d62bc4baSyz147064 val_desc_t *pd_optval; 184d62bc4baSyz147064 185d62bc4baSyz147064 /* 186d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 187d62bc4baSyz147064 */ 188d62bc4baSyz147064 uint_t pd_noptval; 189d62bc4baSyz147064 190d62bc4baSyz147064 /* 1914eaa4710SRishi Srivatsavai * callback to set link property; set to NULL if this property is 1924eaa4710SRishi Srivatsavai * read-only and may be called before or after permanent update; see 1934eaa4710SRishi Srivatsavai * flags. 194d62bc4baSyz147064 */ 195f4b3ec61Sdh155122 pd_setf_t *pd_set; 196d62bc4baSyz147064 197d62bc4baSyz147064 /* 198d62bc4baSyz147064 * callback to get modifiable link property 199d62bc4baSyz147064 */ 200f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 201d62bc4baSyz147064 202d62bc4baSyz147064 /* 203d62bc4baSyz147064 * callback to get current link property 204d62bc4baSyz147064 */ 205f4b3ec61Sdh155122 pd_getf_t *pd_get; 206d62bc4baSyz147064 207d62bc4baSyz147064 /* 208d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 209d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 210d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 211d62bc4baSyz147064 * valid. 212d62bc4baSyz147064 */ 213f4b3ec61Sdh155122 pd_checkf_t *pd_check; 214d62bc4baSyz147064 215d62bc4baSyz147064 uint_t pd_flags; 216e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 217e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 2184eaa4710SRishi Srivatsavai #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 219d62bc4baSyz147064 /* 220d62bc4baSyz147064 * indicate link classes this property applies to. 221d62bc4baSyz147064 */ 222d62bc4baSyz147064 datalink_class_t pd_class; 223d62bc4baSyz147064 224d62bc4baSyz147064 /* 225d62bc4baSyz147064 * indicate link media type this property applies to. 226d62bc4baSyz147064 */ 227d62bc4baSyz147064 datalink_media_t pd_dmedia; 228da14cebeSEric Cheng }; 229f4b3ec61Sdh155122 2303fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 231e7801d59Ssowmini 232bcb5c89dSSowmini Varadhan /* 233bcb5c89dSSowmini Varadhan * Supported link properties enumerated in the prop_table[] array are 234bcb5c89dSSowmini Varadhan * computed using the callback functions in that array. To compute the 235bcb5c89dSSowmini Varadhan * property value, multiple distinct system calls may be needed (e.g., 236bcb5c89dSSowmini Varadhan * for wifi speed, we need to issue system calls to get desired/supported 237bcb5c89dSSowmini Varadhan * rates). The link_attr[] table enumerates the interfaces to the kernel, 238bcb5c89dSSowmini Varadhan * and the type/size of the data passed in the user-kernel interface. 239bcb5c89dSSowmini Varadhan */ 240bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = { 241bcb5c89dSSowmini Varadhan { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 242e7801d59Ssowmini 243bcb5c89dSSowmini Varadhan { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 244e7801d59Ssowmini 245bcb5c89dSSowmini Varadhan { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 246e7801d59Ssowmini 247bcb5c89dSSowmini Varadhan { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 248e7801d59Ssowmini 249bcb5c89dSSowmini Varadhan { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 250e7801d59Ssowmini 251bcb5c89dSSowmini Varadhan { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 252e7801d59Ssowmini 253bcb5c89dSSowmini Varadhan { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 254e7801d59Ssowmini 255bcb5c89dSSowmini Varadhan { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2563bc21d0aSAruna Ramakrishna - Sun Microsystems 257aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 258aca118b7Slucy wang - Sun Microsystems - Beijing China 259aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 260aca118b7Slucy wang - Sun Microsystems - Beijing China 261bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2623bc21d0aSAruna Ramakrishna - Sun Microsystems 263bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 264e7801d59Ssowmini 265bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 266e7801d59Ssowmini 267bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 268e7801d59Ssowmini 269bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 270e7801d59Ssowmini 271bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 272e7801d59Ssowmini 273bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 274e7801d59Ssowmini 275bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 276e7801d59Ssowmini 277bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 278e7801d59Ssowmini 279bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 280e7801d59Ssowmini 281bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 282e7801d59Ssowmini 283bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 284e7801d59Ssowmini 285bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 286e7801d59Ssowmini 287bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 288bcb5c89dSSowmini Varadhan 289bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 290bcb5c89dSSowmini Varadhan 291bcb5c89dSSowmini Varadhan { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 292bcb5c89dSSowmini Varadhan 293bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 294bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 295bcb5c89dSSowmini Varadhan 296bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 297bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 298bcb5c89dSSowmini Varadhan 299bcb5c89dSSowmini Varadhan { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 300bcb5c89dSSowmini Varadhan 301bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 302bcb5c89dSSowmini Varadhan 303bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 304bcb5c89dSSowmini Varadhan 305bcb5c89dSSowmini Varadhan { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 306bcb5c89dSSowmini Varadhan 307bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 308bcb5c89dSSowmini Varadhan 309bcb5c89dSSowmini Varadhan { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 310bcb5c89dSSowmini Varadhan 311bcb5c89dSSowmini Varadhan /* wl_wpa_ess_t has variable length */ 312bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 313bcb5c89dSSowmini Varadhan 314bcb5c89dSSowmini Varadhan { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 315bcb5c89dSSowmini Varadhan 316bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 317bcb5c89dSSowmini Varadhan 318bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 319bcb5c89dSSowmini Varadhan 320bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 321bcb5c89dSSowmini Varadhan 322bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 323bcb5c89dSSowmini Varadhan 324bcb5c89dSSowmini Varadhan /* wl_wpa_ie_t has variable length */ 325bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 326bcb5c89dSSowmini Varadhan 327bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 328bcb5c89dSSowmini Varadhan 329bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 330bcb5c89dSSowmini Varadhan 331bcb5c89dSSowmini Varadhan { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 332bcb5c89dSSowmini Varadhan 333e75f0919SSebastien Roy { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 334e75f0919SSebastien Roy 3352b24ab6bSSebastien Roy { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 3362b24ab6bSSebastien Roy 3372b24ab6bSSebastien Roy { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 3382b24ab6bSSebastien Roy 3394eaa4710SRishi Srivatsavai { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 3404eaa4710SRishi Srivatsavai 3414eaa4710SRishi Srivatsavai { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 3424eaa4710SRishi Srivatsavai 3434eaa4710SRishi Srivatsavai { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 3444eaa4710SRishi Srivatsavai 3450dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 3460dc2366fSVenugopal Iyer 3470dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 3480dc2366fSVenugopal Iyer "resource-effective"}, 3490dc2366fSVenugopal Iyer 3500dc2366fSVenugopal Iyer { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 3510dc2366fSVenugopal Iyer 3520dc2366fSVenugopal Iyer { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 3530dc2366fSVenugopal Iyer 3540dc2366fSVenugopal Iyer { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 3550dc2366fSVenugopal Iyer "txrings-available"}, 3560dc2366fSVenugopal Iyer 3570dc2366fSVenugopal Iyer { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 3580dc2366fSVenugopal Iyer "rxrings-available"}, 3590dc2366fSVenugopal Iyer 3600dc2366fSVenugopal Iyer { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 3610dc2366fSVenugopal Iyer 3620dc2366fSVenugopal Iyer { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 363da14cebeSEric Cheng 3641cfa752fSRamaswamy Tummala { MAC_PROP_IB_LINKMODE, sizeof (uint32_t), "linkmode"}, 3651cfa752fSRamaswamy Tummala 36625ec3e3dSEric Cheng { MAC_PROP_PRIVATE, 0, "driver-private"} 367e7801d59Ssowmini }; 368e7801d59Ssowmini 3694eaa4710SRishi Srivatsavai typedef struct bridge_public_prop_s { 3704eaa4710SRishi Srivatsavai const char *bpp_name; 3714eaa4710SRishi Srivatsavai int bpp_code; 3724eaa4710SRishi Srivatsavai } bridge_public_prop_t; 3734eaa4710SRishi Srivatsavai 3744eaa4710SRishi Srivatsavai static const bridge_public_prop_t bridge_prop[] = { 3754eaa4710SRishi Srivatsavai { "stp", PT_CFG_NON_STP }, 3764eaa4710SRishi Srivatsavai { "stp_priority", PT_CFG_PRIO }, 3774eaa4710SRishi Srivatsavai { "stp_cost", PT_CFG_COST }, 3784eaa4710SRishi Srivatsavai { "stp_edge", PT_CFG_EDGE }, 3794eaa4710SRishi Srivatsavai { "stp_p2p", PT_CFG_P2P }, 3804eaa4710SRishi Srivatsavai { "stp_mcheck", PT_CFG_MCHECK }, 3814eaa4710SRishi Srivatsavai { NULL, 0 } 3824eaa4710SRishi Srivatsavai }; 3834eaa4710SRishi Srivatsavai 384e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 385e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 386e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 387e7801d59Ssowmini }; 388e7801d59Ssowmini static val_desc_t link_status_vals[] = { 389e7801d59Ssowmini { "up", LINK_STATE_UP }, 390e7801d59Ssowmini { "down", LINK_STATE_DOWN } 391e7801d59Ssowmini }; 392e7801d59Ssowmini static val_desc_t link_01_vals[] = { 393e7801d59Ssowmini { "1", 1 }, 394e7801d59Ssowmini { "0", 0 } 395e7801d59Ssowmini }; 396e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 397e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 398e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 399e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 400e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 401e7801d59Ssowmini }; 402da14cebeSEric Cheng static val_desc_t link_priority_vals[] = { 403da14cebeSEric Cheng { "low", MPL_LOW }, 404da14cebeSEric Cheng { "medium", MPL_MEDIUM }, 405da14cebeSEric Cheng { "high", MPL_HIGH } 406da14cebeSEric Cheng }; 407e7801d59Ssowmini 408e75f0919SSebastien Roy static val_desc_t link_tagmode_vals[] = { 409e75f0919SSebastien Roy { "normal", LINK_TAGMODE_NORMAL }, 410e75f0919SSebastien Roy { "vlanonly", LINK_TAGMODE_VLANONLY } 411e75f0919SSebastien Roy }; 412e75f0919SSebastien Roy 41325ec3e3dSEric Cheng static val_desc_t link_protect_vals[] = { 41425ec3e3dSEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 4150dc2366fSVenugopal Iyer { "restricted", MPT_RESTRICTED }, 41625ec3e3dSEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 4170dc2366fSVenugopal Iyer { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 41825ec3e3dSEric Cheng }; 41925ec3e3dSEric Cheng 420d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 421d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 422d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 423d62bc4baSyz147064 }; 424d62bc4baSyz147064 425d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 426d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 427d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 428d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 429d62bc4baSyz147064 }; 430d62bc4baSyz147064 4314eaa4710SRishi Srivatsavai static val_desc_t stp_p2p_vals[] = { 4324eaa4710SRishi Srivatsavai { "true", P2P_FORCE_TRUE }, 4334eaa4710SRishi Srivatsavai { "false", P2P_FORCE_FALSE }, 4344eaa4710SRishi Srivatsavai { "auto", P2P_AUTO } 4354eaa4710SRishi Srivatsavai }; 4364eaa4710SRishi Srivatsavai 437c87dd6b7SRajkumar Sivaprakasam static val_desc_t dladm_part_linkmode_vals[] = { 438c87dd6b7SRajkumar Sivaprakasam { "cm", DLADM_PART_CM_MODE }, 439c87dd6b7SRajkumar Sivaprakasam { "ud", DLADM_PART_UD_MODE }, 4401cfa752fSRamaswamy Tummala }; 4411cfa752fSRamaswamy Tummala 442da14cebeSEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 443da14cebeSEric Cheng #define RESET_VAL ((uintptr_t)-1) 4440dc2366fSVenugopal Iyer #define UNSPEC_VAL ((uintptr_t)-2) 445d62bc4baSyz147064 446da14cebeSEric Cheng static prop_desc_t prop_table[] = { 447e7801d59Ssowmini { "channel", { NULL, 0 }, 448e7801d59Ssowmini NULL, 0, NULL, NULL, 4490dc2366fSVenugopal Iyer get_channel, NULL, 0, 450d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 451d62bc4baSyz147064 452d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 453d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 4540dc2366fSVenugopal Iyer set_powermode, NULL, 4550dc2366fSVenugopal Iyer get_powermode, NULL, 0, 456d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 457d62bc4baSyz147064 458d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 459d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 4600dc2366fSVenugopal Iyer set_radio, NULL, 4610dc2366fSVenugopal Iyer get_radio, NULL, 0, 462d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 463d62bc4baSyz147064 464c87dd6b7SRajkumar Sivaprakasam { "linkmode", { "cm", DLADM_PART_CM_MODE }, 465c87dd6b7SRajkumar Sivaprakasam dladm_part_linkmode_vals, VALCNT(dladm_part_linkmode_vals), 4661cfa752fSRamaswamy Tummala set_public_prop, NULL, get_linkmode_prop, NULL, 0, 4671cfa752fSRamaswamy Tummala DATALINK_CLASS_PART, DL_IB }, 4681cfa752fSRamaswamy Tummala 469d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 4700dc2366fSVenugopal Iyer set_rate, get_rate_mod, 4710dc2366fSVenugopal Iyer get_rate, check_rate, 0, 4726b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 473d62bc4baSyz147064 4744045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 4750dc2366fSVenugopal Iyer set_public_prop, NULL, 4760dc2366fSVenugopal Iyer get_autopush, check_autopush, PD_CHECK_ALLOC, 477d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 478d62bc4baSyz147064 4794045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 4800dc2366fSVenugopal Iyer set_zone, NULL, 4810dc2366fSVenugopal Iyer get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 482e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 483e7801d59Ssowmini 4844045d941Ssowmini { "duplex", { "", 0 }, 485e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 4860dc2366fSVenugopal Iyer NULL, NULL, get_duplex, NULL, 487e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 488e7801d59Ssowmini 4896b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 490e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 4910dc2366fSVenugopal Iyer NULL, NULL, get_link_state, NULL, 4924045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 493e7801d59Ssowmini 4940b8f0546SSowmini Varadhan { "adv_autoneg_cap", { "", 0 }, 495e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 4960dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 497e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 498e7801d59Ssowmini 4994045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 5000dc2366fSVenugopal Iyer set_public_prop, get_range, 5010dc2366fSVenugopal Iyer get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 5023bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 503e7801d59Ssowmini 5044045d941Ssowmini { "flowctrl", { "", 0 }, 505e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 5060dc2366fSVenugopal Iyer set_public_prop, NULL, get_flowctl, NULL, 507e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 508e7801d59Ssowmini 509aca118b7Slucy wang - Sun Microsystems - Beijing China { "adv_10gfdx_cap", { "", 0 }, 510aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 5110dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 512aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 513aca118b7Slucy wang - Sun Microsystems - Beijing China 514aca118b7Slucy wang - Sun Microsystems - Beijing China { "en_10gfdx_cap", { "", 0 }, 515aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 5160dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 517aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 518aca118b7Slucy wang - Sun Microsystems - Beijing China 5194045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 5204045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 5210dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 522e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 523e7801d59Ssowmini 5244045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 525e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5260dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 527e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 528e7801d59Ssowmini 5294045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 530e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5310dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 532e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 533e7801d59Ssowmini 5344045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 535e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5360dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 537e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 538e7801d59Ssowmini 5394045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 540e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5410dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 542e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 543e7801d59Ssowmini 5444045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 545e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5460dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 547e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 548e7801d59Ssowmini 5494045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 550e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5510dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 552e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 553e7801d59Ssowmini 5544045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 555e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5560dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 557e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 558e7801d59Ssowmini 5594045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 560e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5610dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 562e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 563e7801d59Ssowmini 5644045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 565e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5660dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 567e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 568e7801d59Ssowmini 5694045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 570e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5710dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 572e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 573e7801d59Ssowmini 5744045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 575e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5760dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 577da14cebeSEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 578e7801d59Ssowmini 579da14cebeSEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 5800dc2366fSVenugopal Iyer set_resource, NULL, 5810dc2366fSVenugopal Iyer get_maxbw, check_maxbw, PD_CHECK_ALLOC, 582da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 583da14cebeSEric Cheng 584da14cebeSEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 5850dc2366fSVenugopal Iyer set_resource, NULL, 5860dc2366fSVenugopal Iyer get_cpus, check_cpus, 0, 587da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 588da14cebeSEric Cheng 5890dc2366fSVenugopal Iyer { "cpus-effective", { "--", 0 }, 5900dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 5910dc2366fSVenugopal Iyer get_cpus, 0, 0, 5920dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5930dc2366fSVenugopal Iyer 5940dc2366fSVenugopal Iyer { "pool", { "--", RESET_VAL }, NULL, 0, 5950dc2366fSVenugopal Iyer set_resource, NULL, 5960dc2366fSVenugopal Iyer get_pool, check_pool, 0, 5970dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 5980dc2366fSVenugopal Iyer 5990dc2366fSVenugopal Iyer { "pool-effective", { "--", 0 }, 6000dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 6010dc2366fSVenugopal Iyer get_pool, 0, 0, 6020dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6030dc2366fSVenugopal Iyer 6040dc2366fSVenugopal Iyer { "priority", { "high", MPL_RESET }, 6050dc2366fSVenugopal Iyer link_priority_vals, VALCNT(link_priority_vals), set_resource, 6060dc2366fSVenugopal Iyer NULL, get_priority, check_prop, 0, 607da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 608e75f0919SSebastien Roy 609e75f0919SSebastien Roy { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 610e75f0919SSebastien Roy link_tagmode_vals, VALCNT(link_tagmode_vals), 6110dc2366fSVenugopal Iyer set_public_prop, NULL, get_tagmode, 612e75f0919SSebastien Roy NULL, 0, 613e75f0919SSebastien Roy DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 6144eaa4710SRishi Srivatsavai DL_ETHER }, 6154eaa4710SRishi Srivatsavai 6162b24ab6bSSebastien Roy { "hoplimit", { "", 0 }, NULL, 0, 6170dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 6180dc2366fSVenugopal Iyer check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 6192b24ab6bSSebastien Roy 6202b24ab6bSSebastien Roy { "encaplimit", { "", 0 }, NULL, 0, 6210dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 6220dc2366fSVenugopal Iyer check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 6232b24ab6bSSebastien Roy 6244eaa4710SRishi Srivatsavai { "forward", { "1", 1 }, 6254eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6264eaa4710SRishi Srivatsavai set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 6274eaa4710SRishi Srivatsavai DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 6284eaa4710SRishi Srivatsavai 6294eaa4710SRishi Srivatsavai { "default_tag", { "1", 1 }, NULL, 0, 6304eaa4710SRishi Srivatsavai set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 6314eaa4710SRishi Srivatsavai 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6324eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6334eaa4710SRishi Srivatsavai 6344eaa4710SRishi Srivatsavai { "learn_limit", { "1000", 1000 }, NULL, 0, 6350dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 6360dc2366fSVenugopal Iyer check_uint32, 0, 6374eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6384eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6394eaa4710SRishi Srivatsavai 6404eaa4710SRishi Srivatsavai { "learn_decay", { "200", 200 }, NULL, 0, 6410dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 6420dc2366fSVenugopal Iyer check_uint32, 0, 6434eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6444eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6454eaa4710SRishi Srivatsavai 6464eaa4710SRishi Srivatsavai { "stp", { "1", 1 }, 6474eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6480dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6494eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6504eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6514eaa4710SRishi Srivatsavai 6524eaa4710SRishi Srivatsavai { "stp_priority", { "128", 128 }, NULL, 0, 6530dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6544eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6554eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6564eaa4710SRishi Srivatsavai 6574eaa4710SRishi Srivatsavai { "stp_cost", { "auto", 0 }, NULL, 0, 6580dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6594eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6604eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6614eaa4710SRishi Srivatsavai 6624eaa4710SRishi Srivatsavai { "stp_edge", { "1", 1 }, 6634eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6640dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6654eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6664eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6674eaa4710SRishi Srivatsavai 6684eaa4710SRishi Srivatsavai { "stp_p2p", { "auto", P2P_AUTO }, 6694eaa4710SRishi Srivatsavai stp_p2p_vals, VALCNT(stp_p2p_vals), 6700dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6714eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6724eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6734eaa4710SRishi Srivatsavai 6744eaa4710SRishi Srivatsavai { "stp_mcheck", { "0", 0 }, 6754eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6760dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6774eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6784eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 67925ec3e3dSEric Cheng 68025ec3e3dSEric Cheng { "protection", { "--", RESET_VAL }, 68125ec3e3dSEric Cheng link_protect_vals, VALCNT(link_protect_vals), 6820dc2366fSVenugopal Iyer set_resource, NULL, get_protection, check_prop, 0, 68325ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 68425ec3e3dSEric Cheng 68525ec3e3dSEric Cheng { "allowed-ips", { "--", 0 }, 6860dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 6870dc2366fSVenugopal Iyer get_allowedips, check_allowedips, PD_CHECK_ALLOC, 68825ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6890dc2366fSVenugopal Iyer 6900dc2366fSVenugopal Iyer { "allowed-dhcp-cids", { "--", 0 }, 6910dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 6920dc2366fSVenugopal Iyer get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 6930dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6940dc2366fSVenugopal Iyer 6950dc2366fSVenugopal Iyer { "rxrings", { "--", RESET_VAL }, NULL, 0, 6960dc2366fSVenugopal Iyer set_resource, get_rings_range, get_rxrings, check_rings, 0, 6970dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6980dc2366fSVenugopal Iyer 6990dc2366fSVenugopal Iyer { "rxrings-effective", { "--", 0 }, 7000dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 7010dc2366fSVenugopal Iyer get_rxrings, NULL, 0, 7020dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7030dc2366fSVenugopal Iyer 7040dc2366fSVenugopal Iyer { "txrings", { "--", RESET_VAL }, NULL, 0, 7050dc2366fSVenugopal Iyer set_resource, get_rings_range, get_txrings, check_rings, 0, 7060dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7070dc2366fSVenugopal Iyer 7080dc2366fSVenugopal Iyer { "txrings-effective", { "--", 0 }, 7090dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 7100dc2366fSVenugopal Iyer get_txrings, NULL, 0, 7110dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7120dc2366fSVenugopal Iyer 7130dc2366fSVenugopal Iyer { "txrings-available", { "", 0 }, NULL, 0, 7140dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7150dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7160dc2366fSVenugopal Iyer 7170dc2366fSVenugopal Iyer { "rxrings-available", { "", 0 }, NULL, 0, 7180dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7190dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7200dc2366fSVenugopal Iyer 7210dc2366fSVenugopal Iyer { "rxhwclnt-available", { "", 0 }, NULL, 0, 7220dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7230dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7240dc2366fSVenugopal Iyer 7250dc2366fSVenugopal Iyer { "txhwclnt-available", { "", 0 }, NULL, 0, 7260dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7270dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7280dc2366fSVenugopal Iyer 729f4b3ec61Sdh155122 }; 730f4b3ec61Sdh155122 731d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 7320ba2cbe9Sxc151355 733da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 7340dc2366fSVenugopal Iyer {"maxbw", extract_maxbw}, 7350dc2366fSVenugopal Iyer {"priority", extract_priority}, 7360dc2366fSVenugopal Iyer {"cpus", extract_cpus}, 7370dc2366fSVenugopal Iyer {"cpus-effective", extract_cpus}, 7380dc2366fSVenugopal Iyer {"pool", extract_pool}, 7390dc2366fSVenugopal Iyer {"pool-effective", extract_pool}, 7400dc2366fSVenugopal Iyer {"protection", extract_protection}, 7410dc2366fSVenugopal Iyer {"allowed-ips", extract_allowedips}, 7420dc2366fSVenugopal Iyer {"allowed-dhcp-cids", extract_allowedcids}, 7430dc2366fSVenugopal Iyer {"rxrings", extract_rxrings}, 7440dc2366fSVenugopal Iyer {"rxrings-effective", extract_rxrings}, 7450dc2366fSVenugopal Iyer {"txrings", extract_txrings}, 7460dc2366fSVenugopal Iyer {"txrings-effective", extract_txrings} 747da14cebeSEric Cheng }; 748da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 749da14cebeSEric Cheng sizeof (resource_prop_t)) 750da14cebeSEric Cheng 751bcb5c89dSSowmini Varadhan /* 752bcb5c89dSSowmini Varadhan * when retrieving private properties, we pass down a buffer with 753bcb5c89dSSowmini Varadhan * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 754bcb5c89dSSowmini Varadhan */ 755bcb5c89dSSowmini Varadhan #define DLADM_PROP_BUF_CHUNK 1024 756bcb5c89dSSowmini Varadhan 7574ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 7584ac67f02SAnurag S. Maskey const char *, char **, uint_t); 7594ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 7604ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 76162ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 76262ee1d25SArtem Kachitchkine datalink_id_t, void *, int (*)(dladm_handle_t, 76362ee1d25SArtem Kachitchkine datalink_id_t, const char *, void *)); 7644ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 7654ac67f02SAnurag S. Maskey datalink_class_t, uint32_t, prop_desc_t *, char **, 7664ac67f02SAnurag S. Maskey uint_t, uint_t); 7674ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 7684ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 7694ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 7704ac67f02SAnurag S. Maskey datalink_id_t, datalink_media_t, uint_t); 771da14cebeSEric Cheng 772d62bc4baSyz147064 /* 773d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 774d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 775d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 776d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 777d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 778d62bc4baSyz147064 */ 779d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 780d62bc4baSyz147064 781d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 782d62bc4baSyz147064 #define AP_DELIMITER '.' 783d62bc4baSyz147064 78425ec3e3dSEric Cheng /* ARGSUSED */ 785d62bc4baSyz147064 static dladm_status_t 7860dc2366fSVenugopal Iyer check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 787c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 7880dc2366fSVenugopal Iyer datalink_media_t media) 7890ba2cbe9Sxc151355 { 790d62bc4baSyz147064 int i, j; 791c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 792c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 7930ba2cbe9Sxc151355 794d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 795d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 79625ec3e3dSEric Cheng if (strcasecmp(prop_val[j], 797d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 7980ba2cbe9Sxc151355 break; 7990ba2cbe9Sxc151355 } 8000ba2cbe9Sxc151355 } 80125ec3e3dSEric Cheng if (i == pdp->pd_noptval) 80225ec3e3dSEric Cheng return (DLADM_STATUS_BADVAL); 8030ba2cbe9Sxc151355 80425ec3e3dSEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 80525ec3e3dSEric Cheng } 80625ec3e3dSEric Cheng return (DLADM_STATUS_OK); 8070ba2cbe9Sxc151355 } 8080ba2cbe9Sxc151355 8090ba2cbe9Sxc151355 static dladm_status_t 8104ac67f02SAnurag S. Maskey i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 8114ac67f02SAnurag S. Maskey datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 8124ac67f02SAnurag S. Maskey uint_t val_cnt, uint_t flags) 8130ba2cbe9Sxc151355 { 8140ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 815d62bc4baSyz147064 val_desc_t *vdp = NULL; 816d62bc4baSyz147064 boolean_t needfree = B_FALSE; 817d62bc4baSyz147064 uint_t cnt, i; 8180ba2cbe9Sxc151355 819d62bc4baSyz147064 if (!(pdp->pd_class & class)) 820d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 8210ba2cbe9Sxc151355 822d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 823d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 824d62bc4baSyz147064 825d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 826d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 827d62bc4baSyz147064 828d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 829d62bc4baSyz147064 return (DLADM_STATUS_OK); 830d62bc4baSyz147064 831d62bc4baSyz147064 if (pdp->pd_set == NULL) 832d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 833d62bc4baSyz147064 834d62bc4baSyz147064 if (prop_val != NULL) { 8350dc2366fSVenugopal Iyer vdp = calloc(val_cnt, sizeof (val_desc_t)); 836d62bc4baSyz147064 if (vdp == NULL) 837d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 838d62bc4baSyz147064 839d62bc4baSyz147064 if (pdp->pd_check != NULL) { 840da14cebeSEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 8414ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, prop_val, 842c569ef53SMichael Lim &val_cnt, flags, &vdp, media); 843d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 8440dc2366fSVenugopal Iyer status = check_prop(handle, pdp, linkid, prop_val, 845c569ef53SMichael Lim &val_cnt, flags, &vdp, media); 846d62bc4baSyz147064 } else { 847d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 8480ba2cbe9Sxc151355 } 8490ba2cbe9Sxc151355 850d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 851d62bc4baSyz147064 goto done; 852d62bc4baSyz147064 853d62bc4baSyz147064 cnt = val_cnt; 854d62bc4baSyz147064 } else { 855da14cebeSEric Cheng boolean_t defval = B_FALSE; 856da14cebeSEric Cheng 857d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 858d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 859d62bc4baSyz147064 8603bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 861da14cebeSEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 862da14cebeSEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 8630dc2366fSVenugopal Iyer if ((vdp = calloc(1, sizeof (val_desc_t))) == NULL) 864d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 8653bc21d0aSAruna Ramakrishna - Sun Microsystems 866da14cebeSEric Cheng if (defval) { 867da14cebeSEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 868da14cebeSEric Cheng sizeof (val_desc_t)); 869da14cebeSEric Cheng } else if (pdp->pd_check != NULL) { 8704ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, 871c569ef53SMichael Lim prop_val, &cnt, flags, &vdp, media); 8723bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 8733bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 8743bc21d0aSAruna Ramakrishna - Sun Microsystems } 8754045d941Ssowmini } else { 8764ac67f02SAnurag S. Maskey status = i_dladm_getset_defval(handle, pdp, linkid, 8774045d941Ssowmini media, flags); 8784045d941Ssowmini return (status); 8794045d941Ssowmini } 880d62bc4baSyz147064 } 8814eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_AFTER_PERM) 8824eaa4710SRishi Srivatsavai status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 8834eaa4710SRishi Srivatsavai DLADM_STATUS_PERMONLY; 8844eaa4710SRishi Srivatsavai else 8854eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 8864eaa4710SRishi Srivatsavai media); 887d62bc4baSyz147064 if (needfree) { 888d62bc4baSyz147064 for (i = 0; i < cnt; i++) 889e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 890d62bc4baSyz147064 } 891d62bc4baSyz147064 done: 892d62bc4baSyz147064 free(vdp); 893d62bc4baSyz147064 return (status); 894d62bc4baSyz147064 } 895d62bc4baSyz147064 896d62bc4baSyz147064 static dladm_status_t 8974ac67f02SAnurag S. Maskey i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 8984ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 899d62bc4baSyz147064 { 900d62bc4baSyz147064 int i; 901d62bc4baSyz147064 boolean_t found = B_FALSE; 902d62bc4baSyz147064 datalink_class_t class; 903d62bc4baSyz147064 uint32_t media; 904d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 905d62bc4baSyz147064 9064ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9074ac67f02SAnurag S. Maskey NULL, 0); 908d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 9090ba2cbe9Sxc151355 return (status); 9100ba2cbe9Sxc151355 911d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 912d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 913d62bc4baSyz147064 dladm_status_t s; 9140ba2cbe9Sxc151355 915d62bc4baSyz147064 if (prop_name != NULL && 916d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 917d62bc4baSyz147064 continue; 918d62bc4baSyz147064 found = B_TRUE; 9194ac67f02SAnurag S. Maskey s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 9204ac67f02SAnurag S. Maskey prop_val, val_cnt, flags); 921d62bc4baSyz147064 922d62bc4baSyz147064 if (prop_name != NULL) { 923d62bc4baSyz147064 status = s; 924d62bc4baSyz147064 break; 925d62bc4baSyz147064 } else { 926d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 927d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 928d62bc4baSyz147064 status = s; 929d62bc4baSyz147064 } 930d62bc4baSyz147064 } 931e7801d59Ssowmini if (!found) { 932e7801d59Ssowmini if (prop_name[0] == '_') { 933e7801d59Ssowmini /* other private properties */ 9343361618bSRishi Srivatsavai status = i_dladm_set_private_prop(handle, linkid, 9353361618bSRishi Srivatsavai prop_name, prop_val, val_cnt, flags); 936e7801d59Ssowmini } else { 9370ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 938e7801d59Ssowmini } 939e7801d59Ssowmini } 9400ba2cbe9Sxc151355 return (status); 9410ba2cbe9Sxc151355 } 9420ba2cbe9Sxc151355 943d62bc4baSyz147064 /* 944d62bc4baSyz147064 * Set/reset link property for specific link 945d62bc4baSyz147064 */ 946d62bc4baSyz147064 dladm_status_t 9474ac67f02SAnurag S. Maskey dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9484ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 9490ba2cbe9Sxc151355 { 950d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 9510ba2cbe9Sxc151355 952d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 953d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 954d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 955d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 956d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 9570ba2cbe9Sxc151355 } 9580ba2cbe9Sxc151355 9593361618bSRishi Srivatsavai /* 9603361618bSRishi Srivatsavai * Check for valid link property against the flags passed 9613361618bSRishi Srivatsavai * and set the link property when active flag is passed. 9623361618bSRishi Srivatsavai */ 9634ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 964d62bc4baSyz147064 val_cnt, flags); 965d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 966d62bc4baSyz147064 return (status); 967d62bc4baSyz147064 968d62bc4baSyz147064 if (flags & DLADM_OPT_PERSIST) { 9694ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 970d62bc4baSyz147064 prop_val, val_cnt); 9714eaa4710SRishi Srivatsavai 9724eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 9734eaa4710SRishi Srivatsavai prop_desc_t *pdp = prop_table; 9744eaa4710SRishi Srivatsavai int i; 9754eaa4710SRishi Srivatsavai 9764eaa4710SRishi Srivatsavai for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 9774eaa4710SRishi Srivatsavai if (!(pdp->pd_flags & PD_AFTER_PERM)) 9784eaa4710SRishi Srivatsavai continue; 9794eaa4710SRishi Srivatsavai if (prop_name != NULL && 9804eaa4710SRishi Srivatsavai strcasecmp(prop_name, pdp->pd_name) != 0) 9814eaa4710SRishi Srivatsavai continue; 9824eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, NULL, 9834eaa4710SRishi Srivatsavai 0, flags, 0); 9844eaa4710SRishi Srivatsavai } 9854eaa4710SRishi Srivatsavai } 986d62bc4baSyz147064 } 987d62bc4baSyz147064 return (status); 988d62bc4baSyz147064 } 989d62bc4baSyz147064 990d62bc4baSyz147064 /* 99162ee1d25SArtem Kachitchkine * Walk all link properties of the given specific link. 99262ee1d25SArtem Kachitchkine * 99362ee1d25SArtem Kachitchkine * Note: this function currently lacks the ability to walk _all_ private 99462ee1d25SArtem Kachitchkine * properties if the link, because there is no kernel interface to 99562ee1d25SArtem Kachitchkine * retrieve all known private property names. Once such an interface 99662ee1d25SArtem Kachitchkine * is added, this function should be fixed accordingly. 997d62bc4baSyz147064 */ 998d62bc4baSyz147064 dladm_status_t 9994ac67f02SAnurag S. Maskey dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 10004ac67f02SAnurag S. Maskey int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 10010ba2cbe9Sxc151355 { 1002d62bc4baSyz147064 dladm_status_t status; 1003d62bc4baSyz147064 datalink_class_t class; 1004d62bc4baSyz147064 uint_t media; 1005d62bc4baSyz147064 int i; 10060ba2cbe9Sxc151355 1007d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 1008d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 10090ba2cbe9Sxc151355 10104ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10114ac67f02SAnurag S. Maskey NULL, 0); 1012d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1013d62bc4baSyz147064 return (status); 1014d62bc4baSyz147064 101562ee1d25SArtem Kachitchkine /* public */ 1016d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 1017d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 1018d62bc4baSyz147064 continue; 1019d62bc4baSyz147064 1020d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 1021d62bc4baSyz147064 continue; 1022d62bc4baSyz147064 10234ac67f02SAnurag S. Maskey if (func(handle, linkid, prop_table[i].pd_name, arg) == 1024d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 1025d62bc4baSyz147064 break; 1026d62bc4baSyz147064 } 1027d62bc4baSyz147064 } 1028d62bc4baSyz147064 102962ee1d25SArtem Kachitchkine /* private */ 103062ee1d25SArtem Kachitchkine status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 103162ee1d25SArtem Kachitchkine 103262ee1d25SArtem Kachitchkine return (status); 1033d62bc4baSyz147064 } 1034d62bc4baSyz147064 1035d62bc4baSyz147064 /* 1036d62bc4baSyz147064 * Get linkprop of the given specific link. 1037d62bc4baSyz147064 */ 1038d62bc4baSyz147064 dladm_status_t 10394ac67f02SAnurag S. Maskey dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10404ac67f02SAnurag S. Maskey dladm_prop_type_t type, const char *prop_name, char **prop_val, 10414ac67f02SAnurag S. Maskey uint_t *val_cntp) 1042d62bc4baSyz147064 { 1043d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1044d62bc4baSyz147064 datalink_class_t class; 1045d62bc4baSyz147064 uint_t media; 1046d62bc4baSyz147064 prop_desc_t *pdp; 10474045d941Ssowmini uint_t cnt, dld_flags = 0; 1048d62bc4baSyz147064 int i; 1049afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 1050d62bc4baSyz147064 10514045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 10520dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_DEFAULT; 1053f0f2c3a5SGirish Moodalbail else if (type == DLADM_PROP_VAL_MODIFIABLE) 10540dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_POSSIBLE; 10554045d941Ssowmini 1056d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 1057d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 1058d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1059d62bc4baSyz147064 1060d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 1061d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 1062d62bc4baSyz147064 break; 1063d62bc4baSyz147064 1064e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 1065e7801d59Ssowmini if (prop_name[0] == '_') { 1066e7801d59Ssowmini /* 1067e7801d59Ssowmini * private property. 1068e7801d59Ssowmini */ 106962ee1d25SArtem Kachitchkine if (type == DLADM_PROP_VAL_PERSISTENT) 107062ee1d25SArtem Kachitchkine return (i_dladm_get_linkprop_db(handle, linkid, 107162ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp)); 107262ee1d25SArtem Kachitchkine else 107362ee1d25SArtem Kachitchkine return (i_dladm_get_priv_prop(handle, linkid, 107462ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp, type, 107562ee1d25SArtem Kachitchkine dld_flags)); 1076e7801d59Ssowmini } else { 1077d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 1078e7801d59Ssowmini } 1079e7801d59Ssowmini } 1080d62bc4baSyz147064 1081d62bc4baSyz147064 pdp = &prop_table[i]; 1082d62bc4baSyz147064 10834ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10844ac67f02SAnurag S. Maskey NULL, 0); 1085d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1086d62bc4baSyz147064 return (status); 1087d62bc4baSyz147064 1088d62bc4baSyz147064 if (!(pdp->pd_class & class)) 1089d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1090d62bc4baSyz147064 1091d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 1092d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1093d62bc4baSyz147064 1094d62bc4baSyz147064 switch (type) { 1095d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 10964ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 10974ac67f02SAnurag S. Maskey media, dld_flags, &perm_flags); 1098afdda45fSVasumathi Sundaram - Sun Microsystems break; 1099afdda45fSVasumathi Sundaram - Sun Microsystems 1100afdda45fSVasumathi Sundaram - Sun Microsystems case DLADM_PROP_VAL_PERM: 1101afdda45fSVasumathi Sundaram - Sun Microsystems if (pdp->pd_set == NULL) { 1102afdda45fSVasumathi Sundaram - Sun Microsystems perm_flags = MAC_PROP_PERM_READ; 1103afdda45fSVasumathi Sundaram - Sun Microsystems } else { 11044ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 11054ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 1106afdda45fSVasumathi Sundaram - Sun Microsystems } 1107afdda45fSVasumathi Sundaram - Sun Microsystems 1108afdda45fSVasumathi Sundaram - Sun Microsystems *prop_val[0] = '\0'; 110963a6526dSMichael Lim *val_cntp = 1; 1110da14cebeSEric Cheng if (status == DLADM_STATUS_OK) 1111da14cebeSEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 1112d62bc4baSyz147064 break; 1113d62bc4baSyz147064 1114d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 111513a55820Sar224390 /* 111613a55820Sar224390 * If defaults are not defined for the property, 111713a55820Sar224390 * pd_defval.vd_name should be null. If the driver 111813a55820Sar224390 * has to be contacted for the value, vd_name should 111913a55820Sar224390 * be the empty string (""). Otherwise, dladm will 112013a55820Sar224390 * just print whatever is in the table. 112113a55820Sar224390 */ 1122d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 1123d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1124d62bc4baSyz147064 break; 1125d62bc4baSyz147064 } 11264045d941Ssowmini 11274045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 11284ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 11294ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 11304045d941Ssowmini } else { 1131d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 11324045d941Ssowmini } 1133d62bc4baSyz147064 *val_cntp = 1; 1134d62bc4baSyz147064 break; 1135d62bc4baSyz147064 1136d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 1137d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 11384ac67f02SAnurag S. Maskey status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 1139afdda45fSVasumathi Sundaram - Sun Microsystems val_cntp, media, dld_flags, &perm_flags); 1140d62bc4baSyz147064 break; 1141d62bc4baSyz147064 } 1142d62bc4baSyz147064 cnt = pdp->pd_noptval; 1143d62bc4baSyz147064 if (cnt == 0) { 1144d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1145d62bc4baSyz147064 } else if (cnt > *val_cntp) { 1146d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1147d62bc4baSyz147064 } else { 1148d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 1149d62bc4baSyz147064 (void) strcpy(prop_val[i], 1150d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 1151d62bc4baSyz147064 } 1152d62bc4baSyz147064 *val_cntp = cnt; 1153d62bc4baSyz147064 } 1154d62bc4baSyz147064 break; 1155d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 1156d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 1157d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 11584ac67f02SAnurag S. Maskey status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 1159d62bc4baSyz147064 prop_val, val_cntp); 1160d62bc4baSyz147064 break; 1161d62bc4baSyz147064 default: 1162d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 1163d62bc4baSyz147064 break; 1164d62bc4baSyz147064 } 1165d62bc4baSyz147064 1166d62bc4baSyz147064 return (status); 1167d62bc4baSyz147064 } 1168d62bc4baSyz147064 11694eaa4710SRishi Srivatsavai /* 11704eaa4710SRishi Srivatsavai * Get linkprop of the given specific link and run any possible conversion 11714eaa4710SRishi Srivatsavai * of the values using the check function for the property. Fails if the 11724eaa4710SRishi Srivatsavai * check function doesn't succeed for the property value. 11734eaa4710SRishi Srivatsavai */ 11744eaa4710SRishi Srivatsavai dladm_status_t 11754eaa4710SRishi Srivatsavai dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 11764eaa4710SRishi Srivatsavai dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 11774eaa4710SRishi Srivatsavai uint_t *val_cntp) 11784eaa4710SRishi Srivatsavai { 11794eaa4710SRishi Srivatsavai dladm_status_t status; 11804eaa4710SRishi Srivatsavai datalink_class_t class; 11814eaa4710SRishi Srivatsavai uint_t media; 11824eaa4710SRishi Srivatsavai prop_desc_t *pdp; 11834eaa4710SRishi Srivatsavai uint_t dld_flags; 11844eaa4710SRishi Srivatsavai int valc, i; 11854eaa4710SRishi Srivatsavai char **prop_val; 11864eaa4710SRishi Srivatsavai uint_t perm_flags; 11874eaa4710SRishi Srivatsavai 11884eaa4710SRishi Srivatsavai if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 11894eaa4710SRishi Srivatsavai ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 11904eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 11914eaa4710SRishi Srivatsavai 11924eaa4710SRishi Srivatsavai for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 11934eaa4710SRishi Srivatsavai if (strcasecmp(prop_name, pdp->pd_name) == 0) 11944eaa4710SRishi Srivatsavai break; 11954eaa4710SRishi Srivatsavai 11964eaa4710SRishi Srivatsavai if (pdp == prop_table + DLADM_MAX_PROPS) 11974eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 11984eaa4710SRishi Srivatsavai 11994eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_CHECK_ALLOC) 12004eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12014eaa4710SRishi Srivatsavai 12024eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 12034eaa4710SRishi Srivatsavai NULL, 0); 12044eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 12054eaa4710SRishi Srivatsavai return (status); 12064eaa4710SRishi Srivatsavai 12074eaa4710SRishi Srivatsavai if (!(pdp->pd_class & class)) 12084eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12094eaa4710SRishi Srivatsavai 12104eaa4710SRishi Srivatsavai if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 12114eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12124eaa4710SRishi Srivatsavai 12134eaa4710SRishi Srivatsavai prop_val = malloc(*val_cntp * sizeof (*prop_val) + 12144eaa4710SRishi Srivatsavai *val_cntp * DLADM_PROP_VAL_MAX); 12154eaa4710SRishi Srivatsavai if (prop_val == NULL) 12164eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOMEM); 12174eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 12184eaa4710SRishi Srivatsavai prop_val[valc] = (char *)(prop_val + *val_cntp) + 12194eaa4710SRishi Srivatsavai valc * DLADM_PROP_VAL_MAX; 12204eaa4710SRishi Srivatsavai 12210dc2366fSVenugopal Iyer dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 12224eaa4710SRishi Srivatsavai 12234eaa4710SRishi Srivatsavai switch (type) { 12244eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_CURRENT: 12254eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12264eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 12274eaa4710SRishi Srivatsavai break; 12284eaa4710SRishi Srivatsavai 12294eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_DEFAULT: 12304eaa4710SRishi Srivatsavai /* 12314eaa4710SRishi Srivatsavai * If defaults are not defined for the property, 12324eaa4710SRishi Srivatsavai * pd_defval.vd_name should be null. If the driver 12334eaa4710SRishi Srivatsavai * has to be contacted for the value, vd_name should 12344eaa4710SRishi Srivatsavai * be the empty string (""). Otherwise, dladm will 12354eaa4710SRishi Srivatsavai * just print whatever is in the table. 12364eaa4710SRishi Srivatsavai */ 12374eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name == NULL) { 12384eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOTSUP; 12394eaa4710SRishi Srivatsavai break; 12404eaa4710SRishi Srivatsavai } 12414eaa4710SRishi Srivatsavai 12424eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name[0] != '\0') { 12434eaa4710SRishi Srivatsavai *val_cntp = 1; 12444eaa4710SRishi Srivatsavai *ret_val = pdp->pd_defval.vd_val; 12454eaa4710SRishi Srivatsavai free(prop_val); 12464eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 12474eaa4710SRishi Srivatsavai } 12484eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12494eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 12504eaa4710SRishi Srivatsavai break; 12514eaa4710SRishi Srivatsavai 12524eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_PERSISTENT: 12534eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_TEMPONLY) 12544eaa4710SRishi Srivatsavai status = DLADM_STATUS_TEMPONLY; 12554eaa4710SRishi Srivatsavai else 12564eaa4710SRishi Srivatsavai status = i_dladm_get_linkprop_db(handle, linkid, 12574eaa4710SRishi Srivatsavai prop_name, prop_val, val_cntp); 12584eaa4710SRishi Srivatsavai break; 12594eaa4710SRishi Srivatsavai 12604eaa4710SRishi Srivatsavai default: 12614eaa4710SRishi Srivatsavai status = DLADM_STATUS_BADARG; 12624eaa4710SRishi Srivatsavai break; 12634eaa4710SRishi Srivatsavai } 12644eaa4710SRishi Srivatsavai 12654eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 12664eaa4710SRishi Srivatsavai if (pdp->pd_check != NULL) { 12674eaa4710SRishi Srivatsavai val_desc_t *vdp; 12684eaa4710SRishi Srivatsavai 12694eaa4710SRishi Srivatsavai vdp = malloc(sizeof (val_desc_t) * *val_cntp); 12704eaa4710SRishi Srivatsavai if (vdp == NULL) 12714eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOMEM; 12724eaa4710SRishi Srivatsavai else 12734eaa4710SRishi Srivatsavai status = pdp->pd_check(handle, pdp, linkid, 1274c569ef53SMichael Lim prop_val, val_cntp, 0, &vdp, media); 12754eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 12764eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 12774eaa4710SRishi Srivatsavai ret_val[valc] = vdp[valc].vd_val; 12784eaa4710SRishi Srivatsavai } 12794eaa4710SRishi Srivatsavai free(vdp); 12804eaa4710SRishi Srivatsavai } else { 12814eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) { 12824eaa4710SRishi Srivatsavai for (i = 0; i < pdp->pd_noptval; i++) { 12834eaa4710SRishi Srivatsavai if (strcmp(pdp->pd_optval[i].vd_name, 12844eaa4710SRishi Srivatsavai prop_val[valc]) == 0) { 12854eaa4710SRishi Srivatsavai ret_val[valc] = 12864eaa4710SRishi Srivatsavai pdp->pd_optval[i].vd_val; 12874eaa4710SRishi Srivatsavai break; 12884eaa4710SRishi Srivatsavai } 12894eaa4710SRishi Srivatsavai } 12904eaa4710SRishi Srivatsavai if (i == pdp->pd_noptval) { 12914eaa4710SRishi Srivatsavai status = DLADM_STATUS_FAILED; 12924eaa4710SRishi Srivatsavai break; 12934eaa4710SRishi Srivatsavai } 12944eaa4710SRishi Srivatsavai } 12954eaa4710SRishi Srivatsavai } 12964eaa4710SRishi Srivatsavai } 12974eaa4710SRishi Srivatsavai 12984eaa4710SRishi Srivatsavai free(prop_val); 12994eaa4710SRishi Srivatsavai 13004eaa4710SRishi Srivatsavai return (status); 13014eaa4710SRishi Srivatsavai } 13024eaa4710SRishi Srivatsavai 1303d62bc4baSyz147064 /*ARGSUSED*/ 1304d62bc4baSyz147064 static int 13054ac67f02SAnurag S. Maskey i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 13064ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 1307d62bc4baSyz147064 { 1308d62bc4baSyz147064 char *buf, **propvals; 1309d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 13100dc2366fSVenugopal Iyer dladm_status_t status; 13110dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla = arg; 1312d62bc4baSyz147064 1313d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 1314d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 1315d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1316d62bc4baSyz147064 } 1317d62bc4baSyz147064 1318d62bc4baSyz147064 propvals = (char **)(void *)buf; 1319d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 1320d62bc4baSyz147064 propvals[i] = buf + 1321d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 1322d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 1323d62bc4baSyz147064 } 1324d62bc4baSyz147064 13254ac67f02SAnurag S. Maskey if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 13264ac67f02SAnurag S. Maskey prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 1327d62bc4baSyz147064 goto done; 1328d62bc4baSyz147064 } 1329d62bc4baSyz147064 13308d4cf8d8S status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 13310dc2366fSVenugopal Iyer valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 13320dc2366fSVenugopal Iyer 13338d4cf8d8S if (status != DLADM_STATUS_OK) 13340dc2366fSVenugopal Iyer dla->dla_status = status; 1335d62bc4baSyz147064 1336d62bc4baSyz147064 done: 1337d62bc4baSyz147064 if (buf != NULL) 1338d62bc4baSyz147064 free(buf); 1339d62bc4baSyz147064 1340d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1341d62bc4baSyz147064 } 1342d62bc4baSyz147064 1343d62bc4baSyz147064 /*ARGSUSED*/ 1344d62bc4baSyz147064 static int 13454ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 1346d62bc4baSyz147064 { 1347da14cebeSEric Cheng datalink_class_t class; 1348da14cebeSEric Cheng dladm_status_t status; 1349da14cebeSEric Cheng 13504ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 13514ac67f02SAnurag S. Maskey NULL, 0); 1352da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1353da14cebeSEric Cheng return (DLADM_WALK_TERMINATE); 1354da14cebeSEric Cheng 1355da14cebeSEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 13564ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, B_TRUE); 1357da14cebeSEric Cheng 1358d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 13590ba2cbe9Sxc151355 } 13600ba2cbe9Sxc151355 13610ba2cbe9Sxc151355 dladm_status_t 13624ac67f02SAnurag S. Maskey dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 13634ac67f02SAnurag S. Maskey boolean_t any_media) 13640ba2cbe9Sxc151355 { 13658d4cf8d8S dladm_status_t status = DLADM_STATUS_OK; 136630890389Sartem datalink_media_t dmedia; 136730890389Sartem uint32_t media; 13680dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla; 136930890389Sartem 137030890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 137130890389Sartem 13720dc2366fSVenugopal Iyer dla = malloc(sizeof (dladm_linkprop_args_t)); 13730dc2366fSVenugopal Iyer if (dla == NULL) 13740dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 13750dc2366fSVenugopal Iyer dla->dla_flags = DLADM_OPT_BOOT; 13760dc2366fSVenugopal Iyer dla->dla_status = DLADM_STATUS_OK; 13770dc2366fSVenugopal Iyer 1378d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 13794ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 13804ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 13814ac67f02SAnurag S. Maskey } else if (any_media || 13824ac67f02SAnurag S. Maskey ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 13834ac67f02SAnurag S. Maskey 0) == DLADM_STATUS_OK) && 138430890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 13850dc2366fSVenugopal Iyer (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 13864ac67f02SAnurag S. Maskey i_dladm_init_one_prop); 13870dc2366fSVenugopal Iyer status = dla->dla_status; 1388d62bc4baSyz147064 } 13890dc2366fSVenugopal Iyer free(dla); 13908d4cf8d8S return (status); 13910ba2cbe9Sxc151355 } 1392f4b3ec61Sdh155122 1393e7801d59Ssowmini /* ARGSUSED */ 1394f4b3ec61Sdh155122 static dladm_status_t 13950dc2366fSVenugopal Iyer get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1396da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1397da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1398f4b3ec61Sdh155122 { 1399d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 1400d62bc4baSyz147064 zoneid_t zid; 1401d62bc4baSyz147064 dladm_status_t status; 1402f4b3ec61Sdh155122 14034045d941Ssowmini if (flags != 0) 14044045d941Ssowmini return (DLADM_STATUS_NOTSUP); 14054045d941Ssowmini 14060dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 14070dc2366fSVenugopal Iyer perm_flags, &zid, sizeof (zid)); 1408d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1409d62bc4baSyz147064 return (status); 1410d62bc4baSyz147064 1411d62bc4baSyz147064 *val_cnt = 1; 1412d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 1413afdda45fSVasumathi Sundaram - Sun Microsystems if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 1414f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1415afdda45fSVasumathi Sundaram - Sun Microsystems } 1416f4b3ec61Sdh155122 1417d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 141847a01978Sbw } else { 1419d62bc4baSyz147064 *prop_val[0] = '\0'; 142047a01978Sbw } 1421f4b3ec61Sdh155122 1422f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1423f4b3ec61Sdh155122 } 1424f4b3ec61Sdh155122 1425f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 1426f4b3ec61Sdh155122 1427f4b3ec61Sdh155122 static int 1428f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 1429f4b3ec61Sdh155122 { 1430f4b3ec61Sdh155122 char root[MAXPATHLEN]; 1431f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 1432f4b3ec61Sdh155122 void *dlhandle; 1433f4b3ec61Sdh155122 void *sym; 1434f4b3ec61Sdh155122 int ret; 1435f4b3ec61Sdh155122 1436f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 1437f4b3ec61Sdh155122 return (-1); 1438f4b3ec61Sdh155122 1439f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 1440f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1441f4b3ec61Sdh155122 return (-1); 1442f4b3ec61Sdh155122 } 1443f4b3ec61Sdh155122 1444f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 1445f4b3ec61Sdh155122 1446f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 1447f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 1448f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1449f4b3ec61Sdh155122 return (ret); 1450f4b3ec61Sdh155122 } 1451f4b3ec61Sdh155122 1452f4b3ec61Sdh155122 static dladm_status_t 14534ac67f02SAnurag S. Maskey i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 14544ac67f02SAnurag S. Maskey datalink_id_t linkid, boolean_t add) 1455f4b3ec61Sdh155122 { 1456f4b3ec61Sdh155122 char path[MAXPATHLEN]; 1457d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1458f4b3ec61Sdh155122 di_prof_t prof = NULL; 1459f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 1460f4b3ec61Sdh155122 dladm_status_t status; 1461d62bc4baSyz147064 int ret; 1462f4b3ec61Sdh155122 1463f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 1464f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1465f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 1466f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1467f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 1468f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1469f4b3ec61Sdh155122 14704ac67f02SAnurag S. Maskey status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 1471f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1472d62bc4baSyz147064 goto cleanup; 1473f4b3ec61Sdh155122 1474d62bc4baSyz147064 if (add) 1475d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 1476d62bc4baSyz147064 else 1477d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 1478f4b3ec61Sdh155122 1479d62bc4baSyz147064 if (ret != 0) { 1480d62bc4baSyz147064 status = dladm_errno2status(errno); 1481d62bc4baSyz147064 goto cleanup; 1482f4b3ec61Sdh155122 } 1483f4b3ec61Sdh155122 1484d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 1485d62bc4baSyz147064 status = dladm_errno2status(errno); 1486d62bc4baSyz147064 cleanup: 1487d62bc4baSyz147064 if (prof) 1488d62bc4baSyz147064 di_prof_fini(prof); 1489d62bc4baSyz147064 1490d62bc4baSyz147064 return (status); 1491f4b3ec61Sdh155122 } 1492f4b3ec61Sdh155122 1493e7801d59Ssowmini /* ARGSUSED */ 1494f4b3ec61Sdh155122 static dladm_status_t 14950dc2366fSVenugopal Iyer set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 14964ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1497f4b3ec61Sdh155122 { 14983bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1499f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 15003bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1501f4b3ec61Sdh155122 1502f4b3ec61Sdh155122 if (val_cnt != 1) 1503f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1504f4b3ec61Sdh155122 15053bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 15063bc21d0aSAruna Ramakrishna - Sun Microsystems 15070dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15080dc2366fSVenugopal Iyer NULL, &zid_old, sizeof (zid_old)); 1509f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1510f4b3ec61Sdh155122 return (status); 1511f4b3ec61Sdh155122 15123bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 15133bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 15142b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 15152b24ab6bSSebastien Roy 15160dc2366fSVenugopal Iyer if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 15172b24ab6bSSebastien Roy flags, media)) != DLADM_STATUS_OK) 15183bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 15193bc21d0aSAruna Ramakrishna - Sun Microsystems 1520d62bc4baSyz147064 /* 15212b24ab6bSSebastien Roy * It is okay to fail to update the /dev entry (some vanity-named 15222b24ab6bSSebastien Roy * links do not have a /dev entry). 1523d62bc4baSyz147064 */ 1524d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 15254ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_old, linkid, 15264ac67f02SAnurag S. Maskey B_FALSE); 1527d62bc4baSyz147064 } 15282b24ab6bSSebastien Roy if (zid_new != GLOBAL_ZONEID) 15294ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 1530f4b3ec61Sdh155122 1531f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1532f4b3ec61Sdh155122 } 1533f4b3ec61Sdh155122 1534f4b3ec61Sdh155122 /* ARGSUSED */ 1535f4b3ec61Sdh155122 static dladm_status_t 15360dc2366fSVenugopal Iyer check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1537c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 15380dc2366fSVenugopal Iyer datalink_media_t media) 1539f4b3ec61Sdh155122 { 15403bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 15413bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 15423bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 15433bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1544c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1545c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1546f4b3ec61Sdh155122 1547f4b3ec61Sdh155122 if (val_cnt != 1) 1548f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1549f4b3ec61Sdh155122 15503bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 15513bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 15523bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1553f4b3ec61Sdh155122 1554da14cebeSEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 15553bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 15563bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 15573bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 15583bc21d0aSAruna Ramakrishna - Sun Microsystems } 15593bc21d0aSAruna Ramakrishna - Sun Microsystems 15603bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1561f4b3ec61Sdh155122 ushort_t flags; 1562f4b3ec61Sdh155122 15633bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1564f4b3ec61Sdh155122 sizeof (flags)) < 0) { 15653bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 15663bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1567f4b3ec61Sdh155122 } 1568f4b3ec61Sdh155122 1569f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 15703bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 15713bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1572f4b3ec61Sdh155122 } 1573f4b3ec61Sdh155122 } 1574f4b3ec61Sdh155122 15753bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15763bc21d0aSAruna Ramakrishna - Sun Microsystems 15773bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 15782b24ab6bSSebastien Roy dzp->diz_linkid = linkid; 15793bc21d0aSAruna Ramakrishna - Sun Microsystems 15803bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1581f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 15823bc21d0aSAruna Ramakrishna - Sun Microsystems done: 15833bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 15843bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1585f4b3ec61Sdh155122 } 1586f4b3ec61Sdh155122 1587e7801d59Ssowmini /* ARGSUSED */ 1588f4b3ec61Sdh155122 static dladm_status_t 15890dc2366fSVenugopal Iyer get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1590da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1591da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1592da14cebeSEric Cheng { 1593da14cebeSEric Cheng mac_resource_props_t mrp; 1594da14cebeSEric Cheng dladm_status_t status; 1595da14cebeSEric Cheng 15960dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 15970dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 15980dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1599da14cebeSEric Cheng return (status); 1600da14cebeSEric Cheng 1601da14cebeSEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 16020dc2366fSVenugopal Iyer *val_cnt = 0; 16030dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1604da14cebeSEric Cheng } 16050dc2366fSVenugopal Iyer 16060dc2366fSVenugopal Iyer (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 1607da14cebeSEric Cheng *val_cnt = 1; 1608da14cebeSEric Cheng return (DLADM_STATUS_OK); 1609da14cebeSEric Cheng } 1610da14cebeSEric Cheng 1611da14cebeSEric Cheng /* ARGSUSED */ 1612da14cebeSEric Cheng static dladm_status_t 16130dc2366fSVenugopal Iyer check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1614c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 16150dc2366fSVenugopal Iyer datalink_media_t media) 1616da14cebeSEric Cheng { 1617da14cebeSEric Cheng uint64_t *maxbw; 1618da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1619c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1620c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1621da14cebeSEric Cheng 1622da14cebeSEric Cheng if (val_cnt != 1) 1623da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1624da14cebeSEric Cheng 1625da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 1626da14cebeSEric Cheng if (maxbw == NULL) 1627da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1628da14cebeSEric Cheng 1629da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 1630da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1631da14cebeSEric Cheng free(maxbw); 1632da14cebeSEric Cheng return (status); 1633da14cebeSEric Cheng } 1634da14cebeSEric Cheng 1635da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 1636da14cebeSEric Cheng free(maxbw); 1637da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 1638da14cebeSEric Cheng } 1639da14cebeSEric Cheng 1640da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 1641da14cebeSEric Cheng return (DLADM_STATUS_OK); 1642da14cebeSEric Cheng } 1643da14cebeSEric Cheng 1644da14cebeSEric Cheng /* ARGSUSED */ 1645da14cebeSEric Cheng dladm_status_t 16460dc2366fSVenugopal Iyer extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 1647da14cebeSEric Cheng { 164825ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1649da14cebeSEric Cheng 16500dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 16510dc2366fSVenugopal Iyer mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 16520dc2366fSVenugopal Iyer } else { 1653da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 16540dc2366fSVenugopal Iyer } 1655da14cebeSEric Cheng mrp->mrp_mask |= MRP_MAXBW; 1656da14cebeSEric Cheng 1657da14cebeSEric Cheng return (DLADM_STATUS_OK); 1658da14cebeSEric Cheng } 1659da14cebeSEric Cheng 1660da14cebeSEric Cheng /* ARGSUSED */ 1661da14cebeSEric Cheng static dladm_status_t 16620dc2366fSVenugopal Iyer get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1663da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1664da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1665da14cebeSEric Cheng { 16660dc2366fSVenugopal Iyer dladm_status_t status; 1667da14cebeSEric Cheng mac_resource_props_t mrp; 1668c569ef53SMichael Lim mac_propval_range_t *pv_range; 1669c569ef53SMichael Lim int err; 1670da14cebeSEric Cheng 16710dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 16720dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 16730dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 16740dc2366fSVenugopal Iyer sizeof (mrp)); 16750dc2366fSVenugopal Iyer } else { 16760dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 16770dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 16780dc2366fSVenugopal Iyer } 16790dc2366fSVenugopal Iyer 16800dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1681da14cebeSEric Cheng return (status); 1682da14cebeSEric Cheng 1683c569ef53SMichael Lim if (mrp.mrp_ncpus > *val_cnt) 1684da14cebeSEric Cheng return (DLADM_STATUS_TOOSMALL); 1685da14cebeSEric Cheng 1686c569ef53SMichael Lim if (mrp.mrp_ncpus == 0) { 16870dc2366fSVenugopal Iyer *val_cnt = 0; 1688da14cebeSEric Cheng return (DLADM_STATUS_OK); 1689da14cebeSEric Cheng } 1690da14cebeSEric Cheng 1691c569ef53SMichael Lim /* Sort CPU list and convert it to a mac_propval_range */ 1692c569ef53SMichael Lim status = dladm_list2range(mrp.mrp_cpu, mrp.mrp_ncpus, 1693c569ef53SMichael Lim MAC_PROPVAL_UINT32, &pv_range); 1694c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1695c569ef53SMichael Lim return (status); 1696c569ef53SMichael Lim 1697c569ef53SMichael Lim /* Write CPU ranges and individual CPUs */ 1698c569ef53SMichael Lim err = dladm_range2strs(pv_range, prop_val); 1699c569ef53SMichael Lim if (err != 0) { 1700c569ef53SMichael Lim free(pv_range); 1701c569ef53SMichael Lim return (dladm_errno2status(err)); 1702da14cebeSEric Cheng } 1703c569ef53SMichael Lim 1704c569ef53SMichael Lim *val_cnt = pv_range->mpr_count; 1705c569ef53SMichael Lim free(pv_range); 1706c569ef53SMichael Lim 1707da14cebeSEric Cheng return (DLADM_STATUS_OK); 1708da14cebeSEric Cheng } 1709da14cebeSEric Cheng 1710da14cebeSEric Cheng /* ARGSUSED */ 1711da14cebeSEric Cheng static dladm_status_t 17120dc2366fSVenugopal Iyer check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1713c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 17140dc2366fSVenugopal Iyer datalink_media_t media) 1715da14cebeSEric Cheng { 1716da14cebeSEric Cheng int i, j, rc; 1717da14cebeSEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 17180dc2366fSVenugopal Iyer mac_resource_props_t mrp; 1719c569ef53SMichael Lim mac_propval_range_t *pv_range; 17200dc2366fSVenugopal Iyer uint_t perm_flags; 1721c569ef53SMichael Lim uint32_t ncpus; 1722c569ef53SMichael Lim uint32_t *cpus = mrp.mrp_cpu; 1723c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1724c569ef53SMichael Lim val_desc_t *newvdp; 1725c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1726c569ef53SMichael Lim dladm_status_t status = DLADM_STATUS_OK; 1727da14cebeSEric Cheng 17280dc2366fSVenugopal Iyer /* Get the current pool property */ 17290dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 17300dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 17310dc2366fSVenugopal Iyer 17320dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 17330dc2366fSVenugopal Iyer /* Can't set cpus if a pool is set */ 17340dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) != 0) 17350dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 17360dc2366fSVenugopal Iyer } 17370dc2366fSVenugopal Iyer 1738c569ef53SMichael Lim /* Read ranges and convert to mac_propval_range */ 1739c569ef53SMichael Lim status = dladm_strs2range(prop_val, val_cnt, MAC_PROPVAL_UINT32, 1740c569ef53SMichael Lim &pv_range); 1741c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1742c569ef53SMichael Lim goto done1; 1743da14cebeSEric Cheng 1744c569ef53SMichael Lim /* Convert mac_propval_range to a single CPU list */ 1745c569ef53SMichael Lim ncpus = MRP_NCPUS; 1746c569ef53SMichael Lim status = dladm_range2list(pv_range, cpus, &ncpus); 1747c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1748c569ef53SMichael Lim goto done1; 17490dc2366fSVenugopal Iyer 1750c569ef53SMichael Lim /* 1751c569ef53SMichael Lim * If a range of CPUs was entered, update value count and reallocate 1752c569ef53SMichael Lim * the array of val_desc_t's. The array allocated was sized for 1753c569ef53SMichael Lim * indvidual elements, but needs to be reallocated to accomodate the 1754c569ef53SMichael Lim * expanded list of CPUs. 1755c569ef53SMichael Lim */ 1756c569ef53SMichael Lim if (val_cnt < ncpus) { 1757c569ef53SMichael Lim newvdp = calloc(*val_cntp, sizeof (val_desc_t)); 1758c569ef53SMichael Lim if (newvdp == NULL) { 1759c569ef53SMichael Lim status = DLADM_STATUS_NOMEM; 1760c569ef53SMichael Lim goto done1; 1761c569ef53SMichael Lim } 1762c569ef53SMichael Lim vdp = newvdp; 1763da14cebeSEric Cheng } 1764da14cebeSEric Cheng 1765c569ef53SMichael Lim /* Check if all CPUs in the list are online */ 1766c569ef53SMichael Lim for (i = 0; i < ncpus; i++) { 1767c569ef53SMichael Lim if (cpus[i] >= nproc) { 1768c569ef53SMichael Lim status = DLADM_STATUS_BADCPUID; 1769c569ef53SMichael Lim goto done2; 1770c569ef53SMichael Lim } 1771c569ef53SMichael Lim 1772c569ef53SMichael Lim rc = p_online(cpus[i], P_STATUS); 1773c569ef53SMichael Lim if (rc < 1) { 1774c569ef53SMichael Lim status = DLADM_STATUS_CPUERR; 1775c569ef53SMichael Lim goto done2; 1776c569ef53SMichael Lim } 1777c569ef53SMichael Lim 1778c569ef53SMichael Lim if (rc != P_ONLINE) { 1779c569ef53SMichael Lim status = DLADM_STATUS_CPUNOTONLINE; 1780c569ef53SMichael Lim goto done2; 1781c569ef53SMichael Lim } 1782c569ef53SMichael Lim 1783c569ef53SMichael Lim vdp[i].vd_val = (uintptr_t)cpus[i]; 1784c569ef53SMichael Lim } 1785c569ef53SMichael Lim 1786c569ef53SMichael Lim /* Check for duplicate CPUs */ 1787c569ef53SMichael Lim for (i = 0; i < *val_cntp; i++) { 1788c569ef53SMichael Lim for (j = 0; j < *val_cntp; j++) { 1789c569ef53SMichael Lim if (i != j && vdp[i].vd_val == vdp[j].vd_val) { 1790c569ef53SMichael Lim status = DLADM_STATUS_BADVAL; 1791c569ef53SMichael Lim goto done2; 1792da14cebeSEric Cheng } 1793da14cebeSEric Cheng } 1794c569ef53SMichael Lim } 1795c569ef53SMichael Lim 1796c569ef53SMichael Lim /* Update *val_cntp and *vdpp if everything was OK */ 1797c569ef53SMichael Lim if (val_cnt < ncpus) { 1798c569ef53SMichael Lim *val_cntp = ncpus; 1799c569ef53SMichael Lim free(*vdpp); 1800c569ef53SMichael Lim *vdpp = newvdp; 1801c569ef53SMichael Lim } 1802c569ef53SMichael Lim 1803c569ef53SMichael Lim status = DLADM_STATUS_OK; 1804c569ef53SMichael Lim goto done1; 1805c569ef53SMichael Lim 1806c569ef53SMichael Lim done2: 1807c569ef53SMichael Lim free(newvdp); 1808c569ef53SMichael Lim done1: 1809c569ef53SMichael Lim free(pv_range); 1810c569ef53SMichael Lim return (status); 1811da14cebeSEric Cheng } 18120dc2366fSVenugopal Iyer 18130dc2366fSVenugopal Iyer /* ARGSUSED */ 18140dc2366fSVenugopal Iyer dladm_status_t 18150dc2366fSVenugopal Iyer extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 18160dc2366fSVenugopal Iyer { 18170dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 18180dc2366fSVenugopal Iyer int i; 18190dc2366fSVenugopal Iyer 18200dc2366fSVenugopal Iyer if (vdp[0].vd_val == RESET_VAL) { 18210dc2366fSVenugopal Iyer bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 18220dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_CPUS; 18230dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 18240dc2366fSVenugopal Iyer } 18250dc2366fSVenugopal Iyer 18260dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) 18270dc2366fSVenugopal Iyer mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 18280dc2366fSVenugopal Iyer 18290dc2366fSVenugopal Iyer mrp->mrp_ncpus = cnt; 18300dc2366fSVenugopal Iyer mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 18310dc2366fSVenugopal Iyer mrp->mrp_fanout_mode = MCM_CPUS; 18320dc2366fSVenugopal Iyer mrp->mrp_rx_intr_cpu = -1; 18330dc2366fSVenugopal Iyer 18340dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 18350dc2366fSVenugopal Iyer } 18360dc2366fSVenugopal Iyer 18370dc2366fSVenugopal Iyer /* 18380dc2366fSVenugopal Iyer * Get the pool datalink property from the kernel. This is used 18390dc2366fSVenugopal Iyer * for both the user specified pool and effective pool properties. 18400dc2366fSVenugopal Iyer */ 18410dc2366fSVenugopal Iyer /* ARGSUSED */ 18420dc2366fSVenugopal Iyer static dladm_status_t 18430dc2366fSVenugopal Iyer get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18440dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 18450dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 18460dc2366fSVenugopal Iyer { 18470dc2366fSVenugopal Iyer mac_resource_props_t mrp; 18480dc2366fSVenugopal Iyer dladm_status_t status; 18490dc2366fSVenugopal Iyer 18500dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "pool-effective") == 0) { 18510dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 18520dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 18530dc2366fSVenugopal Iyer sizeof (mrp)); 18540dc2366fSVenugopal Iyer } else { 18550dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 18560dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 18570dc2366fSVenugopal Iyer } 18580dc2366fSVenugopal Iyer 18590dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 18600dc2366fSVenugopal Iyer return (status); 18610dc2366fSVenugopal Iyer 18620dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) == 0) { 18630dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 18640dc2366fSVenugopal Iyer } else { 18650dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 18660dc2366fSVenugopal Iyer "%s", mrp.mrp_pool); 18670dc2366fSVenugopal Iyer } 18680dc2366fSVenugopal Iyer *val_cnt = 1; 18690dc2366fSVenugopal Iyer 18700dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 18710dc2366fSVenugopal Iyer } 18720dc2366fSVenugopal Iyer 18730dc2366fSVenugopal Iyer /* ARGSUSED */ 18740dc2366fSVenugopal Iyer static dladm_status_t 18750dc2366fSVenugopal Iyer check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1876c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 18770dc2366fSVenugopal Iyer datalink_media_t media) 18780dc2366fSVenugopal Iyer { 18790dc2366fSVenugopal Iyer pool_conf_t *poolconf; 18800dc2366fSVenugopal Iyer pool_t *pool; 18810dc2366fSVenugopal Iyer mac_resource_props_t mrp; 18820dc2366fSVenugopal Iyer dladm_status_t status; 18830dc2366fSVenugopal Iyer uint_t perm_flags; 18840dc2366fSVenugopal Iyer char *poolname; 1885c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 18860dc2366fSVenugopal Iyer 18870dc2366fSVenugopal Iyer /* Get the current cpus property */ 18880dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 18890dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 18900dc2366fSVenugopal Iyer 18910dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 18920dc2366fSVenugopal Iyer /* Can't set pool if cpus are set */ 18930dc2366fSVenugopal Iyer if (mrp.mrp_ncpus != 0) 18940dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 18950dc2366fSVenugopal Iyer } 18960dc2366fSVenugopal Iyer 18970dc2366fSVenugopal Iyer poolname = malloc(sizeof (mrp.mrp_pool)); 18980dc2366fSVenugopal Iyer if (poolname == NULL) 18990dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 19000dc2366fSVenugopal Iyer 19010dc2366fSVenugopal Iyer /* Check for pool's availability if not booting */ 19020dc2366fSVenugopal Iyer if ((flags & DLADM_OPT_BOOT) == 0) { 19030dc2366fSVenugopal Iyer 19040dc2366fSVenugopal Iyer /* Allocate and open pool configuration */ 19050dc2366fSVenugopal Iyer if ((poolconf = pool_conf_alloc()) == NULL) 19060dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19070dc2366fSVenugopal Iyer 19080dc2366fSVenugopal Iyer if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 19090dc2366fSVenugopal Iyer != PO_SUCCESS) { 19100dc2366fSVenugopal Iyer pool_conf_free(poolconf); 19110dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19120dc2366fSVenugopal Iyer } 19130dc2366fSVenugopal Iyer 19140dc2366fSVenugopal Iyer /* Look for pool name */ 19150dc2366fSVenugopal Iyer if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 19160dc2366fSVenugopal Iyer pool_conf_free(poolconf); 19170dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19180dc2366fSVenugopal Iyer } 19190dc2366fSVenugopal Iyer 19200dc2366fSVenugopal Iyer pool_conf_free(poolconf); 19210dc2366fSVenugopal Iyer free(pool); 19220dc2366fSVenugopal Iyer } 19230dc2366fSVenugopal Iyer 19240dc2366fSVenugopal Iyer (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 19250dc2366fSVenugopal Iyer vdp->vd_val = (uintptr_t)poolname; 1926da14cebeSEric Cheng 1927da14cebeSEric Cheng return (DLADM_STATUS_OK); 1928da14cebeSEric Cheng } 1929da14cebeSEric Cheng 1930da14cebeSEric Cheng /* ARGSUSED */ 1931da14cebeSEric Cheng dladm_status_t 19320dc2366fSVenugopal Iyer extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 1933da14cebeSEric Cheng { 19340dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1935da14cebeSEric Cheng 19360dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 19370dc2366fSVenugopal Iyer bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 19380dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 19390dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1940da14cebeSEric Cheng } 19410dc2366fSVenugopal Iyer 19420dc2366fSVenugopal Iyer (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 19430dc2366fSVenugopal Iyer sizeof (mrp->mrp_pool)); 19440dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 19450dc2366fSVenugopal Iyer /* 19460dc2366fSVenugopal Iyer * Use MCM_CPUS since the fanout count is not user specified 19470dc2366fSVenugopal Iyer * and will be determined by the cpu list generated from the 19480dc2366fSVenugopal Iyer * pool. 19490dc2366fSVenugopal Iyer */ 1950da14cebeSEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 1951da14cebeSEric Cheng 1952da14cebeSEric Cheng return (DLADM_STATUS_OK); 1953da14cebeSEric Cheng } 1954da14cebeSEric Cheng 1955da14cebeSEric Cheng /* ARGSUSED */ 1956da14cebeSEric Cheng static dladm_status_t 19570dc2366fSVenugopal Iyer get_priority(dladm_handle_t handle, prop_desc_t *pdp, 195862ee1d25SArtem Kachitchkine datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 195962ee1d25SArtem Kachitchkine datalink_media_t media, uint_t flags, uint_t *perm_flags) 1960da14cebeSEric Cheng { 1961da14cebeSEric Cheng mac_resource_props_t mrp; 1962da14cebeSEric Cheng mac_priority_level_t pri; 1963da14cebeSEric Cheng dladm_status_t status; 1964da14cebeSEric Cheng 19650dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 19660dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 19670dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1968da14cebeSEric Cheng return (status); 1969da14cebeSEric Cheng 1970da14cebeSEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 1971da14cebeSEric Cheng mrp.mrp_priority; 1972da14cebeSEric Cheng 1973da14cebeSEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 1974da14cebeSEric Cheng *val_cnt = 1; 1975da14cebeSEric Cheng return (DLADM_STATUS_OK); 1976da14cebeSEric Cheng } 1977da14cebeSEric Cheng 1978da14cebeSEric Cheng /* ARGSUSED */ 1979da14cebeSEric Cheng dladm_status_t 19800dc2366fSVenugopal Iyer extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 1981da14cebeSEric Cheng { 198225ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1983da14cebeSEric Cheng 19840dc2366fSVenugopal Iyer if (cnt != 1) 19850dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19860dc2366fSVenugopal Iyer 19870dc2366fSVenugopal Iyer mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 1988da14cebeSEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 1989da14cebeSEric Cheng 1990da14cebeSEric Cheng return (DLADM_STATUS_OK); 1991da14cebeSEric Cheng } 1992da14cebeSEric Cheng 19930dc2366fSVenugopal Iyer /* 19940dc2366fSVenugopal Iyer * Determines the size of the structure that needs to be sent to drivers 19950dc2366fSVenugopal Iyer * for retrieving the property range values. 19960dc2366fSVenugopal Iyer */ 19970dc2366fSVenugopal Iyer static int 1998*0591ddd0SPrakash Jalan i_dladm_range_size(mac_propval_range_t *r, size_t *sz, uint_t *rcount) 19990dc2366fSVenugopal Iyer { 20000dc2366fSVenugopal Iyer uint_t count = r->mpr_count; 20010dc2366fSVenugopal Iyer 20020dc2366fSVenugopal Iyer *sz = sizeof (mac_propval_range_t); 2003*0591ddd0SPrakash Jalan *rcount = count; 20040dc2366fSVenugopal Iyer --count; 20050dc2366fSVenugopal Iyer 20060dc2366fSVenugopal Iyer switch (r->mpr_type) { 20070dc2366fSVenugopal Iyer case MAC_PROPVAL_UINT32: 20080dc2366fSVenugopal Iyer *sz += (count * sizeof (mac_propval_uint32_range_t)); 20090dc2366fSVenugopal Iyer return (0); 20100dc2366fSVenugopal Iyer default: 20110dc2366fSVenugopal Iyer break; 20120dc2366fSVenugopal Iyer } 20130dc2366fSVenugopal Iyer *sz = 0; 2014*0591ddd0SPrakash Jalan *rcount = 0; 20150dc2366fSVenugopal Iyer return (EINVAL); 20160dc2366fSVenugopal Iyer } 20170dc2366fSVenugopal Iyer 20180dc2366fSVenugopal Iyer 2019da14cebeSEric Cheng /* ARGSUSED */ 2020da14cebeSEric Cheng static dladm_status_t 20210dc2366fSVenugopal Iyer check_rings(dladm_handle_t handle, prop_desc_t *pdp, 2022c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 2023c569ef53SMichael Lim val_desc_t **vp, datalink_media_t media) 20240dc2366fSVenugopal Iyer { 2025c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2026c569ef53SMichael Lim val_desc_t *v = *vp; 2027c569ef53SMichael Lim 20280dc2366fSVenugopal Iyer if (val_cnt != 1) 20290dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20300dc2366fSVenugopal Iyer if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 20310dc2366fSVenugopal Iyer v->vd_val = UNSPEC_VAL; 20320dc2366fSVenugopal Iyer } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 20330dc2366fSVenugopal Iyer v->vd_val = 0; 20340dc2366fSVenugopal Iyer } else { 20350dc2366fSVenugopal Iyer v->vd_val = strtoul(prop_val[0], NULL, 0); 20360dc2366fSVenugopal Iyer if (v->vd_val == 0) 20370dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20380dc2366fSVenugopal Iyer } 20390dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 20400dc2366fSVenugopal Iyer } 20410dc2366fSVenugopal Iyer 20420dc2366fSVenugopal Iyer /* ARGSUSED */ 20430dc2366fSVenugopal Iyer static dladm_status_t 20440dc2366fSVenugopal Iyer get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 20450dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 20460dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 20470dc2366fSVenugopal Iyer { 20480dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 20490dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 20500dc2366fSVenugopal Iyer mac_propval_range_t *rangep; 20510dc2366fSVenugopal Iyer size_t sz; 20520dc2366fSVenugopal Iyer mac_propval_uint32_range_t *ur; 20530dc2366fSVenugopal Iyer 20540dc2366fSVenugopal Iyer sz = sizeof (mac_propval_range_t); 20550dc2366fSVenugopal Iyer 20560dc2366fSVenugopal Iyer if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 20570dc2366fSVenugopal Iyer &status)) == NULL) 20580dc2366fSVenugopal Iyer return (status); 20590dc2366fSVenugopal Iyer 20600dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 20610dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 20620dc2366fSVenugopal Iyer return (status); 20630dc2366fSVenugopal Iyer 20640dc2366fSVenugopal Iyer rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 20650dc2366fSVenugopal Iyer *val_cnt = 1; 20660dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 20670dc2366fSVenugopal Iyer /* This is the case where the dev doesn't have any rings/groups */ 20680dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 20690dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 20700dc2366fSVenugopal Iyer /* 20710dc2366fSVenugopal Iyer * This is the case where the dev supports rings, but static 20720dc2366fSVenugopal Iyer * grouping. 20730dc2366fSVenugopal Iyer */ 20740dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max && 20750dc2366fSVenugopal Iyer ur->mpur_max == 0) { 20760dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 20770dc2366fSVenugopal Iyer /* 20780dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 20790dc2366fSVenugopal Iyer * grouping, but has only one value (say 2 rings and 2 groups). 20800dc2366fSVenugopal Iyer */ 20810dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max) { 20820dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 20830dc2366fSVenugopal Iyer ur->mpur_min); 20840dc2366fSVenugopal Iyer /* 20850dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 20860dc2366fSVenugopal Iyer * grouping and has a range of rings. 20870dc2366fSVenugopal Iyer */ 20880dc2366fSVenugopal Iyer } else { 20890dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 20900dc2366fSVenugopal Iyer "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 20910dc2366fSVenugopal Iyer } 20920dc2366fSVenugopal Iyer free(dip); 20930dc2366fSVenugopal Iyer return (status); 20940dc2366fSVenugopal Iyer } 20950dc2366fSVenugopal Iyer 20960dc2366fSVenugopal Iyer 20970dc2366fSVenugopal Iyer /* ARGSUSED */ 20980dc2366fSVenugopal Iyer static dladm_status_t 20990dc2366fSVenugopal Iyer get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21000dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 21010dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 21020dc2366fSVenugopal Iyer { 21030dc2366fSVenugopal Iyer mac_resource_props_t mrp; 21040dc2366fSVenugopal Iyer dladm_status_t status; 21050dc2366fSVenugopal Iyer uint32_t nrings = 0; 21060dc2366fSVenugopal Iyer 21070dc2366fSVenugopal Iyer /* 21080dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 21090dc2366fSVenugopal Iyer */ 21100dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 21110dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 21120dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 21130dc2366fSVenugopal Iyer sizeof (mrp)); 21140dc2366fSVenugopal Iyer } else { 21150dc2366fSVenugopal Iyer /* 21160dc2366fSVenugopal Iyer * Get the permissions from the "rxrings" property. 21170dc2366fSVenugopal Iyer */ 21180dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "rxrings", 21190dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 21200dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 21210dc2366fSVenugopal Iyer return (status); 21220dc2366fSVenugopal Iyer 21230dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 21240dc2366fSVenugopal Iyer "resource", flags, NULL, &mrp, sizeof (mrp)); 21250dc2366fSVenugopal Iyer } 21260dc2366fSVenugopal Iyer 21270dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 21280dc2366fSVenugopal Iyer return (status); 21290dc2366fSVenugopal Iyer 21300dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 21310dc2366fSVenugopal Iyer *val_cnt = 0; 21320dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21330dc2366fSVenugopal Iyer } 21340dc2366fSVenugopal Iyer nrings = mrp.mrp_nrxrings; 21350dc2366fSVenugopal Iyer *val_cnt = 1; 21360dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 21370dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 21380dc2366fSVenugopal Iyer else if (nrings == 0) 21390dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 21400dc2366fSVenugopal Iyer else 21410dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 21420dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21430dc2366fSVenugopal Iyer } 21440dc2366fSVenugopal Iyer 21450dc2366fSVenugopal Iyer /* ARGSUSED */ 21460dc2366fSVenugopal Iyer dladm_status_t 21470dc2366fSVenugopal Iyer extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 21480dc2366fSVenugopal Iyer { 21490dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 21500dc2366fSVenugopal Iyer 21510dc2366fSVenugopal Iyer mrp->mrp_nrxrings = 0; 21520dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 21530dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 21540dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 21550dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 21560dc2366fSVenugopal Iyer else 21570dc2366fSVenugopal Iyer mrp->mrp_nrxrings = vdp->vd_val; 21580dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_RX_RINGS; 21590dc2366fSVenugopal Iyer 21600dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21610dc2366fSVenugopal Iyer } 21620dc2366fSVenugopal Iyer 21630dc2366fSVenugopal Iyer /* ARGSUSED */ 21640dc2366fSVenugopal Iyer static dladm_status_t 21650dc2366fSVenugopal Iyer get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21660dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 21670dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 21680dc2366fSVenugopal Iyer { 21690dc2366fSVenugopal Iyer mac_resource_props_t mrp; 21700dc2366fSVenugopal Iyer dladm_status_t status; 21710dc2366fSVenugopal Iyer uint32_t nrings = 0; 21720dc2366fSVenugopal Iyer 21730dc2366fSVenugopal Iyer 21740dc2366fSVenugopal Iyer /* 21750dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 21760dc2366fSVenugopal Iyer */ 21770dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 21780dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 21790dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 21800dc2366fSVenugopal Iyer sizeof (mrp)); 21810dc2366fSVenugopal Iyer } else { 21820dc2366fSVenugopal Iyer /* 21830dc2366fSVenugopal Iyer * Get the permissions from the "txrings" property. 21840dc2366fSVenugopal Iyer */ 21850dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "txrings", 21860dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 21870dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 21880dc2366fSVenugopal Iyer return (status); 21890dc2366fSVenugopal Iyer 21900dc2366fSVenugopal Iyer /* 21910dc2366fSVenugopal Iyer * Get the number of rings from the "resource" property. 21920dc2366fSVenugopal Iyer */ 21930dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 21940dc2366fSVenugopal Iyer flags, NULL, &mrp, sizeof (mrp)); 21950dc2366fSVenugopal Iyer } 21960dc2366fSVenugopal Iyer 21970dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 21980dc2366fSVenugopal Iyer return (status); 21990dc2366fSVenugopal Iyer 22000dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 22010dc2366fSVenugopal Iyer *val_cnt = 0; 22020dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22030dc2366fSVenugopal Iyer } 22040dc2366fSVenugopal Iyer nrings = mrp.mrp_ntxrings; 22050dc2366fSVenugopal Iyer *val_cnt = 1; 22060dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 22070dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 22080dc2366fSVenugopal Iyer else if (nrings == 0) 22090dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 22100dc2366fSVenugopal Iyer else 22110dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 22120dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22130dc2366fSVenugopal Iyer } 22140dc2366fSVenugopal Iyer 22150dc2366fSVenugopal Iyer /* ARGSUSED */ 22160dc2366fSVenugopal Iyer dladm_status_t 22170dc2366fSVenugopal Iyer extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 22180dc2366fSVenugopal Iyer { 22190dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 22200dc2366fSVenugopal Iyer 22210dc2366fSVenugopal Iyer mrp->mrp_ntxrings = 0; 22220dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 22230dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 22240dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 22250dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 22260dc2366fSVenugopal Iyer else 22270dc2366fSVenugopal Iyer mrp->mrp_ntxrings = vdp->vd_val; 22280dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_TX_RINGS; 22290dc2366fSVenugopal Iyer 22300dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22310dc2366fSVenugopal Iyer } 22320dc2366fSVenugopal Iyer 22330dc2366fSVenugopal Iyer /* ARGSUSED */ 22340dc2366fSVenugopal Iyer static dladm_status_t 22350dc2366fSVenugopal Iyer get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22360dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 22370dc2366fSVenugopal Iyer uint_t *perm_flags) 22380dc2366fSVenugopal Iyer { 22390dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 22400dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTDEFINED); 22410dc2366fSVenugopal Iyer 22420dc2366fSVenugopal Iyer return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 22430dc2366fSVenugopal Iyer flags, perm_flags)); 22440dc2366fSVenugopal Iyer } 22450dc2366fSVenugopal Iyer 22460dc2366fSVenugopal Iyer /* ARGSUSED */ 22470dc2366fSVenugopal Iyer static dladm_status_t 22480dc2366fSVenugopal Iyer set_resource(dladm_handle_t handle, prop_desc_t *pdp, 224925ec3e3dSEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 225025ec3e3dSEric Cheng uint_t flags, datalink_media_t media) 225125ec3e3dSEric Cheng { 225225ec3e3dSEric Cheng mac_resource_props_t mrp; 225325ec3e3dSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 225425ec3e3dSEric Cheng dld_ioc_macprop_t *dip; 22550dc2366fSVenugopal Iyer int i; 225625ec3e3dSEric Cheng 225725ec3e3dSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 22580dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 225925ec3e3dSEric Cheng flags, &status); 226025ec3e3dSEric Cheng 226125ec3e3dSEric Cheng if (dip == NULL) 226225ec3e3dSEric Cheng return (status); 226325ec3e3dSEric Cheng 22640dc2366fSVenugopal Iyer for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 22650dc2366fSVenugopal Iyer resource_prop_t *rp = &rsrc_prop_table[i]; 22660dc2366fSVenugopal Iyer 22670dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, rp->rp_name) != 0) 22680dc2366fSVenugopal Iyer continue; 22690dc2366fSVenugopal Iyer 22700dc2366fSVenugopal Iyer status = rp->rp_extract(vdp, val_cnt, &mrp); 227125ec3e3dSEric Cheng if (status != DLADM_STATUS_OK) 227225ec3e3dSEric Cheng goto done; 227325ec3e3dSEric Cheng 22740dc2366fSVenugopal Iyer break; 227525ec3e3dSEric Cheng } 227625ec3e3dSEric Cheng 227725ec3e3dSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 227825ec3e3dSEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 227925ec3e3dSEric Cheng 228025ec3e3dSEric Cheng done: 228125ec3e3dSEric Cheng free(dip); 228225ec3e3dSEric Cheng return (status); 228325ec3e3dSEric Cheng } 228425ec3e3dSEric Cheng 228525ec3e3dSEric Cheng /* ARGSUSED */ 228625ec3e3dSEric Cheng static dladm_status_t 22870dc2366fSVenugopal Iyer get_protection(dladm_handle_t handle, prop_desc_t *pdp, 228825ec3e3dSEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 228925ec3e3dSEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 229025ec3e3dSEric Cheng { 229125ec3e3dSEric Cheng mac_resource_props_t mrp; 229225ec3e3dSEric Cheng mac_protect_t *p; 229325ec3e3dSEric Cheng dladm_status_t status; 22940dc2366fSVenugopal Iyer uint32_t i, cnt = 0, setbits[32]; 229525ec3e3dSEric Cheng 22960dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 22970dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 22980dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 229925ec3e3dSEric Cheng return (status); 230025ec3e3dSEric Cheng 230125ec3e3dSEric Cheng p = &mrp.mrp_protect; 23020dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 23030dc2366fSVenugopal Iyer *val_cnt = 0; 23040dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23050dc2366fSVenugopal Iyer } 230625ec3e3dSEric Cheng dladm_find_setbits32(p->mp_types, setbits, &cnt); 230725ec3e3dSEric Cheng if (cnt > *val_cnt) 230825ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 230925ec3e3dSEric Cheng 231025ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 231125ec3e3dSEric Cheng (void) dladm_protect2str(setbits[i], prop_val[i]); 231225ec3e3dSEric Cheng 231325ec3e3dSEric Cheng *val_cnt = cnt; 231425ec3e3dSEric Cheng return (DLADM_STATUS_OK); 231525ec3e3dSEric Cheng } 231625ec3e3dSEric Cheng 23170dc2366fSVenugopal Iyer /* ARGSUSED */ 23180dc2366fSVenugopal Iyer static dladm_status_t 23190dc2366fSVenugopal Iyer get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 23200dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 23210dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 23220dc2366fSVenugopal Iyer { 23230dc2366fSVenugopal Iyer mac_resource_props_t mrp; 23240dc2366fSVenugopal Iyer mac_protect_t *p; 23250dc2366fSVenugopal Iyer dladm_status_t status; 23260dc2366fSVenugopal Iyer int i; 23270dc2366fSVenugopal Iyer 23280dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 23290dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 23300dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 23310dc2366fSVenugopal Iyer return (status); 23320dc2366fSVenugopal Iyer 23330dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 23340dc2366fSVenugopal Iyer if (p->mp_ipaddrcnt == 0) { 23350dc2366fSVenugopal Iyer *val_cnt = 0; 23360dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23370dc2366fSVenugopal Iyer } 233825ec3e3dSEric Cheng if (p->mp_ipaddrcnt > *val_cnt) 233925ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 234025ec3e3dSEric Cheng 234125ec3e3dSEric Cheng for (i = 0; i < p->mp_ipaddrcnt; i++) { 23420dc2366fSVenugopal Iyer if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 23430dc2366fSVenugopal Iyer ipaddr_t v4addr; 23440dc2366fSVenugopal Iyer 23450dc2366fSVenugopal Iyer v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 23460dc2366fSVenugopal Iyer (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 23470dc2366fSVenugopal Iyer } else { 23480dc2366fSVenugopal Iyer (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 234925ec3e3dSEric Cheng prop_val[i]); 235025ec3e3dSEric Cheng } 23510dc2366fSVenugopal Iyer } 235225ec3e3dSEric Cheng *val_cnt = p->mp_ipaddrcnt; 235325ec3e3dSEric Cheng return (DLADM_STATUS_OK); 235425ec3e3dSEric Cheng } 235525ec3e3dSEric Cheng 235625ec3e3dSEric Cheng dladm_status_t 23570dc2366fSVenugopal Iyer extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 235825ec3e3dSEric Cheng { 235925ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 236025ec3e3dSEric Cheng uint32_t types = 0; 236125ec3e3dSEric Cheng int i; 236225ec3e3dSEric Cheng 236325ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 236425ec3e3dSEric Cheng types |= (uint32_t)vdp[i].vd_val; 236525ec3e3dSEric Cheng 236625ec3e3dSEric Cheng mrp->mrp_protect.mp_types = types; 236725ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 236825ec3e3dSEric Cheng return (DLADM_STATUS_OK); 236925ec3e3dSEric Cheng } 237025ec3e3dSEric Cheng 237125ec3e3dSEric Cheng dladm_status_t 23720dc2366fSVenugopal Iyer extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 237325ec3e3dSEric Cheng { 237425ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 237525ec3e3dSEric Cheng mac_protect_t *p = &mrp->mrp_protect; 237625ec3e3dSEric Cheng int i; 237725ec3e3dSEric Cheng 237825ec3e3dSEric Cheng if (vdp->vd_val == 0) { 237925ec3e3dSEric Cheng cnt = (uint_t)-1; 238025ec3e3dSEric Cheng } else { 23810dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 23820dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 23830dc2366fSVenugopal Iyer sizeof (mac_ipaddr_t)); 23840dc2366fSVenugopal Iyer } 238525ec3e3dSEric Cheng } 238625ec3e3dSEric Cheng p->mp_ipaddrcnt = cnt; 238725ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 238825ec3e3dSEric Cheng return (DLADM_STATUS_OK); 238925ec3e3dSEric Cheng } 239025ec3e3dSEric Cheng 23910dc2366fSVenugopal Iyer static dladm_status_t 23920dc2366fSVenugopal Iyer check_single_ip(char *buf, mac_ipaddr_t *addr) 23930dc2366fSVenugopal Iyer { 23940dc2366fSVenugopal Iyer dladm_status_t status; 23950dc2366fSVenugopal Iyer ipaddr_t v4addr; 23960dc2366fSVenugopal Iyer in6_addr_t v6addr; 23970dc2366fSVenugopal Iyer boolean_t isv4 = B_TRUE; 23980dc2366fSVenugopal Iyer 23990dc2366fSVenugopal Iyer status = dladm_str2ipv4addr(buf, &v4addr); 24000dc2366fSVenugopal Iyer if (status == DLADM_STATUS_INVALID_IP) { 24010dc2366fSVenugopal Iyer status = dladm_str2ipv6addr(buf, &v6addr); 24020dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) 24030dc2366fSVenugopal Iyer isv4 = B_FALSE; 24040dc2366fSVenugopal Iyer } 24050dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 24060dc2366fSVenugopal Iyer return (status); 24070dc2366fSVenugopal Iyer 24080dc2366fSVenugopal Iyer if (isv4) { 24090dc2366fSVenugopal Iyer if (v4addr == INADDR_ANY) 24100dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 24110dc2366fSVenugopal Iyer 24120dc2366fSVenugopal Iyer IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 24130dc2366fSVenugopal Iyer addr->ip_version = IPV4_VERSION; 24140dc2366fSVenugopal Iyer } else { 24150dc2366fSVenugopal Iyer if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 24160dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 24170dc2366fSVenugopal Iyer 24180dc2366fSVenugopal Iyer addr->ip_addr = v6addr; 24190dc2366fSVenugopal Iyer addr->ip_version = IPV6_VERSION; 24200dc2366fSVenugopal Iyer } 24210dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 24220dc2366fSVenugopal Iyer } 24230dc2366fSVenugopal Iyer 242425ec3e3dSEric Cheng /* ARGSUSED */ 242525ec3e3dSEric Cheng static dladm_status_t 24260dc2366fSVenugopal Iyer check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2427c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 2428c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 242925ec3e3dSEric Cheng { 243025ec3e3dSEric Cheng dladm_status_t status; 24310dc2366fSVenugopal Iyer mac_ipaddr_t *addr; 243225ec3e3dSEric Cheng int i; 2433c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2434c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 243525ec3e3dSEric Cheng 243625ec3e3dSEric Cheng if (val_cnt > MPT_MAXIPADDR) 243725ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 243825ec3e3dSEric Cheng 243925ec3e3dSEric Cheng for (i = 0; i < val_cnt; i++) { 24400dc2366fSVenugopal Iyer if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 24410dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 24420dc2366fSVenugopal Iyer goto fail; 244325ec3e3dSEric Cheng } 24440dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)addr; 24450dc2366fSVenugopal Iyer 24460dc2366fSVenugopal Iyer status = check_single_ip(prop_val[i], addr); 24470dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 24480dc2366fSVenugopal Iyer goto fail; 24490dc2366fSVenugopal Iyer } 24500dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 24510dc2366fSVenugopal Iyer 24520dc2366fSVenugopal Iyer fail: 24530dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 24540dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 24550dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 24560dc2366fSVenugopal Iyer } 24570dc2366fSVenugopal Iyer return (status); 24580dc2366fSVenugopal Iyer } 24590dc2366fSVenugopal Iyer 24600dc2366fSVenugopal Iyer static void 24610dc2366fSVenugopal Iyer dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 24620dc2366fSVenugopal Iyer { 24630dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 24640dc2366fSVenugopal Iyer uint_t hexlen; 24650dc2366fSVenugopal Iyer 24660dc2366fSVenugopal Iyer switch (cid->dc_form) { 24670dc2366fSVenugopal Iyer case CIDFORM_TYPED: { 24680dc2366fSVenugopal Iyer uint16_t duidtype, hwtype; 24690dc2366fSVenugopal Iyer uint32_t timestamp, ennum; 24700dc2366fSVenugopal Iyer char *lladdr; 24710dc2366fSVenugopal Iyer 24720dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (duidtype)) 24730dc2366fSVenugopal Iyer goto fail; 24740dc2366fSVenugopal Iyer 24750dc2366fSVenugopal Iyer bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 24760dc2366fSVenugopal Iyer duidtype = ntohs(duidtype); 24770dc2366fSVenugopal Iyer switch (duidtype) { 24780dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 24790dc2366fSVenugopal Iyer duid_llt_t llt; 24800dc2366fSVenugopal Iyer 24810dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (llt)) 24820dc2366fSVenugopal Iyer goto fail; 24830dc2366fSVenugopal Iyer 24840dc2366fSVenugopal Iyer bcopy(cid->dc_id, &llt, sizeof (llt)); 24850dc2366fSVenugopal Iyer hwtype = ntohs(llt.dllt_hwtype); 24860dc2366fSVenugopal Iyer timestamp = ntohl(llt.dllt_time); 24870dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 24880dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 24890dc2366fSVenugopal Iyer if (lladdr == NULL) 24900dc2366fSVenugopal Iyer goto fail; 24910dc2366fSVenugopal Iyer 24920dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 24930dc2366fSVenugopal Iyer duidtype, hwtype, timestamp, lladdr); 24940dc2366fSVenugopal Iyer free(lladdr); 24950dc2366fSVenugopal Iyer break; 24960dc2366fSVenugopal Iyer } 24970dc2366fSVenugopal Iyer case DHCPV6_DUID_EN: { 24980dc2366fSVenugopal Iyer duid_en_t en; 24990dc2366fSVenugopal Iyer 25000dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (en)) 25010dc2366fSVenugopal Iyer goto fail; 25020dc2366fSVenugopal Iyer 25030dc2366fSVenugopal Iyer bcopy(cid->dc_id, &en, sizeof (en)); 25040dc2366fSVenugopal Iyer ennum = DHCPV6_GET_ENTNUM(&en); 25050dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 25060dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (en), 25070dc2366fSVenugopal Iyer cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 25080dc2366fSVenugopal Iyer goto fail; 25090dc2366fSVenugopal Iyer 25100dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 25110dc2366fSVenugopal Iyer duidtype, ennum, tmp_buf); 25120dc2366fSVenugopal Iyer break; 25130dc2366fSVenugopal Iyer } 25140dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 25150dc2366fSVenugopal Iyer duid_ll_t ll; 25160dc2366fSVenugopal Iyer 25170dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (ll)) 25180dc2366fSVenugopal Iyer goto fail; 25190dc2366fSVenugopal Iyer 25200dc2366fSVenugopal Iyer bcopy(cid->dc_id, &ll, sizeof (ll)); 25210dc2366fSVenugopal Iyer hwtype = ntohs(ll.dll_hwtype); 25220dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 25230dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 25240dc2366fSVenugopal Iyer if (lladdr == NULL) 25250dc2366fSVenugopal Iyer goto fail; 25260dc2366fSVenugopal Iyer 25270dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 25280dc2366fSVenugopal Iyer duidtype, hwtype, lladdr); 25290dc2366fSVenugopal Iyer free(lladdr); 25300dc2366fSVenugopal Iyer break; 25310dc2366fSVenugopal Iyer } 25320dc2366fSVenugopal Iyer default: { 25330dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 25340dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 25350dc2366fSVenugopal Iyer cid->dc_len - sizeof (duidtype), 25360dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 25370dc2366fSVenugopal Iyer goto fail; 25380dc2366fSVenugopal Iyer 25390dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 25400dc2366fSVenugopal Iyer duidtype, tmp_buf); 25410dc2366fSVenugopal Iyer } 25420dc2366fSVenugopal Iyer } 25430dc2366fSVenugopal Iyer break; 25440dc2366fSVenugopal Iyer } 25450dc2366fSVenugopal Iyer case CIDFORM_HEX: { 25460dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 25470dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id, cid->dc_len, 25480dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 25490dc2366fSVenugopal Iyer goto fail; 25500dc2366fSVenugopal Iyer 25510dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 25520dc2366fSVenugopal Iyer break; 25530dc2366fSVenugopal Iyer } 25540dc2366fSVenugopal Iyer case CIDFORM_STR: { 25550dc2366fSVenugopal Iyer int i; 25560dc2366fSVenugopal Iyer 25570dc2366fSVenugopal Iyer for (i = 0; i < cid->dc_len; i++) { 25580dc2366fSVenugopal Iyer if (!isprint(cid->dc_id[i])) 25590dc2366fSVenugopal Iyer goto fail; 25600dc2366fSVenugopal Iyer } 25610dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 25620dc2366fSVenugopal Iyer break; 25630dc2366fSVenugopal Iyer } 25640dc2366fSVenugopal Iyer default: 25650dc2366fSVenugopal Iyer goto fail; 25660dc2366fSVenugopal Iyer } 25670dc2366fSVenugopal Iyer return; 25680dc2366fSVenugopal Iyer 25690dc2366fSVenugopal Iyer fail: 25700dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 25710dc2366fSVenugopal Iyer } 25720dc2366fSVenugopal Iyer 25730dc2366fSVenugopal Iyer static dladm_status_t 25740dc2366fSVenugopal Iyer dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 25750dc2366fSVenugopal Iyer { 25760dc2366fSVenugopal Iyer char *ptr = buf; 25770dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 25780dc2366fSVenugopal Iyer uint_t hexlen, cidlen; 25790dc2366fSVenugopal Iyer 25800dc2366fSVenugopal Iyer bzero(cid, sizeof (*cid)); 25810dc2366fSVenugopal Iyer if (isdigit(*ptr) && 25820dc2366fSVenugopal Iyer ptr[strspn(ptr, "0123456789")] == '.') { 25830dc2366fSVenugopal Iyer char *cp; 25840dc2366fSVenugopal Iyer ulong_t duidtype; 25850dc2366fSVenugopal Iyer ulong_t subtype; 25860dc2366fSVenugopal Iyer ulong_t timestamp; 25870dc2366fSVenugopal Iyer uchar_t *lladdr; 25880dc2366fSVenugopal Iyer int addrlen; 25890dc2366fSVenugopal Iyer 25900dc2366fSVenugopal Iyer errno = 0; 25910dc2366fSVenugopal Iyer duidtype = strtoul(ptr, &cp, 0); 25920dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.' || 25930dc2366fSVenugopal Iyer duidtype > USHRT_MAX) 25940dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 25950dc2366fSVenugopal Iyer ptr = cp + 1; 25960dc2366fSVenugopal Iyer 25970dc2366fSVenugopal Iyer if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 25980dc2366fSVenugopal Iyer errno = 0; 25990dc2366fSVenugopal Iyer subtype = strtoul(ptr, &cp, 0); 26000dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 26010dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26020dc2366fSVenugopal Iyer ptr = cp + 1; 26030dc2366fSVenugopal Iyer } 26040dc2366fSVenugopal Iyer switch (duidtype) { 26050dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 26060dc2366fSVenugopal Iyer duid_llt_t llt; 26070dc2366fSVenugopal Iyer 26080dc2366fSVenugopal Iyer errno = 0; 26090dc2366fSVenugopal Iyer timestamp = strtoul(ptr, &cp, 0); 26100dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 26110dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26120dc2366fSVenugopal Iyer 26130dc2366fSVenugopal Iyer ptr = cp + 1; 26140dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 26150dc2366fSVenugopal Iyer if (lladdr == NULL) 26160dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26170dc2366fSVenugopal Iyer 26180dc2366fSVenugopal Iyer cidlen = sizeof (llt) + addrlen; 26190dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 26200dc2366fSVenugopal Iyer free(lladdr); 26210dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 26220dc2366fSVenugopal Iyer } 26230dc2366fSVenugopal Iyer llt.dllt_dutype = htons(duidtype); 26240dc2366fSVenugopal Iyer llt.dllt_hwtype = htons(subtype); 26250dc2366fSVenugopal Iyer llt.dllt_time = htonl(timestamp); 26260dc2366fSVenugopal Iyer bcopy(&llt, cid->dc_id, sizeof (llt)); 26270dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 26280dc2366fSVenugopal Iyer free(lladdr); 26290dc2366fSVenugopal Iyer break; 26300dc2366fSVenugopal Iyer } 26310dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 26320dc2366fSVenugopal Iyer duid_ll_t ll; 26330dc2366fSVenugopal Iyer 26340dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 26350dc2366fSVenugopal Iyer if (lladdr == NULL) 26360dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26370dc2366fSVenugopal Iyer 26380dc2366fSVenugopal Iyer cidlen = sizeof (ll) + addrlen; 26390dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 26400dc2366fSVenugopal Iyer free(lladdr); 26410dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 26420dc2366fSVenugopal Iyer } 26430dc2366fSVenugopal Iyer ll.dll_dutype = htons(duidtype); 26440dc2366fSVenugopal Iyer ll.dll_hwtype = htons(subtype); 26450dc2366fSVenugopal Iyer bcopy(&ll, cid->dc_id, sizeof (ll)); 26460dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 26470dc2366fSVenugopal Iyer free(lladdr); 26480dc2366fSVenugopal Iyer break; 26490dc2366fSVenugopal Iyer } 26500dc2366fSVenugopal Iyer default: { 26510dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 26520dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), 26530dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 26540dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26550dc2366fSVenugopal Iyer 26560dc2366fSVenugopal Iyer if (duidtype == DHCPV6_DUID_EN) { 26570dc2366fSVenugopal Iyer duid_en_t en; 26580dc2366fSVenugopal Iyer 26590dc2366fSVenugopal Iyer en.den_dutype = htons(duidtype); 26600dc2366fSVenugopal Iyer DHCPV6_SET_ENTNUM(&en, subtype); 26610dc2366fSVenugopal Iyer 26620dc2366fSVenugopal Iyer cidlen = sizeof (en) + hexlen; 26630dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 26640dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 26650dc2366fSVenugopal Iyer 26660dc2366fSVenugopal Iyer bcopy(&en, cid->dc_id, sizeof (en)); 26670dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (en), 26680dc2366fSVenugopal Iyer hexlen); 26690dc2366fSVenugopal Iyer } else { 26700dc2366fSVenugopal Iyer uint16_t dutype = htons(duidtype); 26710dc2366fSVenugopal Iyer 26720dc2366fSVenugopal Iyer cidlen = sizeof (dutype) + hexlen; 26730dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 26740dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 26750dc2366fSVenugopal Iyer 26760dc2366fSVenugopal Iyer bcopy(&dutype, cid->dc_id, sizeof (dutype)); 26770dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 26780dc2366fSVenugopal Iyer hexlen); 26790dc2366fSVenugopal Iyer } 26800dc2366fSVenugopal Iyer break; 26810dc2366fSVenugopal Iyer } 26820dc2366fSVenugopal Iyer } 26830dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_TYPED; 26840dc2366fSVenugopal Iyer } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 26850dc2366fSVenugopal Iyer ptr += 2; 26860dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 26870dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 26880dc2366fSVenugopal Iyer &hexlen) != 0) { 26890dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26900dc2366fSVenugopal Iyer } 26910dc2366fSVenugopal Iyer cidlen = hexlen; 26920dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 26930dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 26940dc2366fSVenugopal Iyer 26950dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id, cidlen); 26960dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_HEX; 26970dc2366fSVenugopal Iyer } else { 26980dc2366fSVenugopal Iyer cidlen = strlen(ptr); 26990dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 27000dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27010dc2366fSVenugopal Iyer 27020dc2366fSVenugopal Iyer bcopy(ptr, cid->dc_id, cidlen); 27030dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_STR; 27040dc2366fSVenugopal Iyer } 27050dc2366fSVenugopal Iyer cid->dc_len = cidlen; 270625ec3e3dSEric Cheng return (DLADM_STATUS_OK); 270725ec3e3dSEric Cheng } 270825ec3e3dSEric Cheng 270925ec3e3dSEric Cheng /* ARGSUSED */ 271025ec3e3dSEric Cheng static dladm_status_t 27110dc2366fSVenugopal Iyer get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 27120dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27130dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 27140dc2366fSVenugopal Iyer { 27150dc2366fSVenugopal Iyer mac_resource_props_t mrp; 27160dc2366fSVenugopal Iyer mac_protect_t *p; 27170dc2366fSVenugopal Iyer dladm_status_t status; 27180dc2366fSVenugopal Iyer int i; 27190dc2366fSVenugopal Iyer 27200dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 27210dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 27220dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 27230dc2366fSVenugopal Iyer return (status); 27240dc2366fSVenugopal Iyer 27250dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 27260dc2366fSVenugopal Iyer if (p->mp_cidcnt == 0) { 27270dc2366fSVenugopal Iyer *val_cnt = 0; 27280dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 27290dc2366fSVenugopal Iyer } 27300dc2366fSVenugopal Iyer if (p->mp_cidcnt > *val_cnt) 27310dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 27320dc2366fSVenugopal Iyer 27330dc2366fSVenugopal Iyer for (i = 0; i < p->mp_cidcnt; i++) { 27340dc2366fSVenugopal Iyer mac_dhcpcid_t *cid = &p->mp_cids[i]; 27350dc2366fSVenugopal Iyer 27360dc2366fSVenugopal Iyer dladm_cid2str(cid, prop_val[i]); 27370dc2366fSVenugopal Iyer } 27380dc2366fSVenugopal Iyer *val_cnt = p->mp_cidcnt; 27390dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 27400dc2366fSVenugopal Iyer } 27410dc2366fSVenugopal Iyer 27420dc2366fSVenugopal Iyer dladm_status_t 27430dc2366fSVenugopal Iyer extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 27440dc2366fSVenugopal Iyer { 27450dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 27460dc2366fSVenugopal Iyer mac_protect_t *p = &mrp->mrp_protect; 27470dc2366fSVenugopal Iyer int i; 27480dc2366fSVenugopal Iyer 27490dc2366fSVenugopal Iyer if (vdp->vd_val == 0) { 27500dc2366fSVenugopal Iyer cnt = (uint_t)-1; 27510dc2366fSVenugopal Iyer } else { 27520dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 27530dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 27540dc2366fSVenugopal Iyer sizeof (mac_dhcpcid_t)); 27550dc2366fSVenugopal Iyer } 27560dc2366fSVenugopal Iyer } 27570dc2366fSVenugopal Iyer p->mp_cidcnt = cnt; 27580dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_PROTECT; 27590dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 27600dc2366fSVenugopal Iyer } 27610dc2366fSVenugopal Iyer 27620dc2366fSVenugopal Iyer /* ARGSUSED */ 27630dc2366fSVenugopal Iyer static dladm_status_t 27640dc2366fSVenugopal Iyer check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2765c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, 2766c569ef53SMichael Lim uint_t flags, val_desc_t **vdpp, datalink_media_t media) 27670dc2366fSVenugopal Iyer { 27680dc2366fSVenugopal Iyer dladm_status_t status; 27690dc2366fSVenugopal Iyer mac_dhcpcid_t *cid; 27700dc2366fSVenugopal Iyer int i; 2771c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2772c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 27730dc2366fSVenugopal Iyer 27740dc2366fSVenugopal Iyer if (val_cnt > MPT_MAXCID) 27750dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 27760dc2366fSVenugopal Iyer 27770dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 27780dc2366fSVenugopal Iyer if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 27790dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 27800dc2366fSVenugopal Iyer goto fail; 27810dc2366fSVenugopal Iyer } 27820dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)cid; 27830dc2366fSVenugopal Iyer 27840dc2366fSVenugopal Iyer status = dladm_str2cid(prop_val[i], cid); 27850dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 27860dc2366fSVenugopal Iyer goto fail; 27870dc2366fSVenugopal Iyer } 27880dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 27890dc2366fSVenugopal Iyer 27900dc2366fSVenugopal Iyer fail: 27910dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 27920dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 27930dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 27940dc2366fSVenugopal Iyer } 27950dc2366fSVenugopal Iyer return (status); 27960dc2366fSVenugopal Iyer } 27970dc2366fSVenugopal Iyer 27980dc2366fSVenugopal Iyer /* ARGSUSED */ 27990dc2366fSVenugopal Iyer static dladm_status_t 28000dc2366fSVenugopal Iyer get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2801da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2802da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2803d62bc4baSyz147064 { 28043bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 28053bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 28063bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 2807d62bc4baSyz147064 28080dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 2809149b7eb2SSowmini Varadhan return (DLADM_STATUS_NOTDEFINED); 28104045d941Ssowmini 28110dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 28120dc2366fSVenugopal Iyer perm_flags, &dlap, sizeof (dlap)); 28130dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 28140dc2366fSVenugopal Iyer return (status); 28150dc2366fSVenugopal Iyer 28160dc2366fSVenugopal Iyer if (dlap.dap_npush == 0) { 28170dc2366fSVenugopal Iyer *val_cnt = 0; 2818da14cebeSEric Cheng return (DLADM_STATUS_OK); 2819d62bc4baSyz147064 } 28203bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 2821d62bc4baSyz147064 if (i != 0) { 2822d62bc4baSyz147064 (void) snprintf(*prop_val + len, 2823d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 2824d62bc4baSyz147064 len += 1; 2825d62bc4baSyz147064 } 2826d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 28273bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 28283bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 28293bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 2830d62bc4baSyz147064 (void) snprintf(*prop_val + len, 2831d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 2832d62bc4baSyz147064 AP_ANCHOR); 2833d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 2834d62bc4baSyz147064 } 2835d62bc4baSyz147064 } 28360dc2366fSVenugopal Iyer *val_cnt = 1; 2837d62bc4baSyz147064 return (DLADM_STATUS_OK); 2838d62bc4baSyz147064 } 2839d62bc4baSyz147064 2840d62bc4baSyz147064 /* 2841d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 2842d62bc4baSyz147064 * DLADM_STATUS_* code. 2843d62bc4baSyz147064 */ 2844d62bc4baSyz147064 dladm_status_t 2845d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 2846d62bc4baSyz147064 { 2847d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 2848d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 2849d62bc4baSyz147064 2850d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 2851d62bc4baSyz147064 /* 2852d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 2853d62bc4baSyz147064 * be after at least one module. 2854d62bc4baSyz147064 */ 2855d62bc4baSyz147064 if (dlap->dap_anchor != 0) 2856d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 2857d62bc4baSyz147064 if (dlap->dap_npush == 0) 2858d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 2859d62bc4baSyz147064 2860d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 2861d62bc4baSyz147064 return (DLADM_STATUS_OK); 2862d62bc4baSyz147064 } 2863285e94f9SMichael Lim if (dlap->dap_npush >= MAXAPUSH) 2864d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2865d62bc4baSyz147064 2866d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 2867d62bc4baSyz147064 FMNAMESZ + 1); 2868d62bc4baSyz147064 2869d62bc4baSyz147064 return (DLADM_STATUS_OK); 2870d62bc4baSyz147064 } 2871d62bc4baSyz147064 2872d62bc4baSyz147064 /* 2873d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 2874d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 2875d62bc4baSyz147064 * latter is used in the autopush(1M) file. 2876d62bc4baSyz147064 */ 2877d62bc4baSyz147064 /* ARGSUSED */ 2878d62bc4baSyz147064 static dladm_status_t 28790dc2366fSVenugopal Iyer check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2880c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 28810dc2366fSVenugopal Iyer datalink_media_t media) 2882d62bc4baSyz147064 { 2883d62bc4baSyz147064 char *module; 2884d62bc4baSyz147064 struct dlautopush *dlap; 2885d62bc4baSyz147064 dladm_status_t status; 2886d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 2887d62bc4baSyz147064 char delimiters[4]; 2888c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2889c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 2890d62bc4baSyz147064 2891d62bc4baSyz147064 if (val_cnt != 1) 2892d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 2893d62bc4baSyz147064 28943bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 2895d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 2896d62bc4baSyz147064 if (dlap == NULL) 2897d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 2898d62bc4baSyz147064 2899d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 2900d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 2901d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 2902d62bc4baSyz147064 module = strtok(val, delimiters); 2903d62bc4baSyz147064 while (module != NULL) { 2904d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 2905d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2906d62bc4baSyz147064 return (status); 2907d62bc4baSyz147064 module = strtok(NULL, delimiters); 2908d62bc4baSyz147064 } 2909d62bc4baSyz147064 2910d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 29113bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 29123bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 29133bc21d0aSAruna Ramakrishna - Sun Microsystems } 2914d62bc4baSyz147064 return (DLADM_STATUS_OK); 2915d62bc4baSyz147064 } 2916d62bc4baSyz147064 2917bcb5c89dSSowmini Varadhan #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 2918bcb5c89dSSowmini Varadhan 2919e7801d59Ssowmini /* ARGSUSED */ 2920d62bc4baSyz147064 static dladm_status_t 29210dc2366fSVenugopal Iyer get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 29224ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 29234ac67f02SAnurag S. Maskey uint_t *perm_flags) 2924d62bc4baSyz147064 { 2925d62bc4baSyz147064 wl_rates_t *wrp; 2926d62bc4baSyz147064 uint_t i; 2927d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 2928d62bc4baSyz147064 2929bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 2930bcb5c89dSSowmini Varadhan if (wrp == NULL) 2931bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 2932d62bc4baSyz147064 29334ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 29344ac67f02SAnurag S. Maskey B_FALSE); 2935d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2936d62bc4baSyz147064 goto done; 2937d62bc4baSyz147064 2938d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 2939d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 2940d62bc4baSyz147064 goto done; 2941d62bc4baSyz147064 } 2942d62bc4baSyz147064 2943d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 2944d62bc4baSyz147064 prop_val[0][0] = '\0'; 2945d62bc4baSyz147064 *val_cnt = 1; 2946d62bc4baSyz147064 goto done; 2947d62bc4baSyz147064 } 2948d62bc4baSyz147064 2949d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 2950d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 2951d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 2952d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 2953d62bc4baSyz147064 } 2954d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 2955da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_RW; 2956d62bc4baSyz147064 2957d62bc4baSyz147064 done: 2958bcb5c89dSSowmini Varadhan free(wrp); 2959d62bc4baSyz147064 return (status); 2960d62bc4baSyz147064 } 2961d62bc4baSyz147064 2962d62bc4baSyz147064 static dladm_status_t 29630dc2366fSVenugopal Iyer get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2964da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2965da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2966d62bc4baSyz147064 { 2967afdda45fSVasumathi Sundaram - Sun Microsystems if (media != DL_WIFI) { 29680dc2366fSVenugopal Iyer return (get_speed(handle, pdp, linkid, prop_val, 29690dc2366fSVenugopal Iyer val_cnt, media, flags, perm_flags)); 2970afdda45fSVasumathi Sundaram - Sun Microsystems } 29716b9e797cSsowmini 29720dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 2973da14cebeSEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 2974d62bc4baSyz147064 } 2975d62bc4baSyz147064 29764045d941Ssowmini /* ARGSUSED */ 2977d62bc4baSyz147064 static dladm_status_t 29780dc2366fSVenugopal Iyer get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2979da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2980da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2981d62bc4baSyz147064 { 29826b9e797cSsowmini switch (media) { 29836b9e797cSsowmini case DL_ETHER: 29844045d941Ssowmini /* 29854045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 29864045d941Ssowmini * links can have a speed of 5.5 Gbps. 29874045d941Ssowmini */ 29884045d941Ssowmini return (DLADM_STATUS_NOTSUP); 29896b9e797cSsowmini 29906b9e797cSsowmini case DL_WIFI: 29910dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, 29924ac67f02SAnurag S. Maskey val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 29936b9e797cSsowmini default: 29946b9e797cSsowmini return (DLADM_STATUS_BADARG); 29956b9e797cSsowmini } 2996d62bc4baSyz147064 } 2997d62bc4baSyz147064 2998d62bc4baSyz147064 static dladm_status_t 29990dc2366fSVenugopal Iyer set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 30004ac67f02SAnurag S. Maskey dladm_wlan_rates_t *rates) 3001f4b3ec61Sdh155122 { 3002f4b3ec61Sdh155122 int i; 3003d62bc4baSyz147064 uint_t len; 3004d62bc4baSyz147064 wl_rates_t *wrp; 3005d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 3006d62bc4baSyz147064 3007bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 3008bcb5c89dSSowmini Varadhan if (wrp == NULL) 3009d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 3010d62bc4baSyz147064 3011bcb5c89dSSowmini Varadhan bzero(wrp, WLDP_BUFSIZE); 3012d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 3013d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 3014d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 3015d62bc4baSyz147064 3016d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 3017d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 30184ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, 30194ac67f02SAnurag S. Maskey MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 3020d62bc4baSyz147064 3021bcb5c89dSSowmini Varadhan free(wrp); 3022d62bc4baSyz147064 return (status); 3023d62bc4baSyz147064 } 3024d62bc4baSyz147064 3025e7801d59Ssowmini /* ARGSUSED */ 3026d62bc4baSyz147064 static dladm_status_t 30270dc2366fSVenugopal Iyer set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 30286b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3029d62bc4baSyz147064 { 3030d62bc4baSyz147064 dladm_wlan_rates_t rates; 3031f4b3ec61Sdh155122 dladm_status_t status; 3032f4b3ec61Sdh155122 30336b9e797cSsowmini /* 30346b9e797cSsowmini * can currently set rate on WIFI links only. 30356b9e797cSsowmini */ 30366b9e797cSsowmini if (media != DL_WIFI) 30376b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 30386b9e797cSsowmini 3039d62bc4baSyz147064 if (val_cnt != 1) 3040d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3041f4b3ec61Sdh155122 3042d62bc4baSyz147064 rates.wr_cnt = 1; 3043d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 3044f4b3ec61Sdh155122 30450dc2366fSVenugopal Iyer status = set_wlan_rate(handle, linkid, &rates); 3046f4b3ec61Sdh155122 3047d62bc4baSyz147064 return (status); 3048d62bc4baSyz147064 } 3049d62bc4baSyz147064 3050d62bc4baSyz147064 /* ARGSUSED */ 3051d62bc4baSyz147064 static dladm_status_t 30520dc2366fSVenugopal Iyer check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3053c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 30540dc2366fSVenugopal Iyer datalink_media_t media) 3055d62bc4baSyz147064 { 3056d62bc4baSyz147064 int i; 3057d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 3058d62bc4baSyz147064 char *buf, **modval; 3059d62bc4baSyz147064 dladm_status_t status; 3060afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 3061c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3062c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 3063d62bc4baSyz147064 3064d62bc4baSyz147064 if (val_cnt != 1) 3065d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3066d62bc4baSyz147064 3067d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 3068d62bc4baSyz147064 MAX_SUPPORT_RATES); 3069d62bc4baSyz147064 if (buf == NULL) { 3070d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 3071d62bc4baSyz147064 goto done; 3072d62bc4baSyz147064 } 3073d62bc4baSyz147064 3074d62bc4baSyz147064 modval = (char **)(void *)buf; 3075d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 3076d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 3077d62bc4baSyz147064 i * DLADM_STRSIZE; 3078d62bc4baSyz147064 } 3079d62bc4baSyz147064 30800dc2366fSVenugopal Iyer status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 30814ac67f02SAnurag S. Maskey media, 0, &perm_flags); 3082d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3083d62bc4baSyz147064 goto done; 3084d62bc4baSyz147064 3085d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 3086d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 3087e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 3088e7801d59Ssowmini (atof(*prop_val) * 2); 3089f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 3090f4b3ec61Sdh155122 break; 3091f4b3ec61Sdh155122 } 3092d62bc4baSyz147064 } 3093d62bc4baSyz147064 if (i == modval_cnt) 3094d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 3095d62bc4baSyz147064 done: 3096d62bc4baSyz147064 free(buf); 3097d62bc4baSyz147064 return (status); 3098d62bc4baSyz147064 } 3099f4b3ec61Sdh155122 3100d62bc4baSyz147064 static dladm_status_t 31010dc2366fSVenugopal Iyer get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 31024ac67f02SAnurag S. Maskey int buflen) 3103d62bc4baSyz147064 { 31044ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 3105bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 3106d62bc4baSyz147064 } 3107d62bc4baSyz147064 3108e7801d59Ssowmini /* ARGSUSED */ 3109d62bc4baSyz147064 static dladm_status_t 31100dc2366fSVenugopal Iyer get_channel(dladm_handle_t handle, prop_desc_t *pdp, 31114ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 31124ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3113d62bc4baSyz147064 { 3114d62bc4baSyz147064 uint32_t channel; 3115bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 31160dc2366fSVenugopal Iyer dladm_status_t status; 3117bcb5c89dSSowmini Varadhan wl_phy_conf_t wl_phy_conf; 3118d62bc4baSyz147064 31190dc2366fSVenugopal Iyer if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 3120bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 31210dc2366fSVenugopal Iyer return (status); 3122d62bc4baSyz147064 3123bcb5c89dSSowmini Varadhan (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 31240dc2366fSVenugopal Iyer if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 31250dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3126d62bc4baSyz147064 3127d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 3128d62bc4baSyz147064 *val_cnt = 1; 3129da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 31300dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3131d62bc4baSyz147064 } 3132d62bc4baSyz147064 3133e7801d59Ssowmini /* ARGSUSED */ 3134d62bc4baSyz147064 static dladm_status_t 31350dc2366fSVenugopal Iyer get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 31364ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 31374ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3138d62bc4baSyz147064 { 3139bcb5c89dSSowmini Varadhan wl_ps_mode_t mode; 3140d62bc4baSyz147064 const char *s; 3141bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 31420dc2366fSVenugopal Iyer dladm_status_t status; 3143d62bc4baSyz147064 31440dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 31450dc2366fSVenugopal Iyer MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 31460dc2366fSVenugopal Iyer return (status); 3147d62bc4baSyz147064 3148bcb5c89dSSowmini Varadhan (void) memcpy(&mode, buf, sizeof (mode)); 3149bcb5c89dSSowmini Varadhan switch (mode.wl_ps_mode) { 3150d62bc4baSyz147064 case WL_PM_AM: 3151d62bc4baSyz147064 s = "off"; 3152f4b3ec61Sdh155122 break; 3153d62bc4baSyz147064 case WL_PM_MPS: 3154d62bc4baSyz147064 s = "max"; 3155d62bc4baSyz147064 break; 3156d62bc4baSyz147064 case WL_PM_FAST: 3157d62bc4baSyz147064 s = "fast"; 3158f4b3ec61Sdh155122 break; 3159f4b3ec61Sdh155122 default: 31600dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3161f4b3ec61Sdh155122 } 3162d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3163d62bc4baSyz147064 *val_cnt = 1; 3164afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 31650dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3166d62bc4baSyz147064 } 3167d62bc4baSyz147064 31680dc2366fSVenugopal Iyer /* ARGSUSED */ 3169d62bc4baSyz147064 static dladm_status_t 31700dc2366fSVenugopal Iyer set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 31710dc2366fSVenugopal Iyer datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 31720dc2366fSVenugopal Iyer datalink_media_t media) 3173d62bc4baSyz147064 { 31740dc2366fSVenugopal Iyer dladm_wlan_powermode_t powermode = vdp->vd_val; 3175d62bc4baSyz147064 wl_ps_mode_t ps_mode; 3176d62bc4baSyz147064 31770dc2366fSVenugopal Iyer if (val_cnt != 1) 31780dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 31790dc2366fSVenugopal Iyer 3180d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 3181d62bc4baSyz147064 31820dc2366fSVenugopal Iyer switch (powermode) { 3183d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 3184d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 3185d62bc4baSyz147064 break; 3186d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 3187d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 3188d62bc4baSyz147064 break; 3189d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 3190d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 3191d62bc4baSyz147064 break; 3192d62bc4baSyz147064 default: 3193d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3194d62bc4baSyz147064 } 31954ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &ps_mode, 31964ac67f02SAnurag S. Maskey MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 3197d62bc4baSyz147064 } 3198d62bc4baSyz147064 3199d62bc4baSyz147064 /* ARGSUSED */ 3200d62bc4baSyz147064 static dladm_status_t 32010dc2366fSVenugopal Iyer get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3202da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3203da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3204d62bc4baSyz147064 { 3205d62bc4baSyz147064 wl_radio_t radio; 3206d62bc4baSyz147064 const char *s; 3207bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 32080dc2366fSVenugopal Iyer dladm_status_t status; 3209d62bc4baSyz147064 32100dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 32110dc2366fSVenugopal Iyer MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 32120dc2366fSVenugopal Iyer return (status); 3213d62bc4baSyz147064 3214bcb5c89dSSowmini Varadhan (void) memcpy(&radio, buf, sizeof (radio)); 3215d62bc4baSyz147064 switch (radio) { 3216d62bc4baSyz147064 case B_TRUE: 3217d62bc4baSyz147064 s = "on"; 3218d62bc4baSyz147064 break; 3219d62bc4baSyz147064 case B_FALSE: 3220d62bc4baSyz147064 s = "off"; 3221d62bc4baSyz147064 break; 3222d62bc4baSyz147064 default: 32230dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3224d62bc4baSyz147064 } 3225d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3226d62bc4baSyz147064 *val_cnt = 1; 3227afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 32280dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3229d62bc4baSyz147064 } 3230d62bc4baSyz147064 32310dc2366fSVenugopal Iyer /* ARGSUSED */ 3232d62bc4baSyz147064 static dladm_status_t 32330dc2366fSVenugopal Iyer set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 32340dc2366fSVenugopal Iyer val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3235d62bc4baSyz147064 { 32360dc2366fSVenugopal Iyer dladm_wlan_radio_t radio = vdp->vd_val; 3237d62bc4baSyz147064 wl_radio_t r; 3238d62bc4baSyz147064 32390dc2366fSVenugopal Iyer if (val_cnt != 1) 32400dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 32410dc2366fSVenugopal Iyer 32420dc2366fSVenugopal Iyer switch (radio) { 3243d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 3244d62bc4baSyz147064 r = B_TRUE; 3245d62bc4baSyz147064 break; 3246d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 3247d62bc4baSyz147064 r = B_FALSE; 3248d62bc4baSyz147064 break; 3249d62bc4baSyz147064 default: 3250d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3251d62bc4baSyz147064 } 32524ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 3253bcb5c89dSSowmini Varadhan sizeof (r), B_TRUE)); 3254d62bc4baSyz147064 } 3255d62bc4baSyz147064 3256d62bc4baSyz147064 /* ARGSUSED */ 3257d62bc4baSyz147064 static dladm_status_t 32580dc2366fSVenugopal Iyer check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 3259c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 3260c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 32612b24ab6bSSebastien Roy { 32622b24ab6bSSebastien Roy int32_t hlim; 32632b24ab6bSSebastien Roy char *ep; 3264c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3265c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 32662b24ab6bSSebastien Roy 32672b24ab6bSSebastien Roy if (val_cnt != 1) 32682b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 32692b24ab6bSSebastien Roy 32702b24ab6bSSebastien Roy errno = 0; 32712b24ab6bSSebastien Roy hlim = strtol(*prop_val, &ep, 10); 32722b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || hlim < 1 || 32732b24ab6bSSebastien Roy hlim > (int32_t)UINT8_MAX) 32742b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 32752b24ab6bSSebastien Roy vdp->vd_val = hlim; 32762b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 32772b24ab6bSSebastien Roy } 32782b24ab6bSSebastien Roy 32792b24ab6bSSebastien Roy /* ARGSUSED */ 32802b24ab6bSSebastien Roy static dladm_status_t 32810dc2366fSVenugopal Iyer check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3282c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 32830dc2366fSVenugopal Iyer datalink_media_t media) 32842b24ab6bSSebastien Roy { 32852b24ab6bSSebastien Roy int32_t elim; 32862b24ab6bSSebastien Roy char *ep; 3287c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3288c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 32892b24ab6bSSebastien Roy 32902b24ab6bSSebastien Roy if (media != DL_IPV6) 32912b24ab6bSSebastien Roy return (DLADM_STATUS_BADARG); 32922b24ab6bSSebastien Roy 32932b24ab6bSSebastien Roy if (val_cnt != 1) 32942b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 32952b24ab6bSSebastien Roy 32962b24ab6bSSebastien Roy errno = 0; 32972b24ab6bSSebastien Roy elim = strtol(*prop_val, &ep, 10); 32982b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || elim < 0 || 32992b24ab6bSSebastien Roy elim > (int32_t)UINT8_MAX) 33002b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 33012b24ab6bSSebastien Roy vdp->vd_val = elim; 33022b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 33032b24ab6bSSebastien Roy } 33042b24ab6bSSebastien Roy 3305d62bc4baSyz147064 static dladm_status_t 33064ac67f02SAnurag S. Maskey i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 33074ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 3308d62bc4baSyz147064 { 3309d62bc4baSyz147064 char buf[MAXLINELEN]; 3310d62bc4baSyz147064 int i; 3311d62bc4baSyz147064 dladm_conf_t conf; 3312d62bc4baSyz147064 dladm_status_t status; 3313d62bc4baSyz147064 331432715170SCathy Zhou status = dladm_open_conf(handle, linkid, &conf); 3315f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 3316f4b3ec61Sdh155122 return (status); 3317f4b3ec61Sdh155122 3318d62bc4baSyz147064 /* 3319d62bc4baSyz147064 * reset case. 3320d62bc4baSyz147064 */ 3321d62bc4baSyz147064 if (val_cnt == 0) { 33224ac67f02SAnurag S. Maskey status = dladm_unset_conf_field(handle, conf, prop_name); 3323d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 33244ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3325d62bc4baSyz147064 goto done; 3326f4b3ec61Sdh155122 } 3327f4b3ec61Sdh155122 3328d62bc4baSyz147064 buf[0] = '\0'; 3329d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 3330d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 3331d62bc4baSyz147064 if (i != val_cnt - 1) 3332d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 3333d62bc4baSyz147064 } 3334f4b3ec61Sdh155122 33354ac67f02SAnurag S. Maskey status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 33364ac67f02SAnurag S. Maskey buf); 3337d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 33384ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3339d62bc4baSyz147064 3340d62bc4baSyz147064 done: 33414ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3342f4b3ec61Sdh155122 return (status); 3343f4b3ec61Sdh155122 } 3344f4b3ec61Sdh155122 3345f4b3ec61Sdh155122 static dladm_status_t 33464ac67f02SAnurag S. Maskey i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 33474ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 3348f4b3ec61Sdh155122 { 3349d62bc4baSyz147064 char buf[MAXLINELEN], *str; 3350d62bc4baSyz147064 uint_t cnt = 0; 3351d62bc4baSyz147064 dladm_conf_t conf; 3352d62bc4baSyz147064 dladm_status_t status; 3353f4b3ec61Sdh155122 335432715170SCathy Zhou status = dladm_getsnap_conf(handle, linkid, &conf); 3355d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3356f4b3ec61Sdh155122 return (status); 3357d62bc4baSyz147064 33584ac67f02SAnurag S. Maskey status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 3359d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3360d62bc4baSyz147064 goto done; 3361d62bc4baSyz147064 3362d62bc4baSyz147064 str = strtok(buf, ","); 3363d62bc4baSyz147064 while (str != NULL) { 3364d62bc4baSyz147064 if (cnt == *val_cntp) { 3365d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 3366d62bc4baSyz147064 goto done; 3367d62bc4baSyz147064 } 3368d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 3369d62bc4baSyz147064 str = strtok(NULL, ","); 3370f4b3ec61Sdh155122 } 3371f4b3ec61Sdh155122 3372d62bc4baSyz147064 *val_cntp = cnt; 3373f4b3ec61Sdh155122 3374d62bc4baSyz147064 done: 33754ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3376d62bc4baSyz147064 return (status); 3377f4b3ec61Sdh155122 } 3378e7801d59Ssowmini 337962ee1d25SArtem Kachitchkine /* 338062ee1d25SArtem Kachitchkine * Walk persistent private link properties of a link. 338162ee1d25SArtem Kachitchkine */ 338262ee1d25SArtem Kachitchkine static dladm_status_t 338362ee1d25SArtem Kachitchkine i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 338462ee1d25SArtem Kachitchkine void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 338562ee1d25SArtem Kachitchkine { 338662ee1d25SArtem Kachitchkine dladm_status_t status; 338762ee1d25SArtem Kachitchkine dladm_conf_t conf; 338862ee1d25SArtem Kachitchkine char last_attr[MAXLINKATTRLEN]; 338962ee1d25SArtem Kachitchkine char attr[MAXLINKATTRLEN]; 339062ee1d25SArtem Kachitchkine char attrval[MAXLINKATTRVALLEN]; 339162ee1d25SArtem Kachitchkine size_t attrsz; 339262ee1d25SArtem Kachitchkine 339362ee1d25SArtem Kachitchkine if (linkid == DATALINK_INVALID_LINKID || func == NULL) 339462ee1d25SArtem Kachitchkine return (DLADM_STATUS_BADARG); 339562ee1d25SArtem Kachitchkine 339632715170SCathy Zhou status = dladm_getsnap_conf(handle, linkid, &conf); 339762ee1d25SArtem Kachitchkine if (status != DLADM_STATUS_OK) 339862ee1d25SArtem Kachitchkine return (status); 339962ee1d25SArtem Kachitchkine 340062ee1d25SArtem Kachitchkine last_attr[0] = '\0'; 340162ee1d25SArtem Kachitchkine while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 340262ee1d25SArtem Kachitchkine attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 340362ee1d25SArtem Kachitchkine if (attr[0] == '_') { 340462ee1d25SArtem Kachitchkine if (func(handle, linkid, attr, arg) == 340562ee1d25SArtem Kachitchkine DLADM_WALK_TERMINATE) 340662ee1d25SArtem Kachitchkine break; 340762ee1d25SArtem Kachitchkine } 340862ee1d25SArtem Kachitchkine (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 340962ee1d25SArtem Kachitchkine } 341062ee1d25SArtem Kachitchkine 341162ee1d25SArtem Kachitchkine dladm_destroy_conf(handle, conf); 341262ee1d25SArtem Kachitchkine return (DLADM_STATUS_OK); 341362ee1d25SArtem Kachitchkine } 341462ee1d25SArtem Kachitchkine 3415bcb5c89dSSowmini Varadhan static link_attr_t * 3416e7801d59Ssowmini dladm_name2prop(const char *prop_name) 3417e7801d59Ssowmini { 3418bcb5c89dSSowmini Varadhan link_attr_t *p; 3419e7801d59Ssowmini 3420bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3421e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 3422e7801d59Ssowmini break; 3423e7801d59Ssowmini } 3424e7801d59Ssowmini return (p); 3425e7801d59Ssowmini } 3426e7801d59Ssowmini 3427bcb5c89dSSowmini Varadhan static link_attr_t * 3428bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid) 3429bcb5c89dSSowmini Varadhan { 3430bcb5c89dSSowmini Varadhan link_attr_t *p; 3431bcb5c89dSSowmini Varadhan 3432bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3433bcb5c89dSSowmini Varadhan if (p->pp_id == propid) 3434bcb5c89dSSowmini Varadhan break; 3435bcb5c89dSSowmini Varadhan } 3436bcb5c89dSSowmini Varadhan return (p); 3437bcb5c89dSSowmini Varadhan } 3438e7801d59Ssowmini 34393fd94f8cSam223141 static dld_ioc_macprop_t * 3440bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 3441bcb5c89dSSowmini Varadhan const char *prop_name, mac_prop_id_t propid, uint_t flags, 3442bcb5c89dSSowmini Varadhan dladm_status_t *status) 3443e7801d59Ssowmini { 3444e7801d59Ssowmini int dsize; 34453fd94f8cSam223141 dld_ioc_macprop_t *dip; 3446e7801d59Ssowmini 3447e7801d59Ssowmini *status = DLADM_STATUS_OK; 34483fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 3449e7801d59Ssowmini dip = malloc(dsize); 3450e7801d59Ssowmini if (dip == NULL) { 3451e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 3452e7801d59Ssowmini return (NULL); 3453e7801d59Ssowmini } 3454e7801d59Ssowmini bzero(dip, dsize); 3455e7801d59Ssowmini dip->pr_valsize = valsize; 34564045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 34576b9e797cSsowmini dip->pr_linkid = linkid; 3458bcb5c89dSSowmini Varadhan dip->pr_num = propid; 34594045d941Ssowmini dip->pr_flags = flags; 3460e7801d59Ssowmini return (dip); 3461e7801d59Ssowmini } 3462e7801d59Ssowmini 3463bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3464bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 3465bcb5c89dSSowmini Varadhan const char *prop_name, uint_t flags, dladm_status_t *status) 3466bcb5c89dSSowmini Varadhan { 3467bcb5c89dSSowmini Varadhan link_attr_t *p; 3468bcb5c89dSSowmini Varadhan 3469bcb5c89dSSowmini Varadhan p = dladm_name2prop(prop_name); 3470bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3471bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 3472bcb5c89dSSowmini Varadhan flags, status)); 3473bcb5c89dSSowmini Varadhan } 3474bcb5c89dSSowmini Varadhan 3475bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3476bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 3477bcb5c89dSSowmini Varadhan mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 3478bcb5c89dSSowmini Varadhan { 3479bcb5c89dSSowmini Varadhan link_attr_t *p; 3480bcb5c89dSSowmini Varadhan 3481bcb5c89dSSowmini Varadhan p = dladm_id2prop(propid); 3482bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3483bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 3484bcb5c89dSSowmini Varadhan flags, status)); 3485bcb5c89dSSowmini Varadhan } 3486bcb5c89dSSowmini Varadhan 3487e7801d59Ssowmini /* ARGSUSED */ 3488e7801d59Ssowmini static dladm_status_t 34890dc2366fSVenugopal Iyer set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 34904ac67f02SAnurag S. Maskey datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 34914ac67f02SAnurag S. Maskey datalink_media_t media) 3492e7801d59Ssowmini { 34933fd94f8cSam223141 dld_ioc_macprop_t *dip; 3494e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 3495e7801d59Ssowmini uint8_t u8; 3496e7801d59Ssowmini uint16_t u16; 3497e7801d59Ssowmini uint32_t u32; 3498e7801d59Ssowmini void *val; 3499e7801d59Ssowmini 3500da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 3501e7801d59Ssowmini if (dip == NULL) 3502e7801d59Ssowmini return (status); 3503e7801d59Ssowmini 3504da14cebeSEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 3505e7801d59Ssowmini val = (void *)vdp->vd_val; 3506e7801d59Ssowmini else { 3507e7801d59Ssowmini /* 3508e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 3509e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 3510e7801d59Ssowmini */ 3511e7801d59Ssowmini switch (dip->pr_valsize) { 3512e7801d59Ssowmini case 1: 3513e7801d59Ssowmini u8 = vdp->vd_val; 3514e7801d59Ssowmini val = &u8; 3515e7801d59Ssowmini break; 3516e7801d59Ssowmini case 2: 3517e7801d59Ssowmini u16 = vdp->vd_val; 3518e7801d59Ssowmini val = &u16; 3519e7801d59Ssowmini break; 3520e7801d59Ssowmini case 4: 3521e7801d59Ssowmini u32 = vdp->vd_val; 3522e7801d59Ssowmini val = &u32; 3523e7801d59Ssowmini break; 3524e7801d59Ssowmini default: 3525e7801d59Ssowmini val = &vdp->vd_val; 3526e7801d59Ssowmini break; 3527e7801d59Ssowmini } 3528e7801d59Ssowmini } 3529e7801d59Ssowmini 35303bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 3531e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 35323bc21d0aSAruna Ramakrishna - Sun Microsystems else 35333bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 35343bc21d0aSAruna Ramakrishna - Sun Microsystems 35354ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 3536bcb5c89dSSowmini Varadhan 3537bcb5c89dSSowmini Varadhan done: 3538bcb5c89dSSowmini Varadhan free(dip); 3539bcb5c89dSSowmini Varadhan return (status); 3540bcb5c89dSSowmini Varadhan } 3541bcb5c89dSSowmini Varadhan 3542bcb5c89dSSowmini Varadhan dladm_status_t 35434ac67f02SAnurag S. Maskey i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 3544bcb5c89dSSowmini Varadhan { 3545bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 3546bcb5c89dSSowmini Varadhan 35474ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), 35484ac67f02SAnurag S. Maskey (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 3549e7801d59Ssowmini status = dladm_errno2status(errno); 3550e7801d59Ssowmini 3551e7801d59Ssowmini return (status); 3552e7801d59Ssowmini } 3553e7801d59Ssowmini 35540dc2366fSVenugopal Iyer static dladm_status_t 35554ac67f02SAnurag S. Maskey i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 35560dc2366fSVenugopal Iyer char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 3557e7801d59Ssowmini { 35580dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 35590dc2366fSVenugopal Iyer dladm_status_t status; 35604045d941Ssowmini 35610dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 35624045d941Ssowmini if (dip == NULL) 35630dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 3564e7801d59Ssowmini 35650dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 35660dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) { 35674045d941Ssowmini free(dip); 35680dc2366fSVenugopal Iyer return (status); 35694045d941Ssowmini } 35700dc2366fSVenugopal Iyer 3571da14cebeSEric Cheng if (perm_flags != NULL) 3572da14cebeSEric Cheng *perm_flags = dip->pr_perm_flags; 3573da14cebeSEric Cheng 35740dc2366fSVenugopal Iyer if (arg != NULL) 35750dc2366fSVenugopal Iyer (void) memcpy(arg, dip->pr_val, size); 35760dc2366fSVenugopal Iyer free(dip); 35770dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3578e7801d59Ssowmini } 3579e7801d59Ssowmini 3580e7801d59Ssowmini /* ARGSUSED */ 3581e7801d59Ssowmini static dladm_status_t 35820dc2366fSVenugopal Iyer check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 3583c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 3584c569ef53SMichael Lim val_desc_t **vp, datalink_media_t media) 3585e7801d59Ssowmini { 3586c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3587c569ef53SMichael Lim val_desc_t *v = *vp; 3588c569ef53SMichael Lim 3589e7801d59Ssowmini if (val_cnt != 1) 3590e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 35914eaa4710SRishi Srivatsavai v->vd_val = strtoul(prop_val[0], NULL, 0); 3592e7801d59Ssowmini return (DLADM_STATUS_OK); 3593e7801d59Ssowmini } 3594e7801d59Ssowmini 3595e7801d59Ssowmini /* ARGSUSED */ 3596e7801d59Ssowmini static dladm_status_t 35970dc2366fSVenugopal Iyer get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 35984ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 35994ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3600e7801d59Ssowmini { 3601e7801d59Ssowmini link_duplex_t link_duplex; 3602e7801d59Ssowmini dladm_status_t status; 3603e7801d59Ssowmini 36044ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 3605e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 3606e7801d59Ssowmini return (status); 3607e7801d59Ssowmini 3608e7801d59Ssowmini switch (link_duplex) { 3609e7801d59Ssowmini case LINK_DUPLEX_FULL: 3610e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 3611e7801d59Ssowmini break; 3612e7801d59Ssowmini case LINK_DUPLEX_HALF: 3613e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 3614e7801d59Ssowmini break; 3615e7801d59Ssowmini default: 3616e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3617e7801d59Ssowmini break; 3618e7801d59Ssowmini } 3619e7801d59Ssowmini *val_cnt = 1; 3620e7801d59Ssowmini return (DLADM_STATUS_OK); 3621e7801d59Ssowmini } 3622e7801d59Ssowmini 3623e7801d59Ssowmini /* ARGSUSED */ 3624e7801d59Ssowmini static dladm_status_t 36250dc2366fSVenugopal Iyer get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 36260dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 36270dc2366fSVenugopal Iyer uint_t *perm_flags) 3628e7801d59Ssowmini { 3629e7801d59Ssowmini uint64_t ifspeed = 0; 3630e7801d59Ssowmini dladm_status_t status; 3631e7801d59Ssowmini 36324ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 3633e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 3634e7801d59Ssowmini return (status); 36354045d941Ssowmini 36366b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 36376b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 36386b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 36396b9e797cSsowmini } else { 3640e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 3641e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 36426b9e797cSsowmini } 3643e7801d59Ssowmini *val_cnt = 1; 3644da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 3645e7801d59Ssowmini return (DLADM_STATUS_OK); 3646e7801d59Ssowmini } 3647e7801d59Ssowmini 3648e7801d59Ssowmini /* ARGSUSED */ 3649e7801d59Ssowmini static dladm_status_t 36500dc2366fSVenugopal Iyer get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 36514ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36524ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3653e7801d59Ssowmini { 3654e7801d59Ssowmini link_state_t link_state; 3655e7801d59Ssowmini dladm_status_t status; 3656e7801d59Ssowmini 36570dc2366fSVenugopal Iyer status = dladm_get_state(handle, linkid, &link_state); 36584045d941Ssowmini if (status != DLADM_STATUS_OK) 3659e7801d59Ssowmini return (status); 3660da14cebeSEric Cheng 3661e7801d59Ssowmini switch (link_state) { 3662e7801d59Ssowmini case LINK_STATE_UP: 3663e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 3664e7801d59Ssowmini break; 3665e7801d59Ssowmini case LINK_STATE_DOWN: 3666e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 3667e7801d59Ssowmini break; 3668e7801d59Ssowmini default: 3669e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3670e7801d59Ssowmini break; 3671e7801d59Ssowmini } 3672e7801d59Ssowmini *val_cnt = 1; 36734784fcbdSSowmini Varadhan *perm_flags = MAC_PROP_PERM_READ; 3674e7801d59Ssowmini return (DLADM_STATUS_OK); 3675e7801d59Ssowmini } 3676e7801d59Ssowmini 3677e7801d59Ssowmini /* ARGSUSED */ 3678e7801d59Ssowmini static dladm_status_t 36790dc2366fSVenugopal Iyer get_binary(dladm_handle_t handle, prop_desc_t *pdp, 36804ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 36814ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3682e7801d59Ssowmini { 3683e7801d59Ssowmini dladm_status_t status; 36840dc2366fSVenugopal Iyer uint_t v = 0; 3685e7801d59Ssowmini 36860dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 36870dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 36880dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3689e7801d59Ssowmini return (status); 3690da14cebeSEric Cheng 36910dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 3692e7801d59Ssowmini *val_cnt = 1; 3693e7801d59Ssowmini return (DLADM_STATUS_OK); 3694e7801d59Ssowmini } 3695e7801d59Ssowmini 36966b9e797cSsowmini /* ARGSUSED */ 3697e7801d59Ssowmini static dladm_status_t 36980dc2366fSVenugopal Iyer get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 36994ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37004ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3701e7801d59Ssowmini { 37020dc2366fSVenugopal Iyer dladm_status_t status; 37034045d941Ssowmini uint32_t v = 0; 3704e7801d59Ssowmini 37050dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 37060dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 37070dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3708e7801d59Ssowmini return (status); 3709da14cebeSEric Cheng 37104045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 3711e7801d59Ssowmini *val_cnt = 1; 3712e7801d59Ssowmini return (DLADM_STATUS_OK); 3713e7801d59Ssowmini } 3714e7801d59Ssowmini 3715f0f2c3a5SGirish Moodalbail /* ARGSUSED */ 3716f0f2c3a5SGirish Moodalbail static dladm_status_t 37170dc2366fSVenugopal Iyer get_range(dladm_handle_t handle, prop_desc_t *pdp, 3718f0f2c3a5SGirish Moodalbail datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3719f0f2c3a5SGirish Moodalbail datalink_media_t media, uint_t flags, uint_t *perm_flags) 3720f0f2c3a5SGirish Moodalbail { 3721f0f2c3a5SGirish Moodalbail dld_ioc_macprop_t *dip; 3722f0f2c3a5SGirish Moodalbail dladm_status_t status = DLADM_STATUS_OK; 3723f0f2c3a5SGirish Moodalbail size_t sz; 3724*0591ddd0SPrakash Jalan uint_t rcount; 3725f0f2c3a5SGirish Moodalbail mac_propval_range_t *rangep; 3726f0f2c3a5SGirish Moodalbail 3727f0f2c3a5SGirish Moodalbail /* 3728f0f2c3a5SGirish Moodalbail * As caller we don't know number of value ranges, the driver 3729f0f2c3a5SGirish Moodalbail * supports. To begin with we assume that number to be 1. If the 3730f0f2c3a5SGirish Moodalbail * buffer size is insufficient, driver returns back with the 3731f0f2c3a5SGirish Moodalbail * actual count of value ranges. See mac.h for more details. 3732f0f2c3a5SGirish Moodalbail */ 3733*0591ddd0SPrakash Jalan sz = sizeof (mac_propval_range_t); 3734*0591ddd0SPrakash Jalan rcount = 1; 3735f0f2c3a5SGirish Moodalbail retry: 3736f0f2c3a5SGirish Moodalbail if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 3737f0f2c3a5SGirish Moodalbail &status)) == NULL) 3738f0f2c3a5SGirish Moodalbail return (status); 3739f0f2c3a5SGirish Moodalbail 3740*0591ddd0SPrakash Jalan rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 3741*0591ddd0SPrakash Jalan rangep->mpr_count = rcount; 3742*0591ddd0SPrakash Jalan 3743f0f2c3a5SGirish Moodalbail status = i_dladm_macprop(handle, dip, B_FALSE); 3744f0f2c3a5SGirish Moodalbail if (status != DLADM_STATUS_OK) { 3745f0f2c3a5SGirish Moodalbail if (status == DLADM_STATUS_TOOSMALL) { 3746f0f2c3a5SGirish Moodalbail int err; 3747f0f2c3a5SGirish Moodalbail 3748*0591ddd0SPrakash Jalan if ((err = i_dladm_range_size(rangep, &sz, &rcount)) 3749*0591ddd0SPrakash Jalan == 0) { 3750f0f2c3a5SGirish Moodalbail free(dip); 3751f0f2c3a5SGirish Moodalbail goto retry; 3752f0f2c3a5SGirish Moodalbail } else { 3753f0f2c3a5SGirish Moodalbail status = dladm_errno2status(err); 3754f0f2c3a5SGirish Moodalbail } 3755f0f2c3a5SGirish Moodalbail } 3756f0f2c3a5SGirish Moodalbail free(dip); 3757f0f2c3a5SGirish Moodalbail return (status); 3758f0f2c3a5SGirish Moodalbail } 37590dc2366fSVenugopal Iyer 37600dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 37610dc2366fSVenugopal Iyer *val_cnt = 1; 37620dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 37630dc2366fSVenugopal Iyer goto done; 37640dc2366fSVenugopal Iyer } 3765f0f2c3a5SGirish Moodalbail 3766f0f2c3a5SGirish Moodalbail switch (rangep->mpr_type) { 3767f0f2c3a5SGirish Moodalbail case MAC_PROPVAL_UINT32: { 3768f0f2c3a5SGirish Moodalbail mac_propval_uint32_range_t *ur; 3769f0f2c3a5SGirish Moodalbail uint_t count = rangep->mpr_count, i; 3770f0f2c3a5SGirish Moodalbail 37710dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 3772f0f2c3a5SGirish Moodalbail 3773f0f2c3a5SGirish Moodalbail for (i = 0; i < count; i++, ur++) { 3774f0f2c3a5SGirish Moodalbail if (ur->mpur_min == ur->mpur_max) { 3775f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 3776f0f2c3a5SGirish Moodalbail "%ld", ur->mpur_min); 3777f0f2c3a5SGirish Moodalbail } else { 3778f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 3779f0f2c3a5SGirish Moodalbail "%ld-%ld", ur->mpur_min, ur->mpur_max); 3780f0f2c3a5SGirish Moodalbail } 3781f0f2c3a5SGirish Moodalbail } 3782f0f2c3a5SGirish Moodalbail *val_cnt = count; 3783f0f2c3a5SGirish Moodalbail break; 3784f0f2c3a5SGirish Moodalbail } 3785f0f2c3a5SGirish Moodalbail default: 3786f0f2c3a5SGirish Moodalbail status = DLADM_STATUS_BADARG; 3787f0f2c3a5SGirish Moodalbail break; 3788f0f2c3a5SGirish Moodalbail } 37890dc2366fSVenugopal Iyer done: 3790f0f2c3a5SGirish Moodalbail free(dip); 3791f0f2c3a5SGirish Moodalbail return (status); 3792f0f2c3a5SGirish Moodalbail } 3793f0f2c3a5SGirish Moodalbail 37946b9e797cSsowmini /* ARGSUSED */ 3795e7801d59Ssowmini static dladm_status_t 37960dc2366fSVenugopal Iyer get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 3797e75f0919SSebastien Roy datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3798e75f0919SSebastien Roy datalink_media_t media, uint_t flags, uint_t *perm_flags) 3799e75f0919SSebastien Roy { 3800e75f0919SSebastien Roy link_tagmode_t mode; 3801e75f0919SSebastien Roy dladm_status_t status; 3802e75f0919SSebastien Roy 38030dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 38040dc2366fSVenugopal Iyer perm_flags, &mode, sizeof (mode)); 38050dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3806e75f0919SSebastien Roy return (status); 3807e75f0919SSebastien Roy 3808e75f0919SSebastien Roy switch (mode) { 3809e75f0919SSebastien Roy case LINK_TAGMODE_NORMAL: 3810e75f0919SSebastien Roy (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 3811e75f0919SSebastien Roy break; 3812e75f0919SSebastien Roy case LINK_TAGMODE_VLANONLY: 3813e75f0919SSebastien Roy (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 3814e75f0919SSebastien Roy break; 3815e75f0919SSebastien Roy default: 3816e75f0919SSebastien Roy (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 3817e75f0919SSebastien Roy } 3818e75f0919SSebastien Roy *val_cnt = 1; 3819e75f0919SSebastien Roy return (DLADM_STATUS_OK); 3820e75f0919SSebastien Roy } 3821e75f0919SSebastien Roy 3822e75f0919SSebastien Roy /* ARGSUSED */ 3823e75f0919SSebastien Roy static dladm_status_t 38240dc2366fSVenugopal Iyer get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 38254ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 38264ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3827e7801d59Ssowmini { 3828e7801d59Ssowmini link_flowctrl_t v; 3829e7801d59Ssowmini dladm_status_t status; 3830e7801d59Ssowmini 38310dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 38320dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 38330dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3834e7801d59Ssowmini return (status); 3835da14cebeSEric Cheng 3836e7801d59Ssowmini switch (v) { 3837e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 3838e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 3839e7801d59Ssowmini break; 3840e7801d59Ssowmini case LINK_FLOWCTRL_RX: 3841e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 3842e7801d59Ssowmini break; 3843e7801d59Ssowmini case LINK_FLOWCTRL_TX: 3844e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 3845e7801d59Ssowmini break; 3846e7801d59Ssowmini case LINK_FLOWCTRL_BI: 3847e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 3848e7801d59Ssowmini break; 3849e7801d59Ssowmini } 3850e7801d59Ssowmini *val_cnt = 1; 3851e7801d59Ssowmini return (DLADM_STATUS_OK); 3852e7801d59Ssowmini } 3853e7801d59Ssowmini 3854e7801d59Ssowmini 3855e7801d59Ssowmini /* ARGSUSED */ 3856e7801d59Ssowmini static dladm_status_t 38573361618bSRishi Srivatsavai i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 38584ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 38594ac67f02SAnurag S. Maskey 3860e7801d59Ssowmini { 3861bcb5c89dSSowmini Varadhan int i, slen; 3862eae72b5bSSebastien Roy int bufsize = 0; 38633fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 3864e7801d59Ssowmini uchar_t *dp; 3865bcb5c89dSSowmini Varadhan link_attr_t *p; 38664045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 3867e7801d59Ssowmini 3868e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 3869e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 3870e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3871e7801d59Ssowmini p = dladm_name2prop(prop_name); 38723fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 3873e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3874e7801d59Ssowmini 38753361618bSRishi Srivatsavai if (!(flags & DLADM_OPT_ACTIVE)) 38763361618bSRishi Srivatsavai return (DLADM_STATUS_OK); 38773361618bSRishi Srivatsavai 3878e7801d59Ssowmini /* 3879e7801d59Ssowmini * private properties: all parsing is done in the kernel. 3880e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 3881e7801d59Ssowmini */ 3882e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 3883e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 3884e7801d59Ssowmini } 38854045d941Ssowmini 38864045d941Ssowmini if (prop_val == NULL) { 38874045d941Ssowmini /* 38884045d941Ssowmini * getting default value. so use more buffer space. 38894045d941Ssowmini */ 3890bcb5c89dSSowmini Varadhan bufsize += DLADM_PROP_BUF_CHUNK; 38914045d941Ssowmini } 38924045d941Ssowmini 3893bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 38940dc2366fSVenugopal Iyer (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 3895e7801d59Ssowmini if (dip == NULL) 3896e7801d59Ssowmini return (status); 3897e7801d59Ssowmini 3898e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 3899e7801d59Ssowmini slen = 0; 3900bcb5c89dSSowmini Varadhan 39014045d941Ssowmini if (prop_val == NULL) { 39024ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_FALSE); 390362ee1d25SArtem Kachitchkine dip->pr_flags = 0; 39044045d941Ssowmini } else { 3905e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 3906e7801d59Ssowmini int plen = 0; 3907e7801d59Ssowmini 3908e7801d59Ssowmini plen = strlen(prop_val[i]); 3909e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 3910e7801d59Ssowmini slen += plen; 3911e7801d59Ssowmini /* 3912e7801d59Ssowmini * add a "," separator and update dp. 3913e7801d59Ssowmini */ 3914e7801d59Ssowmini if (i != (val_cnt -1)) 3915e7801d59Ssowmini dp[slen++] = ','; 3916e7801d59Ssowmini dp += (plen + 1); 3917e7801d59Ssowmini } 3918e7801d59Ssowmini } 391962ee1d25SArtem Kachitchkine if (status == DLADM_STATUS_OK) 392062ee1d25SArtem Kachitchkine status = i_dladm_macprop(handle, dip, B_TRUE); 39214045d941Ssowmini 3922e7801d59Ssowmini free(dip); 3923e7801d59Ssowmini return (status); 3924e7801d59Ssowmini } 3925e7801d59Ssowmini 3926e7801d59Ssowmini static dladm_status_t 392762ee1d25SArtem Kachitchkine i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 39284ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cnt, 39294ac67f02SAnurag S. Maskey dladm_prop_type_t type, uint_t dld_flags) 3930e7801d59Ssowmini { 3931e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 39323fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 3933bcb5c89dSSowmini Varadhan link_attr_t *p; 3934e7801d59Ssowmini 3935e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 3936e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 3937e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3938e7801d59Ssowmini 3939e7801d59Ssowmini p = dladm_name2prop(prop_name); 39403fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 3941e7801d59Ssowmini return (DLADM_STATUS_BADARG); 3942e7801d59Ssowmini 3943e7801d59Ssowmini /* 3944e7801d59Ssowmini * private properties: all parsing is done in the kernel. 3945e7801d59Ssowmini */ 3946bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 3947bcb5c89dSSowmini Varadhan dld_flags, &status); 3948e7801d59Ssowmini if (dip == NULL) 3949e7801d59Ssowmini return (status); 3950e7801d59Ssowmini 39514ac67f02SAnurag S. Maskey if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 39524ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 3953afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_PERM) { 3954da14cebeSEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 395562ee1d25SArtem Kachitchkine } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 395662ee1d25SArtem Kachitchkine *prop_val[0] = '\0'; 3957afdda45fSVasumathi Sundaram - Sun Microsystems } else { 3958afdda45fSVasumathi Sundaram - Sun Microsystems (void) strncpy(*prop_val, dip->pr_val, 3959afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_MAX); 3960afdda45fSVasumathi Sundaram - Sun Microsystems } 3961e7801d59Ssowmini *val_cnt = 1; 396262ee1d25SArtem Kachitchkine } else if ((status == DLADM_STATUS_NOTSUP) && 396362ee1d25SArtem Kachitchkine (type == DLADM_PROP_VAL_CURRENT)) { 396462ee1d25SArtem Kachitchkine status = DLADM_STATUS_NOTFOUND; 3965e7801d59Ssowmini } 39664045d941Ssowmini free(dip); 39674045d941Ssowmini return (status); 39684045d941Ssowmini } 39694045d941Ssowmini 39704045d941Ssowmini 39714045d941Ssowmini static dladm_status_t 39724ac67f02SAnurag S. Maskey i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 39734ac67f02SAnurag S. Maskey datalink_id_t linkid, datalink_media_t media, uint_t flags) 39744045d941Ssowmini { 39754045d941Ssowmini dladm_status_t status; 39764045d941Ssowmini char **prop_vals = NULL, *buf; 39774045d941Ssowmini size_t bufsize; 39784045d941Ssowmini uint_t cnt; 39794045d941Ssowmini int i; 3980afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 39814045d941Ssowmini 39824045d941Ssowmini /* 39834045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 39844045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 39854045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 39864045d941Ssowmini */ 39874045d941Ssowmini bufsize = 39884045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 39894045d941Ssowmini buf = malloc(bufsize); 39904045d941Ssowmini prop_vals = (char **)(void *)buf; 39914045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 39924045d941Ssowmini prop_vals[i] = buf + 39934045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 39944045d941Ssowmini i * DLADM_PROP_VAL_MAX; 39954045d941Ssowmini } 399613a55820Sar224390 399713a55820Sar224390 /* 39983bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 39993bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 40003bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 40013bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 40023bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 40033bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 40043bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 40053bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 400613a55820Sar224390 */ 40074ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 40080dc2366fSVenugopal Iyer DLD_PROP_DEFAULT, &perm_flags); 40094045d941Ssowmini if (status == DLADM_STATUS_OK) { 4010afdda45fSVasumathi Sundaram - Sun Microsystems if (perm_flags == MAC_PROP_PERM_RW) { 40114ac67f02SAnurag S. Maskey status = i_dladm_set_single_prop(handle, linkid, 40124ac67f02SAnurag S. Maskey pdp->pd_class, media, pdp, prop_vals, cnt, flags); 40134045d941Ssowmini } 4014afdda45fSVasumathi Sundaram - Sun Microsystems else 4015afdda45fSVasumathi Sundaram - Sun Microsystems status = DLADM_STATUS_NOTSUP; 4016afdda45fSVasumathi Sundaram - Sun Microsystems } 40174045d941Ssowmini free(buf); 4018e7801d59Ssowmini return (status); 4019e7801d59Ssowmini } 4020bcb5c89dSSowmini Varadhan 40214eaa4710SRishi Srivatsavai /* ARGSUSED */ 40224eaa4710SRishi Srivatsavai static dladm_status_t 40230dc2366fSVenugopal Iyer get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 40244eaa4710SRishi Srivatsavai char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 40254eaa4710SRishi Srivatsavai uint_t *perm_flags) 40264eaa4710SRishi Srivatsavai { 40274eaa4710SRishi Srivatsavai const bridge_public_prop_t *bpp; 40284eaa4710SRishi Srivatsavai dladm_status_t retv; 40294eaa4710SRishi Srivatsavai int val, i; 40304eaa4710SRishi Srivatsavai 40314eaa4710SRishi Srivatsavai if (flags != 0) 40324eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 40334eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 40344eaa4710SRishi Srivatsavai *val_cnt = 1; 40354eaa4710SRishi Srivatsavai for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 40364eaa4710SRishi Srivatsavai if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 40374eaa4710SRishi Srivatsavai break; 40384eaa4710SRishi Srivatsavai retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 40394eaa4710SRishi Srivatsavai /* If the daemon isn't running, then return the persistent value */ 40404eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 40414eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 40424eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 40434eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 40444eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 40454eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40464eaa4710SRishi Srivatsavai } 40474eaa4710SRishi Srivatsavai if (retv != DLADM_STATUS_OK) { 40484eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 40494eaa4710SRishi Srivatsavai return (retv); 40504eaa4710SRishi Srivatsavai } 40514eaa4710SRishi Srivatsavai if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 40524eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 40534eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 40544eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40554eaa4710SRishi Srivatsavai } 40564eaa4710SRishi Srivatsavai for (i = 0; i < pd->pd_noptval; i++) { 40574eaa4710SRishi Srivatsavai if (val == pd->pd_optval[i].vd_val) { 40584eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 40594eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 40604eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40614eaa4710SRishi Srivatsavai } 40624eaa4710SRishi Srivatsavai } 40634eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 40644eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40654eaa4710SRishi Srivatsavai } 40664eaa4710SRishi Srivatsavai 40674eaa4710SRishi Srivatsavai /* ARGSUSED1 */ 40684eaa4710SRishi Srivatsavai static dladm_status_t 40694eaa4710SRishi Srivatsavai set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 40704eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 40714eaa4710SRishi Srivatsavai { 40724eaa4710SRishi Srivatsavai /* 40734eaa4710SRishi Srivatsavai * Special case for mcheck: the daemon resets the value to zero, and we 40744eaa4710SRishi Srivatsavai * don't want the daemon to refresh itself; it leads to deadlock. 40754eaa4710SRishi Srivatsavai */ 40764eaa4710SRishi Srivatsavai if (flags & DLADM_OPT_NOREFRESH) 40774eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 40784eaa4710SRishi Srivatsavai 40794eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 40804eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 40814eaa4710SRishi Srivatsavai } 40824eaa4710SRishi Srivatsavai 40834eaa4710SRishi Srivatsavai /* 40844eaa4710SRishi Srivatsavai * This is used only for stp_priority, stp_cost, and stp_mcheck. 40854eaa4710SRishi Srivatsavai */ 40864eaa4710SRishi Srivatsavai /* ARGSUSED */ 40874eaa4710SRishi Srivatsavai static dladm_status_t 40884eaa4710SRishi Srivatsavai check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 4089c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 4090c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 40914eaa4710SRishi Srivatsavai { 40924eaa4710SRishi Srivatsavai char *cp; 40934eaa4710SRishi Srivatsavai boolean_t iscost; 4094c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 4095c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 40964eaa4710SRishi Srivatsavai 40974eaa4710SRishi Srivatsavai if (val_cnt != 1) 40984eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 40994eaa4710SRishi Srivatsavai 41004eaa4710SRishi Srivatsavai if (prop_val == NULL) { 41014eaa4710SRishi Srivatsavai vdp->vd_val = 0; 41024eaa4710SRishi Srivatsavai } else { 41034eaa4710SRishi Srivatsavai /* Only stp_priority and stp_cost use this function */ 41044eaa4710SRishi Srivatsavai iscost = strcmp(pd->pd_name, "stp_cost") == 0; 41054eaa4710SRishi Srivatsavai 41064eaa4710SRishi Srivatsavai if (iscost && strcmp(prop_val[0], "auto") == 0) { 41074eaa4710SRishi Srivatsavai /* Illegal value 0 is allowed to mean "automatic" */ 41084eaa4710SRishi Srivatsavai vdp->vd_val = 0; 41094eaa4710SRishi Srivatsavai } else { 41104eaa4710SRishi Srivatsavai errno = 0; 41114eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 41124eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 41134eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 41144eaa4710SRishi Srivatsavai } 41154eaa4710SRishi Srivatsavai } 41164eaa4710SRishi Srivatsavai 41174eaa4710SRishi Srivatsavai if (iscost) { 41184eaa4710SRishi Srivatsavai return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 41194eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 41204eaa4710SRishi Srivatsavai } else { 41214eaa4710SRishi Srivatsavai if (vdp->vd_val > 255) 41224eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 41234eaa4710SRishi Srivatsavai /* 41244eaa4710SRishi Srivatsavai * If the user is setting stp_mcheck non-zero, then (per the 41254eaa4710SRishi Srivatsavai * IEEE management standards and UNH testing) we need to check 41264eaa4710SRishi Srivatsavai * whether this link is part of a bridge that is running RSTP. 41274eaa4710SRishi Srivatsavai * If it's not, then setting the flag is an error. Note that 41284eaa4710SRishi Srivatsavai * errors are intentionally discarded here; it's the value 41294eaa4710SRishi Srivatsavai * that's the problem -- it's not a bad value, merely one that 41304eaa4710SRishi Srivatsavai * can't be used now. 41314eaa4710SRishi Srivatsavai */ 41324eaa4710SRishi Srivatsavai if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 41334eaa4710SRishi Srivatsavai vdp->vd_val != 0) { 41344eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 41354eaa4710SRishi Srivatsavai UID_STP_CFG_T cfg; 41364eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot; 41374eaa4710SRishi Srivatsavai 41384eaa4710SRishi Srivatsavai if (dladm_bridge_getlink(handle, linkid, bridge, 41394eaa4710SRishi Srivatsavai sizeof (bridge)) != DLADM_STATUS_OK || 41404eaa4710SRishi Srivatsavai dladm_bridge_get_properties(bridge, &cfg, 41414eaa4710SRishi Srivatsavai &brprot) != DLADM_STATUS_OK) 41424eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 41434eaa4710SRishi Srivatsavai if (cfg.force_version <= 1) 41444eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 41454eaa4710SRishi Srivatsavai } 41464eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 41474eaa4710SRishi Srivatsavai } 41484eaa4710SRishi Srivatsavai } 41494eaa4710SRishi Srivatsavai 41504eaa4710SRishi Srivatsavai /* ARGSUSED */ 41514eaa4710SRishi Srivatsavai static dladm_status_t 41524eaa4710SRishi Srivatsavai get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 41534eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 41544eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 41554eaa4710SRishi Srivatsavai { 41564eaa4710SRishi Srivatsavai dladm_status_t retv; 41574eaa4710SRishi Srivatsavai uint_t val; 41584eaa4710SRishi Srivatsavai 41594eaa4710SRishi Srivatsavai if (flags != 0) 41604eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 41614eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 41624eaa4710SRishi Srivatsavai *val_cnt = 1; 41634eaa4710SRishi Srivatsavai retv = dladm_bridge_get_forwarding(handle, linkid, &val); 41644eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 41654eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 41664eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 41674eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 41684eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 41694eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 41704eaa4710SRishi Srivatsavai } 41714eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_OK) 41724eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 41734eaa4710SRishi Srivatsavai else 41744eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 41754eaa4710SRishi Srivatsavai return (retv); 41764eaa4710SRishi Srivatsavai } 41774eaa4710SRishi Srivatsavai 41784eaa4710SRishi Srivatsavai /* ARGSUSED */ 41794eaa4710SRishi Srivatsavai static dladm_status_t 41804eaa4710SRishi Srivatsavai set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 41814eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 41824eaa4710SRishi Srivatsavai { 41834eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 41844eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 41854eaa4710SRishi Srivatsavai } 41864eaa4710SRishi Srivatsavai 41874eaa4710SRishi Srivatsavai /* ARGSUSED */ 41884eaa4710SRishi Srivatsavai static dladm_status_t 41894eaa4710SRishi Srivatsavai get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 41904eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 41914eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 41924eaa4710SRishi Srivatsavai { 41934eaa4710SRishi Srivatsavai dladm_status_t status; 41944eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 41954eaa4710SRishi Srivatsavai uint16_t pvid; 41964eaa4710SRishi Srivatsavai 41974eaa4710SRishi Srivatsavai if (flags != 0) 41984eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 41994eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 42004eaa4710SRishi Srivatsavai *val_cnt = 1; 42014eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 42024eaa4710SRishi Srivatsavai 0, &status); 42034eaa4710SRishi Srivatsavai if (dip == NULL) 42044eaa4710SRishi Srivatsavai return (status); 42054eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_FALSE); 42064eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 42074eaa4710SRishi Srivatsavai (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 42084eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 42094eaa4710SRishi Srivatsavai } else { 42104eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 42114eaa4710SRishi Srivatsavai } 42124eaa4710SRishi Srivatsavai free(dip); 42134eaa4710SRishi Srivatsavai return (status); 42144eaa4710SRishi Srivatsavai } 42154eaa4710SRishi Srivatsavai 42164eaa4710SRishi Srivatsavai /* ARGSUSED */ 42174eaa4710SRishi Srivatsavai static dladm_status_t 42184eaa4710SRishi Srivatsavai set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 42194eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 42204eaa4710SRishi Srivatsavai { 42214eaa4710SRishi Srivatsavai dladm_status_t status; 42224eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 42234eaa4710SRishi Srivatsavai uint16_t pvid; 42244eaa4710SRishi Srivatsavai 42254eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 42264eaa4710SRishi Srivatsavai 0, &status); 42274eaa4710SRishi Srivatsavai if (dip == NULL) 42284eaa4710SRishi Srivatsavai return (status); 42294eaa4710SRishi Srivatsavai pvid = vdp->vd_val; 42304eaa4710SRishi Srivatsavai (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 42314eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_TRUE); 42324eaa4710SRishi Srivatsavai free(dip); 42334eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 42344eaa4710SRishi Srivatsavai return (status); 42354eaa4710SRishi Srivatsavai 42364eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 42374eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 42384eaa4710SRishi Srivatsavai } 42394eaa4710SRishi Srivatsavai 42404eaa4710SRishi Srivatsavai /* ARGSUSED */ 42414eaa4710SRishi Srivatsavai static dladm_status_t 42424eaa4710SRishi Srivatsavai check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 4243c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 4244c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 42454eaa4710SRishi Srivatsavai { 42464eaa4710SRishi Srivatsavai char *cp; 4247c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 4248c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 42494eaa4710SRishi Srivatsavai 42504eaa4710SRishi Srivatsavai if (val_cnt != 1) 42514eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 42524eaa4710SRishi Srivatsavai 42534eaa4710SRishi Srivatsavai if (prop_val == NULL) { 42544eaa4710SRishi Srivatsavai vdp->vd_val = 1; 42554eaa4710SRishi Srivatsavai } else { 42564eaa4710SRishi Srivatsavai errno = 0; 42574eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 42584eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 42594eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 42604eaa4710SRishi Srivatsavai } 42614eaa4710SRishi Srivatsavai 42624eaa4710SRishi Srivatsavai return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 42634eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 42644eaa4710SRishi Srivatsavai } 42654eaa4710SRishi Srivatsavai 4266bcb5c89dSSowmini Varadhan dladm_status_t 42674ac67f02SAnurag S. Maskey i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 42684ac67f02SAnurag S. Maskey mac_prop_id_t cmd, size_t len, boolean_t set) 4269bcb5c89dSSowmini Varadhan { 4270bcb5c89dSSowmini Varadhan uint32_t flags; 4271bcb5c89dSSowmini Varadhan dladm_status_t status; 4272bcb5c89dSSowmini Varadhan uint32_t media; 4273bcb5c89dSSowmini Varadhan dld_ioc_macprop_t *dip; 4274bcb5c89dSSowmini Varadhan void *dp; 4275bcb5c89dSSowmini Varadhan 42764ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 42774ac67f02SAnurag S. Maskey &media, NULL, 0)) != DLADM_STATUS_OK) { 4278bcb5c89dSSowmini Varadhan return (status); 4279bcb5c89dSSowmini Varadhan } 4280bcb5c89dSSowmini Varadhan 4281bcb5c89dSSowmini Varadhan if (media != DL_WIFI) 4282bcb5c89dSSowmini Varadhan return (DLADM_STATUS_BADARG); 4283bcb5c89dSSowmini Varadhan 4284bcb5c89dSSowmini Varadhan if (!(flags & DLADM_OPT_ACTIVE)) 4285bcb5c89dSSowmini Varadhan return (DLADM_STATUS_TEMPONLY); 4286bcb5c89dSSowmini Varadhan 4287bcb5c89dSSowmini Varadhan if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 4288bcb5c89dSSowmini Varadhan len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 4289bcb5c89dSSowmini Varadhan 4290bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 4291bcb5c89dSSowmini Varadhan if (dip == NULL) 4292bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 4293bcb5c89dSSowmini Varadhan 4294bcb5c89dSSowmini Varadhan dp = (uchar_t *)dip->pr_val; 4295bcb5c89dSSowmini Varadhan if (set) 4296bcb5c89dSSowmini Varadhan (void) memcpy(dp, buf, len); 4297bcb5c89dSSowmini Varadhan 42984ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, set); 42990b8f0546SSowmini Varadhan if (status == DLADM_STATUS_OK) { 4300bcb5c89dSSowmini Varadhan if (!set) 4301bcb5c89dSSowmini Varadhan (void) memcpy(buf, dp, len); 4302bcb5c89dSSowmini Varadhan } 4303bcb5c89dSSowmini Varadhan 4304bcb5c89dSSowmini Varadhan free(dip); 4305bcb5c89dSSowmini Varadhan return (status); 4306bcb5c89dSSowmini Varadhan } 4307bcb5c89dSSowmini Varadhan 4308da14cebeSEric Cheng dladm_status_t 4309da14cebeSEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 4310da14cebeSEric Cheng { 431162ee1d25SArtem Kachitchkine return (dladm_parse_args(str, listp, novalues)); 4312da14cebeSEric Cheng } 4313da14cebeSEric Cheng 4314da14cebeSEric Cheng /* 4315da14cebeSEric Cheng * Retrieve the one link property from the database 4316da14cebeSEric Cheng */ 4317da14cebeSEric Cheng /*ARGSUSED*/ 4318da14cebeSEric Cheng static int 43194ac67f02SAnurag S. Maskey i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 43204ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 4321da14cebeSEric Cheng { 4322da14cebeSEric Cheng dladm_arg_list_t *proplist = arg; 4323da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4324da14cebeSEric Cheng 4325da14cebeSEric Cheng aip = &proplist->al_info[proplist->al_count]; 4326da14cebeSEric Cheng /* 4327da14cebeSEric Cheng * it is fine to point to prop_name since prop_name points to the 4328da14cebeSEric Cheng * prop_table[n].pd_name. 4329da14cebeSEric Cheng */ 4330da14cebeSEric Cheng aip->ai_name = prop_name; 4331da14cebeSEric Cheng 43324ac67f02SAnurag S. Maskey (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 43334ac67f02SAnurag S. Maskey prop_name, aip->ai_val, &aip->ai_count); 4334da14cebeSEric Cheng 4335da14cebeSEric Cheng if (aip->ai_count != 0) 4336da14cebeSEric Cheng proplist->al_count++; 4337da14cebeSEric Cheng 4338da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 4339da14cebeSEric Cheng } 4340da14cebeSEric Cheng 4341da14cebeSEric Cheng 4342da14cebeSEric Cheng /* 4343da14cebeSEric Cheng * Retrieve all link properties for a link from the database and 4344da14cebeSEric Cheng * return a property list. 4345da14cebeSEric Cheng */ 4346da14cebeSEric Cheng dladm_status_t 43474ac67f02SAnurag S. Maskey dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 43484ac67f02SAnurag S. Maskey dladm_arg_list_t **listp) 4349da14cebeSEric Cheng { 4350da14cebeSEric Cheng dladm_arg_list_t *list; 4351da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 4352da14cebeSEric Cheng 4353da14cebeSEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 4354da14cebeSEric Cheng if (list == NULL) 4355da14cebeSEric Cheng return (dladm_errno2status(errno)); 4356da14cebeSEric Cheng 43574ac67f02SAnurag S. Maskey status = dladm_walk_linkprop(handle, linkid, list, 43584ac67f02SAnurag S. Maskey i_dladm_get_one_prop); 4359da14cebeSEric Cheng 4360da14cebeSEric Cheng *listp = list; 4361da14cebeSEric Cheng return (status); 4362da14cebeSEric Cheng } 4363da14cebeSEric Cheng 4364da14cebeSEric Cheng /* 4365da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 4366da14cebeSEric Cheng * convert to a kernel structure. 4367da14cebeSEric Cheng */ 4368da14cebeSEric Cheng static dladm_status_t 43694ac67f02SAnurag S. Maskey i_dladm_link_proplist_extract_one(dladm_handle_t handle, 43700dc2366fSVenugopal Iyer dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 4371da14cebeSEric Cheng { 4372da14cebeSEric Cheng dladm_status_t status; 4373da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4374da14cebeSEric Cheng int i, j; 4375da14cebeSEric Cheng 4376da14cebeSEric Cheng /* Find named property in proplist */ 4377da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 4378da14cebeSEric Cheng aip = &proplist->al_info[i]; 4379da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 4380da14cebeSEric Cheng break; 4381da14cebeSEric Cheng } 4382da14cebeSEric Cheng 4383da14cebeSEric Cheng /* Property not in list */ 4384da14cebeSEric Cheng if (i == proplist->al_count) 4385da14cebeSEric Cheng return (DLADM_STATUS_OK); 4386da14cebeSEric Cheng 4387da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 4388da14cebeSEric Cheng prop_desc_t *pdp = &prop_table[i]; 4389da14cebeSEric Cheng val_desc_t *vdp; 4390da14cebeSEric Cheng 4391da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 4392da14cebeSEric Cheng if (vdp == NULL) 4393da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 4394da14cebeSEric Cheng 4395da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 4396da14cebeSEric Cheng continue; 4397da14cebeSEric Cheng 4398da14cebeSEric Cheng if (aip->ai_val == NULL) 4399da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 4400da14cebeSEric Cheng 4401da14cebeSEric Cheng /* Check property value */ 4402da14cebeSEric Cheng if (pdp->pd_check != NULL) { 44034ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 4404c569ef53SMichael Lim &(aip->ai_count), flags, &vdp, 0); 4405da14cebeSEric Cheng } else { 4406da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4407da14cebeSEric Cheng } 4408da14cebeSEric Cheng 4409da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4410da14cebeSEric Cheng return (status); 4411da14cebeSEric Cheng 4412da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 4413da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 4414da14cebeSEric Cheng 4415da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 4416da14cebeSEric Cheng continue; 4417da14cebeSEric Cheng 4418da14cebeSEric Cheng /* Extract kernel structure */ 4419da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 442025ec3e3dSEric Cheng status = rpp->rp_extract(vdp, 442125ec3e3dSEric Cheng aip->ai_count, arg); 4422da14cebeSEric Cheng } else { 4423da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4424da14cebeSEric Cheng } 4425da14cebeSEric Cheng break; 4426da14cebeSEric Cheng } 4427da14cebeSEric Cheng 4428da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4429da14cebeSEric Cheng return (status); 4430da14cebeSEric Cheng 4431da14cebeSEric Cheng break; 4432da14cebeSEric Cheng } 4433da14cebeSEric Cheng return (status); 4434da14cebeSEric Cheng } 4435da14cebeSEric Cheng 4436da14cebeSEric Cheng /* 4437da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 4438da14cebeSEric Cheng */ 4439da14cebeSEric Cheng dladm_status_t 44404ac67f02SAnurag S. Maskey dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 44410dc2366fSVenugopal Iyer mac_resource_props_t *mrp, uint_t flags) 4442da14cebeSEric Cheng { 444325ec3e3dSEric Cheng dladm_status_t status; 444425ec3e3dSEric Cheng int i; 4445da14cebeSEric Cheng 444625ec3e3dSEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 444725ec3e3dSEric Cheng status = i_dladm_link_proplist_extract_one(handle, 44480dc2366fSVenugopal Iyer proplist, rsrc_prop_table[i].rp_name, flags, mrp); 4449da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4450da14cebeSEric Cheng return (status); 445125ec3e3dSEric Cheng } 4452da14cebeSEric Cheng return (status); 4453da14cebeSEric Cheng } 4454da14cebeSEric Cheng 4455da14cebeSEric Cheng static const char * 4456da14cebeSEric Cheng dladm_perm2str(uint_t perm, char *buf) 4457da14cebeSEric Cheng { 4458da14cebeSEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 4459da14cebeSEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 4460da14cebeSEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 4461da14cebeSEric Cheng return (buf); 4462da14cebeSEric Cheng } 44634784fcbdSSowmini Varadhan 44644784fcbdSSowmini Varadhan dladm_status_t 44650dc2366fSVenugopal Iyer dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 44664ac67f02SAnurag S. Maskey link_state_t *state) 44674784fcbdSSowmini Varadhan { 44684784fcbdSSowmini Varadhan uint_t perms; 44694784fcbdSSowmini Varadhan 44700dc2366fSVenugopal Iyer return (i_dladm_get_public_prop(handle, linkid, "state", 0, 44710dc2366fSVenugopal Iyer &perms, state, sizeof (*state))); 44724784fcbdSSowmini Varadhan } 447362ee1d25SArtem Kachitchkine 447462ee1d25SArtem Kachitchkine boolean_t 447562ee1d25SArtem Kachitchkine dladm_attr_is_linkprop(const char *name) 447662ee1d25SArtem Kachitchkine { 447762ee1d25SArtem Kachitchkine /* non-property attribute names */ 447862ee1d25SArtem Kachitchkine const char *nonprop[] = { 447962ee1d25SArtem Kachitchkine /* dlmgmtd core attributes */ 448062ee1d25SArtem Kachitchkine "name", 448162ee1d25SArtem Kachitchkine "class", 448262ee1d25SArtem Kachitchkine "media", 448362ee1d25SArtem Kachitchkine FPHYMAJ, 448462ee1d25SArtem Kachitchkine FPHYINST, 448562ee1d25SArtem Kachitchkine FDEVNAME, 448662ee1d25SArtem Kachitchkine 448762ee1d25SArtem Kachitchkine /* other attributes for vlan, aggr, etc */ 448862ee1d25SArtem Kachitchkine DLADM_ATTR_NAMES 448962ee1d25SArtem Kachitchkine }; 449062ee1d25SArtem Kachitchkine boolean_t is_nonprop = B_FALSE; 449162ee1d25SArtem Kachitchkine int i; 449262ee1d25SArtem Kachitchkine 449362ee1d25SArtem Kachitchkine for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 449462ee1d25SArtem Kachitchkine if (strcmp(name, nonprop[i]) == 0) { 449562ee1d25SArtem Kachitchkine is_nonprop = B_TRUE; 449662ee1d25SArtem Kachitchkine break; 449762ee1d25SArtem Kachitchkine } 449862ee1d25SArtem Kachitchkine } 449962ee1d25SArtem Kachitchkine 450062ee1d25SArtem Kachitchkine return (!is_nonprop); 450162ee1d25SArtem Kachitchkine } 45020dc2366fSVenugopal Iyer 45030dc2366fSVenugopal Iyer dladm_status_t 45040dc2366fSVenugopal Iyer dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 45050dc2366fSVenugopal Iyer dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 45060dc2366fSVenugopal Iyer { 45070dc2366fSVenugopal Iyer char *buf, **propvals; 45080dc2366fSVenugopal Iyer uint_t valcnt = DLADM_MAX_PROP_VALCNT; 45090dc2366fSVenugopal Iyer int i; 45100dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 4511550b6e40SSowmini Varadhan size_t bufsize; 45120dc2366fSVenugopal Iyer 45130dc2366fSVenugopal Iyer *is_set = B_FALSE; 45140dc2366fSVenugopal Iyer 4515550b6e40SSowmini Varadhan bufsize = (sizeof (char *) + DLADM_PROP_VAL_MAX) * 4516550b6e40SSowmini Varadhan DLADM_MAX_PROP_VALCNT; 4517550b6e40SSowmini Varadhan if ((buf = calloc(1, bufsize)) == NULL) 45180dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 45190dc2366fSVenugopal Iyer 45200dc2366fSVenugopal Iyer propvals = (char **)(void *)buf; 45210dc2366fSVenugopal Iyer for (i = 0; i < valcnt; i++) { 45220dc2366fSVenugopal Iyer propvals[i] = buf + 45230dc2366fSVenugopal Iyer sizeof (char *) * DLADM_MAX_PROP_VALCNT + 45240dc2366fSVenugopal Iyer i * DLADM_PROP_VAL_MAX; 45250dc2366fSVenugopal Iyer } 45260dc2366fSVenugopal Iyer 45270dc2366fSVenugopal Iyer if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 45280dc2366fSVenugopal Iyer &valcnt) != DLADM_STATUS_OK) { 45290dc2366fSVenugopal Iyer goto done; 45300dc2366fSVenugopal Iyer } 45310dc2366fSVenugopal Iyer 4532550b6e40SSowmini Varadhan /* 4533550b6e40SSowmini Varadhan * valcnt is always set to 1 by get_pool(), hence we need to check 4534550b6e40SSowmini Varadhan * for a non-null string to see if it is set. For protection and 4535550b6e40SSowmini Varadhan * allowed-ips, we can check either the *propval or the valcnt. 4536550b6e40SSowmini Varadhan */ 4537550b6e40SSowmini Varadhan if ((strcmp(prop_name, "pool") == 0 || 4538550b6e40SSowmini Varadhan strcmp(prop_name, "protection") == 0 || 4539550b6e40SSowmini Varadhan strcmp(prop_name, "allowed-ips") == 0) && 4540550b6e40SSowmini Varadhan (strlen(*propvals) != 0)) { 45410dc2366fSVenugopal Iyer *is_set = B_TRUE; 45420dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 45430dc2366fSVenugopal Iyer *is_set = B_TRUE; 45440dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 45450dc2366fSVenugopal Iyer (strcmp(propvals[0], "true") == 0)) { 45460dc2366fSVenugopal Iyer *is_set = B_TRUE; 45470dc2366fSVenugopal Iyer } 45480dc2366fSVenugopal Iyer 45490dc2366fSVenugopal Iyer done: 45500dc2366fSVenugopal Iyer if (buf != NULL) 45510dc2366fSVenugopal Iyer free(buf); 45520dc2366fSVenugopal Iyer return (status); 45530dc2366fSVenugopal Iyer } 45541cfa752fSRamaswamy Tummala 45551cfa752fSRamaswamy Tummala /* ARGSUSED */ 45561cfa752fSRamaswamy Tummala static dladm_status_t 45571cfa752fSRamaswamy Tummala get_linkmode_prop(dladm_handle_t handle, prop_desc_t *pdp, 45581cfa752fSRamaswamy Tummala datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 45591cfa752fSRamaswamy Tummala datalink_media_t media, uint_t flags, uint_t *perm_flags) 45601cfa752fSRamaswamy Tummala { 45611cfa752fSRamaswamy Tummala char *s; 45621cfa752fSRamaswamy Tummala uint32_t v; 45631cfa752fSRamaswamy Tummala dladm_status_t status; 45641cfa752fSRamaswamy Tummala 45651cfa752fSRamaswamy Tummala status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 45661cfa752fSRamaswamy Tummala perm_flags, &v, sizeof (v)); 45671cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 45681cfa752fSRamaswamy Tummala return (status); 45691cfa752fSRamaswamy Tummala 45701cfa752fSRamaswamy Tummala switch (v) { 4571c87dd6b7SRajkumar Sivaprakasam case DLADM_PART_CM_MODE: 45721cfa752fSRamaswamy Tummala s = "cm"; 45731cfa752fSRamaswamy Tummala break; 4574c87dd6b7SRajkumar Sivaprakasam case DLADM_PART_UD_MODE: 45751cfa752fSRamaswamy Tummala s = "ud"; 45761cfa752fSRamaswamy Tummala break; 45771cfa752fSRamaswamy Tummala default: 45781cfa752fSRamaswamy Tummala s = ""; 45791cfa752fSRamaswamy Tummala break; 45801cfa752fSRamaswamy Tummala } 45811cfa752fSRamaswamy Tummala (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); 45821cfa752fSRamaswamy Tummala 45831cfa752fSRamaswamy Tummala *val_cnt = 1; 45841cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 45851cfa752fSRamaswamy Tummala } 4586