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. 23*e03914f9SRobert Mustacchi * Copyright (c) 2014, Joyent, Inc. All rights reserved. 240ba2cbe9Sxc151355 */ 250ba2cbe9Sxc151355 260ba2cbe9Sxc151355 #include <stdlib.h> 27c569ef53SMichael Lim #include <string.h> 280ba2cbe9Sxc151355 #include <strings.h> 290ba2cbe9Sxc151355 #include <errno.h> 300ba2cbe9Sxc151355 #include <ctype.h> 31d62bc4baSyz147064 #include <stddef.h> 32f4b3ec61Sdh155122 #include <sys/types.h> 330ba2cbe9Sxc151355 #include <sys/stat.h> 34f4b3ec61Sdh155122 #include <sys/dld.h> 35f4b3ec61Sdh155122 #include <sys/zone.h> 36f4b3ec61Sdh155122 #include <fcntl.h> 37f4b3ec61Sdh155122 #include <unistd.h> 38f4b3ec61Sdh155122 #include <libdevinfo.h> 39f4b3ec61Sdh155122 #include <zone.h> 40f595a68aSyz147064 #include <libdllink.h> 410ba2cbe9Sxc151355 #include <libdladm_impl.h> 42d62bc4baSyz147064 #include <libdlwlan_impl.h> 43f595a68aSyz147064 #include <libdlwlan.h> 44d62bc4baSyz147064 #include <libdlvlan.h> 45da14cebeSEric Cheng #include <libdlvnic.h> 461cfa752fSRamaswamy Tummala #include <libdlib.h> 47da14cebeSEric Cheng #include <libintl.h> 48f4b3ec61Sdh155122 #include <dlfcn.h> 49f4b3ec61Sdh155122 #include <link.h> 50d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 51e7801d59Ssowmini #include <libdladm.h> 52da14cebeSEric Cheng #include <libdlstat.h> 53e7801d59Ssowmini #include <sys/param.h> 54da14cebeSEric Cheng #include <sys/debug.h> 55da14cebeSEric Cheng #include <sys/dld.h> 56e7801d59Ssowmini #include <inttypes.h> 57e7801d59Ssowmini #include <sys/ethernet.h> 582b24ab6bSSebastien Roy #include <inet/iptun.h> 59bcb5c89dSSowmini Varadhan #include <net/wpa.h> 60bcb5c89dSSowmini Varadhan #include <sys/sysmacros.h> 614eaa4710SRishi Srivatsavai #include <sys/vlan.h> 624eaa4710SRishi Srivatsavai #include <libdlbridge.h> 634eaa4710SRishi Srivatsavai #include <stp_in.h> 640dc2366fSVenugopal Iyer #include <netinet/dhcp.h> 650dc2366fSVenugopal Iyer #include <netinet/dhcp6.h> 660dc2366fSVenugopal Iyer #include <net/if_types.h> 670dc2366fSVenugopal Iyer #include <libinetutil.h> 680dc2366fSVenugopal Iyer #include <pool.h> 691a41ca23SJerry Jelinek #include <libdlaggr.h> 70f4b3ec61Sdh155122 71d62bc4baSyz147064 /* 72d62bc4baSyz147064 * The linkprop get() callback. 73da14cebeSEric Cheng * - pd: pointer to the prop_desc_t 74d62bc4baSyz147064 * - propstrp: a property string array to keep the returned property. 75d62bc4baSyz147064 * Caller allocated. 76d62bc4baSyz147064 * - cntp: number of returned properties. 77d62bc4baSyz147064 * Caller also uses it to indicate how many it expects. 78d62bc4baSyz147064 */ 79e7801d59Ssowmini struct prop_desc; 80da14cebeSEric Cheng typedef struct prop_desc prop_desc_t; 81e7801d59Ssowmini 824ac67f02SAnurag S. Maskey typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 836b9e797cSsowmini datalink_id_t, char **propstp, uint_t *cntp, 84afdda45fSVasumathi Sundaram - Sun Microsystems datalink_media_t, uint_t, uint_t *); 85f4b3ec61Sdh155122 86d62bc4baSyz147064 /* 87d62bc4baSyz147064 * The linkprop set() callback. 88d62bc4baSyz147064 * - propval: a val_desc_t array which keeps the property values to be set. 89d62bc4baSyz147064 * - cnt: number of properties to be set. 90e7801d59Ssowmini * - flags: additional flags passed down the system call. 91e7801d59Ssowmini * 92e7801d59Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 93e7801d59Ssowmini * a format suitable for kernel consumption. This may require allocation 94e7801d59Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 95e7801d59Ssowmini * by all other pd_sets) which invokes the ioctl. 96d62bc4baSyz147064 */ 974ac67f02SAnurag S. Maskey typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 986b9e797cSsowmini val_desc_t *propval, uint_t cnt, uint_t flags, 996b9e797cSsowmini datalink_media_t); 100f4b3ec61Sdh155122 101d62bc4baSyz147064 /* 102d62bc4baSyz147064 * The linkprop check() callback. 103d62bc4baSyz147064 * - propstrp: property string array which keeps the property to be checked. 104d62bc4baSyz147064 * - cnt: number of properties. 105d62bc4baSyz147064 * - propval: return value; the property values of the given property strings. 106e7801d59Ssowmini * 107e7801d59Ssowmini * pd_check checks that the input values are valid. It does so by 108e7801d59Ssowmini * iteraring through the pd_modval list for the property. If 109e7801d59Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 110e7801d59Ssowmini * specific to this property can be used. If the input values are 111e7801d59Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 112e7801d59Ssowmini * with either a val_desc_t found on the pd_modval list or something 113e7801d59Ssowmini * generated on the fly. 114d62bc4baSyz147064 */ 1154ac67f02SAnurag S. Maskey typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 116c569ef53SMichael Lim datalink_id_t, char **propstrp, uint_t *cnt, 117c569ef53SMichael Lim uint_t flags, val_desc_t **propval, 1180dc2366fSVenugopal Iyer datalink_media_t); 119f4b3ec61Sdh155122 120bcb5c89dSSowmini Varadhan typedef struct link_attr_s { 1213fd94f8cSam223141 mac_prop_id_t pp_id; 122e7801d59Ssowmini size_t pp_valsize; 123e7801d59Ssowmini char *pp_name; 124bcb5c89dSSowmini Varadhan } link_attr_t; 125e7801d59Ssowmini 1260dc2366fSVenugopal Iyer typedef struct dladm_linkprop_args_s { 1270dc2366fSVenugopal Iyer dladm_status_t dla_status; 1280dc2366fSVenugopal Iyer uint_t dla_flags; 1290dc2366fSVenugopal Iyer } dladm_linkprop_args_t; 1300dc2366fSVenugopal Iyer 131bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 132bcb5c89dSSowmini Varadhan const char *, uint_t, dladm_status_t *); 133bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 134da14cebeSEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 1350dc2366fSVenugopal Iyer static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 1360dc2366fSVenugopal Iyer char *, uint_t, uint_t *, void *, size_t); 137da14cebeSEric Cheng 1383361618bSRishi Srivatsavai static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1394ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 14062ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1414ac67f02SAnurag S. Maskey const char *, char **, uint_t *, dladm_prop_type_t, 1424ac67f02SAnurag S. Maskey uint_t); 1430dc2366fSVenugopal Iyer static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1440dc2366fSVenugopal Iyer static const char *dladm_perm2str(uint_t, char *); 145bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *); 146bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t); 147da14cebeSEric Cheng 1480dc2366fSVenugopal Iyer static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 1490dc2366fSVenugopal Iyer get_speed, get_channel, get_powermode, get_radio, 1500dc2366fSVenugopal Iyer get_duplex, get_link_state, get_binary, get_uint32, 1510dc2366fSVenugopal Iyer get_flowctl, get_maxbw, get_cpus, get_priority, 1520dc2366fSVenugopal Iyer get_tagmode, get_range, get_stp, get_bridge_forward, 1530dc2366fSVenugopal Iyer get_bridge_pvid, get_protection, get_rxrings, 1541a41ca23SJerry Jelinek get_txrings, get_cntavail, get_secondary_macs, 1550dc2366fSVenugopal Iyer get_allowedips, get_allowedcids, get_pool, 1561cfa752fSRamaswamy Tummala get_rings_range, get_linkmode_prop; 157da14cebeSEric Cheng 1580dc2366fSVenugopal Iyer static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 1590dc2366fSVenugopal Iyer set_public_prop, set_resource, set_stp_prop, 1601a41ca23SJerry Jelinek set_bridge_forward, set_bridge_pvid, set_secondary_macs; 161f4b3ec61Sdh155122 1620dc2366fSVenugopal Iyer static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 1630dc2366fSVenugopal Iyer check_encaplim, check_uint32, check_maxbw, check_cpus, 1640dc2366fSVenugopal Iyer check_stp_prop, check_bridge_pvid, check_allowedips, 1651a41ca23SJerry Jelinek check_allowedcids, check_secondary_macs, check_rings, 1660dc2366fSVenugopal Iyer check_pool, check_prop; 1676b9e797cSsowmini 168da14cebeSEric Cheng struct prop_desc { 169d62bc4baSyz147064 /* 170d62bc4baSyz147064 * link property name 171d62bc4baSyz147064 */ 172f4b3ec61Sdh155122 char *pd_name; 173d62bc4baSyz147064 174d62bc4baSyz147064 /* 175d62bc4baSyz147064 * default property value, can be set to { "", NULL } 176d62bc4baSyz147064 */ 177f4b3ec61Sdh155122 val_desc_t pd_defval; 178d62bc4baSyz147064 179d62bc4baSyz147064 /* 180d62bc4baSyz147064 * list of optional property values, can be NULL. 181d62bc4baSyz147064 * 182d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 183d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 184d62bc4baSyz147064 */ 185d62bc4baSyz147064 val_desc_t *pd_optval; 186d62bc4baSyz147064 187d62bc4baSyz147064 /* 188d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 189d62bc4baSyz147064 */ 190d62bc4baSyz147064 uint_t pd_noptval; 191d62bc4baSyz147064 192d62bc4baSyz147064 /* 1934eaa4710SRishi Srivatsavai * callback to set link property; set to NULL if this property is 1944eaa4710SRishi Srivatsavai * read-only and may be called before or after permanent update; see 1954eaa4710SRishi Srivatsavai * flags. 196d62bc4baSyz147064 */ 197f4b3ec61Sdh155122 pd_setf_t *pd_set; 198d62bc4baSyz147064 199d62bc4baSyz147064 /* 200d62bc4baSyz147064 * callback to get modifiable link property 201d62bc4baSyz147064 */ 202f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 203d62bc4baSyz147064 204d62bc4baSyz147064 /* 205d62bc4baSyz147064 * callback to get current link property 206d62bc4baSyz147064 */ 207f4b3ec61Sdh155122 pd_getf_t *pd_get; 208d62bc4baSyz147064 209d62bc4baSyz147064 /* 210d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 211d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 212d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 213d62bc4baSyz147064 * valid. 214d62bc4baSyz147064 */ 215f4b3ec61Sdh155122 pd_checkf_t *pd_check; 216d62bc4baSyz147064 217d62bc4baSyz147064 uint_t pd_flags; 218e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 219e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 2204eaa4710SRishi Srivatsavai #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 221d62bc4baSyz147064 /* 222d62bc4baSyz147064 * indicate link classes this property applies to. 223d62bc4baSyz147064 */ 224d62bc4baSyz147064 datalink_class_t pd_class; 225d62bc4baSyz147064 226d62bc4baSyz147064 /* 227d62bc4baSyz147064 * indicate link media type this property applies to. 228d62bc4baSyz147064 */ 229d62bc4baSyz147064 datalink_media_t pd_dmedia; 230da14cebeSEric Cheng }; 231f4b3ec61Sdh155122 2323fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 233e7801d59Ssowmini 234bcb5c89dSSowmini Varadhan /* 235bcb5c89dSSowmini Varadhan * Supported link properties enumerated in the prop_table[] array are 236bcb5c89dSSowmini Varadhan * computed using the callback functions in that array. To compute the 237bcb5c89dSSowmini Varadhan * property value, multiple distinct system calls may be needed (e.g., 238bcb5c89dSSowmini Varadhan * for wifi speed, we need to issue system calls to get desired/supported 239bcb5c89dSSowmini Varadhan * rates). The link_attr[] table enumerates the interfaces to the kernel, 240bcb5c89dSSowmini Varadhan * and the type/size of the data passed in the user-kernel interface. 241bcb5c89dSSowmini Varadhan */ 242bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = { 243bcb5c89dSSowmini Varadhan { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 244e7801d59Ssowmini 245bcb5c89dSSowmini Varadhan { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 246e7801d59Ssowmini 247bcb5c89dSSowmini Varadhan { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 248e7801d59Ssowmini 249bcb5c89dSSowmini Varadhan { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 250e7801d59Ssowmini 251bcb5c89dSSowmini Varadhan { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 252e7801d59Ssowmini 253bcb5c89dSSowmini Varadhan { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 254e7801d59Ssowmini 255bcb5c89dSSowmini Varadhan { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 256e7801d59Ssowmini 257bcb5c89dSSowmini Varadhan { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2583bc21d0aSAruna Ramakrishna - Sun Microsystems 259aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 260aca118b7Slucy wang - Sun Microsystems - Beijing China 261aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 262aca118b7Slucy wang - Sun Microsystems - Beijing China 263bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2643bc21d0aSAruna Ramakrishna - Sun Microsystems 265bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 266e7801d59Ssowmini 267bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 268e7801d59Ssowmini 269bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 270e7801d59Ssowmini 271bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 272e7801d59Ssowmini 273bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 274e7801d59Ssowmini 275bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 276e7801d59Ssowmini 277bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 278e7801d59Ssowmini 279bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 280e7801d59Ssowmini 281bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 282e7801d59Ssowmini 283bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 284e7801d59Ssowmini 285bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 286e7801d59Ssowmini 287bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 288e7801d59Ssowmini 289bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 290bcb5c89dSSowmini Varadhan 291bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 292bcb5c89dSSowmini Varadhan 293bcb5c89dSSowmini Varadhan { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 294bcb5c89dSSowmini Varadhan 295bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 296bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 297bcb5c89dSSowmini Varadhan 298bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 299bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 300bcb5c89dSSowmini Varadhan 301bcb5c89dSSowmini Varadhan { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 302bcb5c89dSSowmini Varadhan 303bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 304bcb5c89dSSowmini Varadhan 305bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 306bcb5c89dSSowmini Varadhan 307bcb5c89dSSowmini Varadhan { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 308bcb5c89dSSowmini Varadhan 309bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 310bcb5c89dSSowmini Varadhan 311bcb5c89dSSowmini Varadhan { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 312bcb5c89dSSowmini Varadhan 313bcb5c89dSSowmini Varadhan /* wl_wpa_ess_t has variable length */ 314bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 315bcb5c89dSSowmini Varadhan 316bcb5c89dSSowmini Varadhan { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 317bcb5c89dSSowmini Varadhan 318bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 319bcb5c89dSSowmini Varadhan 320bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 321bcb5c89dSSowmini Varadhan 322bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 323bcb5c89dSSowmini Varadhan 324bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 325bcb5c89dSSowmini Varadhan 326bcb5c89dSSowmini Varadhan /* wl_wpa_ie_t has variable length */ 327bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 328bcb5c89dSSowmini Varadhan 329bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 330bcb5c89dSSowmini Varadhan 331bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 332bcb5c89dSSowmini Varadhan 333bcb5c89dSSowmini Varadhan { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 334bcb5c89dSSowmini Varadhan 335e75f0919SSebastien Roy { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 336e75f0919SSebastien Roy 3372b24ab6bSSebastien Roy { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 3382b24ab6bSSebastien Roy 3392b24ab6bSSebastien Roy { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 3402b24ab6bSSebastien Roy 3414eaa4710SRishi Srivatsavai { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 3424eaa4710SRishi Srivatsavai 3434eaa4710SRishi Srivatsavai { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 3444eaa4710SRishi Srivatsavai 3454eaa4710SRishi Srivatsavai { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 3464eaa4710SRishi Srivatsavai 3470dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 3480dc2366fSVenugopal Iyer 3490dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 3500dc2366fSVenugopal Iyer "resource-effective"}, 3510dc2366fSVenugopal Iyer 3520dc2366fSVenugopal Iyer { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 3530dc2366fSVenugopal Iyer 3540dc2366fSVenugopal Iyer { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 3550dc2366fSVenugopal Iyer 3560dc2366fSVenugopal Iyer { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 3570dc2366fSVenugopal Iyer "txrings-available"}, 3580dc2366fSVenugopal Iyer 3590dc2366fSVenugopal Iyer { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 3600dc2366fSVenugopal Iyer "rxrings-available"}, 3610dc2366fSVenugopal Iyer 3620dc2366fSVenugopal Iyer { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 3630dc2366fSVenugopal Iyer 3640dc2366fSVenugopal Iyer { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 365da14cebeSEric Cheng 3661cfa752fSRamaswamy Tummala { MAC_PROP_IB_LINKMODE, sizeof (uint32_t), "linkmode"}, 3671cfa752fSRamaswamy Tummala 3681a41ca23SJerry Jelinek { MAC_PROP_SECONDARY_ADDRS, sizeof (mac_secondary_addr_t), 3691a41ca23SJerry Jelinek "secondary-macs"}, 3701a41ca23SJerry Jelinek 37125ec3e3dSEric Cheng { MAC_PROP_PRIVATE, 0, "driver-private"} 372e7801d59Ssowmini }; 373e7801d59Ssowmini 3744eaa4710SRishi Srivatsavai typedef struct bridge_public_prop_s { 3754eaa4710SRishi Srivatsavai const char *bpp_name; 3764eaa4710SRishi Srivatsavai int bpp_code; 3774eaa4710SRishi Srivatsavai } bridge_public_prop_t; 3784eaa4710SRishi Srivatsavai 3794eaa4710SRishi Srivatsavai static const bridge_public_prop_t bridge_prop[] = { 3804eaa4710SRishi Srivatsavai { "stp", PT_CFG_NON_STP }, 3814eaa4710SRishi Srivatsavai { "stp_priority", PT_CFG_PRIO }, 3824eaa4710SRishi Srivatsavai { "stp_cost", PT_CFG_COST }, 3834eaa4710SRishi Srivatsavai { "stp_edge", PT_CFG_EDGE }, 3844eaa4710SRishi Srivatsavai { "stp_p2p", PT_CFG_P2P }, 3854eaa4710SRishi Srivatsavai { "stp_mcheck", PT_CFG_MCHECK }, 3864eaa4710SRishi Srivatsavai { NULL, 0 } 3874eaa4710SRishi Srivatsavai }; 3884eaa4710SRishi Srivatsavai 389e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 390e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 391e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 392e7801d59Ssowmini }; 393e7801d59Ssowmini static val_desc_t link_status_vals[] = { 394e7801d59Ssowmini { "up", LINK_STATE_UP }, 395e7801d59Ssowmini { "down", LINK_STATE_DOWN } 396e7801d59Ssowmini }; 397e7801d59Ssowmini static val_desc_t link_01_vals[] = { 398e7801d59Ssowmini { "1", 1 }, 399e7801d59Ssowmini { "0", 0 } 400e7801d59Ssowmini }; 401e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 402e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 403e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 404e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 405e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 406e7801d59Ssowmini }; 407da14cebeSEric Cheng static val_desc_t link_priority_vals[] = { 408da14cebeSEric Cheng { "low", MPL_LOW }, 409da14cebeSEric Cheng { "medium", MPL_MEDIUM }, 410da14cebeSEric Cheng { "high", MPL_HIGH } 411da14cebeSEric Cheng }; 412e7801d59Ssowmini 413e75f0919SSebastien Roy static val_desc_t link_tagmode_vals[] = { 414e75f0919SSebastien Roy { "normal", LINK_TAGMODE_NORMAL }, 415e75f0919SSebastien Roy { "vlanonly", LINK_TAGMODE_VLANONLY } 416e75f0919SSebastien Roy }; 417e75f0919SSebastien Roy 41825ec3e3dSEric Cheng static val_desc_t link_protect_vals[] = { 41925ec3e3dSEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 4200dc2366fSVenugopal Iyer { "restricted", MPT_RESTRICTED }, 42125ec3e3dSEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 4220dc2366fSVenugopal Iyer { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 42325ec3e3dSEric Cheng }; 42425ec3e3dSEric Cheng 425d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 426d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 427d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 428d62bc4baSyz147064 }; 429d62bc4baSyz147064 430d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 431d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 432d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 433d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 434d62bc4baSyz147064 }; 435d62bc4baSyz147064 4364eaa4710SRishi Srivatsavai static val_desc_t stp_p2p_vals[] = { 4374eaa4710SRishi Srivatsavai { "true", P2P_FORCE_TRUE }, 4384eaa4710SRishi Srivatsavai { "false", P2P_FORCE_FALSE }, 4394eaa4710SRishi Srivatsavai { "auto", P2P_AUTO } 4404eaa4710SRishi Srivatsavai }; 4414eaa4710SRishi Srivatsavai 442c87dd6b7SRajkumar Sivaprakasam static val_desc_t dladm_part_linkmode_vals[] = { 443c87dd6b7SRajkumar Sivaprakasam { "cm", DLADM_PART_CM_MODE }, 444c87dd6b7SRajkumar Sivaprakasam { "ud", DLADM_PART_UD_MODE }, 4451cfa752fSRamaswamy Tummala }; 4461cfa752fSRamaswamy Tummala 447da14cebeSEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 448da14cebeSEric Cheng #define RESET_VAL ((uintptr_t)-1) 4490dc2366fSVenugopal Iyer #define UNSPEC_VAL ((uintptr_t)-2) 450d62bc4baSyz147064 4511a41ca23SJerry Jelinek /* 4521a41ca23SJerry Jelinek * For the default, if defaults are not defined for the property, 4531a41ca23SJerry Jelinek * pd_defval.vd_name should be null. If the driver has to be contacted for the 4541a41ca23SJerry Jelinek * value, vd_name should be the empty string (""). Otherwise, dladm will 4551a41ca23SJerry Jelinek * just print whatever is in the table. 4561a41ca23SJerry Jelinek */ 457da14cebeSEric Cheng static prop_desc_t prop_table[] = { 458e7801d59Ssowmini { "channel", { NULL, 0 }, 459e7801d59Ssowmini NULL, 0, NULL, NULL, 4600dc2366fSVenugopal Iyer get_channel, NULL, 0, 461d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 462d62bc4baSyz147064 463d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 464d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 4650dc2366fSVenugopal Iyer set_powermode, NULL, 4660dc2366fSVenugopal Iyer get_powermode, NULL, 0, 467d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 468d62bc4baSyz147064 469d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 470d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 4710dc2366fSVenugopal Iyer set_radio, NULL, 4720dc2366fSVenugopal Iyer get_radio, NULL, 0, 473d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 474d62bc4baSyz147064 475c87dd6b7SRajkumar Sivaprakasam { "linkmode", { "cm", DLADM_PART_CM_MODE }, 476c87dd6b7SRajkumar Sivaprakasam dladm_part_linkmode_vals, VALCNT(dladm_part_linkmode_vals), 4771cfa752fSRamaswamy Tummala set_public_prop, NULL, get_linkmode_prop, NULL, 0, 4781cfa752fSRamaswamy Tummala DATALINK_CLASS_PART, DL_IB }, 4791cfa752fSRamaswamy Tummala 480d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 4810dc2366fSVenugopal Iyer set_rate, get_rate_mod, 4820dc2366fSVenugopal Iyer get_rate, check_rate, 0, 4836b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 484d62bc4baSyz147064 4854045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 4860dc2366fSVenugopal Iyer set_public_prop, NULL, 4870dc2366fSVenugopal Iyer get_autopush, check_autopush, PD_CHECK_ALLOC, 488d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 489d62bc4baSyz147064 4904045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 4910dc2366fSVenugopal Iyer set_zone, NULL, 4920dc2366fSVenugopal Iyer get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 493e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 494e7801d59Ssowmini 4954045d941Ssowmini { "duplex", { "", 0 }, 496e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 4970dc2366fSVenugopal Iyer NULL, NULL, get_duplex, NULL, 498e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 499e7801d59Ssowmini 5006b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 501e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 5020dc2366fSVenugopal Iyer NULL, NULL, get_link_state, NULL, 5034045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 504e7801d59Ssowmini 5050b8f0546SSowmini Varadhan { "adv_autoneg_cap", { "", 0 }, 506e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5070dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 508e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 509e7801d59Ssowmini 5104045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 5110dc2366fSVenugopal Iyer set_public_prop, get_range, 5120dc2366fSVenugopal Iyer get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 5133bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 514e7801d59Ssowmini 5154045d941Ssowmini { "flowctrl", { "", 0 }, 516e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 5170dc2366fSVenugopal Iyer set_public_prop, NULL, get_flowctl, NULL, 518e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 519e7801d59Ssowmini 5201a41ca23SJerry Jelinek { "secondary-macs", { "--", 0 }, NULL, 0, 5211a41ca23SJerry Jelinek set_secondary_macs, NULL, 5221a41ca23SJerry Jelinek get_secondary_macs, check_secondary_macs, PD_CHECK_ALLOC, 5231a41ca23SJerry Jelinek DATALINK_CLASS_VNIC, DL_ETHER }, 5241a41ca23SJerry Jelinek 525aca118b7Slucy wang - Sun Microsystems - Beijing China { "adv_10gfdx_cap", { "", 0 }, 526aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 5270dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 528aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 529aca118b7Slucy wang - Sun Microsystems - Beijing China 530aca118b7Slucy wang - Sun Microsystems - Beijing China { "en_10gfdx_cap", { "", 0 }, 531aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 5320dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 533aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 534aca118b7Slucy wang - Sun Microsystems - Beijing China 5354045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 5364045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 5370dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 538e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 539e7801d59Ssowmini 5404045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 541e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5420dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 543e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 544e7801d59Ssowmini 5454045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 546e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5470dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 548e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 549e7801d59Ssowmini 5504045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 551e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5520dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 553e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 554e7801d59Ssowmini 5554045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 556e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5570dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 558e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 559e7801d59Ssowmini 5604045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 561e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5620dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 563e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 564e7801d59Ssowmini 5654045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 566e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5670dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 568e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 569e7801d59Ssowmini 5704045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 571e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5720dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 573e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 574e7801d59Ssowmini 5754045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 576e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5770dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 578e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 579e7801d59Ssowmini 5804045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 581e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5820dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 583e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 584e7801d59Ssowmini 5854045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 586e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5870dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 588e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 589e7801d59Ssowmini 5904045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 591e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5920dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 593da14cebeSEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 594e7801d59Ssowmini 595da14cebeSEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 5960dc2366fSVenugopal Iyer set_resource, NULL, 5970dc2366fSVenugopal Iyer get_maxbw, check_maxbw, PD_CHECK_ALLOC, 598da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 599da14cebeSEric Cheng 600da14cebeSEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 6010dc2366fSVenugopal Iyer set_resource, NULL, 6020dc2366fSVenugopal Iyer get_cpus, check_cpus, 0, 603da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 604da14cebeSEric Cheng 6050dc2366fSVenugopal Iyer { "cpus-effective", { "--", 0 }, 6060dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 6070dc2366fSVenugopal Iyer get_cpus, 0, 0, 6080dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6090dc2366fSVenugopal Iyer 6100dc2366fSVenugopal Iyer { "pool", { "--", RESET_VAL }, NULL, 0, 6110dc2366fSVenugopal Iyer set_resource, NULL, 6120dc2366fSVenugopal Iyer get_pool, check_pool, 0, 6130dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6140dc2366fSVenugopal Iyer 6150dc2366fSVenugopal Iyer { "pool-effective", { "--", 0 }, 6160dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 6170dc2366fSVenugopal Iyer get_pool, 0, 0, 6180dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 6190dc2366fSVenugopal Iyer 6200dc2366fSVenugopal Iyer { "priority", { "high", MPL_RESET }, 6210dc2366fSVenugopal Iyer link_priority_vals, VALCNT(link_priority_vals), set_resource, 6220dc2366fSVenugopal Iyer NULL, get_priority, check_prop, 0, 623da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 624e75f0919SSebastien Roy 625e75f0919SSebastien Roy { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 626e75f0919SSebastien Roy link_tagmode_vals, VALCNT(link_tagmode_vals), 6270dc2366fSVenugopal Iyer set_public_prop, NULL, get_tagmode, 628e75f0919SSebastien Roy NULL, 0, 629e75f0919SSebastien Roy DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 6304eaa4710SRishi Srivatsavai DL_ETHER }, 6314eaa4710SRishi Srivatsavai 6322b24ab6bSSebastien Roy { "hoplimit", { "", 0 }, NULL, 0, 6330dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 6340dc2366fSVenugopal Iyer check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 6352b24ab6bSSebastien Roy 6362b24ab6bSSebastien Roy { "encaplimit", { "", 0 }, NULL, 0, 6370dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 6380dc2366fSVenugopal Iyer check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 6392b24ab6bSSebastien Roy 6404eaa4710SRishi Srivatsavai { "forward", { "1", 1 }, 6414eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6424eaa4710SRishi Srivatsavai set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 6434eaa4710SRishi Srivatsavai DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 6444eaa4710SRishi Srivatsavai 6454eaa4710SRishi Srivatsavai { "default_tag", { "1", 1 }, NULL, 0, 6464eaa4710SRishi Srivatsavai set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 6474eaa4710SRishi Srivatsavai 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6484eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6494eaa4710SRishi Srivatsavai 6504eaa4710SRishi Srivatsavai { "learn_limit", { "1000", 1000 }, NULL, 0, 6510dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 6520dc2366fSVenugopal Iyer check_uint32, 0, 6534eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6544eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6554eaa4710SRishi Srivatsavai 6564eaa4710SRishi Srivatsavai { "learn_decay", { "200", 200 }, NULL, 0, 6570dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 6580dc2366fSVenugopal Iyer check_uint32, 0, 6594eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6604eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6614eaa4710SRishi Srivatsavai 6624eaa4710SRishi Srivatsavai { "stp", { "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_priority", { "128", 128 }, NULL, 0, 6690dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6704eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6714eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6724eaa4710SRishi Srivatsavai 6734eaa4710SRishi Srivatsavai { "stp_cost", { "auto", 0 }, NULL, 0, 6740dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6754eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6764eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6774eaa4710SRishi Srivatsavai 6784eaa4710SRishi Srivatsavai { "stp_edge", { "1", 1 }, 6794eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6800dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6814eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6824eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6834eaa4710SRishi Srivatsavai 6844eaa4710SRishi Srivatsavai { "stp_p2p", { "auto", P2P_AUTO }, 6854eaa4710SRishi Srivatsavai stp_p2p_vals, VALCNT(stp_p2p_vals), 6860dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 6874eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6884eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 6894eaa4710SRishi Srivatsavai 6904eaa4710SRishi Srivatsavai { "stp_mcheck", { "0", 0 }, 6914eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 6920dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 6934eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 6944eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 69525ec3e3dSEric Cheng 69625ec3e3dSEric Cheng { "protection", { "--", RESET_VAL }, 69725ec3e3dSEric Cheng link_protect_vals, VALCNT(link_protect_vals), 6980dc2366fSVenugopal Iyer set_resource, NULL, get_protection, check_prop, 0, 69925ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 70025ec3e3dSEric Cheng 70125ec3e3dSEric Cheng { "allowed-ips", { "--", 0 }, 7020dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 7030dc2366fSVenugopal Iyer get_allowedips, check_allowedips, PD_CHECK_ALLOC, 70425ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7050dc2366fSVenugopal Iyer 7060dc2366fSVenugopal Iyer { "allowed-dhcp-cids", { "--", 0 }, 7070dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 7080dc2366fSVenugopal Iyer get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 7090dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7100dc2366fSVenugopal Iyer 7110dc2366fSVenugopal Iyer { "rxrings", { "--", RESET_VAL }, NULL, 0, 7120dc2366fSVenugopal Iyer set_resource, get_rings_range, get_rxrings, check_rings, 0, 7130dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7140dc2366fSVenugopal Iyer 7150dc2366fSVenugopal Iyer { "rxrings-effective", { "--", 0 }, 7160dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 7170dc2366fSVenugopal Iyer get_rxrings, NULL, 0, 7180dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7190dc2366fSVenugopal Iyer 7200dc2366fSVenugopal Iyer { "txrings", { "--", RESET_VAL }, NULL, 0, 7210dc2366fSVenugopal Iyer set_resource, get_rings_range, get_txrings, check_rings, 0, 7220dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7230dc2366fSVenugopal Iyer 7240dc2366fSVenugopal Iyer { "txrings-effective", { "--", 0 }, 7250dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 7260dc2366fSVenugopal Iyer get_txrings, NULL, 0, 7270dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7280dc2366fSVenugopal Iyer 7290dc2366fSVenugopal Iyer { "txrings-available", { "", 0 }, NULL, 0, 7300dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7310dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7320dc2366fSVenugopal Iyer 7330dc2366fSVenugopal Iyer { "rxrings-available", { "", 0 }, NULL, 0, 7340dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7350dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7360dc2366fSVenugopal Iyer 7370dc2366fSVenugopal Iyer { "rxhwclnt-available", { "", 0 }, NULL, 0, 7380dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7390dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7400dc2366fSVenugopal Iyer 7410dc2366fSVenugopal Iyer { "txhwclnt-available", { "", 0 }, NULL, 0, 7420dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 7430dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7440dc2366fSVenugopal Iyer 745f4b3ec61Sdh155122 }; 746f4b3ec61Sdh155122 747d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 7480ba2cbe9Sxc151355 749da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 7500dc2366fSVenugopal Iyer {"maxbw", extract_maxbw}, 7510dc2366fSVenugopal Iyer {"priority", extract_priority}, 7520dc2366fSVenugopal Iyer {"cpus", extract_cpus}, 7530dc2366fSVenugopal Iyer {"cpus-effective", extract_cpus}, 7540dc2366fSVenugopal Iyer {"pool", extract_pool}, 7550dc2366fSVenugopal Iyer {"pool-effective", extract_pool}, 7560dc2366fSVenugopal Iyer {"protection", extract_protection}, 7570dc2366fSVenugopal Iyer {"allowed-ips", extract_allowedips}, 7580dc2366fSVenugopal Iyer {"allowed-dhcp-cids", extract_allowedcids}, 7590dc2366fSVenugopal Iyer {"rxrings", extract_rxrings}, 7600dc2366fSVenugopal Iyer {"rxrings-effective", extract_rxrings}, 7610dc2366fSVenugopal Iyer {"txrings", extract_txrings}, 7620dc2366fSVenugopal Iyer {"txrings-effective", extract_txrings} 763da14cebeSEric Cheng }; 764da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 765da14cebeSEric Cheng sizeof (resource_prop_t)) 766da14cebeSEric Cheng 767bcb5c89dSSowmini Varadhan /* 768bcb5c89dSSowmini Varadhan * when retrieving private properties, we pass down a buffer with 769bcb5c89dSSowmini Varadhan * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 770bcb5c89dSSowmini Varadhan */ 771bcb5c89dSSowmini Varadhan #define DLADM_PROP_BUF_CHUNK 1024 772bcb5c89dSSowmini Varadhan 7734ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 7744ac67f02SAnurag S. Maskey const char *, char **, uint_t); 7754ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 7764ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 77762ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 77862ee1d25SArtem Kachitchkine datalink_id_t, void *, int (*)(dladm_handle_t, 77962ee1d25SArtem Kachitchkine datalink_id_t, const char *, void *)); 7804ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 7814ac67f02SAnurag S. Maskey datalink_class_t, uint32_t, prop_desc_t *, char **, 7824ac67f02SAnurag S. Maskey uint_t, uint_t); 7834ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 7844ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 7854ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 7864ac67f02SAnurag S. Maskey datalink_id_t, datalink_media_t, uint_t); 787da14cebeSEric Cheng 788d62bc4baSyz147064 /* 789d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 790d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 791d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 792d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 793d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 794d62bc4baSyz147064 */ 795d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 796d62bc4baSyz147064 797d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 798d62bc4baSyz147064 #define AP_DELIMITER '.' 799d62bc4baSyz147064 80025ec3e3dSEric Cheng /* ARGSUSED */ 801d62bc4baSyz147064 static dladm_status_t 8020dc2366fSVenugopal Iyer check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 803c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 8040dc2366fSVenugopal Iyer datalink_media_t media) 8050ba2cbe9Sxc151355 { 806d62bc4baSyz147064 int i, j; 807c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 808c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 8090ba2cbe9Sxc151355 810d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 811d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 81225ec3e3dSEric Cheng if (strcasecmp(prop_val[j], 813d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 8140ba2cbe9Sxc151355 break; 8150ba2cbe9Sxc151355 } 8160ba2cbe9Sxc151355 } 81725ec3e3dSEric Cheng if (i == pdp->pd_noptval) 81825ec3e3dSEric Cheng return (DLADM_STATUS_BADVAL); 8190ba2cbe9Sxc151355 82025ec3e3dSEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 82125ec3e3dSEric Cheng } 82225ec3e3dSEric Cheng return (DLADM_STATUS_OK); 8230ba2cbe9Sxc151355 } 8240ba2cbe9Sxc151355 8250ba2cbe9Sxc151355 static dladm_status_t 8264ac67f02SAnurag S. Maskey i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 8274ac67f02SAnurag S. Maskey datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 8284ac67f02SAnurag S. Maskey uint_t val_cnt, uint_t flags) 8290ba2cbe9Sxc151355 { 8300ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 831d62bc4baSyz147064 val_desc_t *vdp = NULL; 832d62bc4baSyz147064 boolean_t needfree = B_FALSE; 833d62bc4baSyz147064 uint_t cnt, i; 8340ba2cbe9Sxc151355 835d62bc4baSyz147064 if (!(pdp->pd_class & class)) 836d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 8370ba2cbe9Sxc151355 838d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 839d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 840d62bc4baSyz147064 841d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 842d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 843d62bc4baSyz147064 844d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 845d62bc4baSyz147064 return (DLADM_STATUS_OK); 846d62bc4baSyz147064 847d62bc4baSyz147064 if (pdp->pd_set == NULL) 848d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 849d62bc4baSyz147064 850d62bc4baSyz147064 if (prop_val != NULL) { 8510dc2366fSVenugopal Iyer vdp = calloc(val_cnt, sizeof (val_desc_t)); 852d62bc4baSyz147064 if (vdp == NULL) 853d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 854d62bc4baSyz147064 855d62bc4baSyz147064 if (pdp->pd_check != NULL) { 856da14cebeSEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 8574ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, prop_val, 858c569ef53SMichael Lim &val_cnt, flags, &vdp, media); 859d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 8600dc2366fSVenugopal Iyer status = check_prop(handle, pdp, linkid, prop_val, 861c569ef53SMichael Lim &val_cnt, flags, &vdp, media); 862d62bc4baSyz147064 } else { 863d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 8640ba2cbe9Sxc151355 } 8650ba2cbe9Sxc151355 866d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 867d62bc4baSyz147064 goto done; 868d62bc4baSyz147064 869d62bc4baSyz147064 cnt = val_cnt; 870d62bc4baSyz147064 } else { 871da14cebeSEric Cheng boolean_t defval = B_FALSE; 872da14cebeSEric Cheng 873d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 874d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 875d62bc4baSyz147064 8763bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 877da14cebeSEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 878da14cebeSEric Cheng if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 || defval) { 8790dc2366fSVenugopal Iyer if ((vdp = calloc(1, sizeof (val_desc_t))) == NULL) 880d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 8813bc21d0aSAruna Ramakrishna - Sun Microsystems 882da14cebeSEric Cheng if (defval) { 883da14cebeSEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 884da14cebeSEric Cheng sizeof (val_desc_t)); 885da14cebeSEric Cheng } else if (pdp->pd_check != NULL) { 8864ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, 887c569ef53SMichael Lim prop_val, &cnt, flags, &vdp, media); 8883bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 8893bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 8903bc21d0aSAruna Ramakrishna - Sun Microsystems } 8914045d941Ssowmini } else { 8924ac67f02SAnurag S. Maskey status = i_dladm_getset_defval(handle, pdp, linkid, 8934045d941Ssowmini media, flags); 8944045d941Ssowmini return (status); 8954045d941Ssowmini } 896d62bc4baSyz147064 } 8974eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_AFTER_PERM) 8984eaa4710SRishi Srivatsavai status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 8994eaa4710SRishi Srivatsavai DLADM_STATUS_PERMONLY; 9004eaa4710SRishi Srivatsavai else 9014eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 9024eaa4710SRishi Srivatsavai media); 903d62bc4baSyz147064 if (needfree) { 904d62bc4baSyz147064 for (i = 0; i < cnt; i++) 905e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 906d62bc4baSyz147064 } 907d62bc4baSyz147064 done: 908d62bc4baSyz147064 free(vdp); 909d62bc4baSyz147064 return (status); 910d62bc4baSyz147064 } 911d62bc4baSyz147064 912d62bc4baSyz147064 static dladm_status_t 9134ac67f02SAnurag S. Maskey i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9144ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 915d62bc4baSyz147064 { 916d62bc4baSyz147064 int i; 917d62bc4baSyz147064 boolean_t found = B_FALSE; 918d62bc4baSyz147064 datalink_class_t class; 919d62bc4baSyz147064 uint32_t media; 920d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 921d62bc4baSyz147064 9224ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 9234ac67f02SAnurag S. Maskey NULL, 0); 924d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 9250ba2cbe9Sxc151355 return (status); 9260ba2cbe9Sxc151355 927d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 928d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 929d62bc4baSyz147064 dladm_status_t s; 9300ba2cbe9Sxc151355 931d62bc4baSyz147064 if (prop_name != NULL && 932d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 933d62bc4baSyz147064 continue; 934d62bc4baSyz147064 found = B_TRUE; 9354ac67f02SAnurag S. Maskey s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 9364ac67f02SAnurag S. Maskey prop_val, val_cnt, flags); 937d62bc4baSyz147064 938d62bc4baSyz147064 if (prop_name != NULL) { 939d62bc4baSyz147064 status = s; 940d62bc4baSyz147064 break; 941d62bc4baSyz147064 } else { 942d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 943d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 944d62bc4baSyz147064 status = s; 945d62bc4baSyz147064 } 946d62bc4baSyz147064 } 947e7801d59Ssowmini if (!found) { 948e7801d59Ssowmini if (prop_name[0] == '_') { 949e7801d59Ssowmini /* other private properties */ 9503361618bSRishi Srivatsavai status = i_dladm_set_private_prop(handle, linkid, 9513361618bSRishi Srivatsavai prop_name, prop_val, val_cnt, flags); 952e7801d59Ssowmini } else { 9530ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 954e7801d59Ssowmini } 955e7801d59Ssowmini } 9560ba2cbe9Sxc151355 return (status); 9570ba2cbe9Sxc151355 } 9580ba2cbe9Sxc151355 959d62bc4baSyz147064 /* 960d62bc4baSyz147064 * Set/reset link property for specific link 961d62bc4baSyz147064 */ 962d62bc4baSyz147064 dladm_status_t 9634ac67f02SAnurag S. Maskey dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 9644ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 9650ba2cbe9Sxc151355 { 966d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 9670ba2cbe9Sxc151355 968d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 969d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 970d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 971d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 972d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 9730ba2cbe9Sxc151355 } 9740ba2cbe9Sxc151355 9753361618bSRishi Srivatsavai /* 9763361618bSRishi Srivatsavai * Check for valid link property against the flags passed 9773361618bSRishi Srivatsavai * and set the link property when active flag is passed. 9783361618bSRishi Srivatsavai */ 9794ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 980d62bc4baSyz147064 val_cnt, flags); 981d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 982d62bc4baSyz147064 return (status); 983d62bc4baSyz147064 984d62bc4baSyz147064 if (flags & DLADM_OPT_PERSIST) { 9854ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 986d62bc4baSyz147064 prop_val, val_cnt); 9874eaa4710SRishi Srivatsavai 9884eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 9894eaa4710SRishi Srivatsavai prop_desc_t *pdp = prop_table; 9904eaa4710SRishi Srivatsavai int i; 9914eaa4710SRishi Srivatsavai 9924eaa4710SRishi Srivatsavai for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 9934eaa4710SRishi Srivatsavai if (!(pdp->pd_flags & PD_AFTER_PERM)) 9944eaa4710SRishi Srivatsavai continue; 9954eaa4710SRishi Srivatsavai if (prop_name != NULL && 9964eaa4710SRishi Srivatsavai strcasecmp(prop_name, pdp->pd_name) != 0) 9974eaa4710SRishi Srivatsavai continue; 9984eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, NULL, 9994eaa4710SRishi Srivatsavai 0, flags, 0); 10004eaa4710SRishi Srivatsavai } 10014eaa4710SRishi Srivatsavai } 1002d62bc4baSyz147064 } 1003d62bc4baSyz147064 return (status); 1004d62bc4baSyz147064 } 1005d62bc4baSyz147064 1006d62bc4baSyz147064 /* 100762ee1d25SArtem Kachitchkine * Walk all link properties of the given specific link. 100862ee1d25SArtem Kachitchkine * 100962ee1d25SArtem Kachitchkine * Note: this function currently lacks the ability to walk _all_ private 101062ee1d25SArtem Kachitchkine * properties if the link, because there is no kernel interface to 101162ee1d25SArtem Kachitchkine * retrieve all known private property names. Once such an interface 101262ee1d25SArtem Kachitchkine * is added, this function should be fixed accordingly. 1013d62bc4baSyz147064 */ 1014d62bc4baSyz147064 dladm_status_t 10154ac67f02SAnurag S. Maskey dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 10164ac67f02SAnurag S. Maskey int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 10170ba2cbe9Sxc151355 { 1018d62bc4baSyz147064 dladm_status_t status; 1019d62bc4baSyz147064 datalink_class_t class; 1020d62bc4baSyz147064 uint_t media; 1021d62bc4baSyz147064 int i; 10220ba2cbe9Sxc151355 1023d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 1024d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 10250ba2cbe9Sxc151355 10264ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 10274ac67f02SAnurag S. Maskey NULL, 0); 1028d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1029d62bc4baSyz147064 return (status); 1030d62bc4baSyz147064 103162ee1d25SArtem Kachitchkine /* public */ 1032d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 1033d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 1034d62bc4baSyz147064 continue; 1035d62bc4baSyz147064 1036d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 1037d62bc4baSyz147064 continue; 1038d62bc4baSyz147064 10394ac67f02SAnurag S. Maskey if (func(handle, linkid, prop_table[i].pd_name, arg) == 1040d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 1041d62bc4baSyz147064 break; 1042d62bc4baSyz147064 } 1043d62bc4baSyz147064 } 1044d62bc4baSyz147064 104562ee1d25SArtem Kachitchkine /* private */ 104662ee1d25SArtem Kachitchkine status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 104762ee1d25SArtem Kachitchkine 104862ee1d25SArtem Kachitchkine return (status); 1049d62bc4baSyz147064 } 1050d62bc4baSyz147064 1051d62bc4baSyz147064 /* 1052d62bc4baSyz147064 * Get linkprop of the given specific link. 1053d62bc4baSyz147064 */ 1054d62bc4baSyz147064 dladm_status_t 10554ac67f02SAnurag S. Maskey dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10564ac67f02SAnurag S. Maskey dladm_prop_type_t type, const char *prop_name, char **prop_val, 10574ac67f02SAnurag S. Maskey uint_t *val_cntp) 1058d62bc4baSyz147064 { 1059d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1060d62bc4baSyz147064 datalink_class_t class; 1061d62bc4baSyz147064 uint_t media; 1062d62bc4baSyz147064 prop_desc_t *pdp; 10634045d941Ssowmini uint_t cnt, dld_flags = 0; 1064d62bc4baSyz147064 int i; 1065afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 1066d62bc4baSyz147064 10674045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 10680dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_DEFAULT; 1069f0f2c3a5SGirish Moodalbail else if (type == DLADM_PROP_VAL_MODIFIABLE) 10700dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_POSSIBLE; 10714045d941Ssowmini 1072d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 1073d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 1074d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1075d62bc4baSyz147064 1076d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 1077d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 1078d62bc4baSyz147064 break; 1079d62bc4baSyz147064 1080e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 1081e7801d59Ssowmini if (prop_name[0] == '_') { 1082e7801d59Ssowmini /* 1083e7801d59Ssowmini * private property. 1084e7801d59Ssowmini */ 108562ee1d25SArtem Kachitchkine if (type == DLADM_PROP_VAL_PERSISTENT) 108662ee1d25SArtem Kachitchkine return (i_dladm_get_linkprop_db(handle, linkid, 108762ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp)); 108862ee1d25SArtem Kachitchkine else 108962ee1d25SArtem Kachitchkine return (i_dladm_get_priv_prop(handle, linkid, 109062ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp, type, 109162ee1d25SArtem Kachitchkine dld_flags)); 1092e7801d59Ssowmini } else { 1093d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 1094e7801d59Ssowmini } 1095e7801d59Ssowmini } 1096d62bc4baSyz147064 1097d62bc4baSyz147064 pdp = &prop_table[i]; 1098d62bc4baSyz147064 10994ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 11004ac67f02SAnurag S. Maskey NULL, 0); 1101d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1102d62bc4baSyz147064 return (status); 1103d62bc4baSyz147064 1104d62bc4baSyz147064 if (!(pdp->pd_class & class)) 1105d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1106d62bc4baSyz147064 1107d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 1108d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1109d62bc4baSyz147064 1110d62bc4baSyz147064 switch (type) { 1111d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 11124ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 11134ac67f02SAnurag S. Maskey media, dld_flags, &perm_flags); 1114afdda45fSVasumathi Sundaram - Sun Microsystems break; 1115afdda45fSVasumathi Sundaram - Sun Microsystems 1116afdda45fSVasumathi Sundaram - Sun Microsystems case DLADM_PROP_VAL_PERM: 1117afdda45fSVasumathi Sundaram - Sun Microsystems if (pdp->pd_set == NULL) { 1118afdda45fSVasumathi Sundaram - Sun Microsystems perm_flags = MAC_PROP_PERM_READ; 1119afdda45fSVasumathi Sundaram - Sun Microsystems } else { 11204ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 11214ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 1122afdda45fSVasumathi Sundaram - Sun Microsystems } 1123afdda45fSVasumathi Sundaram - Sun Microsystems 1124afdda45fSVasumathi Sundaram - Sun Microsystems *prop_val[0] = '\0'; 112563a6526dSMichael Lim *val_cntp = 1; 1126da14cebeSEric Cheng if (status == DLADM_STATUS_OK) 1127da14cebeSEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 1128d62bc4baSyz147064 break; 1129d62bc4baSyz147064 1130d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 113113a55820Sar224390 /* 113213a55820Sar224390 * If defaults are not defined for the property, 113313a55820Sar224390 * pd_defval.vd_name should be null. If the driver 113413a55820Sar224390 * has to be contacted for the value, vd_name should 113513a55820Sar224390 * be the empty string (""). Otherwise, dladm will 113613a55820Sar224390 * just print whatever is in the table. 113713a55820Sar224390 */ 1138d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 1139d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1140d62bc4baSyz147064 break; 1141d62bc4baSyz147064 } 11424045d941Ssowmini 11434045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 11444ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 11454ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 11464045d941Ssowmini } else { 1147d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 11484045d941Ssowmini } 1149d62bc4baSyz147064 *val_cntp = 1; 1150d62bc4baSyz147064 break; 1151d62bc4baSyz147064 1152d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 1153d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 11544ac67f02SAnurag S. Maskey status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 1155afdda45fSVasumathi Sundaram - Sun Microsystems val_cntp, media, dld_flags, &perm_flags); 1156d62bc4baSyz147064 break; 1157d62bc4baSyz147064 } 1158d62bc4baSyz147064 cnt = pdp->pd_noptval; 1159d62bc4baSyz147064 if (cnt == 0) { 1160d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1161d62bc4baSyz147064 } else if (cnt > *val_cntp) { 1162d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1163d62bc4baSyz147064 } else { 1164d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 1165d62bc4baSyz147064 (void) strcpy(prop_val[i], 1166d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 1167d62bc4baSyz147064 } 1168d62bc4baSyz147064 *val_cntp = cnt; 1169d62bc4baSyz147064 } 1170d62bc4baSyz147064 break; 1171d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 1172d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 1173d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 11744ac67f02SAnurag S. Maskey status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 1175d62bc4baSyz147064 prop_val, val_cntp); 1176d62bc4baSyz147064 break; 1177d62bc4baSyz147064 default: 1178d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 1179d62bc4baSyz147064 break; 1180d62bc4baSyz147064 } 1181d62bc4baSyz147064 1182d62bc4baSyz147064 return (status); 1183d62bc4baSyz147064 } 1184d62bc4baSyz147064 11854eaa4710SRishi Srivatsavai /* 11864eaa4710SRishi Srivatsavai * Get linkprop of the given specific link and run any possible conversion 11874eaa4710SRishi Srivatsavai * of the values using the check function for the property. Fails if the 11884eaa4710SRishi Srivatsavai * check function doesn't succeed for the property value. 11894eaa4710SRishi Srivatsavai */ 11904eaa4710SRishi Srivatsavai dladm_status_t 11914eaa4710SRishi Srivatsavai dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 11924eaa4710SRishi Srivatsavai dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 11934eaa4710SRishi Srivatsavai uint_t *val_cntp) 11944eaa4710SRishi Srivatsavai { 11954eaa4710SRishi Srivatsavai dladm_status_t status; 11964eaa4710SRishi Srivatsavai datalink_class_t class; 11974eaa4710SRishi Srivatsavai uint_t media; 11984eaa4710SRishi Srivatsavai prop_desc_t *pdp; 11994eaa4710SRishi Srivatsavai uint_t dld_flags; 12004eaa4710SRishi Srivatsavai int valc, i; 12014eaa4710SRishi Srivatsavai char **prop_val; 12024eaa4710SRishi Srivatsavai uint_t perm_flags; 12034eaa4710SRishi Srivatsavai 12044eaa4710SRishi Srivatsavai if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 12054eaa4710SRishi Srivatsavai ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 12064eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12074eaa4710SRishi Srivatsavai 12084eaa4710SRishi Srivatsavai for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 12094eaa4710SRishi Srivatsavai if (strcasecmp(prop_name, pdp->pd_name) == 0) 12104eaa4710SRishi Srivatsavai break; 12114eaa4710SRishi Srivatsavai 12124eaa4710SRishi Srivatsavai if (pdp == prop_table + DLADM_MAX_PROPS) 12134eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 12144eaa4710SRishi Srivatsavai 12154eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_CHECK_ALLOC) 12164eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12174eaa4710SRishi Srivatsavai 12184eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 12194eaa4710SRishi Srivatsavai NULL, 0); 12204eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 12214eaa4710SRishi Srivatsavai return (status); 12224eaa4710SRishi Srivatsavai 12234eaa4710SRishi Srivatsavai if (!(pdp->pd_class & class)) 12244eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12254eaa4710SRishi Srivatsavai 12264eaa4710SRishi Srivatsavai if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 12274eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 12284eaa4710SRishi Srivatsavai 12294eaa4710SRishi Srivatsavai prop_val = malloc(*val_cntp * sizeof (*prop_val) + 12304eaa4710SRishi Srivatsavai *val_cntp * DLADM_PROP_VAL_MAX); 12314eaa4710SRishi Srivatsavai if (prop_val == NULL) 12324eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOMEM); 12334eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 12344eaa4710SRishi Srivatsavai prop_val[valc] = (char *)(prop_val + *val_cntp) + 12354eaa4710SRishi Srivatsavai valc * DLADM_PROP_VAL_MAX; 12364eaa4710SRishi Srivatsavai 12370dc2366fSVenugopal Iyer dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 12384eaa4710SRishi Srivatsavai 12394eaa4710SRishi Srivatsavai switch (type) { 12404eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_CURRENT: 12414eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12424eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 12434eaa4710SRishi Srivatsavai break; 12444eaa4710SRishi Srivatsavai 12454eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_DEFAULT: 12464eaa4710SRishi Srivatsavai /* 12474eaa4710SRishi Srivatsavai * If defaults are not defined for the property, 12484eaa4710SRishi Srivatsavai * pd_defval.vd_name should be null. If the driver 12494eaa4710SRishi Srivatsavai * has to be contacted for the value, vd_name should 12504eaa4710SRishi Srivatsavai * be the empty string (""). Otherwise, dladm will 12514eaa4710SRishi Srivatsavai * just print whatever is in the table. 12524eaa4710SRishi Srivatsavai */ 12534eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name == NULL) { 12544eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOTSUP; 12554eaa4710SRishi Srivatsavai break; 12564eaa4710SRishi Srivatsavai } 12574eaa4710SRishi Srivatsavai 12584eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name[0] != '\0') { 12594eaa4710SRishi Srivatsavai *val_cntp = 1; 12604eaa4710SRishi Srivatsavai *ret_val = pdp->pd_defval.vd_val; 12614eaa4710SRishi Srivatsavai free(prop_val); 12624eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 12634eaa4710SRishi Srivatsavai } 12644eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12654eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 12664eaa4710SRishi Srivatsavai break; 12674eaa4710SRishi Srivatsavai 12684eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_PERSISTENT: 12694eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_TEMPONLY) 12704eaa4710SRishi Srivatsavai status = DLADM_STATUS_TEMPONLY; 12714eaa4710SRishi Srivatsavai else 12724eaa4710SRishi Srivatsavai status = i_dladm_get_linkprop_db(handle, linkid, 12734eaa4710SRishi Srivatsavai prop_name, prop_val, val_cntp); 12744eaa4710SRishi Srivatsavai break; 12754eaa4710SRishi Srivatsavai 12764eaa4710SRishi Srivatsavai default: 12774eaa4710SRishi Srivatsavai status = DLADM_STATUS_BADARG; 12784eaa4710SRishi Srivatsavai break; 12794eaa4710SRishi Srivatsavai } 12804eaa4710SRishi Srivatsavai 12814eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 12824eaa4710SRishi Srivatsavai if (pdp->pd_check != NULL) { 12834eaa4710SRishi Srivatsavai val_desc_t *vdp; 12844eaa4710SRishi Srivatsavai 12854eaa4710SRishi Srivatsavai vdp = malloc(sizeof (val_desc_t) * *val_cntp); 12864eaa4710SRishi Srivatsavai if (vdp == NULL) 12874eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOMEM; 12884eaa4710SRishi Srivatsavai else 12894eaa4710SRishi Srivatsavai status = pdp->pd_check(handle, pdp, linkid, 1290c569ef53SMichael Lim prop_val, val_cntp, 0, &vdp, media); 12914eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 12924eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 12934eaa4710SRishi Srivatsavai ret_val[valc] = vdp[valc].vd_val; 12944eaa4710SRishi Srivatsavai } 12954eaa4710SRishi Srivatsavai free(vdp); 12964eaa4710SRishi Srivatsavai } else { 12974eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) { 12984eaa4710SRishi Srivatsavai for (i = 0; i < pdp->pd_noptval; i++) { 12994eaa4710SRishi Srivatsavai if (strcmp(pdp->pd_optval[i].vd_name, 13004eaa4710SRishi Srivatsavai prop_val[valc]) == 0) { 13014eaa4710SRishi Srivatsavai ret_val[valc] = 13024eaa4710SRishi Srivatsavai pdp->pd_optval[i].vd_val; 13034eaa4710SRishi Srivatsavai break; 13044eaa4710SRishi Srivatsavai } 13054eaa4710SRishi Srivatsavai } 13064eaa4710SRishi Srivatsavai if (i == pdp->pd_noptval) { 13074eaa4710SRishi Srivatsavai status = DLADM_STATUS_FAILED; 13084eaa4710SRishi Srivatsavai break; 13094eaa4710SRishi Srivatsavai } 13104eaa4710SRishi Srivatsavai } 13114eaa4710SRishi Srivatsavai } 13124eaa4710SRishi Srivatsavai } 13134eaa4710SRishi Srivatsavai 13144eaa4710SRishi Srivatsavai free(prop_val); 13154eaa4710SRishi Srivatsavai 13164eaa4710SRishi Srivatsavai return (status); 13174eaa4710SRishi Srivatsavai } 13184eaa4710SRishi Srivatsavai 1319d62bc4baSyz147064 /*ARGSUSED*/ 1320d62bc4baSyz147064 static int 13214ac67f02SAnurag S. Maskey i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 13224ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 1323d62bc4baSyz147064 { 1324d62bc4baSyz147064 char *buf, **propvals; 1325d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 13260dc2366fSVenugopal Iyer dladm_status_t status; 13270dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla = arg; 1328d62bc4baSyz147064 1329d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 1330d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 1331d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1332d62bc4baSyz147064 } 1333d62bc4baSyz147064 1334d62bc4baSyz147064 propvals = (char **)(void *)buf; 1335d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 1336d62bc4baSyz147064 propvals[i] = buf + 1337d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 1338d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 1339d62bc4baSyz147064 } 1340d62bc4baSyz147064 13414ac67f02SAnurag S. Maskey if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 13424ac67f02SAnurag S. Maskey prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 1343d62bc4baSyz147064 goto done; 1344d62bc4baSyz147064 } 1345d62bc4baSyz147064 13468d4cf8d8S status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 13470dc2366fSVenugopal Iyer valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 13480dc2366fSVenugopal Iyer 13498d4cf8d8S if (status != DLADM_STATUS_OK) 13500dc2366fSVenugopal Iyer dla->dla_status = status; 1351d62bc4baSyz147064 1352d62bc4baSyz147064 done: 1353d62bc4baSyz147064 if (buf != NULL) 1354d62bc4baSyz147064 free(buf); 1355d62bc4baSyz147064 1356d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1357d62bc4baSyz147064 } 1358d62bc4baSyz147064 1359d62bc4baSyz147064 /*ARGSUSED*/ 1360d62bc4baSyz147064 static int 13614ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 1362d62bc4baSyz147064 { 1363da14cebeSEric Cheng datalink_class_t class; 1364da14cebeSEric Cheng dladm_status_t status; 1365da14cebeSEric Cheng 13664ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 13674ac67f02SAnurag S. Maskey NULL, 0); 1368da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1369da14cebeSEric Cheng return (DLADM_WALK_TERMINATE); 1370da14cebeSEric Cheng 1371da14cebeSEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 13724ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, B_TRUE); 1373da14cebeSEric Cheng 1374d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 13750ba2cbe9Sxc151355 } 13760ba2cbe9Sxc151355 13770ba2cbe9Sxc151355 dladm_status_t 13784ac67f02SAnurag S. Maskey dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 13794ac67f02SAnurag S. Maskey boolean_t any_media) 13800ba2cbe9Sxc151355 { 13818d4cf8d8S dladm_status_t status = DLADM_STATUS_OK; 138230890389Sartem datalink_media_t dmedia; 138330890389Sartem uint32_t media; 13840dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla; 138530890389Sartem 138630890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 138730890389Sartem 13880dc2366fSVenugopal Iyer dla = malloc(sizeof (dladm_linkprop_args_t)); 13890dc2366fSVenugopal Iyer if (dla == NULL) 13900dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 13910dc2366fSVenugopal Iyer dla->dla_flags = DLADM_OPT_BOOT; 13920dc2366fSVenugopal Iyer dla->dla_status = DLADM_STATUS_OK; 13930dc2366fSVenugopal Iyer 1394d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 13954ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 13964ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 13974ac67f02SAnurag S. Maskey } else if (any_media || 13984ac67f02SAnurag S. Maskey ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 13994ac67f02SAnurag S. Maskey 0) == DLADM_STATUS_OK) && 140030890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 14010dc2366fSVenugopal Iyer (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 14024ac67f02SAnurag S. Maskey i_dladm_init_one_prop); 14030dc2366fSVenugopal Iyer status = dla->dla_status; 1404d62bc4baSyz147064 } 14050dc2366fSVenugopal Iyer free(dla); 14068d4cf8d8S return (status); 14070ba2cbe9Sxc151355 } 1408f4b3ec61Sdh155122 1409e7801d59Ssowmini /* ARGSUSED */ 1410f4b3ec61Sdh155122 static dladm_status_t 14110dc2366fSVenugopal Iyer get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1412da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1413da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1414f4b3ec61Sdh155122 { 1415d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 1416d62bc4baSyz147064 zoneid_t zid; 1417d62bc4baSyz147064 dladm_status_t status; 1418f4b3ec61Sdh155122 14194045d941Ssowmini if (flags != 0) 14204045d941Ssowmini return (DLADM_STATUS_NOTSUP); 14214045d941Ssowmini 14220dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 14230dc2366fSVenugopal Iyer perm_flags, &zid, sizeof (zid)); 1424d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1425d62bc4baSyz147064 return (status); 1426d62bc4baSyz147064 1427d62bc4baSyz147064 *val_cnt = 1; 1428d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 1429afdda45fSVasumathi Sundaram - Sun Microsystems if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 1430f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1431afdda45fSVasumathi Sundaram - Sun Microsystems } 1432f4b3ec61Sdh155122 1433d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 143447a01978Sbw } else { 1435d62bc4baSyz147064 *prop_val[0] = '\0'; 143647a01978Sbw } 1437f4b3ec61Sdh155122 1438f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1439f4b3ec61Sdh155122 } 1440f4b3ec61Sdh155122 1441f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 1442f4b3ec61Sdh155122 1443f4b3ec61Sdh155122 static int 1444f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 1445f4b3ec61Sdh155122 { 1446f4b3ec61Sdh155122 char root[MAXPATHLEN]; 1447f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 1448f4b3ec61Sdh155122 void *dlhandle; 1449f4b3ec61Sdh155122 void *sym; 1450f4b3ec61Sdh155122 int ret; 1451f4b3ec61Sdh155122 1452f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 1453f4b3ec61Sdh155122 return (-1); 1454f4b3ec61Sdh155122 1455f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 1456f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1457f4b3ec61Sdh155122 return (-1); 1458f4b3ec61Sdh155122 } 1459f4b3ec61Sdh155122 1460f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 1461f4b3ec61Sdh155122 1462f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 1463f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 1464f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1465f4b3ec61Sdh155122 return (ret); 1466f4b3ec61Sdh155122 } 1467f4b3ec61Sdh155122 1468f4b3ec61Sdh155122 static dladm_status_t 14694ac67f02SAnurag S. Maskey i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 14704ac67f02SAnurag S. Maskey datalink_id_t linkid, boolean_t add) 1471f4b3ec61Sdh155122 { 1472f4b3ec61Sdh155122 char path[MAXPATHLEN]; 1473d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1474f4b3ec61Sdh155122 di_prof_t prof = NULL; 1475f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 1476f4b3ec61Sdh155122 dladm_status_t status; 1477d62bc4baSyz147064 int ret; 1478f4b3ec61Sdh155122 1479f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 1480f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1481f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 1482f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1483f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 1484f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1485f4b3ec61Sdh155122 14864ac67f02SAnurag S. Maskey status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 1487f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1488d62bc4baSyz147064 goto cleanup; 1489f4b3ec61Sdh155122 1490d62bc4baSyz147064 if (add) 1491d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 1492d62bc4baSyz147064 else 1493d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 1494f4b3ec61Sdh155122 1495d62bc4baSyz147064 if (ret != 0) { 1496d62bc4baSyz147064 status = dladm_errno2status(errno); 1497d62bc4baSyz147064 goto cleanup; 1498f4b3ec61Sdh155122 } 1499f4b3ec61Sdh155122 1500d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 1501d62bc4baSyz147064 status = dladm_errno2status(errno); 1502d62bc4baSyz147064 cleanup: 1503d62bc4baSyz147064 if (prof) 1504d62bc4baSyz147064 di_prof_fini(prof); 1505d62bc4baSyz147064 1506d62bc4baSyz147064 return (status); 1507f4b3ec61Sdh155122 } 1508f4b3ec61Sdh155122 1509e7801d59Ssowmini /* ARGSUSED */ 1510f4b3ec61Sdh155122 static dladm_status_t 15110dc2366fSVenugopal Iyer set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 15124ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1513f4b3ec61Sdh155122 { 15143bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1515f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 15163bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1517f4b3ec61Sdh155122 1518f4b3ec61Sdh155122 if (val_cnt != 1) 1519f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1520f4b3ec61Sdh155122 15213bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 15223bc21d0aSAruna Ramakrishna - Sun Microsystems 15230dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15240dc2366fSVenugopal Iyer NULL, &zid_old, sizeof (zid_old)); 1525f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1526f4b3ec61Sdh155122 return (status); 1527f4b3ec61Sdh155122 15283bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 15293bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 15302b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 15312b24ab6bSSebastien Roy 15320dc2366fSVenugopal Iyer if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 15332b24ab6bSSebastien Roy flags, media)) != DLADM_STATUS_OK) 15343bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 15353bc21d0aSAruna Ramakrishna - Sun Microsystems 1536d62bc4baSyz147064 /* 15372b24ab6bSSebastien Roy * It is okay to fail to update the /dev entry (some vanity-named 15382b24ab6bSSebastien Roy * links do not have a /dev entry). 1539d62bc4baSyz147064 */ 1540d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 15414ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_old, linkid, 15424ac67f02SAnurag S. Maskey B_FALSE); 1543d62bc4baSyz147064 } 15442b24ab6bSSebastien Roy if (zid_new != GLOBAL_ZONEID) 15454ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 1546f4b3ec61Sdh155122 1547f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1548f4b3ec61Sdh155122 } 1549f4b3ec61Sdh155122 1550f4b3ec61Sdh155122 /* ARGSUSED */ 1551f4b3ec61Sdh155122 static dladm_status_t 15520dc2366fSVenugopal Iyer check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1553c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 15540dc2366fSVenugopal Iyer datalink_media_t media) 1555f4b3ec61Sdh155122 { 15563bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 15573bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 15583bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 15593bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1560c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1561c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1562f4b3ec61Sdh155122 1563f4b3ec61Sdh155122 if (val_cnt != 1) 1564f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1565f4b3ec61Sdh155122 15663bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 15673bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 15683bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1569f4b3ec61Sdh155122 1570da14cebeSEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 15713bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 15723bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 15733bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 15743bc21d0aSAruna Ramakrishna - Sun Microsystems } 15753bc21d0aSAruna Ramakrishna - Sun Microsystems 15763bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1577f4b3ec61Sdh155122 ushort_t flags; 1578f4b3ec61Sdh155122 15793bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1580f4b3ec61Sdh155122 sizeof (flags)) < 0) { 15813bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 15823bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1583f4b3ec61Sdh155122 } 1584f4b3ec61Sdh155122 1585f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 15863bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 15873bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1588f4b3ec61Sdh155122 } 1589f4b3ec61Sdh155122 } 1590f4b3ec61Sdh155122 15913bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 15923bc21d0aSAruna Ramakrishna - Sun Microsystems 15933bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 15942b24ab6bSSebastien Roy dzp->diz_linkid = linkid; 15953bc21d0aSAruna Ramakrishna - Sun Microsystems 15963bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1597f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 15983bc21d0aSAruna Ramakrishna - Sun Microsystems done: 15993bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 16003bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1601f4b3ec61Sdh155122 } 1602f4b3ec61Sdh155122 1603e7801d59Ssowmini /* ARGSUSED */ 1604f4b3ec61Sdh155122 static dladm_status_t 16050dc2366fSVenugopal Iyer get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1606da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1607da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1608da14cebeSEric Cheng { 1609da14cebeSEric Cheng mac_resource_props_t mrp; 1610da14cebeSEric Cheng dladm_status_t status; 1611da14cebeSEric Cheng 16120dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 16130dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 16140dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1615da14cebeSEric Cheng return (status); 1616da14cebeSEric Cheng 1617da14cebeSEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 16180dc2366fSVenugopal Iyer *val_cnt = 0; 16190dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1620da14cebeSEric Cheng } 16210dc2366fSVenugopal Iyer 16220dc2366fSVenugopal Iyer (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 1623da14cebeSEric Cheng *val_cnt = 1; 1624da14cebeSEric Cheng return (DLADM_STATUS_OK); 1625da14cebeSEric Cheng } 1626da14cebeSEric Cheng 1627da14cebeSEric Cheng /* ARGSUSED */ 1628da14cebeSEric Cheng static dladm_status_t 16290dc2366fSVenugopal Iyer check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1630c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 16310dc2366fSVenugopal Iyer datalink_media_t media) 1632da14cebeSEric Cheng { 1633da14cebeSEric Cheng uint64_t *maxbw; 1634da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1635c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1636c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1637da14cebeSEric Cheng 1638da14cebeSEric Cheng if (val_cnt != 1) 1639da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1640da14cebeSEric Cheng 1641da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 1642da14cebeSEric Cheng if (maxbw == NULL) 1643da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1644da14cebeSEric Cheng 1645da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 1646da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1647da14cebeSEric Cheng free(maxbw); 1648da14cebeSEric Cheng return (status); 1649da14cebeSEric Cheng } 1650da14cebeSEric Cheng 1651da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 1652da14cebeSEric Cheng free(maxbw); 1653da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 1654da14cebeSEric Cheng } 1655da14cebeSEric Cheng 1656da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 1657da14cebeSEric Cheng return (DLADM_STATUS_OK); 1658da14cebeSEric Cheng } 1659da14cebeSEric Cheng 1660da14cebeSEric Cheng /* ARGSUSED */ 1661da14cebeSEric Cheng dladm_status_t 16620dc2366fSVenugopal Iyer extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 1663da14cebeSEric Cheng { 166425ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1665da14cebeSEric Cheng 16660dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 16670dc2366fSVenugopal Iyer mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 16680dc2366fSVenugopal Iyer } else { 1669da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 16700dc2366fSVenugopal Iyer } 1671da14cebeSEric Cheng mrp->mrp_mask |= MRP_MAXBW; 1672da14cebeSEric Cheng 1673da14cebeSEric Cheng return (DLADM_STATUS_OK); 1674da14cebeSEric Cheng } 1675da14cebeSEric Cheng 1676da14cebeSEric Cheng /* ARGSUSED */ 1677da14cebeSEric Cheng static dladm_status_t 16780dc2366fSVenugopal Iyer get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1679da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1680da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1681da14cebeSEric Cheng { 16820dc2366fSVenugopal Iyer dladm_status_t status; 1683da14cebeSEric Cheng mac_resource_props_t mrp; 1684c569ef53SMichael Lim mac_propval_range_t *pv_range; 1685c569ef53SMichael Lim int err; 1686da14cebeSEric Cheng 16870dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 16880dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 16890dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 16900dc2366fSVenugopal Iyer sizeof (mrp)); 16910dc2366fSVenugopal Iyer } else { 16920dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 16930dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 16940dc2366fSVenugopal Iyer } 16950dc2366fSVenugopal Iyer 16960dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1697da14cebeSEric Cheng return (status); 1698da14cebeSEric Cheng 1699c569ef53SMichael Lim if (mrp.mrp_ncpus > *val_cnt) 1700da14cebeSEric Cheng return (DLADM_STATUS_TOOSMALL); 1701da14cebeSEric Cheng 1702c569ef53SMichael Lim if (mrp.mrp_ncpus == 0) { 17030dc2366fSVenugopal Iyer *val_cnt = 0; 1704da14cebeSEric Cheng return (DLADM_STATUS_OK); 1705da14cebeSEric Cheng } 1706da14cebeSEric Cheng 1707c569ef53SMichael Lim /* Sort CPU list and convert it to a mac_propval_range */ 1708c569ef53SMichael Lim status = dladm_list2range(mrp.mrp_cpu, mrp.mrp_ncpus, 1709c569ef53SMichael Lim MAC_PROPVAL_UINT32, &pv_range); 1710c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1711c569ef53SMichael Lim return (status); 1712c569ef53SMichael Lim 1713c569ef53SMichael Lim /* Write CPU ranges and individual CPUs */ 1714c569ef53SMichael Lim err = dladm_range2strs(pv_range, prop_val); 1715c569ef53SMichael Lim if (err != 0) { 1716c569ef53SMichael Lim free(pv_range); 1717c569ef53SMichael Lim return (dladm_errno2status(err)); 1718da14cebeSEric Cheng } 1719c569ef53SMichael Lim 1720c569ef53SMichael Lim *val_cnt = pv_range->mpr_count; 1721c569ef53SMichael Lim free(pv_range); 1722c569ef53SMichael Lim 1723da14cebeSEric Cheng return (DLADM_STATUS_OK); 1724da14cebeSEric Cheng } 1725da14cebeSEric Cheng 1726da14cebeSEric Cheng /* ARGSUSED */ 1727da14cebeSEric Cheng static dladm_status_t 17280dc2366fSVenugopal Iyer check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1729c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 17300dc2366fSVenugopal Iyer datalink_media_t media) 1731da14cebeSEric Cheng { 1732da14cebeSEric Cheng int i, j, rc; 1733da14cebeSEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 17340dc2366fSVenugopal Iyer mac_resource_props_t mrp; 1735c569ef53SMichael Lim mac_propval_range_t *pv_range; 17360dc2366fSVenugopal Iyer uint_t perm_flags; 1737c569ef53SMichael Lim uint32_t ncpus; 1738c569ef53SMichael Lim uint32_t *cpus = mrp.mrp_cpu; 1739c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1740c569ef53SMichael Lim val_desc_t *newvdp; 1741c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1742c569ef53SMichael Lim dladm_status_t status = DLADM_STATUS_OK; 1743da14cebeSEric Cheng 17440dc2366fSVenugopal Iyer /* Get the current pool property */ 17450dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 17460dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 17470dc2366fSVenugopal Iyer 17480dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 17490dc2366fSVenugopal Iyer /* Can't set cpus if a pool is set */ 17500dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) != 0) 17510dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 17520dc2366fSVenugopal Iyer } 17530dc2366fSVenugopal Iyer 1754c569ef53SMichael Lim /* Read ranges and convert to mac_propval_range */ 1755c569ef53SMichael Lim status = dladm_strs2range(prop_val, val_cnt, MAC_PROPVAL_UINT32, 1756c569ef53SMichael Lim &pv_range); 1757c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1758c569ef53SMichael Lim goto done1; 1759da14cebeSEric Cheng 1760c569ef53SMichael Lim /* Convert mac_propval_range to a single CPU list */ 1761c569ef53SMichael Lim ncpus = MRP_NCPUS; 1762c569ef53SMichael Lim status = dladm_range2list(pv_range, cpus, &ncpus); 1763c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1764c569ef53SMichael Lim goto done1; 17650dc2366fSVenugopal Iyer 1766c569ef53SMichael Lim /* 1767c569ef53SMichael Lim * If a range of CPUs was entered, update value count and reallocate 1768c569ef53SMichael Lim * the array of val_desc_t's. The array allocated was sized for 1769c569ef53SMichael Lim * indvidual elements, but needs to be reallocated to accomodate the 1770c569ef53SMichael Lim * expanded list of CPUs. 1771c569ef53SMichael Lim */ 1772c569ef53SMichael Lim if (val_cnt < ncpus) { 1773c569ef53SMichael Lim newvdp = calloc(*val_cntp, sizeof (val_desc_t)); 1774c569ef53SMichael Lim if (newvdp == NULL) { 1775c569ef53SMichael Lim status = DLADM_STATUS_NOMEM; 1776c569ef53SMichael Lim goto done1; 1777c569ef53SMichael Lim } 1778c569ef53SMichael Lim vdp = newvdp; 1779da14cebeSEric Cheng } 1780da14cebeSEric Cheng 1781c569ef53SMichael Lim /* Check if all CPUs in the list are online */ 1782c569ef53SMichael Lim for (i = 0; i < ncpus; i++) { 1783c569ef53SMichael Lim if (cpus[i] >= nproc) { 1784c569ef53SMichael Lim status = DLADM_STATUS_BADCPUID; 1785c569ef53SMichael Lim goto done2; 1786c569ef53SMichael Lim } 1787c569ef53SMichael Lim 1788c569ef53SMichael Lim rc = p_online(cpus[i], P_STATUS); 1789c569ef53SMichael Lim if (rc < 1) { 1790c569ef53SMichael Lim status = DLADM_STATUS_CPUERR; 1791c569ef53SMichael Lim goto done2; 1792c569ef53SMichael Lim } 1793c569ef53SMichael Lim 1794c569ef53SMichael Lim if (rc != P_ONLINE) { 1795c569ef53SMichael Lim status = DLADM_STATUS_CPUNOTONLINE; 1796c569ef53SMichael Lim goto done2; 1797c569ef53SMichael Lim } 1798c569ef53SMichael Lim 1799c569ef53SMichael Lim vdp[i].vd_val = (uintptr_t)cpus[i]; 1800c569ef53SMichael Lim } 1801c569ef53SMichael Lim 1802c569ef53SMichael Lim /* Check for duplicate CPUs */ 1803c569ef53SMichael Lim for (i = 0; i < *val_cntp; i++) { 1804c569ef53SMichael Lim for (j = 0; j < *val_cntp; j++) { 1805c569ef53SMichael Lim if (i != j && vdp[i].vd_val == vdp[j].vd_val) { 1806c569ef53SMichael Lim status = DLADM_STATUS_BADVAL; 1807c569ef53SMichael Lim goto done2; 1808da14cebeSEric Cheng } 1809da14cebeSEric Cheng } 1810c569ef53SMichael Lim } 1811c569ef53SMichael Lim 1812c569ef53SMichael Lim /* Update *val_cntp and *vdpp if everything was OK */ 1813c569ef53SMichael Lim if (val_cnt < ncpus) { 1814c569ef53SMichael Lim *val_cntp = ncpus; 1815c569ef53SMichael Lim free(*vdpp); 1816c569ef53SMichael Lim *vdpp = newvdp; 1817c569ef53SMichael Lim } 1818c569ef53SMichael Lim 1819c569ef53SMichael Lim status = DLADM_STATUS_OK; 1820c569ef53SMichael Lim goto done1; 1821c569ef53SMichael Lim 1822c569ef53SMichael Lim done2: 1823c569ef53SMichael Lim free(newvdp); 1824c569ef53SMichael Lim done1: 1825c569ef53SMichael Lim free(pv_range); 1826c569ef53SMichael Lim return (status); 1827da14cebeSEric Cheng } 18280dc2366fSVenugopal Iyer 18290dc2366fSVenugopal Iyer /* ARGSUSED */ 18300dc2366fSVenugopal Iyer dladm_status_t 18310dc2366fSVenugopal Iyer extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 18320dc2366fSVenugopal Iyer { 18330dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 18340dc2366fSVenugopal Iyer int i; 18350dc2366fSVenugopal Iyer 18360dc2366fSVenugopal Iyer if (vdp[0].vd_val == RESET_VAL) { 18370dc2366fSVenugopal Iyer bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 18380dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_CPUS; 18390dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 18400dc2366fSVenugopal Iyer } 18410dc2366fSVenugopal Iyer 18420dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) 18430dc2366fSVenugopal Iyer mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 18440dc2366fSVenugopal Iyer 18450dc2366fSVenugopal Iyer mrp->mrp_ncpus = cnt; 18460dc2366fSVenugopal Iyer mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 18470dc2366fSVenugopal Iyer mrp->mrp_fanout_mode = MCM_CPUS; 18480dc2366fSVenugopal Iyer mrp->mrp_rx_intr_cpu = -1; 18490dc2366fSVenugopal Iyer 18500dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 18510dc2366fSVenugopal Iyer } 18520dc2366fSVenugopal Iyer 18530dc2366fSVenugopal Iyer /* 18540dc2366fSVenugopal Iyer * Get the pool datalink property from the kernel. This is used 18550dc2366fSVenugopal Iyer * for both the user specified pool and effective pool properties. 18560dc2366fSVenugopal Iyer */ 18570dc2366fSVenugopal Iyer /* ARGSUSED */ 18580dc2366fSVenugopal Iyer static dladm_status_t 18590dc2366fSVenugopal Iyer get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 18600dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 18610dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 18620dc2366fSVenugopal Iyer { 18630dc2366fSVenugopal Iyer mac_resource_props_t mrp; 18640dc2366fSVenugopal Iyer dladm_status_t status; 18650dc2366fSVenugopal Iyer 18660dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "pool-effective") == 0) { 18670dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 18680dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 18690dc2366fSVenugopal Iyer sizeof (mrp)); 18700dc2366fSVenugopal Iyer } else { 18710dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 18720dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 18730dc2366fSVenugopal Iyer } 18740dc2366fSVenugopal Iyer 18750dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 18760dc2366fSVenugopal Iyer return (status); 18770dc2366fSVenugopal Iyer 18780dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) == 0) { 18790dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 18800dc2366fSVenugopal Iyer } else { 18810dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 18820dc2366fSVenugopal Iyer "%s", mrp.mrp_pool); 18830dc2366fSVenugopal Iyer } 18840dc2366fSVenugopal Iyer *val_cnt = 1; 18850dc2366fSVenugopal Iyer 18860dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 18870dc2366fSVenugopal Iyer } 18880dc2366fSVenugopal Iyer 18890dc2366fSVenugopal Iyer /* ARGSUSED */ 18900dc2366fSVenugopal Iyer static dladm_status_t 18910dc2366fSVenugopal Iyer check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1892c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 18930dc2366fSVenugopal Iyer datalink_media_t media) 18940dc2366fSVenugopal Iyer { 18950dc2366fSVenugopal Iyer pool_conf_t *poolconf; 18960dc2366fSVenugopal Iyer pool_t *pool; 18970dc2366fSVenugopal Iyer mac_resource_props_t mrp; 18980dc2366fSVenugopal Iyer dladm_status_t status; 18990dc2366fSVenugopal Iyer uint_t perm_flags; 19000dc2366fSVenugopal Iyer char *poolname; 1901c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 19020dc2366fSVenugopal Iyer 19030dc2366fSVenugopal Iyer /* Get the current cpus property */ 19040dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 19050dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 19060dc2366fSVenugopal Iyer 19070dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 19080dc2366fSVenugopal Iyer /* Can't set pool if cpus are set */ 19090dc2366fSVenugopal Iyer if (mrp.mrp_ncpus != 0) 19100dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 19110dc2366fSVenugopal Iyer } 19120dc2366fSVenugopal Iyer 19130dc2366fSVenugopal Iyer poolname = malloc(sizeof (mrp.mrp_pool)); 19140dc2366fSVenugopal Iyer if (poolname == NULL) 19150dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 19160dc2366fSVenugopal Iyer 19170dc2366fSVenugopal Iyer /* Check for pool's availability if not booting */ 19180dc2366fSVenugopal Iyer if ((flags & DLADM_OPT_BOOT) == 0) { 19190dc2366fSVenugopal Iyer 19200dc2366fSVenugopal Iyer /* Allocate and open pool configuration */ 19210dc2366fSVenugopal Iyer if ((poolconf = pool_conf_alloc()) == NULL) 19220dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19230dc2366fSVenugopal Iyer 19240dc2366fSVenugopal Iyer if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 19250dc2366fSVenugopal Iyer != PO_SUCCESS) { 19260dc2366fSVenugopal Iyer pool_conf_free(poolconf); 19270dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19280dc2366fSVenugopal Iyer } 19290dc2366fSVenugopal Iyer 19300dc2366fSVenugopal Iyer /* Look for pool name */ 19310dc2366fSVenugopal Iyer if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 19320dc2366fSVenugopal Iyer pool_conf_free(poolconf); 19330dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 19340dc2366fSVenugopal Iyer } 19350dc2366fSVenugopal Iyer 19360dc2366fSVenugopal Iyer pool_conf_free(poolconf); 19370dc2366fSVenugopal Iyer free(pool); 19380dc2366fSVenugopal Iyer } 19390dc2366fSVenugopal Iyer 19400dc2366fSVenugopal Iyer (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 19410dc2366fSVenugopal Iyer vdp->vd_val = (uintptr_t)poolname; 1942da14cebeSEric Cheng 1943da14cebeSEric Cheng return (DLADM_STATUS_OK); 1944da14cebeSEric Cheng } 1945da14cebeSEric Cheng 1946da14cebeSEric Cheng /* ARGSUSED */ 1947da14cebeSEric Cheng dladm_status_t 19480dc2366fSVenugopal Iyer extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 1949da14cebeSEric Cheng { 19500dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 1951da14cebeSEric Cheng 19520dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 19530dc2366fSVenugopal Iyer bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 19540dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 19550dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1956da14cebeSEric Cheng } 19570dc2366fSVenugopal Iyer 19580dc2366fSVenugopal Iyer (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 19590dc2366fSVenugopal Iyer sizeof (mrp->mrp_pool)); 19600dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 19610dc2366fSVenugopal Iyer /* 19620dc2366fSVenugopal Iyer * Use MCM_CPUS since the fanout count is not user specified 19630dc2366fSVenugopal Iyer * and will be determined by the cpu list generated from the 19640dc2366fSVenugopal Iyer * pool. 19650dc2366fSVenugopal Iyer */ 1966da14cebeSEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 1967da14cebeSEric Cheng 1968da14cebeSEric Cheng return (DLADM_STATUS_OK); 1969da14cebeSEric Cheng } 1970da14cebeSEric Cheng 1971da14cebeSEric Cheng /* ARGSUSED */ 1972da14cebeSEric Cheng static dladm_status_t 19730dc2366fSVenugopal Iyer get_priority(dladm_handle_t handle, prop_desc_t *pdp, 197462ee1d25SArtem Kachitchkine datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 197562ee1d25SArtem Kachitchkine datalink_media_t media, uint_t flags, uint_t *perm_flags) 1976da14cebeSEric Cheng { 1977da14cebeSEric Cheng mac_resource_props_t mrp; 1978da14cebeSEric Cheng mac_priority_level_t pri; 1979da14cebeSEric Cheng dladm_status_t status; 1980da14cebeSEric Cheng 19810dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 19820dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 19830dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1984da14cebeSEric Cheng return (status); 1985da14cebeSEric Cheng 1986da14cebeSEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 1987da14cebeSEric Cheng mrp.mrp_priority; 1988da14cebeSEric Cheng 1989da14cebeSEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 1990da14cebeSEric Cheng *val_cnt = 1; 1991da14cebeSEric Cheng return (DLADM_STATUS_OK); 1992da14cebeSEric Cheng } 1993da14cebeSEric Cheng 1994da14cebeSEric Cheng /* ARGSUSED */ 1995da14cebeSEric Cheng dladm_status_t 19960dc2366fSVenugopal Iyer extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 1997da14cebeSEric Cheng { 199825ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1999da14cebeSEric Cheng 20000dc2366fSVenugopal Iyer if (cnt != 1) 20010dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20020dc2366fSVenugopal Iyer 20030dc2366fSVenugopal Iyer mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 2004da14cebeSEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 2005da14cebeSEric Cheng 2006da14cebeSEric Cheng return (DLADM_STATUS_OK); 2007da14cebeSEric Cheng } 2008da14cebeSEric Cheng 20090dc2366fSVenugopal Iyer /* 20100dc2366fSVenugopal Iyer * Determines the size of the structure that needs to be sent to drivers 20110dc2366fSVenugopal Iyer * for retrieving the property range values. 20120dc2366fSVenugopal Iyer */ 20130dc2366fSVenugopal Iyer static int 20140591ddd0SPrakash Jalan i_dladm_range_size(mac_propval_range_t *r, size_t *sz, uint_t *rcount) 20150dc2366fSVenugopal Iyer { 20160dc2366fSVenugopal Iyer uint_t count = r->mpr_count; 20170dc2366fSVenugopal Iyer 20180dc2366fSVenugopal Iyer *sz = sizeof (mac_propval_range_t); 20190591ddd0SPrakash Jalan *rcount = count; 20200dc2366fSVenugopal Iyer --count; 20210dc2366fSVenugopal Iyer 20220dc2366fSVenugopal Iyer switch (r->mpr_type) { 20230dc2366fSVenugopal Iyer case MAC_PROPVAL_UINT32: 20240dc2366fSVenugopal Iyer *sz += (count * sizeof (mac_propval_uint32_range_t)); 20250dc2366fSVenugopal Iyer return (0); 20260dc2366fSVenugopal Iyer default: 20270dc2366fSVenugopal Iyer break; 20280dc2366fSVenugopal Iyer } 20290dc2366fSVenugopal Iyer *sz = 0; 20300591ddd0SPrakash Jalan *rcount = 0; 20310dc2366fSVenugopal Iyer return (EINVAL); 20320dc2366fSVenugopal Iyer } 20330dc2366fSVenugopal Iyer 20340dc2366fSVenugopal Iyer 2035da14cebeSEric Cheng /* ARGSUSED */ 2036da14cebeSEric Cheng static dladm_status_t 20370dc2366fSVenugopal Iyer check_rings(dladm_handle_t handle, prop_desc_t *pdp, 2038c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 2039c569ef53SMichael Lim val_desc_t **vp, datalink_media_t media) 20400dc2366fSVenugopal Iyer { 2041c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2042c569ef53SMichael Lim val_desc_t *v = *vp; 2043c569ef53SMichael Lim 20440dc2366fSVenugopal Iyer if (val_cnt != 1) 20450dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20460dc2366fSVenugopal Iyer if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 20470dc2366fSVenugopal Iyer v->vd_val = UNSPEC_VAL; 20480dc2366fSVenugopal Iyer } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 20490dc2366fSVenugopal Iyer v->vd_val = 0; 20500dc2366fSVenugopal Iyer } else { 20510dc2366fSVenugopal Iyer v->vd_val = strtoul(prop_val[0], NULL, 0); 20520dc2366fSVenugopal Iyer if (v->vd_val == 0) 20530dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20540dc2366fSVenugopal Iyer } 20550dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 20560dc2366fSVenugopal Iyer } 20570dc2366fSVenugopal Iyer 20580dc2366fSVenugopal Iyer /* ARGSUSED */ 20590dc2366fSVenugopal Iyer static dladm_status_t 20600dc2366fSVenugopal Iyer get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 20610dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 20620dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 20630dc2366fSVenugopal Iyer { 20640dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 20650dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 20660dc2366fSVenugopal Iyer mac_propval_range_t *rangep; 20670dc2366fSVenugopal Iyer size_t sz; 20680dc2366fSVenugopal Iyer mac_propval_uint32_range_t *ur; 20690dc2366fSVenugopal Iyer 20700dc2366fSVenugopal Iyer sz = sizeof (mac_propval_range_t); 20710dc2366fSVenugopal Iyer 20720dc2366fSVenugopal Iyer if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 20730dc2366fSVenugopal Iyer &status)) == NULL) 20740dc2366fSVenugopal Iyer return (status); 20750dc2366fSVenugopal Iyer 20760dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 20770dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 20780dc2366fSVenugopal Iyer return (status); 20790dc2366fSVenugopal Iyer 20800dc2366fSVenugopal Iyer rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 20810dc2366fSVenugopal Iyer *val_cnt = 1; 20820dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 20830dc2366fSVenugopal Iyer /* This is the case where the dev doesn't have any rings/groups */ 20840dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 20850dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 20860dc2366fSVenugopal Iyer /* 20870dc2366fSVenugopal Iyer * This is the case where the dev supports rings, but static 20880dc2366fSVenugopal Iyer * grouping. 20890dc2366fSVenugopal Iyer */ 20900dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max && 20910dc2366fSVenugopal Iyer ur->mpur_max == 0) { 20920dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 20930dc2366fSVenugopal Iyer /* 20940dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 20950dc2366fSVenugopal Iyer * grouping, but has only one value (say 2 rings and 2 groups). 20960dc2366fSVenugopal Iyer */ 20970dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max) { 20980dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 20990dc2366fSVenugopal Iyer ur->mpur_min); 21000dc2366fSVenugopal Iyer /* 21010dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 21020dc2366fSVenugopal Iyer * grouping and has a range of rings. 21030dc2366fSVenugopal Iyer */ 21040dc2366fSVenugopal Iyer } else { 21050dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 21060dc2366fSVenugopal Iyer "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 21070dc2366fSVenugopal Iyer } 21080dc2366fSVenugopal Iyer free(dip); 21090dc2366fSVenugopal Iyer return (status); 21100dc2366fSVenugopal Iyer } 21110dc2366fSVenugopal Iyer 21120dc2366fSVenugopal Iyer 21130dc2366fSVenugopal Iyer /* ARGSUSED */ 21140dc2366fSVenugopal Iyer static dladm_status_t 21150dc2366fSVenugopal Iyer get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21160dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 21170dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 21180dc2366fSVenugopal Iyer { 21190dc2366fSVenugopal Iyer mac_resource_props_t mrp; 21200dc2366fSVenugopal Iyer dladm_status_t status; 21210dc2366fSVenugopal Iyer uint32_t nrings = 0; 21220dc2366fSVenugopal Iyer 21230dc2366fSVenugopal Iyer /* 21240dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 21250dc2366fSVenugopal Iyer */ 21260dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 21270dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 21280dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 21290dc2366fSVenugopal Iyer sizeof (mrp)); 21300dc2366fSVenugopal Iyer } else { 21310dc2366fSVenugopal Iyer /* 21320dc2366fSVenugopal Iyer * Get the permissions from the "rxrings" property. 21330dc2366fSVenugopal Iyer */ 21340dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "rxrings", 21350dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 21360dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 21370dc2366fSVenugopal Iyer return (status); 21380dc2366fSVenugopal Iyer 21390dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 21400dc2366fSVenugopal Iyer "resource", flags, NULL, &mrp, sizeof (mrp)); 21410dc2366fSVenugopal Iyer } 21420dc2366fSVenugopal Iyer 21430dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 21440dc2366fSVenugopal Iyer return (status); 21450dc2366fSVenugopal Iyer 21460dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 21470dc2366fSVenugopal Iyer *val_cnt = 0; 21480dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21490dc2366fSVenugopal Iyer } 21500dc2366fSVenugopal Iyer nrings = mrp.mrp_nrxrings; 21510dc2366fSVenugopal Iyer *val_cnt = 1; 21520dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 21530dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 21540dc2366fSVenugopal Iyer else if (nrings == 0) 21550dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 21560dc2366fSVenugopal Iyer else 21570dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 21580dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21590dc2366fSVenugopal Iyer } 21600dc2366fSVenugopal Iyer 21610dc2366fSVenugopal Iyer /* ARGSUSED */ 21620dc2366fSVenugopal Iyer dladm_status_t 21630dc2366fSVenugopal Iyer extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 21640dc2366fSVenugopal Iyer { 21650dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 21660dc2366fSVenugopal Iyer 21670dc2366fSVenugopal Iyer mrp->mrp_nrxrings = 0; 21680dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 21690dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 21700dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 21710dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 21720dc2366fSVenugopal Iyer else 21730dc2366fSVenugopal Iyer mrp->mrp_nrxrings = vdp->vd_val; 21740dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_RX_RINGS; 21750dc2366fSVenugopal Iyer 21760dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21770dc2366fSVenugopal Iyer } 21780dc2366fSVenugopal Iyer 21790dc2366fSVenugopal Iyer /* ARGSUSED */ 21800dc2366fSVenugopal Iyer static dladm_status_t 21810dc2366fSVenugopal Iyer get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 21820dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 21830dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 21840dc2366fSVenugopal Iyer { 21850dc2366fSVenugopal Iyer mac_resource_props_t mrp; 21860dc2366fSVenugopal Iyer dladm_status_t status; 21870dc2366fSVenugopal Iyer uint32_t nrings = 0; 21880dc2366fSVenugopal Iyer 21890dc2366fSVenugopal Iyer 21900dc2366fSVenugopal Iyer /* 21910dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 21920dc2366fSVenugopal Iyer */ 21930dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 21940dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 21950dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 21960dc2366fSVenugopal Iyer sizeof (mrp)); 21970dc2366fSVenugopal Iyer } else { 21980dc2366fSVenugopal Iyer /* 21990dc2366fSVenugopal Iyer * Get the permissions from the "txrings" property. 22000dc2366fSVenugopal Iyer */ 22010dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "txrings", 22020dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 22030dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 22040dc2366fSVenugopal Iyer return (status); 22050dc2366fSVenugopal Iyer 22060dc2366fSVenugopal Iyer /* 22070dc2366fSVenugopal Iyer * Get the number of rings from the "resource" property. 22080dc2366fSVenugopal Iyer */ 22090dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 22100dc2366fSVenugopal Iyer flags, NULL, &mrp, sizeof (mrp)); 22110dc2366fSVenugopal Iyer } 22120dc2366fSVenugopal Iyer 22130dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 22140dc2366fSVenugopal Iyer return (status); 22150dc2366fSVenugopal Iyer 22160dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 22170dc2366fSVenugopal Iyer *val_cnt = 0; 22180dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22190dc2366fSVenugopal Iyer } 22200dc2366fSVenugopal Iyer nrings = mrp.mrp_ntxrings; 22210dc2366fSVenugopal Iyer *val_cnt = 1; 22220dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 22230dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 22240dc2366fSVenugopal Iyer else if (nrings == 0) 22250dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 22260dc2366fSVenugopal Iyer else 22270dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 22280dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22290dc2366fSVenugopal Iyer } 22300dc2366fSVenugopal Iyer 22310dc2366fSVenugopal Iyer /* ARGSUSED */ 22320dc2366fSVenugopal Iyer dladm_status_t 22330dc2366fSVenugopal Iyer extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 22340dc2366fSVenugopal Iyer { 22350dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 22360dc2366fSVenugopal Iyer 22370dc2366fSVenugopal Iyer mrp->mrp_ntxrings = 0; 22380dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 22390dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 22400dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 22410dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 22420dc2366fSVenugopal Iyer else 22430dc2366fSVenugopal Iyer mrp->mrp_ntxrings = vdp->vd_val; 22440dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_TX_RINGS; 22450dc2366fSVenugopal Iyer 22460dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22470dc2366fSVenugopal Iyer } 22480dc2366fSVenugopal Iyer 22490dc2366fSVenugopal Iyer /* ARGSUSED */ 22500dc2366fSVenugopal Iyer static dladm_status_t 22510dc2366fSVenugopal Iyer get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22520dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 22530dc2366fSVenugopal Iyer uint_t *perm_flags) 22540dc2366fSVenugopal Iyer { 22550dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 22560dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTDEFINED); 22570dc2366fSVenugopal Iyer 22580dc2366fSVenugopal Iyer return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 22590dc2366fSVenugopal Iyer flags, perm_flags)); 22600dc2366fSVenugopal Iyer } 22610dc2366fSVenugopal Iyer 22620dc2366fSVenugopal Iyer /* ARGSUSED */ 22630dc2366fSVenugopal Iyer static dladm_status_t 22640dc2366fSVenugopal Iyer set_resource(dladm_handle_t handle, prop_desc_t *pdp, 226525ec3e3dSEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 226625ec3e3dSEric Cheng uint_t flags, datalink_media_t media) 226725ec3e3dSEric Cheng { 226825ec3e3dSEric Cheng mac_resource_props_t mrp; 226925ec3e3dSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 227025ec3e3dSEric Cheng dld_ioc_macprop_t *dip; 22710dc2366fSVenugopal Iyer int i; 227225ec3e3dSEric Cheng 227325ec3e3dSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 22740dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 227525ec3e3dSEric Cheng flags, &status); 227625ec3e3dSEric Cheng 227725ec3e3dSEric Cheng if (dip == NULL) 227825ec3e3dSEric Cheng return (status); 227925ec3e3dSEric Cheng 22800dc2366fSVenugopal Iyer for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 22810dc2366fSVenugopal Iyer resource_prop_t *rp = &rsrc_prop_table[i]; 22820dc2366fSVenugopal Iyer 22830dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, rp->rp_name) != 0) 22840dc2366fSVenugopal Iyer continue; 22850dc2366fSVenugopal Iyer 22860dc2366fSVenugopal Iyer status = rp->rp_extract(vdp, val_cnt, &mrp); 228725ec3e3dSEric Cheng if (status != DLADM_STATUS_OK) 228825ec3e3dSEric Cheng goto done; 228925ec3e3dSEric Cheng 22900dc2366fSVenugopal Iyer break; 229125ec3e3dSEric Cheng } 229225ec3e3dSEric Cheng 229325ec3e3dSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 229425ec3e3dSEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 229525ec3e3dSEric Cheng 229625ec3e3dSEric Cheng done: 229725ec3e3dSEric Cheng free(dip); 229825ec3e3dSEric Cheng return (status); 229925ec3e3dSEric Cheng } 230025ec3e3dSEric Cheng 230125ec3e3dSEric Cheng /* ARGSUSED */ 230225ec3e3dSEric Cheng static dladm_status_t 23030dc2366fSVenugopal Iyer get_protection(dladm_handle_t handle, prop_desc_t *pdp, 230425ec3e3dSEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 230525ec3e3dSEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 230625ec3e3dSEric Cheng { 230725ec3e3dSEric Cheng mac_resource_props_t mrp; 230825ec3e3dSEric Cheng mac_protect_t *p; 230925ec3e3dSEric Cheng dladm_status_t status; 23100dc2366fSVenugopal Iyer uint32_t i, cnt = 0, setbits[32]; 231125ec3e3dSEric Cheng 23120dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 23130dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 23140dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 231525ec3e3dSEric Cheng return (status); 231625ec3e3dSEric Cheng 231725ec3e3dSEric Cheng p = &mrp.mrp_protect; 23180dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 23190dc2366fSVenugopal Iyer *val_cnt = 0; 23200dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23210dc2366fSVenugopal Iyer } 232225ec3e3dSEric Cheng dladm_find_setbits32(p->mp_types, setbits, &cnt); 232325ec3e3dSEric Cheng if (cnt > *val_cnt) 232425ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 232525ec3e3dSEric Cheng 232625ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 232725ec3e3dSEric Cheng (void) dladm_protect2str(setbits[i], prop_val[i]); 232825ec3e3dSEric Cheng 232925ec3e3dSEric Cheng *val_cnt = cnt; 233025ec3e3dSEric Cheng return (DLADM_STATUS_OK); 233125ec3e3dSEric Cheng } 233225ec3e3dSEric Cheng 23330dc2366fSVenugopal Iyer /* ARGSUSED */ 23340dc2366fSVenugopal Iyer static dladm_status_t 23350dc2366fSVenugopal Iyer get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 23360dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 23370dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 23380dc2366fSVenugopal Iyer { 23390dc2366fSVenugopal Iyer mac_resource_props_t mrp; 23400dc2366fSVenugopal Iyer mac_protect_t *p; 23410dc2366fSVenugopal Iyer dladm_status_t status; 23420dc2366fSVenugopal Iyer int i; 23430dc2366fSVenugopal Iyer 23440dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 23450dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 23460dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 23470dc2366fSVenugopal Iyer return (status); 23480dc2366fSVenugopal Iyer 23490dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 23500dc2366fSVenugopal Iyer if (p->mp_ipaddrcnt == 0) { 23510dc2366fSVenugopal Iyer *val_cnt = 0; 23520dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23530dc2366fSVenugopal Iyer } 235425ec3e3dSEric Cheng if (p->mp_ipaddrcnt > *val_cnt) 235525ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 235625ec3e3dSEric Cheng 235725ec3e3dSEric Cheng for (i = 0; i < p->mp_ipaddrcnt; i++) { 2358*e03914f9SRobert Mustacchi int len; 23590dc2366fSVenugopal Iyer if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 23600dc2366fSVenugopal Iyer ipaddr_t v4addr; 23610dc2366fSVenugopal Iyer 23620dc2366fSVenugopal Iyer v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 23630dc2366fSVenugopal Iyer (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 23640dc2366fSVenugopal Iyer } else { 23650dc2366fSVenugopal Iyer (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 236625ec3e3dSEric Cheng prop_val[i]); 236725ec3e3dSEric Cheng } 2368*e03914f9SRobert Mustacchi len = strlen(prop_val[i]); 2369*e03914f9SRobert Mustacchi (void) sprintf(prop_val[i] + len, "/%d", 2370*e03914f9SRobert Mustacchi p->mp_ipaddrs[i].ip_netmask); 23710dc2366fSVenugopal Iyer } 237225ec3e3dSEric Cheng *val_cnt = p->mp_ipaddrcnt; 237325ec3e3dSEric Cheng return (DLADM_STATUS_OK); 237425ec3e3dSEric Cheng } 237525ec3e3dSEric Cheng 237625ec3e3dSEric Cheng dladm_status_t 23770dc2366fSVenugopal Iyer extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 237825ec3e3dSEric Cheng { 237925ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 238025ec3e3dSEric Cheng uint32_t types = 0; 238125ec3e3dSEric Cheng int i; 238225ec3e3dSEric Cheng 238325ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 238425ec3e3dSEric Cheng types |= (uint32_t)vdp[i].vd_val; 238525ec3e3dSEric Cheng 238625ec3e3dSEric Cheng mrp->mrp_protect.mp_types = types; 238725ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 238825ec3e3dSEric Cheng return (DLADM_STATUS_OK); 238925ec3e3dSEric Cheng } 239025ec3e3dSEric Cheng 239125ec3e3dSEric Cheng dladm_status_t 23920dc2366fSVenugopal Iyer extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 239325ec3e3dSEric Cheng { 239425ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 239525ec3e3dSEric Cheng mac_protect_t *p = &mrp->mrp_protect; 239625ec3e3dSEric Cheng int i; 239725ec3e3dSEric Cheng 239825ec3e3dSEric Cheng if (vdp->vd_val == 0) { 239925ec3e3dSEric Cheng cnt = (uint_t)-1; 240025ec3e3dSEric Cheng } else { 24010dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 24020dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 24030dc2366fSVenugopal Iyer sizeof (mac_ipaddr_t)); 24040dc2366fSVenugopal Iyer } 240525ec3e3dSEric Cheng } 240625ec3e3dSEric Cheng p->mp_ipaddrcnt = cnt; 240725ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 240825ec3e3dSEric Cheng return (DLADM_STATUS_OK); 240925ec3e3dSEric Cheng } 241025ec3e3dSEric Cheng 24110dc2366fSVenugopal Iyer static dladm_status_t 24120dc2366fSVenugopal Iyer check_single_ip(char *buf, mac_ipaddr_t *addr) 24130dc2366fSVenugopal Iyer { 24140dc2366fSVenugopal Iyer dladm_status_t status; 24150dc2366fSVenugopal Iyer ipaddr_t v4addr; 24160dc2366fSVenugopal Iyer in6_addr_t v6addr; 24170dc2366fSVenugopal Iyer boolean_t isv4 = B_TRUE; 2418*e03914f9SRobert Mustacchi char *p; 2419*e03914f9SRobert Mustacchi uint32_t mask = 0; 2420*e03914f9SRobert Mustacchi 2421*e03914f9SRobert Mustacchi /* 2422*e03914f9SRobert Mustacchi * If the IP address is in CIDR format, parse the bits component 2423*e03914f9SRobert Mustacchi * seperately. An address in this style will be used to indicate an 2424*e03914f9SRobert Mustacchi * entire subnet, so it must be a network number with no host address. 2425*e03914f9SRobert Mustacchi */ 2426*e03914f9SRobert Mustacchi if ((p = strchr(buf, '/')) != NULL) { 2427*e03914f9SRobert Mustacchi char *end = NULL; 2428*e03914f9SRobert Mustacchi 2429*e03914f9SRobert Mustacchi *p++ = '\0'; 2430*e03914f9SRobert Mustacchi if (!isdigit(*p)) 2431*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2432*e03914f9SRobert Mustacchi mask = strtol(p, &end, 10); 2433*e03914f9SRobert Mustacchi if (end != NULL && *end != '\0') 2434*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2435*e03914f9SRobert Mustacchi if (mask > 128|| mask < 1) 2436*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2437*e03914f9SRobert Mustacchi } 24380dc2366fSVenugopal Iyer 24390dc2366fSVenugopal Iyer status = dladm_str2ipv4addr(buf, &v4addr); 24400dc2366fSVenugopal Iyer if (status == DLADM_STATUS_INVALID_IP) { 24410dc2366fSVenugopal Iyer status = dladm_str2ipv6addr(buf, &v6addr); 24420dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) 24430dc2366fSVenugopal Iyer isv4 = B_FALSE; 24440dc2366fSVenugopal Iyer } 24450dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 24460dc2366fSVenugopal Iyer return (status); 24470dc2366fSVenugopal Iyer 24480dc2366fSVenugopal Iyer if (isv4) { 24490dc2366fSVenugopal Iyer if (v4addr == INADDR_ANY) 24500dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 24510dc2366fSVenugopal Iyer 24520dc2366fSVenugopal Iyer IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 24530dc2366fSVenugopal Iyer addr->ip_version = IPV4_VERSION; 2454*e03914f9SRobert Mustacchi if (p != NULL) { 2455*e03914f9SRobert Mustacchi uint32_t smask; 2456*e03914f9SRobert Mustacchi 2457*e03914f9SRobert Mustacchi /* 2458*e03914f9SRobert Mustacchi * Validate the netmask is in the proper range for v4 2459*e03914f9SRobert Mustacchi */ 2460*e03914f9SRobert Mustacchi if (mask > 32 || mask < 1) 2461*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2462*e03914f9SRobert Mustacchi 2463*e03914f9SRobert Mustacchi /* 2464*e03914f9SRobert Mustacchi * We have a CIDR style address, confirm that only the 2465*e03914f9SRobert Mustacchi * network number is set. 2466*e03914f9SRobert Mustacchi */ 2467*e03914f9SRobert Mustacchi smask = 0xFFFFFFFFu << (32 - mask); 2468*e03914f9SRobert Mustacchi if (htonl(v4addr) & ~smask) 2469*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2470*e03914f9SRobert Mustacchi } else { 2471*e03914f9SRobert Mustacchi mask = 32; 2472*e03914f9SRobert Mustacchi } 2473*e03914f9SRobert Mustacchi addr->ip_netmask = mask; 24740dc2366fSVenugopal Iyer } else { 24750dc2366fSVenugopal Iyer if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 24760dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 24770dc2366fSVenugopal Iyer 2478*e03914f9SRobert Mustacchi if (IN6_IS_ADDR_V4MAPPED_ANY(&v6addr)) 2479*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2480*e03914f9SRobert Mustacchi 2481*e03914f9SRobert Mustacchi if (p != NULL) { 2482*e03914f9SRobert Mustacchi int i, off, high; 2483*e03914f9SRobert Mustacchi 2484*e03914f9SRobert Mustacchi /* 2485*e03914f9SRobert Mustacchi * Note that the address in our buffer is stored in 2486*e03914f9SRobert Mustacchi * network byte order. 2487*e03914f9SRobert Mustacchi */ 2488*e03914f9SRobert Mustacchi off = 0; 2489*e03914f9SRobert Mustacchi for (i = 3; i >= 0; i--) { 2490*e03914f9SRobert Mustacchi high = ffsl(ntohl(v6addr._S6_un._S6_u32[i])); 2491*e03914f9SRobert Mustacchi if (high != 0) 2492*e03914f9SRobert Mustacchi break; 2493*e03914f9SRobert Mustacchi off += 32; 2494*e03914f9SRobert Mustacchi } 2495*e03914f9SRobert Mustacchi off += high; 2496*e03914f9SRobert Mustacchi if (128 - off >= mask) 2497*e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2498*e03914f9SRobert Mustacchi } else { 2499*e03914f9SRobert Mustacchi mask = 128; 2500*e03914f9SRobert Mustacchi } 2501*e03914f9SRobert Mustacchi 25020dc2366fSVenugopal Iyer addr->ip_addr = v6addr; 25030dc2366fSVenugopal Iyer addr->ip_version = IPV6_VERSION; 2504*e03914f9SRobert Mustacchi addr->ip_netmask = mask; 25050dc2366fSVenugopal Iyer } 25060dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 25070dc2366fSVenugopal Iyer } 25080dc2366fSVenugopal Iyer 250925ec3e3dSEric Cheng /* ARGSUSED */ 251025ec3e3dSEric Cheng static dladm_status_t 25110dc2366fSVenugopal Iyer check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2512c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 2513c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 251425ec3e3dSEric Cheng { 251525ec3e3dSEric Cheng dladm_status_t status; 25160dc2366fSVenugopal Iyer mac_ipaddr_t *addr; 251725ec3e3dSEric Cheng int i; 2518c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2519c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 252025ec3e3dSEric Cheng 252125ec3e3dSEric Cheng if (val_cnt > MPT_MAXIPADDR) 252225ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 252325ec3e3dSEric Cheng 252425ec3e3dSEric Cheng for (i = 0; i < val_cnt; i++) { 25250dc2366fSVenugopal Iyer if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 25260dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 25270dc2366fSVenugopal Iyer goto fail; 252825ec3e3dSEric Cheng } 25290dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)addr; 25300dc2366fSVenugopal Iyer 25310dc2366fSVenugopal Iyer status = check_single_ip(prop_val[i], addr); 25320dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 25330dc2366fSVenugopal Iyer goto fail; 25340dc2366fSVenugopal Iyer } 25350dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 25360dc2366fSVenugopal Iyer 25370dc2366fSVenugopal Iyer fail: 25380dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 25390dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 25400dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 25410dc2366fSVenugopal Iyer } 25420dc2366fSVenugopal Iyer return (status); 25430dc2366fSVenugopal Iyer } 25440dc2366fSVenugopal Iyer 25450dc2366fSVenugopal Iyer static void 25460dc2366fSVenugopal Iyer dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 25470dc2366fSVenugopal Iyer { 25480dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 25490dc2366fSVenugopal Iyer uint_t hexlen; 25500dc2366fSVenugopal Iyer 25510dc2366fSVenugopal Iyer switch (cid->dc_form) { 25520dc2366fSVenugopal Iyer case CIDFORM_TYPED: { 25530dc2366fSVenugopal Iyer uint16_t duidtype, hwtype; 25540dc2366fSVenugopal Iyer uint32_t timestamp, ennum; 25550dc2366fSVenugopal Iyer char *lladdr; 25560dc2366fSVenugopal Iyer 25570dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (duidtype)) 25580dc2366fSVenugopal Iyer goto fail; 25590dc2366fSVenugopal Iyer 25600dc2366fSVenugopal Iyer bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 25610dc2366fSVenugopal Iyer duidtype = ntohs(duidtype); 25620dc2366fSVenugopal Iyer switch (duidtype) { 25630dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 25640dc2366fSVenugopal Iyer duid_llt_t llt; 25650dc2366fSVenugopal Iyer 25660dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (llt)) 25670dc2366fSVenugopal Iyer goto fail; 25680dc2366fSVenugopal Iyer 25690dc2366fSVenugopal Iyer bcopy(cid->dc_id, &llt, sizeof (llt)); 25700dc2366fSVenugopal Iyer hwtype = ntohs(llt.dllt_hwtype); 25710dc2366fSVenugopal Iyer timestamp = ntohl(llt.dllt_time); 25720dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 25730dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 25740dc2366fSVenugopal Iyer if (lladdr == NULL) 25750dc2366fSVenugopal Iyer goto fail; 25760dc2366fSVenugopal Iyer 25770dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 25780dc2366fSVenugopal Iyer duidtype, hwtype, timestamp, lladdr); 25790dc2366fSVenugopal Iyer free(lladdr); 25800dc2366fSVenugopal Iyer break; 25810dc2366fSVenugopal Iyer } 25820dc2366fSVenugopal Iyer case DHCPV6_DUID_EN: { 25830dc2366fSVenugopal Iyer duid_en_t en; 25840dc2366fSVenugopal Iyer 25850dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (en)) 25860dc2366fSVenugopal Iyer goto fail; 25870dc2366fSVenugopal Iyer 25880dc2366fSVenugopal Iyer bcopy(cid->dc_id, &en, sizeof (en)); 25890dc2366fSVenugopal Iyer ennum = DHCPV6_GET_ENTNUM(&en); 25900dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 25910dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (en), 25920dc2366fSVenugopal Iyer cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 25930dc2366fSVenugopal Iyer goto fail; 25940dc2366fSVenugopal Iyer 25950dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 25960dc2366fSVenugopal Iyer duidtype, ennum, tmp_buf); 25970dc2366fSVenugopal Iyer break; 25980dc2366fSVenugopal Iyer } 25990dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 26000dc2366fSVenugopal Iyer duid_ll_t ll; 26010dc2366fSVenugopal Iyer 26020dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (ll)) 26030dc2366fSVenugopal Iyer goto fail; 26040dc2366fSVenugopal Iyer 26050dc2366fSVenugopal Iyer bcopy(cid->dc_id, &ll, sizeof (ll)); 26060dc2366fSVenugopal Iyer hwtype = ntohs(ll.dll_hwtype); 26070dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 26080dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 26090dc2366fSVenugopal Iyer if (lladdr == NULL) 26100dc2366fSVenugopal Iyer goto fail; 26110dc2366fSVenugopal Iyer 26120dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 26130dc2366fSVenugopal Iyer duidtype, hwtype, lladdr); 26140dc2366fSVenugopal Iyer free(lladdr); 26150dc2366fSVenugopal Iyer break; 26160dc2366fSVenugopal Iyer } 26170dc2366fSVenugopal Iyer default: { 26180dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 26190dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 26200dc2366fSVenugopal Iyer cid->dc_len - sizeof (duidtype), 26210dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 26220dc2366fSVenugopal Iyer goto fail; 26230dc2366fSVenugopal Iyer 26240dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 26250dc2366fSVenugopal Iyer duidtype, tmp_buf); 26260dc2366fSVenugopal Iyer } 26270dc2366fSVenugopal Iyer } 26280dc2366fSVenugopal Iyer break; 26290dc2366fSVenugopal Iyer } 26300dc2366fSVenugopal Iyer case CIDFORM_HEX: { 26310dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 26320dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id, cid->dc_len, 26330dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 26340dc2366fSVenugopal Iyer goto fail; 26350dc2366fSVenugopal Iyer 26360dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 26370dc2366fSVenugopal Iyer break; 26380dc2366fSVenugopal Iyer } 26390dc2366fSVenugopal Iyer case CIDFORM_STR: { 26400dc2366fSVenugopal Iyer int i; 26410dc2366fSVenugopal Iyer 26420dc2366fSVenugopal Iyer for (i = 0; i < cid->dc_len; i++) { 26430dc2366fSVenugopal Iyer if (!isprint(cid->dc_id[i])) 26440dc2366fSVenugopal Iyer goto fail; 26450dc2366fSVenugopal Iyer } 26460dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 26470dc2366fSVenugopal Iyer break; 26480dc2366fSVenugopal Iyer } 26490dc2366fSVenugopal Iyer default: 26500dc2366fSVenugopal Iyer goto fail; 26510dc2366fSVenugopal Iyer } 26520dc2366fSVenugopal Iyer return; 26530dc2366fSVenugopal Iyer 26540dc2366fSVenugopal Iyer fail: 26550dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 26560dc2366fSVenugopal Iyer } 26570dc2366fSVenugopal Iyer 26580dc2366fSVenugopal Iyer static dladm_status_t 26590dc2366fSVenugopal Iyer dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 26600dc2366fSVenugopal Iyer { 26610dc2366fSVenugopal Iyer char *ptr = buf; 26620dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 26630dc2366fSVenugopal Iyer uint_t hexlen, cidlen; 26640dc2366fSVenugopal Iyer 26650dc2366fSVenugopal Iyer bzero(cid, sizeof (*cid)); 26660dc2366fSVenugopal Iyer if (isdigit(*ptr) && 26670dc2366fSVenugopal Iyer ptr[strspn(ptr, "0123456789")] == '.') { 26680dc2366fSVenugopal Iyer char *cp; 26690dc2366fSVenugopal Iyer ulong_t duidtype; 26700dc2366fSVenugopal Iyer ulong_t subtype; 26710dc2366fSVenugopal Iyer ulong_t timestamp; 26720dc2366fSVenugopal Iyer uchar_t *lladdr; 26730dc2366fSVenugopal Iyer int addrlen; 26740dc2366fSVenugopal Iyer 26750dc2366fSVenugopal Iyer errno = 0; 26760dc2366fSVenugopal Iyer duidtype = strtoul(ptr, &cp, 0); 26770dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.' || 26780dc2366fSVenugopal Iyer duidtype > USHRT_MAX) 26790dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26800dc2366fSVenugopal Iyer ptr = cp + 1; 26810dc2366fSVenugopal Iyer 26820dc2366fSVenugopal Iyer if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 26830dc2366fSVenugopal Iyer errno = 0; 26840dc2366fSVenugopal Iyer subtype = strtoul(ptr, &cp, 0); 26850dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 26860dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26870dc2366fSVenugopal Iyer ptr = cp + 1; 26880dc2366fSVenugopal Iyer } 26890dc2366fSVenugopal Iyer switch (duidtype) { 26900dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 26910dc2366fSVenugopal Iyer duid_llt_t llt; 26920dc2366fSVenugopal Iyer 26930dc2366fSVenugopal Iyer errno = 0; 26940dc2366fSVenugopal Iyer timestamp = strtoul(ptr, &cp, 0); 26950dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 26960dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 26970dc2366fSVenugopal Iyer 26980dc2366fSVenugopal Iyer ptr = cp + 1; 26990dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 27000dc2366fSVenugopal Iyer if (lladdr == NULL) 27010dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 27020dc2366fSVenugopal Iyer 27030dc2366fSVenugopal Iyer cidlen = sizeof (llt) + addrlen; 27040dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 27050dc2366fSVenugopal Iyer free(lladdr); 27060dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27070dc2366fSVenugopal Iyer } 27080dc2366fSVenugopal Iyer llt.dllt_dutype = htons(duidtype); 27090dc2366fSVenugopal Iyer llt.dllt_hwtype = htons(subtype); 27100dc2366fSVenugopal Iyer llt.dllt_time = htonl(timestamp); 27110dc2366fSVenugopal Iyer bcopy(&llt, cid->dc_id, sizeof (llt)); 27120dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 27130dc2366fSVenugopal Iyer free(lladdr); 27140dc2366fSVenugopal Iyer break; 27150dc2366fSVenugopal Iyer } 27160dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 27170dc2366fSVenugopal Iyer duid_ll_t ll; 27180dc2366fSVenugopal Iyer 27190dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 27200dc2366fSVenugopal Iyer if (lladdr == NULL) 27210dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 27220dc2366fSVenugopal Iyer 27230dc2366fSVenugopal Iyer cidlen = sizeof (ll) + addrlen; 27240dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 27250dc2366fSVenugopal Iyer free(lladdr); 27260dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27270dc2366fSVenugopal Iyer } 27280dc2366fSVenugopal Iyer ll.dll_dutype = htons(duidtype); 27290dc2366fSVenugopal Iyer ll.dll_hwtype = htons(subtype); 27300dc2366fSVenugopal Iyer bcopy(&ll, cid->dc_id, sizeof (ll)); 27310dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 27320dc2366fSVenugopal Iyer free(lladdr); 27330dc2366fSVenugopal Iyer break; 27340dc2366fSVenugopal Iyer } 27350dc2366fSVenugopal Iyer default: { 27360dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 27370dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), 27380dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 27390dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 27400dc2366fSVenugopal Iyer 27410dc2366fSVenugopal Iyer if (duidtype == DHCPV6_DUID_EN) { 27420dc2366fSVenugopal Iyer duid_en_t en; 27430dc2366fSVenugopal Iyer 27440dc2366fSVenugopal Iyer en.den_dutype = htons(duidtype); 27450dc2366fSVenugopal Iyer DHCPV6_SET_ENTNUM(&en, subtype); 27460dc2366fSVenugopal Iyer 27470dc2366fSVenugopal Iyer cidlen = sizeof (en) + hexlen; 27480dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 27490dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27500dc2366fSVenugopal Iyer 27510dc2366fSVenugopal Iyer bcopy(&en, cid->dc_id, sizeof (en)); 27520dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (en), 27530dc2366fSVenugopal Iyer hexlen); 27540dc2366fSVenugopal Iyer } else { 27550dc2366fSVenugopal Iyer uint16_t dutype = htons(duidtype); 27560dc2366fSVenugopal Iyer 27570dc2366fSVenugopal Iyer cidlen = sizeof (dutype) + hexlen; 27580dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 27590dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27600dc2366fSVenugopal Iyer 27610dc2366fSVenugopal Iyer bcopy(&dutype, cid->dc_id, sizeof (dutype)); 27620dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 27630dc2366fSVenugopal Iyer hexlen); 27640dc2366fSVenugopal Iyer } 27650dc2366fSVenugopal Iyer break; 27660dc2366fSVenugopal Iyer } 27670dc2366fSVenugopal Iyer } 27680dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_TYPED; 27690dc2366fSVenugopal Iyer } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 27700dc2366fSVenugopal Iyer ptr += 2; 27710dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 27720dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 27730dc2366fSVenugopal Iyer &hexlen) != 0) { 27740dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 27750dc2366fSVenugopal Iyer } 27760dc2366fSVenugopal Iyer cidlen = hexlen; 27770dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 27780dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27790dc2366fSVenugopal Iyer 27800dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id, cidlen); 27810dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_HEX; 27820dc2366fSVenugopal Iyer } else { 27830dc2366fSVenugopal Iyer cidlen = strlen(ptr); 27840dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 27850dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 27860dc2366fSVenugopal Iyer 27870dc2366fSVenugopal Iyer bcopy(ptr, cid->dc_id, cidlen); 27880dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_STR; 27890dc2366fSVenugopal Iyer } 27900dc2366fSVenugopal Iyer cid->dc_len = cidlen; 279125ec3e3dSEric Cheng return (DLADM_STATUS_OK); 279225ec3e3dSEric Cheng } 279325ec3e3dSEric Cheng 279425ec3e3dSEric Cheng /* ARGSUSED */ 279525ec3e3dSEric Cheng static dladm_status_t 27960dc2366fSVenugopal Iyer get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 27970dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 27980dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 27990dc2366fSVenugopal Iyer { 28000dc2366fSVenugopal Iyer mac_resource_props_t mrp; 28010dc2366fSVenugopal Iyer mac_protect_t *p; 28020dc2366fSVenugopal Iyer dladm_status_t status; 28030dc2366fSVenugopal Iyer int i; 28040dc2366fSVenugopal Iyer 28050dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 28060dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 28070dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 28080dc2366fSVenugopal Iyer return (status); 28090dc2366fSVenugopal Iyer 28100dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 28110dc2366fSVenugopal Iyer if (p->mp_cidcnt == 0) { 28120dc2366fSVenugopal Iyer *val_cnt = 0; 28130dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 28140dc2366fSVenugopal Iyer } 28150dc2366fSVenugopal Iyer if (p->mp_cidcnt > *val_cnt) 28160dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 28170dc2366fSVenugopal Iyer 28180dc2366fSVenugopal Iyer for (i = 0; i < p->mp_cidcnt; i++) { 28190dc2366fSVenugopal Iyer mac_dhcpcid_t *cid = &p->mp_cids[i]; 28200dc2366fSVenugopal Iyer 28210dc2366fSVenugopal Iyer dladm_cid2str(cid, prop_val[i]); 28220dc2366fSVenugopal Iyer } 28230dc2366fSVenugopal Iyer *val_cnt = p->mp_cidcnt; 28240dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 28250dc2366fSVenugopal Iyer } 28260dc2366fSVenugopal Iyer 28270dc2366fSVenugopal Iyer dladm_status_t 28280dc2366fSVenugopal Iyer extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 28290dc2366fSVenugopal Iyer { 28300dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 28310dc2366fSVenugopal Iyer mac_protect_t *p = &mrp->mrp_protect; 28320dc2366fSVenugopal Iyer int i; 28330dc2366fSVenugopal Iyer 28340dc2366fSVenugopal Iyer if (vdp->vd_val == 0) { 28350dc2366fSVenugopal Iyer cnt = (uint_t)-1; 28360dc2366fSVenugopal Iyer } else { 28370dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 28380dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 28390dc2366fSVenugopal Iyer sizeof (mac_dhcpcid_t)); 28400dc2366fSVenugopal Iyer } 28410dc2366fSVenugopal Iyer } 28420dc2366fSVenugopal Iyer p->mp_cidcnt = cnt; 28430dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_PROTECT; 28440dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 28450dc2366fSVenugopal Iyer } 28460dc2366fSVenugopal Iyer 28470dc2366fSVenugopal Iyer /* ARGSUSED */ 28480dc2366fSVenugopal Iyer static dladm_status_t 28490dc2366fSVenugopal Iyer check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2850c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, 2851c569ef53SMichael Lim uint_t flags, val_desc_t **vdpp, datalink_media_t media) 28520dc2366fSVenugopal Iyer { 28530dc2366fSVenugopal Iyer dladm_status_t status; 28540dc2366fSVenugopal Iyer mac_dhcpcid_t *cid; 28550dc2366fSVenugopal Iyer int i; 2856c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2857c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 28580dc2366fSVenugopal Iyer 28590dc2366fSVenugopal Iyer if (val_cnt > MPT_MAXCID) 28600dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 28610dc2366fSVenugopal Iyer 28620dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 28630dc2366fSVenugopal Iyer if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 28640dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 28650dc2366fSVenugopal Iyer goto fail; 28660dc2366fSVenugopal Iyer } 28670dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)cid; 28680dc2366fSVenugopal Iyer 28690dc2366fSVenugopal Iyer status = dladm_str2cid(prop_val[i], cid); 28700dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 28710dc2366fSVenugopal Iyer goto fail; 28720dc2366fSVenugopal Iyer } 28730dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 28740dc2366fSVenugopal Iyer 28750dc2366fSVenugopal Iyer fail: 28760dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 28770dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 28780dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 28790dc2366fSVenugopal Iyer } 28800dc2366fSVenugopal Iyer return (status); 28810dc2366fSVenugopal Iyer } 28820dc2366fSVenugopal Iyer 28830dc2366fSVenugopal Iyer /* ARGSUSED */ 28840dc2366fSVenugopal Iyer static dladm_status_t 28851a41ca23SJerry Jelinek get_secondary_macs(dladm_handle_t handle, prop_desc_t *pdp, 28861a41ca23SJerry Jelinek datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 28871a41ca23SJerry Jelinek datalink_media_t media, uint_t flags, uint_t *perm_flags) 28881a41ca23SJerry Jelinek { 28891a41ca23SJerry Jelinek mac_secondary_addr_t sa; 28901a41ca23SJerry Jelinek dladm_status_t status; 28911a41ca23SJerry Jelinek int i; 28921a41ca23SJerry Jelinek 28931a41ca23SJerry Jelinek status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 28941a41ca23SJerry Jelinek perm_flags, &sa, sizeof (sa)); 28951a41ca23SJerry Jelinek if (status != DLADM_STATUS_OK) 28961a41ca23SJerry Jelinek return (status); 28971a41ca23SJerry Jelinek 28981a41ca23SJerry Jelinek if (sa.ms_addrcnt > *val_cnt) 28991a41ca23SJerry Jelinek return (DLADM_STATUS_BADVALCNT); 29001a41ca23SJerry Jelinek 29011a41ca23SJerry Jelinek for (i = 0; i < sa.ms_addrcnt; i++) { 29021a41ca23SJerry Jelinek if (dladm_aggr_macaddr2str( 29031a41ca23SJerry Jelinek (const unsigned char *)&sa.ms_addrs[i], prop_val[i]) == 29041a41ca23SJerry Jelinek NULL) { 29051a41ca23SJerry Jelinek *val_cnt = i; 29061a41ca23SJerry Jelinek return (DLADM_STATUS_NOMEM); 29071a41ca23SJerry Jelinek } 29081a41ca23SJerry Jelinek } 29091a41ca23SJerry Jelinek *val_cnt = sa.ms_addrcnt; 29101a41ca23SJerry Jelinek return (DLADM_STATUS_OK); 29111a41ca23SJerry Jelinek } 29121a41ca23SJerry Jelinek 29131a41ca23SJerry Jelinek /* ARGSUSED */ 29141a41ca23SJerry Jelinek static dladm_status_t 29151a41ca23SJerry Jelinek check_secondary_macs(dladm_handle_t handle, prop_desc_t *pdp, 29161a41ca23SJerry Jelinek datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 29171a41ca23SJerry Jelinek val_desc_t **vdpp, datalink_media_t media) 29181a41ca23SJerry Jelinek { 29191a41ca23SJerry Jelinek dladm_status_t status; 29201a41ca23SJerry Jelinek uchar_t *addr; 29211a41ca23SJerry Jelinek uint_t len = 0; 29221a41ca23SJerry Jelinek int i; 29231a41ca23SJerry Jelinek uint_t val_cnt = *val_cntp; 29241a41ca23SJerry Jelinek val_desc_t *vdp = *vdpp; 29251a41ca23SJerry Jelinek 29261a41ca23SJerry Jelinek if (val_cnt >= MPT_MAXMACADDR) 29271a41ca23SJerry Jelinek return (DLADM_STATUS_BADVALCNT); 29281a41ca23SJerry Jelinek 29291a41ca23SJerry Jelinek for (i = 0; i < val_cnt; i++) { 29301a41ca23SJerry Jelinek addr = _link_aton(prop_val[i], (int *)&len); 29311a41ca23SJerry Jelinek if (addr == NULL) { 29321a41ca23SJerry Jelinek if (len == (uint_t)-1) 29331a41ca23SJerry Jelinek status = DLADM_STATUS_MACADDRINVAL; 29341a41ca23SJerry Jelinek else 29351a41ca23SJerry Jelinek status = DLADM_STATUS_NOMEM; 29361a41ca23SJerry Jelinek goto fail; 29371a41ca23SJerry Jelinek } 29381a41ca23SJerry Jelinek 29391a41ca23SJerry Jelinek vdp[i].vd_val = (uintptr_t)addr; 29401a41ca23SJerry Jelinek } 29411a41ca23SJerry Jelinek return (DLADM_STATUS_OK); 29421a41ca23SJerry Jelinek 29431a41ca23SJerry Jelinek fail: 29441a41ca23SJerry Jelinek for (i = 0; i < val_cnt; i++) { 29451a41ca23SJerry Jelinek free((void *)vdp[i].vd_val); 29461a41ca23SJerry Jelinek vdp[i].vd_val = NULL; 29471a41ca23SJerry Jelinek } 29481a41ca23SJerry Jelinek return (status); 29491a41ca23SJerry Jelinek } 29501a41ca23SJerry Jelinek 29511a41ca23SJerry Jelinek /* ARGSUSED */ 29521a41ca23SJerry Jelinek static dladm_status_t 29531a41ca23SJerry Jelinek set_secondary_macs(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 29541a41ca23SJerry Jelinek val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 29551a41ca23SJerry Jelinek { 29561a41ca23SJerry Jelinek dladm_status_t status; 29571a41ca23SJerry Jelinek dld_ioc_macprop_t *dip; 29581a41ca23SJerry Jelinek int i; 29591a41ca23SJerry Jelinek mac_secondary_addr_t msa; 29601a41ca23SJerry Jelinek 29611a41ca23SJerry Jelinek dip = i_dladm_buf_alloc_by_name(0, linkid, "secondary-macs", 0, 29621a41ca23SJerry Jelinek &status); 29631a41ca23SJerry Jelinek if (dip == NULL) 29641a41ca23SJerry Jelinek return (status); 29651a41ca23SJerry Jelinek 29661a41ca23SJerry Jelinek if (vdp->vd_val == 0) { 29671a41ca23SJerry Jelinek val_cnt = (uint_t)-1; 29681a41ca23SJerry Jelinek } else { 29691a41ca23SJerry Jelinek for (i = 0; i < val_cnt; i++) { 29701a41ca23SJerry Jelinek bcopy((void *)vdp[i].vd_val, msa.ms_addrs[i], 29711a41ca23SJerry Jelinek MAXMACADDRLEN); 29721a41ca23SJerry Jelinek } 29731a41ca23SJerry Jelinek } 29741a41ca23SJerry Jelinek msa.ms_addrcnt = val_cnt; 29751a41ca23SJerry Jelinek bcopy(&msa, dip->pr_val, dip->pr_valsize); 29761a41ca23SJerry Jelinek 29771a41ca23SJerry Jelinek status = i_dladm_macprop(handle, dip, B_TRUE); 29781a41ca23SJerry Jelinek 29791a41ca23SJerry Jelinek free(dip); 29801a41ca23SJerry Jelinek return (status); 29811a41ca23SJerry Jelinek } 29821a41ca23SJerry Jelinek 29831a41ca23SJerry Jelinek /* ARGSUSED */ 29841a41ca23SJerry Jelinek static dladm_status_t 29850dc2366fSVenugopal Iyer get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2986da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 2987da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 2988d62bc4baSyz147064 { 29893bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 29903bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 29913bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 2992d62bc4baSyz147064 29930dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 2994149b7eb2SSowmini Varadhan return (DLADM_STATUS_NOTDEFINED); 29954045d941Ssowmini 29960dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 29970dc2366fSVenugopal Iyer perm_flags, &dlap, sizeof (dlap)); 29980dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 29990dc2366fSVenugopal Iyer return (status); 30000dc2366fSVenugopal Iyer 30010dc2366fSVenugopal Iyer if (dlap.dap_npush == 0) { 30020dc2366fSVenugopal Iyer *val_cnt = 0; 3003da14cebeSEric Cheng return (DLADM_STATUS_OK); 3004d62bc4baSyz147064 } 30053bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 3006d62bc4baSyz147064 if (i != 0) { 3007d62bc4baSyz147064 (void) snprintf(*prop_val + len, 3008d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 3009d62bc4baSyz147064 len += 1; 3010d62bc4baSyz147064 } 3011d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 30123bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 30133bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 30143bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 3015d62bc4baSyz147064 (void) snprintf(*prop_val + len, 3016d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 3017d62bc4baSyz147064 AP_ANCHOR); 3018d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 3019d62bc4baSyz147064 } 3020d62bc4baSyz147064 } 30210dc2366fSVenugopal Iyer *val_cnt = 1; 3022d62bc4baSyz147064 return (DLADM_STATUS_OK); 3023d62bc4baSyz147064 } 3024d62bc4baSyz147064 3025d62bc4baSyz147064 /* 3026d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 3027d62bc4baSyz147064 * DLADM_STATUS_* code. 3028d62bc4baSyz147064 */ 3029d62bc4baSyz147064 dladm_status_t 3030d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 3031d62bc4baSyz147064 { 3032d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 3033d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 3034d62bc4baSyz147064 3035d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 3036d62bc4baSyz147064 /* 3037d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 3038d62bc4baSyz147064 * be after at least one module. 3039d62bc4baSyz147064 */ 3040d62bc4baSyz147064 if (dlap->dap_anchor != 0) 3041d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 3042d62bc4baSyz147064 if (dlap->dap_npush == 0) 3043d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 3044d62bc4baSyz147064 3045d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 3046d62bc4baSyz147064 return (DLADM_STATUS_OK); 3047d62bc4baSyz147064 } 3048285e94f9SMichael Lim if (dlap->dap_npush >= MAXAPUSH) 3049d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3050d62bc4baSyz147064 3051d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 3052d62bc4baSyz147064 FMNAMESZ + 1); 3053d62bc4baSyz147064 3054d62bc4baSyz147064 return (DLADM_STATUS_OK); 3055d62bc4baSyz147064 } 3056d62bc4baSyz147064 3057d62bc4baSyz147064 /* 3058d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 3059d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 3060d62bc4baSyz147064 * latter is used in the autopush(1M) file. 3061d62bc4baSyz147064 */ 3062d62bc4baSyz147064 /* ARGSUSED */ 3063d62bc4baSyz147064 static dladm_status_t 30640dc2366fSVenugopal Iyer check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3065c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 30660dc2366fSVenugopal Iyer datalink_media_t media) 3067d62bc4baSyz147064 { 3068d62bc4baSyz147064 char *module; 3069d62bc4baSyz147064 struct dlautopush *dlap; 3070d62bc4baSyz147064 dladm_status_t status; 3071d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 3072d62bc4baSyz147064 char delimiters[4]; 3073c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3074c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 3075d62bc4baSyz147064 3076d62bc4baSyz147064 if (val_cnt != 1) 3077d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3078d62bc4baSyz147064 30793bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 3080d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 3081d62bc4baSyz147064 if (dlap == NULL) 3082d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 3083d62bc4baSyz147064 3084d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 3085d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 3086d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 3087d62bc4baSyz147064 module = strtok(val, delimiters); 3088d62bc4baSyz147064 while (module != NULL) { 3089d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 3090d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3091d62bc4baSyz147064 return (status); 3092d62bc4baSyz147064 module = strtok(NULL, delimiters); 3093d62bc4baSyz147064 } 3094d62bc4baSyz147064 3095d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 30963bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 30973bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 30983bc21d0aSAruna Ramakrishna - Sun Microsystems } 3099d62bc4baSyz147064 return (DLADM_STATUS_OK); 3100d62bc4baSyz147064 } 3101d62bc4baSyz147064 3102bcb5c89dSSowmini Varadhan #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 3103bcb5c89dSSowmini Varadhan 3104e7801d59Ssowmini /* ARGSUSED */ 3105d62bc4baSyz147064 static dladm_status_t 31060dc2366fSVenugopal Iyer get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 31074ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 31084ac67f02SAnurag S. Maskey uint_t *perm_flags) 3109d62bc4baSyz147064 { 3110d62bc4baSyz147064 wl_rates_t *wrp; 3111d62bc4baSyz147064 uint_t i; 3112d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 3113d62bc4baSyz147064 3114bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 3115bcb5c89dSSowmini Varadhan if (wrp == NULL) 3116bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 3117d62bc4baSyz147064 31184ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 31194ac67f02SAnurag S. Maskey B_FALSE); 3120d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3121d62bc4baSyz147064 goto done; 3122d62bc4baSyz147064 3123d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 3124d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 3125d62bc4baSyz147064 goto done; 3126d62bc4baSyz147064 } 3127d62bc4baSyz147064 3128d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 3129d62bc4baSyz147064 prop_val[0][0] = '\0'; 3130d62bc4baSyz147064 *val_cnt = 1; 3131d62bc4baSyz147064 goto done; 3132d62bc4baSyz147064 } 3133d62bc4baSyz147064 3134d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 3135d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 3136d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 3137d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 3138d62bc4baSyz147064 } 3139d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 3140da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_RW; 3141d62bc4baSyz147064 3142d62bc4baSyz147064 done: 3143bcb5c89dSSowmini Varadhan free(wrp); 3144d62bc4baSyz147064 return (status); 3145d62bc4baSyz147064 } 3146d62bc4baSyz147064 3147d62bc4baSyz147064 static dladm_status_t 31480dc2366fSVenugopal Iyer get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3149da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3150da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3151d62bc4baSyz147064 { 3152afdda45fSVasumathi Sundaram - Sun Microsystems if (media != DL_WIFI) { 31530dc2366fSVenugopal Iyer return (get_speed(handle, pdp, linkid, prop_val, 31540dc2366fSVenugopal Iyer val_cnt, media, flags, perm_flags)); 3155afdda45fSVasumathi Sundaram - Sun Microsystems } 31566b9e797cSsowmini 31570dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 3158da14cebeSEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 3159d62bc4baSyz147064 } 3160d62bc4baSyz147064 31614045d941Ssowmini /* ARGSUSED */ 3162d62bc4baSyz147064 static dladm_status_t 31630dc2366fSVenugopal Iyer get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3164da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3165da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3166d62bc4baSyz147064 { 31676b9e797cSsowmini switch (media) { 31686b9e797cSsowmini case DL_ETHER: 31694045d941Ssowmini /* 31704045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 31714045d941Ssowmini * links can have a speed of 5.5 Gbps. 31724045d941Ssowmini */ 31734045d941Ssowmini return (DLADM_STATUS_NOTSUP); 31746b9e797cSsowmini 31756b9e797cSsowmini case DL_WIFI: 31760dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, 31774ac67f02SAnurag S. Maskey val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 31786b9e797cSsowmini default: 31796b9e797cSsowmini return (DLADM_STATUS_BADARG); 31806b9e797cSsowmini } 3181d62bc4baSyz147064 } 3182d62bc4baSyz147064 3183d62bc4baSyz147064 static dladm_status_t 31840dc2366fSVenugopal Iyer set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 31854ac67f02SAnurag S. Maskey dladm_wlan_rates_t *rates) 3186f4b3ec61Sdh155122 { 3187f4b3ec61Sdh155122 int i; 3188d62bc4baSyz147064 uint_t len; 3189d62bc4baSyz147064 wl_rates_t *wrp; 3190d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 3191d62bc4baSyz147064 3192bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 3193bcb5c89dSSowmini Varadhan if (wrp == NULL) 3194d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 3195d62bc4baSyz147064 3196bcb5c89dSSowmini Varadhan bzero(wrp, WLDP_BUFSIZE); 3197d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 3198d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 3199d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 3200d62bc4baSyz147064 3201d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 3202d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 32034ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, 32044ac67f02SAnurag S. Maskey MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 3205d62bc4baSyz147064 3206bcb5c89dSSowmini Varadhan free(wrp); 3207d62bc4baSyz147064 return (status); 3208d62bc4baSyz147064 } 3209d62bc4baSyz147064 3210e7801d59Ssowmini /* ARGSUSED */ 3211d62bc4baSyz147064 static dladm_status_t 32120dc2366fSVenugopal Iyer set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 32136b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3214d62bc4baSyz147064 { 3215d62bc4baSyz147064 dladm_wlan_rates_t rates; 3216f4b3ec61Sdh155122 dladm_status_t status; 3217f4b3ec61Sdh155122 32186b9e797cSsowmini /* 32196b9e797cSsowmini * can currently set rate on WIFI links only. 32206b9e797cSsowmini */ 32216b9e797cSsowmini if (media != DL_WIFI) 32226b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 32236b9e797cSsowmini 3224d62bc4baSyz147064 if (val_cnt != 1) 3225d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3226f4b3ec61Sdh155122 3227d62bc4baSyz147064 rates.wr_cnt = 1; 3228d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 3229f4b3ec61Sdh155122 32300dc2366fSVenugopal Iyer status = set_wlan_rate(handle, linkid, &rates); 3231f4b3ec61Sdh155122 3232d62bc4baSyz147064 return (status); 3233d62bc4baSyz147064 } 3234d62bc4baSyz147064 3235d62bc4baSyz147064 /* ARGSUSED */ 3236d62bc4baSyz147064 static dladm_status_t 32370dc2366fSVenugopal Iyer check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3238c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 32390dc2366fSVenugopal Iyer datalink_media_t media) 3240d62bc4baSyz147064 { 3241d62bc4baSyz147064 int i; 3242d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 3243d62bc4baSyz147064 char *buf, **modval; 3244d62bc4baSyz147064 dladm_status_t status; 3245afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 3246c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3247c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 3248d62bc4baSyz147064 3249d62bc4baSyz147064 if (val_cnt != 1) 3250d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3251d62bc4baSyz147064 3252d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 3253d62bc4baSyz147064 MAX_SUPPORT_RATES); 3254d62bc4baSyz147064 if (buf == NULL) { 3255d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 3256d62bc4baSyz147064 goto done; 3257d62bc4baSyz147064 } 3258d62bc4baSyz147064 3259d62bc4baSyz147064 modval = (char **)(void *)buf; 3260d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 3261d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 3262d62bc4baSyz147064 i * DLADM_STRSIZE; 3263d62bc4baSyz147064 } 3264d62bc4baSyz147064 32650dc2366fSVenugopal Iyer status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 32664ac67f02SAnurag S. Maskey media, 0, &perm_flags); 3267d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3268d62bc4baSyz147064 goto done; 3269d62bc4baSyz147064 3270d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 3271d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 3272e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 3273e7801d59Ssowmini (atof(*prop_val) * 2); 3274f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 3275f4b3ec61Sdh155122 break; 3276f4b3ec61Sdh155122 } 3277d62bc4baSyz147064 } 3278d62bc4baSyz147064 if (i == modval_cnt) 3279d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 3280d62bc4baSyz147064 done: 3281d62bc4baSyz147064 free(buf); 3282d62bc4baSyz147064 return (status); 3283d62bc4baSyz147064 } 3284f4b3ec61Sdh155122 3285d62bc4baSyz147064 static dladm_status_t 32860dc2366fSVenugopal Iyer get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 32874ac67f02SAnurag S. Maskey int buflen) 3288d62bc4baSyz147064 { 32894ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 3290bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 3291d62bc4baSyz147064 } 3292d62bc4baSyz147064 3293e7801d59Ssowmini /* ARGSUSED */ 3294d62bc4baSyz147064 static dladm_status_t 32950dc2366fSVenugopal Iyer get_channel(dladm_handle_t handle, prop_desc_t *pdp, 32964ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 32974ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3298d62bc4baSyz147064 { 3299d62bc4baSyz147064 uint32_t channel; 3300bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 33010dc2366fSVenugopal Iyer dladm_status_t status; 3302bcb5c89dSSowmini Varadhan wl_phy_conf_t wl_phy_conf; 3303d62bc4baSyz147064 33040dc2366fSVenugopal Iyer if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 3305bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 33060dc2366fSVenugopal Iyer return (status); 3307d62bc4baSyz147064 3308bcb5c89dSSowmini Varadhan (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 33090dc2366fSVenugopal Iyer if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 33100dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3311d62bc4baSyz147064 3312d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 3313d62bc4baSyz147064 *val_cnt = 1; 3314da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 33150dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3316d62bc4baSyz147064 } 3317d62bc4baSyz147064 3318e7801d59Ssowmini /* ARGSUSED */ 3319d62bc4baSyz147064 static dladm_status_t 33200dc2366fSVenugopal Iyer get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 33214ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 33224ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3323d62bc4baSyz147064 { 3324bcb5c89dSSowmini Varadhan wl_ps_mode_t mode; 3325d62bc4baSyz147064 const char *s; 3326bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 33270dc2366fSVenugopal Iyer dladm_status_t status; 3328d62bc4baSyz147064 33290dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 33300dc2366fSVenugopal Iyer MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 33310dc2366fSVenugopal Iyer return (status); 3332d62bc4baSyz147064 3333bcb5c89dSSowmini Varadhan (void) memcpy(&mode, buf, sizeof (mode)); 3334bcb5c89dSSowmini Varadhan switch (mode.wl_ps_mode) { 3335d62bc4baSyz147064 case WL_PM_AM: 3336d62bc4baSyz147064 s = "off"; 3337f4b3ec61Sdh155122 break; 3338d62bc4baSyz147064 case WL_PM_MPS: 3339d62bc4baSyz147064 s = "max"; 3340d62bc4baSyz147064 break; 3341d62bc4baSyz147064 case WL_PM_FAST: 3342d62bc4baSyz147064 s = "fast"; 3343f4b3ec61Sdh155122 break; 3344f4b3ec61Sdh155122 default: 33450dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3346f4b3ec61Sdh155122 } 3347d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3348d62bc4baSyz147064 *val_cnt = 1; 3349afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 33500dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3351d62bc4baSyz147064 } 3352d62bc4baSyz147064 33530dc2366fSVenugopal Iyer /* ARGSUSED */ 3354d62bc4baSyz147064 static dladm_status_t 33550dc2366fSVenugopal Iyer set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 33560dc2366fSVenugopal Iyer datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 33570dc2366fSVenugopal Iyer datalink_media_t media) 3358d62bc4baSyz147064 { 33590dc2366fSVenugopal Iyer dladm_wlan_powermode_t powermode = vdp->vd_val; 3360d62bc4baSyz147064 wl_ps_mode_t ps_mode; 3361d62bc4baSyz147064 33620dc2366fSVenugopal Iyer if (val_cnt != 1) 33630dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 33640dc2366fSVenugopal Iyer 3365d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 3366d62bc4baSyz147064 33670dc2366fSVenugopal Iyer switch (powermode) { 3368d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 3369d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 3370d62bc4baSyz147064 break; 3371d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 3372d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 3373d62bc4baSyz147064 break; 3374d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 3375d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 3376d62bc4baSyz147064 break; 3377d62bc4baSyz147064 default: 3378d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3379d62bc4baSyz147064 } 33804ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &ps_mode, 33814ac67f02SAnurag S. Maskey MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 3382d62bc4baSyz147064 } 3383d62bc4baSyz147064 3384d62bc4baSyz147064 /* ARGSUSED */ 3385d62bc4baSyz147064 static dladm_status_t 33860dc2366fSVenugopal Iyer get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3387da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3388da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3389d62bc4baSyz147064 { 3390d62bc4baSyz147064 wl_radio_t radio; 3391d62bc4baSyz147064 const char *s; 3392bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 33930dc2366fSVenugopal Iyer dladm_status_t status; 3394d62bc4baSyz147064 33950dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 33960dc2366fSVenugopal Iyer MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 33970dc2366fSVenugopal Iyer return (status); 3398d62bc4baSyz147064 3399bcb5c89dSSowmini Varadhan (void) memcpy(&radio, buf, sizeof (radio)); 3400d62bc4baSyz147064 switch (radio) { 3401d62bc4baSyz147064 case B_TRUE: 3402d62bc4baSyz147064 s = "on"; 3403d62bc4baSyz147064 break; 3404d62bc4baSyz147064 case B_FALSE: 3405d62bc4baSyz147064 s = "off"; 3406d62bc4baSyz147064 break; 3407d62bc4baSyz147064 default: 34080dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3409d62bc4baSyz147064 } 3410d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3411d62bc4baSyz147064 *val_cnt = 1; 3412afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 34130dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3414d62bc4baSyz147064 } 3415d62bc4baSyz147064 34160dc2366fSVenugopal Iyer /* ARGSUSED */ 3417d62bc4baSyz147064 static dladm_status_t 34180dc2366fSVenugopal Iyer set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 34190dc2366fSVenugopal Iyer val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3420d62bc4baSyz147064 { 34210dc2366fSVenugopal Iyer dladm_wlan_radio_t radio = vdp->vd_val; 3422d62bc4baSyz147064 wl_radio_t r; 3423d62bc4baSyz147064 34240dc2366fSVenugopal Iyer if (val_cnt != 1) 34250dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 34260dc2366fSVenugopal Iyer 34270dc2366fSVenugopal Iyer switch (radio) { 3428d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 3429d62bc4baSyz147064 r = B_TRUE; 3430d62bc4baSyz147064 break; 3431d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 3432d62bc4baSyz147064 r = B_FALSE; 3433d62bc4baSyz147064 break; 3434d62bc4baSyz147064 default: 3435d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3436d62bc4baSyz147064 } 34374ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 3438bcb5c89dSSowmini Varadhan sizeof (r), B_TRUE)); 3439d62bc4baSyz147064 } 3440d62bc4baSyz147064 3441d62bc4baSyz147064 /* ARGSUSED */ 3442d62bc4baSyz147064 static dladm_status_t 34430dc2366fSVenugopal Iyer check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 3444c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 3445c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 34462b24ab6bSSebastien Roy { 34472b24ab6bSSebastien Roy int32_t hlim; 34482b24ab6bSSebastien Roy char *ep; 3449c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3450c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 34512b24ab6bSSebastien Roy 34522b24ab6bSSebastien Roy if (val_cnt != 1) 34532b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 34542b24ab6bSSebastien Roy 34552b24ab6bSSebastien Roy errno = 0; 34562b24ab6bSSebastien Roy hlim = strtol(*prop_val, &ep, 10); 34572b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || hlim < 1 || 34582b24ab6bSSebastien Roy hlim > (int32_t)UINT8_MAX) 34592b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 34602b24ab6bSSebastien Roy vdp->vd_val = hlim; 34612b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 34622b24ab6bSSebastien Roy } 34632b24ab6bSSebastien Roy 34642b24ab6bSSebastien Roy /* ARGSUSED */ 34652b24ab6bSSebastien Roy static dladm_status_t 34660dc2366fSVenugopal Iyer check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3467c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 34680dc2366fSVenugopal Iyer datalink_media_t media) 34692b24ab6bSSebastien Roy { 34702b24ab6bSSebastien Roy int32_t elim; 34712b24ab6bSSebastien Roy char *ep; 3472c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3473c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 34742b24ab6bSSebastien Roy 34752b24ab6bSSebastien Roy if (media != DL_IPV6) 34762b24ab6bSSebastien Roy return (DLADM_STATUS_BADARG); 34772b24ab6bSSebastien Roy 34782b24ab6bSSebastien Roy if (val_cnt != 1) 34792b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 34802b24ab6bSSebastien Roy 34812b24ab6bSSebastien Roy errno = 0; 34822b24ab6bSSebastien Roy elim = strtol(*prop_val, &ep, 10); 34832b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || elim < 0 || 34842b24ab6bSSebastien Roy elim > (int32_t)UINT8_MAX) 34852b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 34862b24ab6bSSebastien Roy vdp->vd_val = elim; 34872b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 34882b24ab6bSSebastien Roy } 34892b24ab6bSSebastien Roy 3490d62bc4baSyz147064 static dladm_status_t 34914ac67f02SAnurag S. Maskey i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 34924ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 3493d62bc4baSyz147064 { 3494d62bc4baSyz147064 char buf[MAXLINELEN]; 3495d62bc4baSyz147064 int i; 3496d62bc4baSyz147064 dladm_conf_t conf; 3497d62bc4baSyz147064 dladm_status_t status; 3498d62bc4baSyz147064 349932715170SCathy Zhou status = dladm_open_conf(handle, linkid, &conf); 3500f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 3501f4b3ec61Sdh155122 return (status); 3502f4b3ec61Sdh155122 3503d62bc4baSyz147064 /* 3504d62bc4baSyz147064 * reset case. 3505d62bc4baSyz147064 */ 3506d62bc4baSyz147064 if (val_cnt == 0) { 35074ac67f02SAnurag S. Maskey status = dladm_unset_conf_field(handle, conf, prop_name); 3508d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 35094ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3510d62bc4baSyz147064 goto done; 3511f4b3ec61Sdh155122 } 3512f4b3ec61Sdh155122 3513d62bc4baSyz147064 buf[0] = '\0'; 3514d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 3515d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 3516d62bc4baSyz147064 if (i != val_cnt - 1) 3517d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 3518d62bc4baSyz147064 } 3519f4b3ec61Sdh155122 35204ac67f02SAnurag S. Maskey status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 35214ac67f02SAnurag S. Maskey buf); 3522d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 35234ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3524d62bc4baSyz147064 3525d62bc4baSyz147064 done: 35264ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3527f4b3ec61Sdh155122 return (status); 3528f4b3ec61Sdh155122 } 3529f4b3ec61Sdh155122 3530f4b3ec61Sdh155122 static dladm_status_t 35314ac67f02SAnurag S. Maskey i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 35324ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 3533f4b3ec61Sdh155122 { 3534d62bc4baSyz147064 char buf[MAXLINELEN], *str; 3535d62bc4baSyz147064 uint_t cnt = 0; 3536d62bc4baSyz147064 dladm_conf_t conf; 3537d62bc4baSyz147064 dladm_status_t status; 3538f4b3ec61Sdh155122 353932715170SCathy Zhou status = dladm_getsnap_conf(handle, linkid, &conf); 3540d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3541f4b3ec61Sdh155122 return (status); 3542d62bc4baSyz147064 35434ac67f02SAnurag S. Maskey status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 3544d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3545d62bc4baSyz147064 goto done; 3546d62bc4baSyz147064 3547d62bc4baSyz147064 str = strtok(buf, ","); 3548d62bc4baSyz147064 while (str != NULL) { 3549d62bc4baSyz147064 if (cnt == *val_cntp) { 3550d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 3551d62bc4baSyz147064 goto done; 3552d62bc4baSyz147064 } 3553d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 3554d62bc4baSyz147064 str = strtok(NULL, ","); 3555f4b3ec61Sdh155122 } 3556f4b3ec61Sdh155122 3557d62bc4baSyz147064 *val_cntp = cnt; 3558f4b3ec61Sdh155122 3559d62bc4baSyz147064 done: 35604ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3561d62bc4baSyz147064 return (status); 3562f4b3ec61Sdh155122 } 3563e7801d59Ssowmini 356462ee1d25SArtem Kachitchkine /* 356562ee1d25SArtem Kachitchkine * Walk persistent private link properties of a link. 356662ee1d25SArtem Kachitchkine */ 356762ee1d25SArtem Kachitchkine static dladm_status_t 356862ee1d25SArtem Kachitchkine i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 356962ee1d25SArtem Kachitchkine void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 357062ee1d25SArtem Kachitchkine { 357162ee1d25SArtem Kachitchkine dladm_status_t status; 357262ee1d25SArtem Kachitchkine dladm_conf_t conf; 357362ee1d25SArtem Kachitchkine char last_attr[MAXLINKATTRLEN]; 357462ee1d25SArtem Kachitchkine char attr[MAXLINKATTRLEN]; 357562ee1d25SArtem Kachitchkine char attrval[MAXLINKATTRVALLEN]; 357662ee1d25SArtem Kachitchkine size_t attrsz; 357762ee1d25SArtem Kachitchkine 357862ee1d25SArtem Kachitchkine if (linkid == DATALINK_INVALID_LINKID || func == NULL) 357962ee1d25SArtem Kachitchkine return (DLADM_STATUS_BADARG); 358062ee1d25SArtem Kachitchkine 358132715170SCathy Zhou status = dladm_getsnap_conf(handle, linkid, &conf); 358262ee1d25SArtem Kachitchkine if (status != DLADM_STATUS_OK) 358362ee1d25SArtem Kachitchkine return (status); 358462ee1d25SArtem Kachitchkine 358562ee1d25SArtem Kachitchkine last_attr[0] = '\0'; 358662ee1d25SArtem Kachitchkine while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 358762ee1d25SArtem Kachitchkine attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 358862ee1d25SArtem Kachitchkine if (attr[0] == '_') { 358962ee1d25SArtem Kachitchkine if (func(handle, linkid, attr, arg) == 359062ee1d25SArtem Kachitchkine DLADM_WALK_TERMINATE) 359162ee1d25SArtem Kachitchkine break; 359262ee1d25SArtem Kachitchkine } 359362ee1d25SArtem Kachitchkine (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 359462ee1d25SArtem Kachitchkine } 359562ee1d25SArtem Kachitchkine 359662ee1d25SArtem Kachitchkine dladm_destroy_conf(handle, conf); 359762ee1d25SArtem Kachitchkine return (DLADM_STATUS_OK); 359862ee1d25SArtem Kachitchkine } 359962ee1d25SArtem Kachitchkine 3600bcb5c89dSSowmini Varadhan static link_attr_t * 3601e7801d59Ssowmini dladm_name2prop(const char *prop_name) 3602e7801d59Ssowmini { 3603bcb5c89dSSowmini Varadhan link_attr_t *p; 3604e7801d59Ssowmini 3605bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3606e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 3607e7801d59Ssowmini break; 3608e7801d59Ssowmini } 3609e7801d59Ssowmini return (p); 3610e7801d59Ssowmini } 3611e7801d59Ssowmini 3612bcb5c89dSSowmini Varadhan static link_attr_t * 3613bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid) 3614bcb5c89dSSowmini Varadhan { 3615bcb5c89dSSowmini Varadhan link_attr_t *p; 3616bcb5c89dSSowmini Varadhan 3617bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3618bcb5c89dSSowmini Varadhan if (p->pp_id == propid) 3619bcb5c89dSSowmini Varadhan break; 3620bcb5c89dSSowmini Varadhan } 3621bcb5c89dSSowmini Varadhan return (p); 3622bcb5c89dSSowmini Varadhan } 3623e7801d59Ssowmini 36243fd94f8cSam223141 static dld_ioc_macprop_t * 3625bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 3626bcb5c89dSSowmini Varadhan const char *prop_name, mac_prop_id_t propid, uint_t flags, 3627bcb5c89dSSowmini Varadhan dladm_status_t *status) 3628e7801d59Ssowmini { 3629e7801d59Ssowmini int dsize; 36303fd94f8cSam223141 dld_ioc_macprop_t *dip; 3631e7801d59Ssowmini 3632e7801d59Ssowmini *status = DLADM_STATUS_OK; 36333fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 3634e7801d59Ssowmini dip = malloc(dsize); 3635e7801d59Ssowmini if (dip == NULL) { 3636e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 3637e7801d59Ssowmini return (NULL); 3638e7801d59Ssowmini } 3639e7801d59Ssowmini bzero(dip, dsize); 3640e7801d59Ssowmini dip->pr_valsize = valsize; 36414045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 36426b9e797cSsowmini dip->pr_linkid = linkid; 3643bcb5c89dSSowmini Varadhan dip->pr_num = propid; 36444045d941Ssowmini dip->pr_flags = flags; 3645e7801d59Ssowmini return (dip); 3646e7801d59Ssowmini } 3647e7801d59Ssowmini 3648bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3649bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 3650bcb5c89dSSowmini Varadhan const char *prop_name, uint_t flags, dladm_status_t *status) 3651bcb5c89dSSowmini Varadhan { 3652bcb5c89dSSowmini Varadhan link_attr_t *p; 3653bcb5c89dSSowmini Varadhan 3654bcb5c89dSSowmini Varadhan p = dladm_name2prop(prop_name); 3655bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3656bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 3657bcb5c89dSSowmini Varadhan flags, status)); 3658bcb5c89dSSowmini Varadhan } 3659bcb5c89dSSowmini Varadhan 3660bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3661bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 3662bcb5c89dSSowmini Varadhan mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 3663bcb5c89dSSowmini Varadhan { 3664bcb5c89dSSowmini Varadhan link_attr_t *p; 3665bcb5c89dSSowmini Varadhan 3666bcb5c89dSSowmini Varadhan p = dladm_id2prop(propid); 3667bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3668bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 3669bcb5c89dSSowmini Varadhan flags, status)); 3670bcb5c89dSSowmini Varadhan } 3671bcb5c89dSSowmini Varadhan 3672e7801d59Ssowmini /* ARGSUSED */ 3673e7801d59Ssowmini static dladm_status_t 36740dc2366fSVenugopal Iyer set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 36754ac67f02SAnurag S. Maskey datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 36764ac67f02SAnurag S. Maskey datalink_media_t media) 3677e7801d59Ssowmini { 36783fd94f8cSam223141 dld_ioc_macprop_t *dip; 3679e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 3680e7801d59Ssowmini uint8_t u8; 3681e7801d59Ssowmini uint16_t u16; 3682e7801d59Ssowmini uint32_t u32; 3683e7801d59Ssowmini void *val; 3684e7801d59Ssowmini 3685da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 3686e7801d59Ssowmini if (dip == NULL) 3687e7801d59Ssowmini return (status); 3688e7801d59Ssowmini 3689da14cebeSEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 3690e7801d59Ssowmini val = (void *)vdp->vd_val; 3691e7801d59Ssowmini else { 3692e7801d59Ssowmini /* 3693e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 3694e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 3695e7801d59Ssowmini */ 3696e7801d59Ssowmini switch (dip->pr_valsize) { 3697e7801d59Ssowmini case 1: 3698e7801d59Ssowmini u8 = vdp->vd_val; 3699e7801d59Ssowmini val = &u8; 3700e7801d59Ssowmini break; 3701e7801d59Ssowmini case 2: 3702e7801d59Ssowmini u16 = vdp->vd_val; 3703e7801d59Ssowmini val = &u16; 3704e7801d59Ssowmini break; 3705e7801d59Ssowmini case 4: 3706e7801d59Ssowmini u32 = vdp->vd_val; 3707e7801d59Ssowmini val = &u32; 3708e7801d59Ssowmini break; 3709e7801d59Ssowmini default: 3710e7801d59Ssowmini val = &vdp->vd_val; 3711e7801d59Ssowmini break; 3712e7801d59Ssowmini } 3713e7801d59Ssowmini } 3714e7801d59Ssowmini 37153bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 3716e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 37173bc21d0aSAruna Ramakrishna - Sun Microsystems else 37183bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 37193bc21d0aSAruna Ramakrishna - Sun Microsystems 37204ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 3721bcb5c89dSSowmini Varadhan 3722bcb5c89dSSowmini Varadhan done: 3723bcb5c89dSSowmini Varadhan free(dip); 3724bcb5c89dSSowmini Varadhan return (status); 3725bcb5c89dSSowmini Varadhan } 3726bcb5c89dSSowmini Varadhan 3727bcb5c89dSSowmini Varadhan dladm_status_t 37284ac67f02SAnurag S. Maskey i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 3729bcb5c89dSSowmini Varadhan { 3730bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 3731bcb5c89dSSowmini Varadhan 37324ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), 37334ac67f02SAnurag S. Maskey (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 3734e7801d59Ssowmini status = dladm_errno2status(errno); 3735e7801d59Ssowmini 3736e7801d59Ssowmini return (status); 3737e7801d59Ssowmini } 3738e7801d59Ssowmini 37390dc2366fSVenugopal Iyer static dladm_status_t 37404ac67f02SAnurag S. Maskey i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 37410dc2366fSVenugopal Iyer char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 3742e7801d59Ssowmini { 37430dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 37440dc2366fSVenugopal Iyer dladm_status_t status; 37454045d941Ssowmini 37460dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 37474045d941Ssowmini if (dip == NULL) 37480dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 3749e7801d59Ssowmini 37500dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 37510dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) { 37524045d941Ssowmini free(dip); 37530dc2366fSVenugopal Iyer return (status); 37544045d941Ssowmini } 37550dc2366fSVenugopal Iyer 3756da14cebeSEric Cheng if (perm_flags != NULL) 3757da14cebeSEric Cheng *perm_flags = dip->pr_perm_flags; 3758da14cebeSEric Cheng 37590dc2366fSVenugopal Iyer if (arg != NULL) 37600dc2366fSVenugopal Iyer (void) memcpy(arg, dip->pr_val, size); 37610dc2366fSVenugopal Iyer free(dip); 37620dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3763e7801d59Ssowmini } 3764e7801d59Ssowmini 3765e7801d59Ssowmini /* ARGSUSED */ 3766e7801d59Ssowmini static dladm_status_t 37670dc2366fSVenugopal Iyer check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 3768c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 3769c569ef53SMichael Lim val_desc_t **vp, datalink_media_t media) 3770e7801d59Ssowmini { 3771c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3772c569ef53SMichael Lim val_desc_t *v = *vp; 3773c569ef53SMichael Lim 3774e7801d59Ssowmini if (val_cnt != 1) 3775e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 37764eaa4710SRishi Srivatsavai v->vd_val = strtoul(prop_val[0], NULL, 0); 3777e7801d59Ssowmini return (DLADM_STATUS_OK); 3778e7801d59Ssowmini } 3779e7801d59Ssowmini 3780e7801d59Ssowmini /* ARGSUSED */ 3781e7801d59Ssowmini static dladm_status_t 37820dc2366fSVenugopal Iyer get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 37834ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 37844ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3785e7801d59Ssowmini { 3786e7801d59Ssowmini link_duplex_t link_duplex; 3787e7801d59Ssowmini dladm_status_t status; 3788e7801d59Ssowmini 37894ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 3790e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 3791e7801d59Ssowmini return (status); 3792e7801d59Ssowmini 3793e7801d59Ssowmini switch (link_duplex) { 3794e7801d59Ssowmini case LINK_DUPLEX_FULL: 3795e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 3796e7801d59Ssowmini break; 3797e7801d59Ssowmini case LINK_DUPLEX_HALF: 3798e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 3799e7801d59Ssowmini break; 3800e7801d59Ssowmini default: 3801e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3802e7801d59Ssowmini break; 3803e7801d59Ssowmini } 3804e7801d59Ssowmini *val_cnt = 1; 3805e7801d59Ssowmini return (DLADM_STATUS_OK); 3806e7801d59Ssowmini } 3807e7801d59Ssowmini 3808e7801d59Ssowmini /* ARGSUSED */ 3809e7801d59Ssowmini static dladm_status_t 38100dc2366fSVenugopal Iyer get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 38110dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 38120dc2366fSVenugopal Iyer uint_t *perm_flags) 3813e7801d59Ssowmini { 3814e7801d59Ssowmini uint64_t ifspeed = 0; 3815e7801d59Ssowmini dladm_status_t status; 3816e7801d59Ssowmini 38174ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 3818e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 3819e7801d59Ssowmini return (status); 38204045d941Ssowmini 38216b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 38226b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 38236b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 38246b9e797cSsowmini } else { 3825e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 3826e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 38276b9e797cSsowmini } 3828e7801d59Ssowmini *val_cnt = 1; 3829da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 3830e7801d59Ssowmini return (DLADM_STATUS_OK); 3831e7801d59Ssowmini } 3832e7801d59Ssowmini 3833e7801d59Ssowmini /* ARGSUSED */ 3834e7801d59Ssowmini static dladm_status_t 38350dc2366fSVenugopal Iyer get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 38364ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 38374ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3838e7801d59Ssowmini { 3839e7801d59Ssowmini link_state_t link_state; 3840e7801d59Ssowmini dladm_status_t status; 3841e7801d59Ssowmini 38420dc2366fSVenugopal Iyer status = dladm_get_state(handle, linkid, &link_state); 38434045d941Ssowmini if (status != DLADM_STATUS_OK) 3844e7801d59Ssowmini return (status); 3845da14cebeSEric Cheng 3846e7801d59Ssowmini switch (link_state) { 3847e7801d59Ssowmini case LINK_STATE_UP: 3848e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 3849e7801d59Ssowmini break; 3850e7801d59Ssowmini case LINK_STATE_DOWN: 3851e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 3852e7801d59Ssowmini break; 3853e7801d59Ssowmini default: 3854e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3855e7801d59Ssowmini break; 3856e7801d59Ssowmini } 3857e7801d59Ssowmini *val_cnt = 1; 38584784fcbdSSowmini Varadhan *perm_flags = MAC_PROP_PERM_READ; 3859e7801d59Ssowmini return (DLADM_STATUS_OK); 3860e7801d59Ssowmini } 3861e7801d59Ssowmini 3862e7801d59Ssowmini /* ARGSUSED */ 3863e7801d59Ssowmini static dladm_status_t 38640dc2366fSVenugopal Iyer get_binary(dladm_handle_t handle, prop_desc_t *pdp, 38654ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 38664ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3867e7801d59Ssowmini { 3868e7801d59Ssowmini dladm_status_t status; 38690dc2366fSVenugopal Iyer uint_t v = 0; 3870e7801d59Ssowmini 38710dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 38720dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 38730dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3874e7801d59Ssowmini return (status); 3875da14cebeSEric Cheng 38760dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 3877e7801d59Ssowmini *val_cnt = 1; 3878e7801d59Ssowmini return (DLADM_STATUS_OK); 3879e7801d59Ssowmini } 3880e7801d59Ssowmini 38816b9e797cSsowmini /* ARGSUSED */ 3882e7801d59Ssowmini static dladm_status_t 38830dc2366fSVenugopal Iyer get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 38844ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 38854ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3886e7801d59Ssowmini { 38870dc2366fSVenugopal Iyer dladm_status_t status; 38884045d941Ssowmini uint32_t v = 0; 3889e7801d59Ssowmini 38900dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 38910dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 38920dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3893e7801d59Ssowmini return (status); 3894da14cebeSEric Cheng 38954045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 3896e7801d59Ssowmini *val_cnt = 1; 3897e7801d59Ssowmini return (DLADM_STATUS_OK); 3898e7801d59Ssowmini } 3899e7801d59Ssowmini 3900f0f2c3a5SGirish Moodalbail /* ARGSUSED */ 3901f0f2c3a5SGirish Moodalbail static dladm_status_t 39020dc2366fSVenugopal Iyer get_range(dladm_handle_t handle, prop_desc_t *pdp, 3903f0f2c3a5SGirish Moodalbail datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3904f0f2c3a5SGirish Moodalbail datalink_media_t media, uint_t flags, uint_t *perm_flags) 3905f0f2c3a5SGirish Moodalbail { 3906f0f2c3a5SGirish Moodalbail dld_ioc_macprop_t *dip; 3907f0f2c3a5SGirish Moodalbail dladm_status_t status = DLADM_STATUS_OK; 3908f0f2c3a5SGirish Moodalbail size_t sz; 39090591ddd0SPrakash Jalan uint_t rcount; 3910f0f2c3a5SGirish Moodalbail mac_propval_range_t *rangep; 3911f0f2c3a5SGirish Moodalbail 3912f0f2c3a5SGirish Moodalbail /* 3913f0f2c3a5SGirish Moodalbail * As caller we don't know number of value ranges, the driver 3914f0f2c3a5SGirish Moodalbail * supports. To begin with we assume that number to be 1. If the 3915f0f2c3a5SGirish Moodalbail * buffer size is insufficient, driver returns back with the 3916f0f2c3a5SGirish Moodalbail * actual count of value ranges. See mac.h for more details. 3917f0f2c3a5SGirish Moodalbail */ 39180591ddd0SPrakash Jalan sz = sizeof (mac_propval_range_t); 39190591ddd0SPrakash Jalan rcount = 1; 3920f0f2c3a5SGirish Moodalbail retry: 3921f0f2c3a5SGirish Moodalbail if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 3922f0f2c3a5SGirish Moodalbail &status)) == NULL) 3923f0f2c3a5SGirish Moodalbail return (status); 3924f0f2c3a5SGirish Moodalbail 39250591ddd0SPrakash Jalan rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 39260591ddd0SPrakash Jalan rangep->mpr_count = rcount; 39270591ddd0SPrakash Jalan 3928f0f2c3a5SGirish Moodalbail status = i_dladm_macprop(handle, dip, B_FALSE); 3929f0f2c3a5SGirish Moodalbail if (status != DLADM_STATUS_OK) { 3930f0f2c3a5SGirish Moodalbail if (status == DLADM_STATUS_TOOSMALL) { 3931f0f2c3a5SGirish Moodalbail int err; 3932f0f2c3a5SGirish Moodalbail 39330591ddd0SPrakash Jalan if ((err = i_dladm_range_size(rangep, &sz, &rcount)) 39340591ddd0SPrakash Jalan == 0) { 3935f0f2c3a5SGirish Moodalbail free(dip); 3936f0f2c3a5SGirish Moodalbail goto retry; 3937f0f2c3a5SGirish Moodalbail } else { 3938f0f2c3a5SGirish Moodalbail status = dladm_errno2status(err); 3939f0f2c3a5SGirish Moodalbail } 3940f0f2c3a5SGirish Moodalbail } 3941f0f2c3a5SGirish Moodalbail free(dip); 3942f0f2c3a5SGirish Moodalbail return (status); 3943f0f2c3a5SGirish Moodalbail } 39440dc2366fSVenugopal Iyer 39450dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 39460dc2366fSVenugopal Iyer *val_cnt = 1; 39470dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 39480dc2366fSVenugopal Iyer goto done; 39490dc2366fSVenugopal Iyer } 3950f0f2c3a5SGirish Moodalbail 3951f0f2c3a5SGirish Moodalbail switch (rangep->mpr_type) { 3952f0f2c3a5SGirish Moodalbail case MAC_PROPVAL_UINT32: { 3953f0f2c3a5SGirish Moodalbail mac_propval_uint32_range_t *ur; 3954f0f2c3a5SGirish Moodalbail uint_t count = rangep->mpr_count, i; 3955f0f2c3a5SGirish Moodalbail 39560dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 3957f0f2c3a5SGirish Moodalbail 3958f0f2c3a5SGirish Moodalbail for (i = 0; i < count; i++, ur++) { 3959f0f2c3a5SGirish Moodalbail if (ur->mpur_min == ur->mpur_max) { 3960f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 3961f0f2c3a5SGirish Moodalbail "%ld", ur->mpur_min); 3962f0f2c3a5SGirish Moodalbail } else { 3963f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 3964f0f2c3a5SGirish Moodalbail "%ld-%ld", ur->mpur_min, ur->mpur_max); 3965f0f2c3a5SGirish Moodalbail } 3966f0f2c3a5SGirish Moodalbail } 3967f0f2c3a5SGirish Moodalbail *val_cnt = count; 3968f0f2c3a5SGirish Moodalbail break; 3969f0f2c3a5SGirish Moodalbail } 3970f0f2c3a5SGirish Moodalbail default: 3971f0f2c3a5SGirish Moodalbail status = DLADM_STATUS_BADARG; 3972f0f2c3a5SGirish Moodalbail break; 3973f0f2c3a5SGirish Moodalbail } 39740dc2366fSVenugopal Iyer done: 3975f0f2c3a5SGirish Moodalbail free(dip); 3976f0f2c3a5SGirish Moodalbail return (status); 3977f0f2c3a5SGirish Moodalbail } 3978f0f2c3a5SGirish Moodalbail 39796b9e797cSsowmini /* ARGSUSED */ 3980e7801d59Ssowmini static dladm_status_t 39810dc2366fSVenugopal Iyer get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 3982e75f0919SSebastien Roy datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 3983e75f0919SSebastien Roy datalink_media_t media, uint_t flags, uint_t *perm_flags) 3984e75f0919SSebastien Roy { 3985e75f0919SSebastien Roy link_tagmode_t mode; 3986e75f0919SSebastien Roy dladm_status_t status; 3987e75f0919SSebastien Roy 39880dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 39890dc2366fSVenugopal Iyer perm_flags, &mode, sizeof (mode)); 39900dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3991e75f0919SSebastien Roy return (status); 3992e75f0919SSebastien Roy 3993e75f0919SSebastien Roy switch (mode) { 3994e75f0919SSebastien Roy case LINK_TAGMODE_NORMAL: 3995e75f0919SSebastien Roy (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 3996e75f0919SSebastien Roy break; 3997e75f0919SSebastien Roy case LINK_TAGMODE_VLANONLY: 3998e75f0919SSebastien Roy (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 3999e75f0919SSebastien Roy break; 4000e75f0919SSebastien Roy default: 4001e75f0919SSebastien Roy (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 4002e75f0919SSebastien Roy } 4003e75f0919SSebastien Roy *val_cnt = 1; 4004e75f0919SSebastien Roy return (DLADM_STATUS_OK); 4005e75f0919SSebastien Roy } 4006e75f0919SSebastien Roy 4007e75f0919SSebastien Roy /* ARGSUSED */ 4008e75f0919SSebastien Roy static dladm_status_t 40090dc2366fSVenugopal Iyer get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 40104ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 40114ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 4012e7801d59Ssowmini { 4013e7801d59Ssowmini link_flowctrl_t v; 4014e7801d59Ssowmini dladm_status_t status; 4015e7801d59Ssowmini 40160dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 40170dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 40180dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 4019e7801d59Ssowmini return (status); 4020da14cebeSEric Cheng 4021e7801d59Ssowmini switch (v) { 4022e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 4023e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 4024e7801d59Ssowmini break; 4025e7801d59Ssowmini case LINK_FLOWCTRL_RX: 4026e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 4027e7801d59Ssowmini break; 4028e7801d59Ssowmini case LINK_FLOWCTRL_TX: 4029e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 4030e7801d59Ssowmini break; 4031e7801d59Ssowmini case LINK_FLOWCTRL_BI: 4032e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 4033e7801d59Ssowmini break; 4034e7801d59Ssowmini } 4035e7801d59Ssowmini *val_cnt = 1; 4036e7801d59Ssowmini return (DLADM_STATUS_OK); 4037e7801d59Ssowmini } 4038e7801d59Ssowmini 4039e7801d59Ssowmini 4040e7801d59Ssowmini /* ARGSUSED */ 4041e7801d59Ssowmini static dladm_status_t 40423361618bSRishi Srivatsavai i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 40434ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 40444ac67f02SAnurag S. Maskey 4045e7801d59Ssowmini { 4046bcb5c89dSSowmini Varadhan int i, slen; 4047eae72b5bSSebastien Roy int bufsize = 0; 40483fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 4049e7801d59Ssowmini uchar_t *dp; 4050bcb5c89dSSowmini Varadhan link_attr_t *p; 40514045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 4052e7801d59Ssowmini 4053e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 4054e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 4055e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4056e7801d59Ssowmini p = dladm_name2prop(prop_name); 40573fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 4058e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4059e7801d59Ssowmini 40603361618bSRishi Srivatsavai if (!(flags & DLADM_OPT_ACTIVE)) 40613361618bSRishi Srivatsavai return (DLADM_STATUS_OK); 40623361618bSRishi Srivatsavai 4063e7801d59Ssowmini /* 4064e7801d59Ssowmini * private properties: all parsing is done in the kernel. 4065e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 4066e7801d59Ssowmini */ 4067e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 4068e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 4069e7801d59Ssowmini } 40704045d941Ssowmini 40714045d941Ssowmini if (prop_val == NULL) { 40724045d941Ssowmini /* 40734045d941Ssowmini * getting default value. so use more buffer space. 40744045d941Ssowmini */ 4075bcb5c89dSSowmini Varadhan bufsize += DLADM_PROP_BUF_CHUNK; 40764045d941Ssowmini } 40774045d941Ssowmini 4078bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 40790dc2366fSVenugopal Iyer (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 4080e7801d59Ssowmini if (dip == NULL) 4081e7801d59Ssowmini return (status); 4082e7801d59Ssowmini 4083e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 4084e7801d59Ssowmini slen = 0; 4085bcb5c89dSSowmini Varadhan 40864045d941Ssowmini if (prop_val == NULL) { 40874ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_FALSE); 408862ee1d25SArtem Kachitchkine dip->pr_flags = 0; 40894045d941Ssowmini } else { 4090e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 4091e7801d59Ssowmini int plen = 0; 4092e7801d59Ssowmini 4093e7801d59Ssowmini plen = strlen(prop_val[i]); 4094e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 4095e7801d59Ssowmini slen += plen; 4096e7801d59Ssowmini /* 4097e7801d59Ssowmini * add a "," separator and update dp. 4098e7801d59Ssowmini */ 4099e7801d59Ssowmini if (i != (val_cnt -1)) 4100e7801d59Ssowmini dp[slen++] = ','; 4101e7801d59Ssowmini dp += (plen + 1); 4102e7801d59Ssowmini } 4103e7801d59Ssowmini } 410462ee1d25SArtem Kachitchkine if (status == DLADM_STATUS_OK) 410562ee1d25SArtem Kachitchkine status = i_dladm_macprop(handle, dip, B_TRUE); 41064045d941Ssowmini 4107e7801d59Ssowmini free(dip); 4108e7801d59Ssowmini return (status); 4109e7801d59Ssowmini } 4110e7801d59Ssowmini 4111e7801d59Ssowmini static dladm_status_t 411262ee1d25SArtem Kachitchkine i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 41134ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cnt, 41144ac67f02SAnurag S. Maskey dladm_prop_type_t type, uint_t dld_flags) 4115e7801d59Ssowmini { 4116e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 41173fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 4118bcb5c89dSSowmini Varadhan link_attr_t *p; 4119e7801d59Ssowmini 4120e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 4121e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 4122e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4123e7801d59Ssowmini 4124e7801d59Ssowmini p = dladm_name2prop(prop_name); 41253fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 4126e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4127e7801d59Ssowmini 4128e7801d59Ssowmini /* 4129e7801d59Ssowmini * private properties: all parsing is done in the kernel. 4130e7801d59Ssowmini */ 4131bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 4132bcb5c89dSSowmini Varadhan dld_flags, &status); 4133e7801d59Ssowmini if (dip == NULL) 4134e7801d59Ssowmini return (status); 4135e7801d59Ssowmini 41364ac67f02SAnurag S. Maskey if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 41374ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 4138afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_PERM) { 4139da14cebeSEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 414062ee1d25SArtem Kachitchkine } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 414162ee1d25SArtem Kachitchkine *prop_val[0] = '\0'; 4142afdda45fSVasumathi Sundaram - Sun Microsystems } else { 4143afdda45fSVasumathi Sundaram - Sun Microsystems (void) strncpy(*prop_val, dip->pr_val, 4144afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_MAX); 4145afdda45fSVasumathi Sundaram - Sun Microsystems } 4146e7801d59Ssowmini *val_cnt = 1; 414762ee1d25SArtem Kachitchkine } else if ((status == DLADM_STATUS_NOTSUP) && 414862ee1d25SArtem Kachitchkine (type == DLADM_PROP_VAL_CURRENT)) { 414962ee1d25SArtem Kachitchkine status = DLADM_STATUS_NOTFOUND; 4150e7801d59Ssowmini } 41514045d941Ssowmini free(dip); 41524045d941Ssowmini return (status); 41534045d941Ssowmini } 41544045d941Ssowmini 41554045d941Ssowmini 41564045d941Ssowmini static dladm_status_t 41574ac67f02SAnurag S. Maskey i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 41584ac67f02SAnurag S. Maskey datalink_id_t linkid, datalink_media_t media, uint_t flags) 41594045d941Ssowmini { 41604045d941Ssowmini dladm_status_t status; 41614045d941Ssowmini char **prop_vals = NULL, *buf; 41624045d941Ssowmini size_t bufsize; 41634045d941Ssowmini uint_t cnt; 41644045d941Ssowmini int i; 4165afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 41664045d941Ssowmini 41674045d941Ssowmini /* 41684045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 41694045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 41704045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 41714045d941Ssowmini */ 41724045d941Ssowmini bufsize = 41734045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 41744045d941Ssowmini buf = malloc(bufsize); 41754045d941Ssowmini prop_vals = (char **)(void *)buf; 41764045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 41774045d941Ssowmini prop_vals[i] = buf + 41784045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 41794045d941Ssowmini i * DLADM_PROP_VAL_MAX; 41804045d941Ssowmini } 418113a55820Sar224390 418213a55820Sar224390 /* 41833bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 41843bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 41853bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 41863bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 41873bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 41883bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 41893bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 41903bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 419113a55820Sar224390 */ 41924ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 41930dc2366fSVenugopal Iyer DLD_PROP_DEFAULT, &perm_flags); 41944045d941Ssowmini if (status == DLADM_STATUS_OK) { 4195afdda45fSVasumathi Sundaram - Sun Microsystems if (perm_flags == MAC_PROP_PERM_RW) { 41964ac67f02SAnurag S. Maskey status = i_dladm_set_single_prop(handle, linkid, 41974ac67f02SAnurag S. Maskey pdp->pd_class, media, pdp, prop_vals, cnt, flags); 41984045d941Ssowmini } 4199afdda45fSVasumathi Sundaram - Sun Microsystems else 4200afdda45fSVasumathi Sundaram - Sun Microsystems status = DLADM_STATUS_NOTSUP; 4201afdda45fSVasumathi Sundaram - Sun Microsystems } 42024045d941Ssowmini free(buf); 4203e7801d59Ssowmini return (status); 4204e7801d59Ssowmini } 4205bcb5c89dSSowmini Varadhan 42064eaa4710SRishi Srivatsavai /* ARGSUSED */ 42074eaa4710SRishi Srivatsavai static dladm_status_t 42080dc2366fSVenugopal Iyer get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 42094eaa4710SRishi Srivatsavai char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 42104eaa4710SRishi Srivatsavai uint_t *perm_flags) 42114eaa4710SRishi Srivatsavai { 42124eaa4710SRishi Srivatsavai const bridge_public_prop_t *bpp; 42134eaa4710SRishi Srivatsavai dladm_status_t retv; 42144eaa4710SRishi Srivatsavai int val, i; 42154eaa4710SRishi Srivatsavai 42164eaa4710SRishi Srivatsavai if (flags != 0) 42174eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 42184eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 42194eaa4710SRishi Srivatsavai *val_cnt = 1; 42204eaa4710SRishi Srivatsavai for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 42214eaa4710SRishi Srivatsavai if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 42224eaa4710SRishi Srivatsavai break; 42234eaa4710SRishi Srivatsavai retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 42244eaa4710SRishi Srivatsavai /* If the daemon isn't running, then return the persistent value */ 42254eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 42264eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 42274eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 42284eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 42294eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 42304eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 42314eaa4710SRishi Srivatsavai } 42324eaa4710SRishi Srivatsavai if (retv != DLADM_STATUS_OK) { 42334eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 42344eaa4710SRishi Srivatsavai return (retv); 42354eaa4710SRishi Srivatsavai } 42364eaa4710SRishi Srivatsavai if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 42374eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 42384eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 42394eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 42404eaa4710SRishi Srivatsavai } 42414eaa4710SRishi Srivatsavai for (i = 0; i < pd->pd_noptval; i++) { 42424eaa4710SRishi Srivatsavai if (val == pd->pd_optval[i].vd_val) { 42434eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 42444eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 42454eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 42464eaa4710SRishi Srivatsavai } 42474eaa4710SRishi Srivatsavai } 42484eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 42494eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 42504eaa4710SRishi Srivatsavai } 42514eaa4710SRishi Srivatsavai 42524eaa4710SRishi Srivatsavai /* ARGSUSED1 */ 42534eaa4710SRishi Srivatsavai static dladm_status_t 42544eaa4710SRishi Srivatsavai set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 42554eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 42564eaa4710SRishi Srivatsavai { 42574eaa4710SRishi Srivatsavai /* 42584eaa4710SRishi Srivatsavai * Special case for mcheck: the daemon resets the value to zero, and we 42594eaa4710SRishi Srivatsavai * don't want the daemon to refresh itself; it leads to deadlock. 42604eaa4710SRishi Srivatsavai */ 42614eaa4710SRishi Srivatsavai if (flags & DLADM_OPT_NOREFRESH) 42624eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 42634eaa4710SRishi Srivatsavai 42644eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 42654eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 42664eaa4710SRishi Srivatsavai } 42674eaa4710SRishi Srivatsavai 42684eaa4710SRishi Srivatsavai /* 42694eaa4710SRishi Srivatsavai * This is used only for stp_priority, stp_cost, and stp_mcheck. 42704eaa4710SRishi Srivatsavai */ 42714eaa4710SRishi Srivatsavai /* ARGSUSED */ 42724eaa4710SRishi Srivatsavai static dladm_status_t 42734eaa4710SRishi Srivatsavai check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 4274c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 4275c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 42764eaa4710SRishi Srivatsavai { 42774eaa4710SRishi Srivatsavai char *cp; 42784eaa4710SRishi Srivatsavai boolean_t iscost; 4279c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 4280c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 42814eaa4710SRishi Srivatsavai 42824eaa4710SRishi Srivatsavai if (val_cnt != 1) 42834eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 42844eaa4710SRishi Srivatsavai 42854eaa4710SRishi Srivatsavai if (prop_val == NULL) { 42864eaa4710SRishi Srivatsavai vdp->vd_val = 0; 42874eaa4710SRishi Srivatsavai } else { 42884eaa4710SRishi Srivatsavai /* Only stp_priority and stp_cost use this function */ 42894eaa4710SRishi Srivatsavai iscost = strcmp(pd->pd_name, "stp_cost") == 0; 42904eaa4710SRishi Srivatsavai 42914eaa4710SRishi Srivatsavai if (iscost && strcmp(prop_val[0], "auto") == 0) { 42924eaa4710SRishi Srivatsavai /* Illegal value 0 is allowed to mean "automatic" */ 42934eaa4710SRishi Srivatsavai vdp->vd_val = 0; 42944eaa4710SRishi Srivatsavai } else { 42954eaa4710SRishi Srivatsavai errno = 0; 42964eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 42974eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 42984eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 42994eaa4710SRishi Srivatsavai } 43004eaa4710SRishi Srivatsavai } 43014eaa4710SRishi Srivatsavai 43024eaa4710SRishi Srivatsavai if (iscost) { 43034eaa4710SRishi Srivatsavai return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 43044eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 43054eaa4710SRishi Srivatsavai } else { 43064eaa4710SRishi Srivatsavai if (vdp->vd_val > 255) 43074eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 43084eaa4710SRishi Srivatsavai /* 43094eaa4710SRishi Srivatsavai * If the user is setting stp_mcheck non-zero, then (per the 43104eaa4710SRishi Srivatsavai * IEEE management standards and UNH testing) we need to check 43114eaa4710SRishi Srivatsavai * whether this link is part of a bridge that is running RSTP. 43124eaa4710SRishi Srivatsavai * If it's not, then setting the flag is an error. Note that 43134eaa4710SRishi Srivatsavai * errors are intentionally discarded here; it's the value 43144eaa4710SRishi Srivatsavai * that's the problem -- it's not a bad value, merely one that 43154eaa4710SRishi Srivatsavai * can't be used now. 43164eaa4710SRishi Srivatsavai */ 43174eaa4710SRishi Srivatsavai if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 43184eaa4710SRishi Srivatsavai vdp->vd_val != 0) { 43194eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 43204eaa4710SRishi Srivatsavai UID_STP_CFG_T cfg; 43214eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot; 43224eaa4710SRishi Srivatsavai 43234eaa4710SRishi Srivatsavai if (dladm_bridge_getlink(handle, linkid, bridge, 43244eaa4710SRishi Srivatsavai sizeof (bridge)) != DLADM_STATUS_OK || 43254eaa4710SRishi Srivatsavai dladm_bridge_get_properties(bridge, &cfg, 43264eaa4710SRishi Srivatsavai &brprot) != DLADM_STATUS_OK) 43274eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 43284eaa4710SRishi Srivatsavai if (cfg.force_version <= 1) 43294eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 43304eaa4710SRishi Srivatsavai } 43314eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43324eaa4710SRishi Srivatsavai } 43334eaa4710SRishi Srivatsavai } 43344eaa4710SRishi Srivatsavai 43354eaa4710SRishi Srivatsavai /* ARGSUSED */ 43364eaa4710SRishi Srivatsavai static dladm_status_t 43374eaa4710SRishi Srivatsavai get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 43384eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 43394eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 43404eaa4710SRishi Srivatsavai { 43414eaa4710SRishi Srivatsavai dladm_status_t retv; 43424eaa4710SRishi Srivatsavai uint_t val; 43434eaa4710SRishi Srivatsavai 43444eaa4710SRishi Srivatsavai if (flags != 0) 43454eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 43464eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 43474eaa4710SRishi Srivatsavai *val_cnt = 1; 43484eaa4710SRishi Srivatsavai retv = dladm_bridge_get_forwarding(handle, linkid, &val); 43494eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 43504eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 43514eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 43524eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 43534eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 43544eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43554eaa4710SRishi Srivatsavai } 43564eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_OK) 43574eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 43584eaa4710SRishi Srivatsavai else 43594eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 43604eaa4710SRishi Srivatsavai return (retv); 43614eaa4710SRishi Srivatsavai } 43624eaa4710SRishi Srivatsavai 43634eaa4710SRishi Srivatsavai /* ARGSUSED */ 43644eaa4710SRishi Srivatsavai static dladm_status_t 43654eaa4710SRishi Srivatsavai set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 43664eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 43674eaa4710SRishi Srivatsavai { 43684eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 43694eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 43704eaa4710SRishi Srivatsavai } 43714eaa4710SRishi Srivatsavai 43724eaa4710SRishi Srivatsavai /* ARGSUSED */ 43734eaa4710SRishi Srivatsavai static dladm_status_t 43744eaa4710SRishi Srivatsavai get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 43754eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 43764eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 43774eaa4710SRishi Srivatsavai { 43784eaa4710SRishi Srivatsavai dladm_status_t status; 43794eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 43804eaa4710SRishi Srivatsavai uint16_t pvid; 43814eaa4710SRishi Srivatsavai 43824eaa4710SRishi Srivatsavai if (flags != 0) 43834eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 43844eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 43854eaa4710SRishi Srivatsavai *val_cnt = 1; 43864eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 43874eaa4710SRishi Srivatsavai 0, &status); 43884eaa4710SRishi Srivatsavai if (dip == NULL) 43894eaa4710SRishi Srivatsavai return (status); 43904eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_FALSE); 43914eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 43924eaa4710SRishi Srivatsavai (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 43934eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 43944eaa4710SRishi Srivatsavai } else { 43954eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 43964eaa4710SRishi Srivatsavai } 43974eaa4710SRishi Srivatsavai free(dip); 43984eaa4710SRishi Srivatsavai return (status); 43994eaa4710SRishi Srivatsavai } 44004eaa4710SRishi Srivatsavai 44014eaa4710SRishi Srivatsavai /* ARGSUSED */ 44024eaa4710SRishi Srivatsavai static dladm_status_t 44034eaa4710SRishi Srivatsavai set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 44044eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 44054eaa4710SRishi Srivatsavai { 44064eaa4710SRishi Srivatsavai dladm_status_t status; 44074eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 44084eaa4710SRishi Srivatsavai uint16_t pvid; 44094eaa4710SRishi Srivatsavai 44104eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 44114eaa4710SRishi Srivatsavai 0, &status); 44124eaa4710SRishi Srivatsavai if (dip == NULL) 44134eaa4710SRishi Srivatsavai return (status); 44144eaa4710SRishi Srivatsavai pvid = vdp->vd_val; 44154eaa4710SRishi Srivatsavai (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 44164eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_TRUE); 44174eaa4710SRishi Srivatsavai free(dip); 44184eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 44194eaa4710SRishi Srivatsavai return (status); 44204eaa4710SRishi Srivatsavai 44214eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 44224eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 44234eaa4710SRishi Srivatsavai } 44244eaa4710SRishi Srivatsavai 44254eaa4710SRishi Srivatsavai /* ARGSUSED */ 44264eaa4710SRishi Srivatsavai static dladm_status_t 44274eaa4710SRishi Srivatsavai check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 4428c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 4429c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 44304eaa4710SRishi Srivatsavai { 44314eaa4710SRishi Srivatsavai char *cp; 4432c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 4433c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 44344eaa4710SRishi Srivatsavai 44354eaa4710SRishi Srivatsavai if (val_cnt != 1) 44364eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 44374eaa4710SRishi Srivatsavai 44384eaa4710SRishi Srivatsavai if (prop_val == NULL) { 44394eaa4710SRishi Srivatsavai vdp->vd_val = 1; 44404eaa4710SRishi Srivatsavai } else { 44414eaa4710SRishi Srivatsavai errno = 0; 44424eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 44434eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 44444eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 44454eaa4710SRishi Srivatsavai } 44464eaa4710SRishi Srivatsavai 44474eaa4710SRishi Srivatsavai return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 44484eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 44494eaa4710SRishi Srivatsavai } 44504eaa4710SRishi Srivatsavai 4451bcb5c89dSSowmini Varadhan dladm_status_t 44524ac67f02SAnurag S. Maskey i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 44534ac67f02SAnurag S. Maskey mac_prop_id_t cmd, size_t len, boolean_t set) 4454bcb5c89dSSowmini Varadhan { 4455bcb5c89dSSowmini Varadhan uint32_t flags; 4456bcb5c89dSSowmini Varadhan dladm_status_t status; 4457bcb5c89dSSowmini Varadhan uint32_t media; 4458bcb5c89dSSowmini Varadhan dld_ioc_macprop_t *dip; 4459bcb5c89dSSowmini Varadhan void *dp; 4460bcb5c89dSSowmini Varadhan 44614ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 44624ac67f02SAnurag S. Maskey &media, NULL, 0)) != DLADM_STATUS_OK) { 4463bcb5c89dSSowmini Varadhan return (status); 4464bcb5c89dSSowmini Varadhan } 4465bcb5c89dSSowmini Varadhan 4466bcb5c89dSSowmini Varadhan if (media != DL_WIFI) 4467bcb5c89dSSowmini Varadhan return (DLADM_STATUS_BADARG); 4468bcb5c89dSSowmini Varadhan 4469bcb5c89dSSowmini Varadhan if (!(flags & DLADM_OPT_ACTIVE)) 4470bcb5c89dSSowmini Varadhan return (DLADM_STATUS_TEMPONLY); 4471bcb5c89dSSowmini Varadhan 4472bcb5c89dSSowmini Varadhan if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 4473bcb5c89dSSowmini Varadhan len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 4474bcb5c89dSSowmini Varadhan 4475bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 4476bcb5c89dSSowmini Varadhan if (dip == NULL) 4477bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 4478bcb5c89dSSowmini Varadhan 4479bcb5c89dSSowmini Varadhan dp = (uchar_t *)dip->pr_val; 4480bcb5c89dSSowmini Varadhan if (set) 4481bcb5c89dSSowmini Varadhan (void) memcpy(dp, buf, len); 4482bcb5c89dSSowmini Varadhan 44834ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, set); 44840b8f0546SSowmini Varadhan if (status == DLADM_STATUS_OK) { 4485bcb5c89dSSowmini Varadhan if (!set) 4486bcb5c89dSSowmini Varadhan (void) memcpy(buf, dp, len); 4487bcb5c89dSSowmini Varadhan } 4488bcb5c89dSSowmini Varadhan 4489bcb5c89dSSowmini Varadhan free(dip); 4490bcb5c89dSSowmini Varadhan return (status); 4491bcb5c89dSSowmini Varadhan } 4492bcb5c89dSSowmini Varadhan 4493da14cebeSEric Cheng dladm_status_t 4494da14cebeSEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 4495da14cebeSEric Cheng { 449662ee1d25SArtem Kachitchkine return (dladm_parse_args(str, listp, novalues)); 4497da14cebeSEric Cheng } 4498da14cebeSEric Cheng 4499da14cebeSEric Cheng /* 4500da14cebeSEric Cheng * Retrieve the one link property from the database 4501da14cebeSEric Cheng */ 4502da14cebeSEric Cheng /*ARGSUSED*/ 4503da14cebeSEric Cheng static int 45044ac67f02SAnurag S. Maskey i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 45054ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 4506da14cebeSEric Cheng { 4507da14cebeSEric Cheng dladm_arg_list_t *proplist = arg; 4508da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4509da14cebeSEric Cheng 4510da14cebeSEric Cheng aip = &proplist->al_info[proplist->al_count]; 4511da14cebeSEric Cheng /* 4512da14cebeSEric Cheng * it is fine to point to prop_name since prop_name points to the 4513da14cebeSEric Cheng * prop_table[n].pd_name. 4514da14cebeSEric Cheng */ 4515da14cebeSEric Cheng aip->ai_name = prop_name; 4516da14cebeSEric Cheng 45174ac67f02SAnurag S. Maskey (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 45184ac67f02SAnurag S. Maskey prop_name, aip->ai_val, &aip->ai_count); 4519da14cebeSEric Cheng 4520da14cebeSEric Cheng if (aip->ai_count != 0) 4521da14cebeSEric Cheng proplist->al_count++; 4522da14cebeSEric Cheng 4523da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 4524da14cebeSEric Cheng } 4525da14cebeSEric Cheng 4526da14cebeSEric Cheng 4527da14cebeSEric Cheng /* 4528da14cebeSEric Cheng * Retrieve all link properties for a link from the database and 4529da14cebeSEric Cheng * return a property list. 4530da14cebeSEric Cheng */ 4531da14cebeSEric Cheng dladm_status_t 45324ac67f02SAnurag S. Maskey dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 45334ac67f02SAnurag S. Maskey dladm_arg_list_t **listp) 4534da14cebeSEric Cheng { 4535da14cebeSEric Cheng dladm_arg_list_t *list; 4536da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 4537da14cebeSEric Cheng 4538da14cebeSEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 4539da14cebeSEric Cheng if (list == NULL) 4540da14cebeSEric Cheng return (dladm_errno2status(errno)); 4541da14cebeSEric Cheng 45424ac67f02SAnurag S. Maskey status = dladm_walk_linkprop(handle, linkid, list, 45434ac67f02SAnurag S. Maskey i_dladm_get_one_prop); 4544da14cebeSEric Cheng 4545da14cebeSEric Cheng *listp = list; 4546da14cebeSEric Cheng return (status); 4547da14cebeSEric Cheng } 4548da14cebeSEric Cheng 4549da14cebeSEric Cheng /* 4550da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 4551da14cebeSEric Cheng * convert to a kernel structure. 4552da14cebeSEric Cheng */ 4553da14cebeSEric Cheng static dladm_status_t 45544ac67f02SAnurag S. Maskey i_dladm_link_proplist_extract_one(dladm_handle_t handle, 45550dc2366fSVenugopal Iyer dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 4556da14cebeSEric Cheng { 4557da14cebeSEric Cheng dladm_status_t status; 4558da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4559da14cebeSEric Cheng int i, j; 4560da14cebeSEric Cheng 4561da14cebeSEric Cheng /* Find named property in proplist */ 4562da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 4563da14cebeSEric Cheng aip = &proplist->al_info[i]; 4564da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 4565da14cebeSEric Cheng break; 4566da14cebeSEric Cheng } 4567da14cebeSEric Cheng 4568da14cebeSEric Cheng /* Property not in list */ 4569da14cebeSEric Cheng if (i == proplist->al_count) 4570da14cebeSEric Cheng return (DLADM_STATUS_OK); 4571da14cebeSEric Cheng 4572da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 4573da14cebeSEric Cheng prop_desc_t *pdp = &prop_table[i]; 4574da14cebeSEric Cheng val_desc_t *vdp; 4575da14cebeSEric Cheng 4576da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 4577da14cebeSEric Cheng if (vdp == NULL) 4578da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 4579da14cebeSEric Cheng 4580da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 4581da14cebeSEric Cheng continue; 4582da14cebeSEric Cheng 4583da14cebeSEric Cheng if (aip->ai_val == NULL) 4584da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 4585da14cebeSEric Cheng 4586da14cebeSEric Cheng /* Check property value */ 4587da14cebeSEric Cheng if (pdp->pd_check != NULL) { 45884ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 4589c569ef53SMichael Lim &(aip->ai_count), flags, &vdp, 0); 4590da14cebeSEric Cheng } else { 4591da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4592da14cebeSEric Cheng } 4593da14cebeSEric Cheng 4594da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4595da14cebeSEric Cheng return (status); 4596da14cebeSEric Cheng 4597da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 4598da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 4599da14cebeSEric Cheng 4600da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 4601da14cebeSEric Cheng continue; 4602da14cebeSEric Cheng 4603da14cebeSEric Cheng /* Extract kernel structure */ 4604da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 460525ec3e3dSEric Cheng status = rpp->rp_extract(vdp, 460625ec3e3dSEric Cheng aip->ai_count, arg); 4607da14cebeSEric Cheng } else { 4608da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4609da14cebeSEric Cheng } 4610da14cebeSEric Cheng break; 4611da14cebeSEric Cheng } 4612da14cebeSEric Cheng 4613da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4614da14cebeSEric Cheng return (status); 4615da14cebeSEric Cheng 4616da14cebeSEric Cheng break; 4617da14cebeSEric Cheng } 4618da14cebeSEric Cheng return (status); 4619da14cebeSEric Cheng } 4620da14cebeSEric Cheng 4621da14cebeSEric Cheng /* 4622da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 4623da14cebeSEric Cheng */ 4624da14cebeSEric Cheng dladm_status_t 46254ac67f02SAnurag S. Maskey dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 46260dc2366fSVenugopal Iyer mac_resource_props_t *mrp, uint_t flags) 4627da14cebeSEric Cheng { 462825ec3e3dSEric Cheng dladm_status_t status; 462925ec3e3dSEric Cheng int i; 4630da14cebeSEric Cheng 463125ec3e3dSEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 463225ec3e3dSEric Cheng status = i_dladm_link_proplist_extract_one(handle, 46330dc2366fSVenugopal Iyer proplist, rsrc_prop_table[i].rp_name, flags, mrp); 4634da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4635da14cebeSEric Cheng return (status); 463625ec3e3dSEric Cheng } 4637da14cebeSEric Cheng return (status); 4638da14cebeSEric Cheng } 4639da14cebeSEric Cheng 4640da14cebeSEric Cheng static const char * 4641da14cebeSEric Cheng dladm_perm2str(uint_t perm, char *buf) 4642da14cebeSEric Cheng { 4643da14cebeSEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 4644da14cebeSEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 4645da14cebeSEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 4646da14cebeSEric Cheng return (buf); 4647da14cebeSEric Cheng } 46484784fcbdSSowmini Varadhan 46494784fcbdSSowmini Varadhan dladm_status_t 46500dc2366fSVenugopal Iyer dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 46514ac67f02SAnurag S. Maskey link_state_t *state) 46524784fcbdSSowmini Varadhan { 46534784fcbdSSowmini Varadhan uint_t perms; 46544784fcbdSSowmini Varadhan 46550dc2366fSVenugopal Iyer return (i_dladm_get_public_prop(handle, linkid, "state", 0, 46560dc2366fSVenugopal Iyer &perms, state, sizeof (*state))); 46574784fcbdSSowmini Varadhan } 465862ee1d25SArtem Kachitchkine 465962ee1d25SArtem Kachitchkine boolean_t 466062ee1d25SArtem Kachitchkine dladm_attr_is_linkprop(const char *name) 466162ee1d25SArtem Kachitchkine { 466262ee1d25SArtem Kachitchkine /* non-property attribute names */ 466362ee1d25SArtem Kachitchkine const char *nonprop[] = { 466462ee1d25SArtem Kachitchkine /* dlmgmtd core attributes */ 466562ee1d25SArtem Kachitchkine "name", 466662ee1d25SArtem Kachitchkine "class", 466762ee1d25SArtem Kachitchkine "media", 466862ee1d25SArtem Kachitchkine FPHYMAJ, 466962ee1d25SArtem Kachitchkine FPHYINST, 467062ee1d25SArtem Kachitchkine FDEVNAME, 467162ee1d25SArtem Kachitchkine 467262ee1d25SArtem Kachitchkine /* other attributes for vlan, aggr, etc */ 467362ee1d25SArtem Kachitchkine DLADM_ATTR_NAMES 467462ee1d25SArtem Kachitchkine }; 467562ee1d25SArtem Kachitchkine boolean_t is_nonprop = B_FALSE; 467662ee1d25SArtem Kachitchkine int i; 467762ee1d25SArtem Kachitchkine 467862ee1d25SArtem Kachitchkine for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 467962ee1d25SArtem Kachitchkine if (strcmp(name, nonprop[i]) == 0) { 468062ee1d25SArtem Kachitchkine is_nonprop = B_TRUE; 468162ee1d25SArtem Kachitchkine break; 468262ee1d25SArtem Kachitchkine } 468362ee1d25SArtem Kachitchkine } 468462ee1d25SArtem Kachitchkine 468562ee1d25SArtem Kachitchkine return (!is_nonprop); 468662ee1d25SArtem Kachitchkine } 46870dc2366fSVenugopal Iyer 46880dc2366fSVenugopal Iyer dladm_status_t 46890dc2366fSVenugopal Iyer dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 46900dc2366fSVenugopal Iyer dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 46910dc2366fSVenugopal Iyer { 46920dc2366fSVenugopal Iyer char *buf, **propvals; 46930dc2366fSVenugopal Iyer uint_t valcnt = DLADM_MAX_PROP_VALCNT; 46940dc2366fSVenugopal Iyer int i; 46950dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 4696550b6e40SSowmini Varadhan size_t bufsize; 46970dc2366fSVenugopal Iyer 46980dc2366fSVenugopal Iyer *is_set = B_FALSE; 46990dc2366fSVenugopal Iyer 4700550b6e40SSowmini Varadhan bufsize = (sizeof (char *) + DLADM_PROP_VAL_MAX) * 4701550b6e40SSowmini Varadhan DLADM_MAX_PROP_VALCNT; 4702550b6e40SSowmini Varadhan if ((buf = calloc(1, bufsize)) == NULL) 47030dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 47040dc2366fSVenugopal Iyer 47050dc2366fSVenugopal Iyer propvals = (char **)(void *)buf; 47060dc2366fSVenugopal Iyer for (i = 0; i < valcnt; i++) { 47070dc2366fSVenugopal Iyer propvals[i] = buf + 47080dc2366fSVenugopal Iyer sizeof (char *) * DLADM_MAX_PROP_VALCNT + 47090dc2366fSVenugopal Iyer i * DLADM_PROP_VAL_MAX; 47100dc2366fSVenugopal Iyer } 47110dc2366fSVenugopal Iyer 47120dc2366fSVenugopal Iyer if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 47130dc2366fSVenugopal Iyer &valcnt) != DLADM_STATUS_OK) { 47140dc2366fSVenugopal Iyer goto done; 47150dc2366fSVenugopal Iyer } 47160dc2366fSVenugopal Iyer 4717550b6e40SSowmini Varadhan /* 4718550b6e40SSowmini Varadhan * valcnt is always set to 1 by get_pool(), hence we need to check 47191a41ca23SJerry Jelinek * for a non-null string to see if it is set. For protection, 47201a41ca23SJerry Jelinek * secondary-macs and allowed-ips, we can check either the *propval 47211a41ca23SJerry Jelinek * or the valcnt. 4722550b6e40SSowmini Varadhan */ 4723550b6e40SSowmini Varadhan if ((strcmp(prop_name, "pool") == 0 || 4724550b6e40SSowmini Varadhan strcmp(prop_name, "protection") == 0 || 47251a41ca23SJerry Jelinek strcmp(prop_name, "secondary-macs") == 0 || 4726550b6e40SSowmini Varadhan strcmp(prop_name, "allowed-ips") == 0) && 4727550b6e40SSowmini Varadhan (strlen(*propvals) != 0)) { 47280dc2366fSVenugopal Iyer *is_set = B_TRUE; 47290dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 47300dc2366fSVenugopal Iyer *is_set = B_TRUE; 47310dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 47320dc2366fSVenugopal Iyer (strcmp(propvals[0], "true") == 0)) { 47330dc2366fSVenugopal Iyer *is_set = B_TRUE; 47340dc2366fSVenugopal Iyer } 47350dc2366fSVenugopal Iyer 47360dc2366fSVenugopal Iyer done: 47370dc2366fSVenugopal Iyer if (buf != NULL) 47380dc2366fSVenugopal Iyer free(buf); 47390dc2366fSVenugopal Iyer return (status); 47400dc2366fSVenugopal Iyer } 47411cfa752fSRamaswamy Tummala 47421cfa752fSRamaswamy Tummala /* ARGSUSED */ 47431cfa752fSRamaswamy Tummala static dladm_status_t 47441cfa752fSRamaswamy Tummala get_linkmode_prop(dladm_handle_t handle, prop_desc_t *pdp, 47451cfa752fSRamaswamy Tummala datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 47461cfa752fSRamaswamy Tummala datalink_media_t media, uint_t flags, uint_t *perm_flags) 47471cfa752fSRamaswamy Tummala { 47481cfa752fSRamaswamy Tummala char *s; 47491cfa752fSRamaswamy Tummala uint32_t v; 47501cfa752fSRamaswamy Tummala dladm_status_t status; 47511cfa752fSRamaswamy Tummala 47521cfa752fSRamaswamy Tummala status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 47531cfa752fSRamaswamy Tummala perm_flags, &v, sizeof (v)); 47541cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 47551cfa752fSRamaswamy Tummala return (status); 47561cfa752fSRamaswamy Tummala 47571cfa752fSRamaswamy Tummala switch (v) { 4758c87dd6b7SRajkumar Sivaprakasam case DLADM_PART_CM_MODE: 47591cfa752fSRamaswamy Tummala s = "cm"; 47601cfa752fSRamaswamy Tummala break; 4761c87dd6b7SRajkumar Sivaprakasam case DLADM_PART_UD_MODE: 47621cfa752fSRamaswamy Tummala s = "ud"; 47631cfa752fSRamaswamy Tummala break; 47641cfa752fSRamaswamy Tummala default: 47651cfa752fSRamaswamy Tummala s = ""; 47661cfa752fSRamaswamy Tummala break; 47671cfa752fSRamaswamy Tummala } 47681cfa752fSRamaswamy Tummala (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); 47691cfa752fSRamaswamy Tummala 47701cfa752fSRamaswamy Tummala *val_cnt = 1; 47711cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 47721cfa752fSRamaswamy Tummala } 4773