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*63cfa7a9SRyan Zezeski * Copyright 2017 Joyent, Inc. 243bc4925dSGarrett D'Amore * Copyright 2015 Garrett D'Amore <garrett@damore.org> 250ba2cbe9Sxc151355 */ 260ba2cbe9Sxc151355 270ba2cbe9Sxc151355 #include <stdlib.h> 28c569ef53SMichael Lim #include <string.h> 290ba2cbe9Sxc151355 #include <strings.h> 300ba2cbe9Sxc151355 #include <errno.h> 310ba2cbe9Sxc151355 #include <ctype.h> 32d62bc4baSyz147064 #include <stddef.h> 33f4b3ec61Sdh155122 #include <sys/types.h> 340ba2cbe9Sxc151355 #include <sys/stat.h> 35f4b3ec61Sdh155122 #include <sys/dld.h> 36f4b3ec61Sdh155122 #include <sys/zone.h> 37f4b3ec61Sdh155122 #include <fcntl.h> 38f4b3ec61Sdh155122 #include <unistd.h> 39f4b3ec61Sdh155122 #include <libdevinfo.h> 40f4b3ec61Sdh155122 #include <zone.h> 41f595a68aSyz147064 #include <libdllink.h> 420ba2cbe9Sxc151355 #include <libdladm_impl.h> 43d62bc4baSyz147064 #include <libdlwlan_impl.h> 44f595a68aSyz147064 #include <libdlwlan.h> 45d62bc4baSyz147064 #include <libdlvlan.h> 46da14cebeSEric Cheng #include <libdlvnic.h> 471cfa752fSRamaswamy Tummala #include <libdlib.h> 48da14cebeSEric Cheng #include <libintl.h> 49f4b3ec61Sdh155122 #include <dlfcn.h> 50f4b3ec61Sdh155122 #include <link.h> 51d62bc4baSyz147064 #include <inet/wifi_ioctl.h> 52e7801d59Ssowmini #include <libdladm.h> 53da14cebeSEric Cheng #include <libdlstat.h> 54e7801d59Ssowmini #include <sys/param.h> 55da14cebeSEric Cheng #include <sys/debug.h> 56da14cebeSEric Cheng #include <sys/dld.h> 57e7801d59Ssowmini #include <inttypes.h> 58e7801d59Ssowmini #include <sys/ethernet.h> 592b24ab6bSSebastien Roy #include <inet/iptun.h> 60bcb5c89dSSowmini Varadhan #include <net/wpa.h> 61bcb5c89dSSowmini Varadhan #include <sys/sysmacros.h> 624eaa4710SRishi Srivatsavai #include <sys/vlan.h> 634eaa4710SRishi Srivatsavai #include <libdlbridge.h> 644eaa4710SRishi Srivatsavai #include <stp_in.h> 650dc2366fSVenugopal Iyer #include <netinet/dhcp.h> 660dc2366fSVenugopal Iyer #include <netinet/dhcp6.h> 670dc2366fSVenugopal Iyer #include <net/if_types.h> 680dc2366fSVenugopal Iyer #include <libinetutil.h> 690dc2366fSVenugopal Iyer #include <pool.h> 701a41ca23SJerry Jelinek #include <libdlaggr.h> 71f4b3ec61Sdh155122 72d62bc4baSyz147064 /* 73d62bc4baSyz147064 * The linkprop get() callback. 74da14cebeSEric Cheng * - pd: pointer to the prop_desc_t 75d62bc4baSyz147064 * - propstrp: a property string array to keep the returned property. 76d62bc4baSyz147064 * Caller allocated. 77d62bc4baSyz147064 * - cntp: number of returned properties. 78d62bc4baSyz147064 * Caller also uses it to indicate how many it expects. 79d62bc4baSyz147064 */ 80e7801d59Ssowmini struct prop_desc; 81da14cebeSEric Cheng typedef struct prop_desc prop_desc_t; 82e7801d59Ssowmini 834ac67f02SAnurag S. Maskey typedef dladm_status_t pd_getf_t(dladm_handle_t, prop_desc_t *pdp, 846b9e797cSsowmini datalink_id_t, char **propstp, uint_t *cntp, 85afdda45fSVasumathi Sundaram - Sun Microsystems datalink_media_t, uint_t, uint_t *); 86f4b3ec61Sdh155122 87d62bc4baSyz147064 /* 88d62bc4baSyz147064 * The linkprop set() callback. 89d62bc4baSyz147064 * - propval: a val_desc_t array which keeps the property values to be set. 90d62bc4baSyz147064 * - cnt: number of properties to be set. 91e7801d59Ssowmini * - flags: additional flags passed down the system call. 92e7801d59Ssowmini * 93e7801d59Ssowmini * pd_set takes val_desc_t given by pd_check(), translates it into 94e7801d59Ssowmini * a format suitable for kernel consumption. This may require allocation 95e7801d59Ssowmini * of ioctl buffers etc. pd_set() may call another common routine (used 96e7801d59Ssowmini * by all other pd_sets) which invokes the ioctl. 97d62bc4baSyz147064 */ 984ac67f02SAnurag S. Maskey typedef dladm_status_t pd_setf_t(dladm_handle_t, prop_desc_t *, datalink_id_t, 996b9e797cSsowmini val_desc_t *propval, uint_t cnt, uint_t flags, 1006b9e797cSsowmini datalink_media_t); 101f4b3ec61Sdh155122 102d62bc4baSyz147064 /* 103d62bc4baSyz147064 * The linkprop check() callback. 104d62bc4baSyz147064 * - propstrp: property string array which keeps the property to be checked. 105d62bc4baSyz147064 * - cnt: number of properties. 106d62bc4baSyz147064 * - propval: return value; the property values of the given property strings. 107e7801d59Ssowmini * 108e7801d59Ssowmini * pd_check checks that the input values are valid. It does so by 109e7801d59Ssowmini * iteraring through the pd_modval list for the property. If 110e7801d59Ssowmini * the modifiable values cannot be expressed as a list, a pd_check 111e7801d59Ssowmini * specific to this property can be used. If the input values are 112e7801d59Ssowmini * verified to be valid, pd_check allocates a val_desc_t and fills it 113e7801d59Ssowmini * with either a val_desc_t found on the pd_modval list or something 114e7801d59Ssowmini * generated on the fly. 115d62bc4baSyz147064 */ 1164ac67f02SAnurag S. Maskey typedef dladm_status_t pd_checkf_t(dladm_handle_t, prop_desc_t *pdp, 117c569ef53SMichael Lim datalink_id_t, char **propstrp, uint_t *cnt, 118c569ef53SMichael Lim uint_t flags, val_desc_t **propval, 1190dc2366fSVenugopal Iyer datalink_media_t); 120f4b3ec61Sdh155122 121bcb5c89dSSowmini Varadhan typedef struct link_attr_s { 1223fd94f8cSam223141 mac_prop_id_t pp_id; 123e7801d59Ssowmini size_t pp_valsize; 124e7801d59Ssowmini char *pp_name; 125bcb5c89dSSowmini Varadhan } link_attr_t; 126e7801d59Ssowmini 1270dc2366fSVenugopal Iyer typedef struct dladm_linkprop_args_s { 1280dc2366fSVenugopal Iyer dladm_status_t dla_status; 1290dc2366fSVenugopal Iyer uint_t dla_flags; 1300dc2366fSVenugopal Iyer } dladm_linkprop_args_t; 1310dc2366fSVenugopal Iyer 132bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, 133bcb5c89dSSowmini Varadhan const char *, uint_t, dladm_status_t *); 134bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, 135da14cebeSEric Cheng mac_prop_id_t, uint_t, dladm_status_t *); 1360dc2366fSVenugopal Iyer static dladm_status_t i_dladm_get_public_prop(dladm_handle_t, datalink_id_t, 1370dc2366fSVenugopal Iyer char *, uint_t, uint_t *, void *, size_t); 138da14cebeSEric Cheng 1393361618bSRishi Srivatsavai static dladm_status_t i_dladm_set_private_prop(dladm_handle_t, datalink_id_t, 1404ac67f02SAnurag S. Maskey const char *, char **, uint_t, uint_t); 14162ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_get_priv_prop(dladm_handle_t, datalink_id_t, 1424ac67f02SAnurag S. Maskey const char *, char **, uint_t *, dladm_prop_type_t, 1434ac67f02SAnurag S. Maskey uint_t); 1440dc2366fSVenugopal Iyer static dladm_status_t i_dladm_macprop(dladm_handle_t, void *, boolean_t); 1450dc2366fSVenugopal Iyer static const char *dladm_perm2str(uint_t, char *); 146bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *); 147bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t); 148da14cebeSEric Cheng 1490dc2366fSVenugopal Iyer static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, 1500dc2366fSVenugopal Iyer get_speed, get_channel, get_powermode, get_radio, 1510dc2366fSVenugopal Iyer get_duplex, get_link_state, get_binary, get_uint32, 1520dc2366fSVenugopal Iyer get_flowctl, get_maxbw, get_cpus, get_priority, 1530dc2366fSVenugopal Iyer get_tagmode, get_range, get_stp, get_bridge_forward, 1540dc2366fSVenugopal Iyer get_bridge_pvid, get_protection, get_rxrings, 1551a41ca23SJerry Jelinek get_txrings, get_cntavail, get_secondary_macs, 1560dc2366fSVenugopal Iyer get_allowedips, get_allowedcids, get_pool, 157098d2c75SRobert Mustacchi get_rings_range, get_linkmode_prop, 158098d2c75SRobert Mustacchi get_promisc_filtered; 159da14cebeSEric Cheng 1600dc2366fSVenugopal Iyer static pd_setf_t set_zone, set_rate, set_powermode, set_radio, 1610dc2366fSVenugopal Iyer set_public_prop, set_resource, set_stp_prop, 162098d2c75SRobert Mustacchi set_bridge_forward, set_bridge_pvid, set_secondary_macs, 163098d2c75SRobert Mustacchi set_promisc_filtered; 164f4b3ec61Sdh155122 1650dc2366fSVenugopal Iyer static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, 1660dc2366fSVenugopal Iyer check_encaplim, check_uint32, check_maxbw, check_cpus, 1670dc2366fSVenugopal Iyer check_stp_prop, check_bridge_pvid, check_allowedips, 1681a41ca23SJerry Jelinek check_allowedcids, check_secondary_macs, check_rings, 1690dc2366fSVenugopal Iyer check_pool, check_prop; 1706b9e797cSsowmini 171da14cebeSEric Cheng struct prop_desc { 172d62bc4baSyz147064 /* 173d62bc4baSyz147064 * link property name 174d62bc4baSyz147064 */ 175f4b3ec61Sdh155122 char *pd_name; 176d62bc4baSyz147064 177d62bc4baSyz147064 /* 178d62bc4baSyz147064 * default property value, can be set to { "", NULL } 179d62bc4baSyz147064 */ 180f4b3ec61Sdh155122 val_desc_t pd_defval; 181d62bc4baSyz147064 182d62bc4baSyz147064 /* 183d62bc4baSyz147064 * list of optional property values, can be NULL. 184d62bc4baSyz147064 * 185d62bc4baSyz147064 * This is set to non-NULL if there is a list of possible property 186d62bc4baSyz147064 * values. pd_optval would point to the array of possible values. 187d62bc4baSyz147064 */ 188d62bc4baSyz147064 val_desc_t *pd_optval; 189d62bc4baSyz147064 190d62bc4baSyz147064 /* 191d62bc4baSyz147064 * count of the above optional property values. 0 if pd_optval is NULL. 192d62bc4baSyz147064 */ 193d62bc4baSyz147064 uint_t pd_noptval; 194d62bc4baSyz147064 195d62bc4baSyz147064 /* 1964eaa4710SRishi Srivatsavai * callback to set link property; set to NULL if this property is 1974eaa4710SRishi Srivatsavai * read-only and may be called before or after permanent update; see 1984eaa4710SRishi Srivatsavai * flags. 199d62bc4baSyz147064 */ 200f4b3ec61Sdh155122 pd_setf_t *pd_set; 201d62bc4baSyz147064 202d62bc4baSyz147064 /* 203d62bc4baSyz147064 * callback to get modifiable link property 204d62bc4baSyz147064 */ 205f4b3ec61Sdh155122 pd_getf_t *pd_getmod; 206d62bc4baSyz147064 207d62bc4baSyz147064 /* 208d62bc4baSyz147064 * callback to get current link property 209d62bc4baSyz147064 */ 210f4b3ec61Sdh155122 pd_getf_t *pd_get; 211d62bc4baSyz147064 212d62bc4baSyz147064 /* 213d62bc4baSyz147064 * callback to validate link property value, set to NULL if pd_optval 214d62bc4baSyz147064 * is not NULL. In that case, validate the value by comparing it with 215d62bc4baSyz147064 * the pd_optval. Return a val_desc_t array pointer if the value is 216d62bc4baSyz147064 * valid. 217d62bc4baSyz147064 */ 218f4b3ec61Sdh155122 pd_checkf_t *pd_check; 219d62bc4baSyz147064 220d62bc4baSyz147064 uint_t pd_flags; 221e7801d59Ssowmini #define PD_TEMPONLY 0x1 /* property is temporary only */ 222e7801d59Ssowmini #define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */ 2234eaa4710SRishi Srivatsavai #define PD_AFTER_PERM 0x4 /* pd_set after db update; no temporary */ 224d62bc4baSyz147064 /* 225d62bc4baSyz147064 * indicate link classes this property applies to. 226d62bc4baSyz147064 */ 227d62bc4baSyz147064 datalink_class_t pd_class; 228d62bc4baSyz147064 229d62bc4baSyz147064 /* 230d62bc4baSyz147064 * indicate link media type this property applies to. 231d62bc4baSyz147064 */ 232d62bc4baSyz147064 datalink_media_t pd_dmedia; 233da14cebeSEric Cheng }; 234f4b3ec61Sdh155122 2353fd94f8cSam223141 #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 236e7801d59Ssowmini 237bcb5c89dSSowmini Varadhan /* 238bcb5c89dSSowmini Varadhan * Supported link properties enumerated in the prop_table[] array are 239bcb5c89dSSowmini Varadhan * computed using the callback functions in that array. To compute the 240bcb5c89dSSowmini Varadhan * property value, multiple distinct system calls may be needed (e.g., 241bcb5c89dSSowmini Varadhan * for wifi speed, we need to issue system calls to get desired/supported 242bcb5c89dSSowmini Varadhan * rates). The link_attr[] table enumerates the interfaces to the kernel, 243bcb5c89dSSowmini Varadhan * and the type/size of the data passed in the user-kernel interface. 244bcb5c89dSSowmini Varadhan */ 245bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = { 246bcb5c89dSSowmini Varadhan { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, 247e7801d59Ssowmini 248bcb5c89dSSowmini Varadhan { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, 249e7801d59Ssowmini 250bcb5c89dSSowmini Varadhan { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, 251e7801d59Ssowmini 252bcb5c89dSSowmini Varadhan { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, 253e7801d59Ssowmini 254bcb5c89dSSowmini Varadhan { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, 255e7801d59Ssowmini 256bcb5c89dSSowmini Varadhan { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, 257e7801d59Ssowmini 258bcb5c89dSSowmini Varadhan { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, 259e7801d59Ssowmini 260bcb5c89dSSowmini Varadhan { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, 2613bc21d0aSAruna Ramakrishna - Sun Microsystems 2623bc4925dSGarrett D'Amore { MAC_PROP_ADV_5000FDX_CAP, sizeof (uint8_t), "adv_5000fdx_cap"}, 2633bc4925dSGarrett D'Amore 2643bc4925dSGarrett D'Amore { MAC_PROP_EN_5000FDX_CAP, sizeof (uint8_t), "en_5000fdx_cap"}, 2653bc4925dSGarrett D'Amore 2663bc4925dSGarrett D'Amore { MAC_PROP_ADV_2500FDX_CAP, sizeof (uint8_t), "adv_2500fdx_cap"}, 2673bc4925dSGarrett D'Amore 2683bc4925dSGarrett D'Amore { MAC_PROP_EN_2500FDX_CAP, sizeof (uint8_t), "en_2500fdx_cap"}, 2693bc4925dSGarrett D'Amore 2703bc4925dSGarrett D'Amore { MAC_PROP_ADV_100GFDX_CAP, sizeof (uint8_t), "adv_100gfdx_cap"}, 2713bc4925dSGarrett D'Amore 2723bc4925dSGarrett D'Amore { MAC_PROP_EN_100GFDX_CAP, sizeof (uint8_t), "en_100gfdx_cap"}, 2733bc4925dSGarrett D'Amore 274422542c1SRobert Mustacchi { MAC_PROP_ADV_50GFDX_CAP, sizeof (uint8_t), "adv_50gfdx_cap"}, 275422542c1SRobert Mustacchi 276422542c1SRobert Mustacchi { MAC_PROP_EN_50GFDX_CAP, sizeof (uint8_t), "en_50gfdx_cap"}, 277422542c1SRobert Mustacchi 2783bc4925dSGarrett D'Amore { MAC_PROP_ADV_40GFDX_CAP, sizeof (uint8_t), "adv_40gfdx_cap"}, 2793bc4925dSGarrett D'Amore 2803bc4925dSGarrett D'Amore { MAC_PROP_EN_40GFDX_CAP, sizeof (uint8_t), "en_40gfdx_cap"}, 2813bc4925dSGarrett D'Amore 282422542c1SRobert Mustacchi { MAC_PROP_ADV_25GFDX_CAP, sizeof (uint8_t), "adv_25gfdx_cap"}, 283422542c1SRobert Mustacchi 284422542c1SRobert Mustacchi { MAC_PROP_EN_25GFDX_CAP, sizeof (uint8_t), "en_25gfdx_cap"}, 285422542c1SRobert Mustacchi 286aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_ADV_10GFDX_CAP, sizeof (uint8_t), "adv_10gfdx_cap"}, 287aca118b7Slucy wang - Sun Microsystems - Beijing China 288aca118b7Slucy wang - Sun Microsystems - Beijing China { MAC_PROP_EN_10GFDX_CAP, sizeof (uint8_t), "en_10gfdx_cap"}, 289aca118b7Slucy wang - Sun Microsystems - Beijing China 290bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, 2913bc21d0aSAruna Ramakrishna - Sun Microsystems 292bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, 293e7801d59Ssowmini 294bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, 295e7801d59Ssowmini 296bcb5c89dSSowmini Varadhan { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, 297e7801d59Ssowmini 298bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, 299e7801d59Ssowmini 300bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, 301e7801d59Ssowmini 302bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, 303e7801d59Ssowmini 304bcb5c89dSSowmini Varadhan { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, 305e7801d59Ssowmini 306bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, 307e7801d59Ssowmini 308bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, 309e7801d59Ssowmini 310bcb5c89dSSowmini Varadhan { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, 311e7801d59Ssowmini 312bcb5c89dSSowmini Varadhan { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, 313e7801d59Ssowmini 314bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, 315e7801d59Ssowmini 316bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, 317bcb5c89dSSowmini Varadhan 318bcb5c89dSSowmini Varadhan { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, 319bcb5c89dSSowmini Varadhan 320bcb5c89dSSowmini Varadhan { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, 321bcb5c89dSSowmini Varadhan 322bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 323bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, 324bcb5c89dSSowmini Varadhan 325bcb5c89dSSowmini Varadhan /* wl_rates_t has variable length */ 326bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, 327bcb5c89dSSowmini Varadhan 328bcb5c89dSSowmini Varadhan { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, 329bcb5c89dSSowmini Varadhan 330bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, 331bcb5c89dSSowmini Varadhan 332bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, 333bcb5c89dSSowmini Varadhan 334bcb5c89dSSowmini Varadhan { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, 335bcb5c89dSSowmini Varadhan 336bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, 337bcb5c89dSSowmini Varadhan 338bcb5c89dSSowmini Varadhan { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, 339bcb5c89dSSowmini Varadhan 340bcb5c89dSSowmini Varadhan /* wl_wpa_ess_t has variable length */ 341bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, 342bcb5c89dSSowmini Varadhan 343bcb5c89dSSowmini Varadhan { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, 344bcb5c89dSSowmini Varadhan 345bcb5c89dSSowmini Varadhan { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, 346bcb5c89dSSowmini Varadhan 347bcb5c89dSSowmini Varadhan { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, 348bcb5c89dSSowmini Varadhan 349bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, 350bcb5c89dSSowmini Varadhan 351bcb5c89dSSowmini Varadhan { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, 352bcb5c89dSSowmini Varadhan 353bcb5c89dSSowmini Varadhan /* wl_wpa_ie_t has variable length */ 354bcb5c89dSSowmini Varadhan { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, 355bcb5c89dSSowmini Varadhan 356bcb5c89dSSowmini Varadhan { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, 357bcb5c89dSSowmini Varadhan 358bcb5c89dSSowmini Varadhan { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, 359bcb5c89dSSowmini Varadhan 360bcb5c89dSSowmini Varadhan { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, 361bcb5c89dSSowmini Varadhan 362e75f0919SSebastien Roy { MAC_PROP_TAGMODE, sizeof (link_tagmode_t), "tagmode"}, 363e75f0919SSebastien Roy 3642b24ab6bSSebastien Roy { MAC_PROP_IPTUN_HOPLIMIT, sizeof (uint32_t), "hoplimit"}, 3652b24ab6bSSebastien Roy 3662b24ab6bSSebastien Roy { MAC_PROP_IPTUN_ENCAPLIMIT, sizeof (uint32_t), "encaplimit"}, 3672b24ab6bSSebastien Roy 3684eaa4710SRishi Srivatsavai { MAC_PROP_PVID, sizeof (uint16_t), "default_tag"}, 3694eaa4710SRishi Srivatsavai 3704eaa4710SRishi Srivatsavai { MAC_PROP_LLIMIT, sizeof (uint32_t), "learn_limit"}, 3714eaa4710SRishi Srivatsavai 3724eaa4710SRishi Srivatsavai { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, 3734eaa4710SRishi Srivatsavai 3740dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE, sizeof (mac_resource_props_t), "resource"}, 3750dc2366fSVenugopal Iyer 3760dc2366fSVenugopal Iyer { MAC_PROP_RESOURCE_EFF, sizeof (mac_resource_props_t), 3770dc2366fSVenugopal Iyer "resource-effective"}, 3780dc2366fSVenugopal Iyer 3790dc2366fSVenugopal Iyer { MAC_PROP_RXRINGSRANGE, sizeof (mac_propval_range_t), "rxrings"}, 3800dc2366fSVenugopal Iyer 3810dc2366fSVenugopal Iyer { MAC_PROP_TXRINGSRANGE, sizeof (mac_propval_range_t), "txrings"}, 3820dc2366fSVenugopal Iyer 3830dc2366fSVenugopal Iyer { MAC_PROP_MAX_TX_RINGS_AVAIL, sizeof (uint_t), 3840dc2366fSVenugopal Iyer "txrings-available"}, 3850dc2366fSVenugopal Iyer 3860dc2366fSVenugopal Iyer { MAC_PROP_MAX_RX_RINGS_AVAIL, sizeof (uint_t), 3870dc2366fSVenugopal Iyer "rxrings-available"}, 3880dc2366fSVenugopal Iyer 3890dc2366fSVenugopal Iyer { MAC_PROP_MAX_RXHWCLNT_AVAIL, sizeof (uint_t), "rxhwclnt-available"}, 3900dc2366fSVenugopal Iyer 3910dc2366fSVenugopal Iyer { MAC_PROP_MAX_TXHWCLNT_AVAIL, sizeof (uint_t), "txhwclnt-available"}, 392da14cebeSEric Cheng 3931cfa752fSRamaswamy Tummala { MAC_PROP_IB_LINKMODE, sizeof (uint32_t), "linkmode"}, 3941cfa752fSRamaswamy Tummala 395098d2c75SRobert Mustacchi { MAC_PROP_VN_PROMISC_FILTERED, sizeof (boolean_t), "promisc-filtered"}, 396098d2c75SRobert Mustacchi 3971a41ca23SJerry Jelinek { MAC_PROP_SECONDARY_ADDRS, sizeof (mac_secondary_addr_t), 3981a41ca23SJerry Jelinek "secondary-macs"}, 3991a41ca23SJerry Jelinek 40025ec3e3dSEric Cheng { MAC_PROP_PRIVATE, 0, "driver-private"} 401e7801d59Ssowmini }; 402e7801d59Ssowmini 4034eaa4710SRishi Srivatsavai typedef struct bridge_public_prop_s { 4044eaa4710SRishi Srivatsavai const char *bpp_name; 4054eaa4710SRishi Srivatsavai int bpp_code; 4064eaa4710SRishi Srivatsavai } bridge_public_prop_t; 4074eaa4710SRishi Srivatsavai 4084eaa4710SRishi Srivatsavai static const bridge_public_prop_t bridge_prop[] = { 4094eaa4710SRishi Srivatsavai { "stp", PT_CFG_NON_STP }, 4104eaa4710SRishi Srivatsavai { "stp_priority", PT_CFG_PRIO }, 4114eaa4710SRishi Srivatsavai { "stp_cost", PT_CFG_COST }, 4124eaa4710SRishi Srivatsavai { "stp_edge", PT_CFG_EDGE }, 4134eaa4710SRishi Srivatsavai { "stp_p2p", PT_CFG_P2P }, 4144eaa4710SRishi Srivatsavai { "stp_mcheck", PT_CFG_MCHECK }, 4154eaa4710SRishi Srivatsavai { NULL, 0 } 4164eaa4710SRishi Srivatsavai }; 4174eaa4710SRishi Srivatsavai 418e7801d59Ssowmini static val_desc_t link_duplex_vals[] = { 419e7801d59Ssowmini { "half", LINK_DUPLEX_HALF }, 420e7801d59Ssowmini { "full", LINK_DUPLEX_HALF } 421e7801d59Ssowmini }; 422e7801d59Ssowmini static val_desc_t link_status_vals[] = { 423e7801d59Ssowmini { "up", LINK_STATE_UP }, 424e7801d59Ssowmini { "down", LINK_STATE_DOWN } 425e7801d59Ssowmini }; 426e7801d59Ssowmini static val_desc_t link_01_vals[] = { 427e7801d59Ssowmini { "1", 1 }, 428e7801d59Ssowmini { "0", 0 } 429e7801d59Ssowmini }; 430e7801d59Ssowmini static val_desc_t link_flow_vals[] = { 431e7801d59Ssowmini { "no", LINK_FLOWCTRL_NONE }, 432e7801d59Ssowmini { "tx", LINK_FLOWCTRL_TX }, 433e7801d59Ssowmini { "rx", LINK_FLOWCTRL_RX }, 434e7801d59Ssowmini { "bi", LINK_FLOWCTRL_BI } 435e7801d59Ssowmini }; 436da14cebeSEric Cheng static val_desc_t link_priority_vals[] = { 437da14cebeSEric Cheng { "low", MPL_LOW }, 438da14cebeSEric Cheng { "medium", MPL_MEDIUM }, 439da14cebeSEric Cheng { "high", MPL_HIGH } 440da14cebeSEric Cheng }; 441e7801d59Ssowmini 442e75f0919SSebastien Roy static val_desc_t link_tagmode_vals[] = { 443e75f0919SSebastien Roy { "normal", LINK_TAGMODE_NORMAL }, 444e75f0919SSebastien Roy { "vlanonly", LINK_TAGMODE_VLANONLY } 445e75f0919SSebastien Roy }; 446e75f0919SSebastien Roy 44725ec3e3dSEric Cheng static val_desc_t link_protect_vals[] = { 44825ec3e3dSEric Cheng { "mac-nospoof", MPT_MACNOSPOOF }, 4490dc2366fSVenugopal Iyer { "restricted", MPT_RESTRICTED }, 45025ec3e3dSEric Cheng { "ip-nospoof", MPT_IPNOSPOOF }, 4510dc2366fSVenugopal Iyer { "dhcp-nospoof", MPT_DHCPNOSPOOF }, 45225ec3e3dSEric Cheng }; 45325ec3e3dSEric Cheng 454098d2c75SRobert Mustacchi static val_desc_t link_promisc_filtered_vals[] = { 455098d2c75SRobert Mustacchi { "off", B_FALSE }, 456098d2c75SRobert Mustacchi { "on", B_TRUE }, 457098d2c75SRobert Mustacchi }; 458098d2c75SRobert Mustacchi 459d62bc4baSyz147064 static val_desc_t dladm_wlan_radio_vals[] = { 460d62bc4baSyz147064 { "on", DLADM_WLAN_RADIO_ON }, 461d62bc4baSyz147064 { "off", DLADM_WLAN_RADIO_OFF } 462d62bc4baSyz147064 }; 463d62bc4baSyz147064 464d62bc4baSyz147064 static val_desc_t dladm_wlan_powermode_vals[] = { 465d62bc4baSyz147064 { "off", DLADM_WLAN_PM_OFF }, 466d62bc4baSyz147064 { "fast", DLADM_WLAN_PM_FAST }, 467d62bc4baSyz147064 { "max", DLADM_WLAN_PM_MAX } 468d62bc4baSyz147064 }; 469d62bc4baSyz147064 4704eaa4710SRishi Srivatsavai static val_desc_t stp_p2p_vals[] = { 4714eaa4710SRishi Srivatsavai { "true", P2P_FORCE_TRUE }, 4724eaa4710SRishi Srivatsavai { "false", P2P_FORCE_FALSE }, 4734eaa4710SRishi Srivatsavai { "auto", P2P_AUTO } 4744eaa4710SRishi Srivatsavai }; 4754eaa4710SRishi Srivatsavai 476c87dd6b7SRajkumar Sivaprakasam static val_desc_t dladm_part_linkmode_vals[] = { 477c87dd6b7SRajkumar Sivaprakasam { "cm", DLADM_PART_CM_MODE }, 478c87dd6b7SRajkumar Sivaprakasam { "ud", DLADM_PART_UD_MODE }, 4791cfa752fSRamaswamy Tummala }; 4801cfa752fSRamaswamy Tummala 481da14cebeSEric Cheng #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) 482da14cebeSEric Cheng #define RESET_VAL ((uintptr_t)-1) 4830dc2366fSVenugopal Iyer #define UNSPEC_VAL ((uintptr_t)-2) 484d62bc4baSyz147064 4851a41ca23SJerry Jelinek /* 4861a41ca23SJerry Jelinek * For the default, if defaults are not defined for the property, 4871a41ca23SJerry Jelinek * pd_defval.vd_name should be null. If the driver has to be contacted for the 4881a41ca23SJerry Jelinek * value, vd_name should be the empty string (""). Otherwise, dladm will 4891a41ca23SJerry Jelinek * just print whatever is in the table. 4901a41ca23SJerry Jelinek */ 491da14cebeSEric Cheng static prop_desc_t prop_table[] = { 492e7801d59Ssowmini { "channel", { NULL, 0 }, 493e7801d59Ssowmini NULL, 0, NULL, NULL, 4940dc2366fSVenugopal Iyer get_channel, NULL, 0, 495d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 496d62bc4baSyz147064 497d62bc4baSyz147064 { "powermode", { "off", DLADM_WLAN_PM_OFF }, 498d62bc4baSyz147064 dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals), 4990dc2366fSVenugopal Iyer set_powermode, NULL, 5000dc2366fSVenugopal Iyer get_powermode, NULL, 0, 501d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 502d62bc4baSyz147064 503d62bc4baSyz147064 { "radio", { "on", DLADM_WLAN_RADIO_ON }, 504d62bc4baSyz147064 dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals), 5050dc2366fSVenugopal Iyer set_radio, NULL, 5060dc2366fSVenugopal Iyer get_radio, NULL, 0, 507d62bc4baSyz147064 DATALINK_CLASS_PHYS, DL_WIFI }, 508d62bc4baSyz147064 509c87dd6b7SRajkumar Sivaprakasam { "linkmode", { "cm", DLADM_PART_CM_MODE }, 510c87dd6b7SRajkumar Sivaprakasam dladm_part_linkmode_vals, VALCNT(dladm_part_linkmode_vals), 5111cfa752fSRamaswamy Tummala set_public_prop, NULL, get_linkmode_prop, NULL, 0, 5121cfa752fSRamaswamy Tummala DATALINK_CLASS_PART, DL_IB }, 5131cfa752fSRamaswamy Tummala 514d62bc4baSyz147064 { "speed", { "", 0 }, NULL, 0, 5150dc2366fSVenugopal Iyer set_rate, get_rate_mod, 5160dc2366fSVenugopal Iyer get_rate, check_rate, 0, 5176b9e797cSsowmini DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE }, 518d62bc4baSyz147064 5194045d941Ssowmini { "autopush", { "", 0 }, NULL, 0, 5200dc2366fSVenugopal Iyer set_public_prop, NULL, 5210dc2366fSVenugopal Iyer get_autopush, check_autopush, PD_CHECK_ALLOC, 522d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 523d62bc4baSyz147064 5244045d941Ssowmini { "zone", { "", 0 }, NULL, 0, 5250dc2366fSVenugopal Iyer set_zone, NULL, 5260dc2366fSVenugopal Iyer get_zone, check_zone, PD_TEMPONLY|PD_CHECK_ALLOC, 527e7801d59Ssowmini DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 528e7801d59Ssowmini 5294045d941Ssowmini { "duplex", { "", 0 }, 530e7801d59Ssowmini link_duplex_vals, VALCNT(link_duplex_vals), 5310dc2366fSVenugopal Iyer NULL, NULL, get_duplex, NULL, 532e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 533e7801d59Ssowmini 5346b9e797cSsowmini { "state", { "up", LINK_STATE_UP }, 535e7801d59Ssowmini link_status_vals, VALCNT(link_status_vals), 5360dc2366fSVenugopal Iyer NULL, NULL, get_link_state, NULL, 5374045d941Ssowmini 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 538e7801d59Ssowmini 5390b8f0546SSowmini Varadhan { "adv_autoneg_cap", { "", 0 }, 540e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 5410dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 542e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 543e7801d59Ssowmini 5444045d941Ssowmini { "mtu", { "", 0 }, NULL, 0, 5450dc2366fSVenugopal Iyer set_public_prop, get_range, 5460dc2366fSVenugopal Iyer get_uint32, check_uint32, 0, DATALINK_CLASS_ALL, 5473bc21d0aSAruna Ramakrishna - Sun Microsystems DATALINK_ANY_MEDIATYPE }, 548e7801d59Ssowmini 5494045d941Ssowmini { "flowctrl", { "", 0 }, 550e7801d59Ssowmini link_flow_vals, VALCNT(link_flow_vals), 5510dc2366fSVenugopal Iyer set_public_prop, NULL, get_flowctl, NULL, 552e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 553e7801d59Ssowmini 5541a41ca23SJerry Jelinek { "secondary-macs", { "--", 0 }, NULL, 0, 5551a41ca23SJerry Jelinek set_secondary_macs, NULL, 5561a41ca23SJerry Jelinek get_secondary_macs, check_secondary_macs, PD_CHECK_ALLOC, 5571a41ca23SJerry Jelinek DATALINK_CLASS_VNIC, DL_ETHER }, 5581a41ca23SJerry Jelinek 5593bc4925dSGarrett D'Amore { "adv_100gfdx_cap", { "", 0 }, 5603bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 5613bc4925dSGarrett D'Amore NULL, NULL, get_binary, NULL, 5623bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5633bc4925dSGarrett D'Amore 5643bc4925dSGarrett D'Amore { "en_100gfdx_cap", { "", 0 }, 5653bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 5663bc4925dSGarrett D'Amore set_public_prop, NULL, get_binary, NULL, 5673bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5683bc4925dSGarrett D'Amore 569422542c1SRobert Mustacchi { "adv_50gfdx_cap", { "", 0 }, 570422542c1SRobert Mustacchi link_01_vals, VALCNT(link_01_vals), 571422542c1SRobert Mustacchi NULL, NULL, get_binary, NULL, 572422542c1SRobert Mustacchi 0, DATALINK_CLASS_PHYS, DL_ETHER }, 573422542c1SRobert Mustacchi 574422542c1SRobert Mustacchi { "en_50gfdx_cap", { "", 0 }, 575422542c1SRobert Mustacchi link_01_vals, VALCNT(link_01_vals), 576422542c1SRobert Mustacchi set_public_prop, NULL, get_binary, NULL, 577422542c1SRobert Mustacchi 0, DATALINK_CLASS_PHYS, DL_ETHER }, 578422542c1SRobert Mustacchi 5793bc4925dSGarrett D'Amore { "adv_40gfdx_cap", { "", 0 }, 5803bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 5813bc4925dSGarrett D'Amore NULL, NULL, get_binary, NULL, 5823bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5833bc4925dSGarrett D'Amore 5843bc4925dSGarrett D'Amore { "en_40gfdx_cap", { "", 0 }, 5853bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 5863bc4925dSGarrett D'Amore set_public_prop, NULL, get_binary, NULL, 5873bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 5883bc4925dSGarrett D'Amore 589422542c1SRobert Mustacchi { "adv_25gfdx_cap", { "", 0 }, 590422542c1SRobert Mustacchi link_01_vals, VALCNT(link_01_vals), 591422542c1SRobert Mustacchi NULL, NULL, get_binary, NULL, 592422542c1SRobert Mustacchi 0, DATALINK_CLASS_PHYS, DL_ETHER }, 593422542c1SRobert Mustacchi 594422542c1SRobert Mustacchi { "en_25gfdx_cap", { "", 0 }, 595422542c1SRobert Mustacchi link_01_vals, VALCNT(link_01_vals), 596422542c1SRobert Mustacchi set_public_prop, NULL, get_binary, NULL, 597422542c1SRobert Mustacchi 0, DATALINK_CLASS_PHYS, DL_ETHER }, 598422542c1SRobert Mustacchi 599aca118b7Slucy wang - Sun Microsystems - Beijing China { "adv_10gfdx_cap", { "", 0 }, 600aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 6010dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 602aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 603aca118b7Slucy wang - Sun Microsystems - Beijing China 604aca118b7Slucy wang - Sun Microsystems - Beijing China { "en_10gfdx_cap", { "", 0 }, 605aca118b7Slucy wang - Sun Microsystems - Beijing China link_01_vals, VALCNT(link_01_vals), 6060dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 607aca118b7Slucy wang - Sun Microsystems - Beijing China 0, DATALINK_CLASS_PHYS, DL_ETHER }, 608aca118b7Slucy wang - Sun Microsystems - Beijing China 6093bc4925dSGarrett D'Amore { "adv_5000fdx_cap", { "", 0 }, 6103bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 6113bc4925dSGarrett D'Amore NULL, NULL, get_binary, NULL, 6123bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 6133bc4925dSGarrett D'Amore 6143bc4925dSGarrett D'Amore { "en_5000fdx_cap", { "", 0 }, 6153bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 6163bc4925dSGarrett D'Amore set_public_prop, NULL, get_binary, NULL, 6173bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 6183bc4925dSGarrett D'Amore 6193bc4925dSGarrett D'Amore { "adv_2500fdx_cap", { "", 0 }, 6203bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 6213bc4925dSGarrett D'Amore NULL, NULL, get_binary, NULL, 6223bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 6233bc4925dSGarrett D'Amore 6243bc4925dSGarrett D'Amore { "en_2500fdx_cap", { "", 0 }, 6253bc4925dSGarrett D'Amore link_01_vals, VALCNT(link_01_vals), 6263bc4925dSGarrett D'Amore set_public_prop, NULL, get_binary, NULL, 6273bc4925dSGarrett D'Amore 0, DATALINK_CLASS_PHYS, DL_ETHER }, 6283bc4925dSGarrett D'Amore 6294045d941Ssowmini { "adv_1000fdx_cap", { "", 0 }, 6304045d941Ssowmini link_01_vals, VALCNT(link_01_vals), 6310dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 632e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 633e7801d59Ssowmini 6344045d941Ssowmini { "en_1000fdx_cap", { "", 0 }, 635e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6360dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 637e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 638e7801d59Ssowmini 6394045d941Ssowmini { "adv_1000hdx_cap", { "", 0 }, 640e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6410dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 642e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 643e7801d59Ssowmini 6444045d941Ssowmini { "en_1000hdx_cap", { "", 0 }, 645e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6460dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 647e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 648e7801d59Ssowmini 6494045d941Ssowmini { "adv_100fdx_cap", { "", 0 }, 650e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6510dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 652e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 653e7801d59Ssowmini 6544045d941Ssowmini { "en_100fdx_cap", { "", 0 }, 655e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6560dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 657e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 658e7801d59Ssowmini 6594045d941Ssowmini { "adv_100hdx_cap", { "", 0 }, 660e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6610dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 662e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 663e7801d59Ssowmini 6644045d941Ssowmini { "en_100hdx_cap", { "", 0 }, 665e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6660dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 667e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 668e7801d59Ssowmini 6694045d941Ssowmini { "adv_10fdx_cap", { "", 0 }, 670e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6710dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 672e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 673e7801d59Ssowmini 6744045d941Ssowmini { "en_10fdx_cap", { "", 0 }, 675e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6760dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 677e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 678e7801d59Ssowmini 6794045d941Ssowmini { "adv_10hdx_cap", { "", 0 }, 680e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6810dc2366fSVenugopal Iyer NULL, NULL, get_binary, NULL, 682e7801d59Ssowmini 0, DATALINK_CLASS_PHYS, DL_ETHER }, 683e7801d59Ssowmini 6844045d941Ssowmini { "en_10hdx_cap", { "", 0 }, 685e7801d59Ssowmini link_01_vals, VALCNT(link_01_vals), 6860dc2366fSVenugopal Iyer set_public_prop, NULL, get_binary, NULL, 687da14cebeSEric Cheng 0, DATALINK_CLASS_PHYS, DL_ETHER }, 688e7801d59Ssowmini 689da14cebeSEric Cheng { "maxbw", { "--", RESET_VAL }, NULL, 0, 6900dc2366fSVenugopal Iyer set_resource, NULL, 6910dc2366fSVenugopal Iyer get_maxbw, check_maxbw, PD_CHECK_ALLOC, 692da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 693da14cebeSEric Cheng 694da14cebeSEric Cheng { "cpus", { "--", RESET_VAL }, NULL, 0, 6950dc2366fSVenugopal Iyer set_resource, NULL, 6960dc2366fSVenugopal Iyer get_cpus, check_cpus, 0, 697da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 698da14cebeSEric Cheng 6990dc2366fSVenugopal Iyer { "cpus-effective", { "--", 0 }, 7000dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 7010dc2366fSVenugopal Iyer get_cpus, 0, 0, 7020dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7030dc2366fSVenugopal Iyer 7040dc2366fSVenugopal Iyer { "pool", { "--", RESET_VAL }, NULL, 0, 7050dc2366fSVenugopal Iyer set_resource, NULL, 7060dc2366fSVenugopal Iyer get_pool, check_pool, 0, 7070dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7080dc2366fSVenugopal Iyer 7090dc2366fSVenugopal Iyer { "pool-effective", { "--", 0 }, 7100dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 7110dc2366fSVenugopal Iyer get_pool, 0, 0, 7120dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 7130dc2366fSVenugopal Iyer 7140dc2366fSVenugopal Iyer { "priority", { "high", MPL_RESET }, 7150dc2366fSVenugopal Iyer link_priority_vals, VALCNT(link_priority_vals), set_resource, 7160dc2366fSVenugopal Iyer NULL, get_priority, check_prop, 0, 717da14cebeSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 718e75f0919SSebastien Roy 719e75f0919SSebastien Roy { "tagmode", { "vlanonly", LINK_TAGMODE_VLANONLY }, 720e75f0919SSebastien Roy link_tagmode_vals, VALCNT(link_tagmode_vals), 7210dc2366fSVenugopal Iyer set_public_prop, NULL, get_tagmode, 722e75f0919SSebastien Roy NULL, 0, 723e75f0919SSebastien Roy DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | DATALINK_CLASS_VNIC, 7244eaa4710SRishi Srivatsavai DL_ETHER }, 7254eaa4710SRishi Srivatsavai 7262b24ab6bSSebastien Roy { "hoplimit", { "", 0 }, NULL, 0, 7270dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 7280dc2366fSVenugopal Iyer check_hoplimit, 0, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE}, 7292b24ab6bSSebastien Roy 7302b24ab6bSSebastien Roy { "encaplimit", { "", 0 }, NULL, 0, 7310dc2366fSVenugopal Iyer set_public_prop, get_range, get_uint32, 7320dc2366fSVenugopal Iyer check_encaplim, 0, DATALINK_CLASS_IPTUN, DL_IPV6}, 7332b24ab6bSSebastien Roy 7344eaa4710SRishi Srivatsavai { "forward", { "1", 1 }, 7354eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 7364eaa4710SRishi Srivatsavai set_bridge_forward, NULL, get_bridge_forward, NULL, PD_AFTER_PERM, 7374eaa4710SRishi Srivatsavai DATALINK_CLASS_ALL & ~DATALINK_CLASS_VNIC, DL_ETHER }, 7384eaa4710SRishi Srivatsavai 7394eaa4710SRishi Srivatsavai { "default_tag", { "1", 1 }, NULL, 0, 7404eaa4710SRishi Srivatsavai set_bridge_pvid, NULL, get_bridge_pvid, check_bridge_pvid, 7414eaa4710SRishi Srivatsavai 0, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7424eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7434eaa4710SRishi Srivatsavai 7444eaa4710SRishi Srivatsavai { "learn_limit", { "1000", 1000 }, NULL, 0, 7450dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 7460dc2366fSVenugopal Iyer check_uint32, 0, 7474eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7484eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7494eaa4710SRishi Srivatsavai 7504eaa4710SRishi Srivatsavai { "learn_decay", { "200", 200 }, NULL, 0, 7510dc2366fSVenugopal Iyer set_public_prop, NULL, get_uint32, 7520dc2366fSVenugopal Iyer check_uint32, 0, 7534eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7544eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7554eaa4710SRishi Srivatsavai 7564eaa4710SRishi Srivatsavai { "stp", { "1", 1 }, 7574eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 7580dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 7594eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7604eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7614eaa4710SRishi Srivatsavai 7624eaa4710SRishi Srivatsavai { "stp_priority", { "128", 128 }, NULL, 0, 7630dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 7644eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7654eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7664eaa4710SRishi Srivatsavai 7674eaa4710SRishi Srivatsavai { "stp_cost", { "auto", 0 }, NULL, 0, 7680dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 7694eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7704eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7714eaa4710SRishi Srivatsavai 7724eaa4710SRishi Srivatsavai { "stp_edge", { "1", 1 }, 7734eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 7740dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 7754eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7764eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7774eaa4710SRishi Srivatsavai 7784eaa4710SRishi Srivatsavai { "stp_p2p", { "auto", P2P_AUTO }, 7794eaa4710SRishi Srivatsavai stp_p2p_vals, VALCNT(stp_p2p_vals), 7800dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, NULL, PD_AFTER_PERM, 7814eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7824eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 7834eaa4710SRishi Srivatsavai 7844eaa4710SRishi Srivatsavai { "stp_mcheck", { "0", 0 }, 7854eaa4710SRishi Srivatsavai link_01_vals, VALCNT(link_01_vals), 7860dc2366fSVenugopal Iyer set_stp_prop, NULL, get_stp, check_stp_prop, PD_AFTER_PERM, 7874eaa4710SRishi Srivatsavai DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| 7884eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, 78925ec3e3dSEric Cheng 79025ec3e3dSEric Cheng { "protection", { "--", RESET_VAL }, 79125ec3e3dSEric Cheng link_protect_vals, VALCNT(link_protect_vals), 7920dc2366fSVenugopal Iyer set_resource, NULL, get_protection, check_prop, 0, 79325ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 79425ec3e3dSEric Cheng 795098d2c75SRobert Mustacchi { "promisc-filtered", { "on", 1 }, 796098d2c75SRobert Mustacchi link_promisc_filtered_vals, VALCNT(link_promisc_filtered_vals), 797098d2c75SRobert Mustacchi set_promisc_filtered, NULL, get_promisc_filtered, check_prop, 0, 798098d2c75SRobert Mustacchi DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE }, 799098d2c75SRobert Mustacchi 800098d2c75SRobert Mustacchi 80125ec3e3dSEric Cheng { "allowed-ips", { "--", 0 }, 8020dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 8030dc2366fSVenugopal Iyer get_allowedips, check_allowedips, PD_CHECK_ALLOC, 80425ec3e3dSEric Cheng DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8050dc2366fSVenugopal Iyer 8060dc2366fSVenugopal Iyer { "allowed-dhcp-cids", { "--", 0 }, 8070dc2366fSVenugopal Iyer NULL, 0, set_resource, NULL, 8080dc2366fSVenugopal Iyer get_allowedcids, check_allowedcids, PD_CHECK_ALLOC, 8090dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8100dc2366fSVenugopal Iyer 8110dc2366fSVenugopal Iyer { "rxrings", { "--", RESET_VAL }, NULL, 0, 8120dc2366fSVenugopal Iyer set_resource, get_rings_range, get_rxrings, check_rings, 0, 8130dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8140dc2366fSVenugopal Iyer 8150dc2366fSVenugopal Iyer { "rxrings-effective", { "--", 0 }, 8160dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 8170dc2366fSVenugopal Iyer get_rxrings, NULL, 0, 8180dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8190dc2366fSVenugopal Iyer 8200dc2366fSVenugopal Iyer { "txrings", { "--", RESET_VAL }, NULL, 0, 8210dc2366fSVenugopal Iyer set_resource, get_rings_range, get_txrings, check_rings, 0, 8220dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8230dc2366fSVenugopal Iyer 8240dc2366fSVenugopal Iyer { "txrings-effective", { "--", 0 }, 8250dc2366fSVenugopal Iyer NULL, 0, NULL, NULL, 8260dc2366fSVenugopal Iyer get_txrings, NULL, 0, 8270dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8280dc2366fSVenugopal Iyer 8290dc2366fSVenugopal Iyer { "txrings-available", { "", 0 }, NULL, 0, 8300dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 8310dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8320dc2366fSVenugopal Iyer 8330dc2366fSVenugopal Iyer { "rxrings-available", { "", 0 }, NULL, 0, 8340dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 8350dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8360dc2366fSVenugopal Iyer 8370dc2366fSVenugopal Iyer { "rxhwclnt-available", { "", 0 }, NULL, 0, 8380dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 8390dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8400dc2366fSVenugopal Iyer 8410dc2366fSVenugopal Iyer { "txhwclnt-available", { "", 0 }, NULL, 0, 8420dc2366fSVenugopal Iyer NULL, NULL, get_cntavail, NULL, 0, 8430dc2366fSVenugopal Iyer DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, 8440dc2366fSVenugopal Iyer 845f4b3ec61Sdh155122 }; 846f4b3ec61Sdh155122 847d62bc4baSyz147064 #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) 8480ba2cbe9Sxc151355 849da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 8500dc2366fSVenugopal Iyer {"maxbw", extract_maxbw}, 8510dc2366fSVenugopal Iyer {"priority", extract_priority}, 8520dc2366fSVenugopal Iyer {"cpus", extract_cpus}, 8530dc2366fSVenugopal Iyer {"cpus-effective", extract_cpus}, 8540dc2366fSVenugopal Iyer {"pool", extract_pool}, 8550dc2366fSVenugopal Iyer {"pool-effective", extract_pool}, 8560dc2366fSVenugopal Iyer {"protection", extract_protection}, 8570dc2366fSVenugopal Iyer {"allowed-ips", extract_allowedips}, 8580dc2366fSVenugopal Iyer {"allowed-dhcp-cids", extract_allowedcids}, 8590dc2366fSVenugopal Iyer {"rxrings", extract_rxrings}, 8600dc2366fSVenugopal Iyer {"rxrings-effective", extract_rxrings}, 8610dc2366fSVenugopal Iyer {"txrings", extract_txrings}, 8620dc2366fSVenugopal Iyer {"txrings-effective", extract_txrings} 863da14cebeSEric Cheng }; 864da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 865da14cebeSEric Cheng sizeof (resource_prop_t)) 866da14cebeSEric Cheng 867bcb5c89dSSowmini Varadhan /* 868bcb5c89dSSowmini Varadhan * when retrieving private properties, we pass down a buffer with 869bcb5c89dSSowmini Varadhan * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. 870bcb5c89dSSowmini Varadhan */ 871bcb5c89dSSowmini Varadhan #define DLADM_PROP_BUF_CHUNK 1024 872bcb5c89dSSowmini Varadhan 8734ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop_db(dladm_handle_t, datalink_id_t, 8744ac67f02SAnurag S. Maskey const char *, char **, uint_t); 8754ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_linkprop_db(dladm_handle_t, datalink_id_t, 8764ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 87762ee1d25SArtem Kachitchkine static dladm_status_t i_dladm_walk_linkprop_priv_db(dladm_handle_t, 87862ee1d25SArtem Kachitchkine datalink_id_t, void *, int (*)(dladm_handle_t, 87962ee1d25SArtem Kachitchkine datalink_id_t, const char *, void *)); 8804ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_single_prop(dladm_handle_t, datalink_id_t, 8814ac67f02SAnurag S. Maskey datalink_class_t, uint32_t, prop_desc_t *, char **, 8824ac67f02SAnurag S. Maskey uint_t, uint_t); 8834ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_linkprop(dladm_handle_t, datalink_id_t, 884*63cfa7a9SRyan Zezeski const char *, char **, uint_t, uint_t, 885*63cfa7a9SRyan Zezeski datalink_class_t, uint32_t); 8864ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, 8874ac67f02SAnurag S. Maskey datalink_id_t, datalink_media_t, uint_t); 888da14cebeSEric Cheng 889d62bc4baSyz147064 /* 890d62bc4baSyz147064 * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all 891d62bc4baSyz147064 * rates to be retrieved. However, we cannot increase it at this 892d62bc4baSyz147064 * time because it will break binary compatibility with unbundled 893d62bc4baSyz147064 * WiFi drivers and utilities. So for now we define an additional 894d62bc4baSyz147064 * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. 895d62bc4baSyz147064 */ 896d62bc4baSyz147064 #define MAX_SUPPORT_RATES 64 897d62bc4baSyz147064 898d62bc4baSyz147064 #define AP_ANCHOR "[anchor]" 899d62bc4baSyz147064 #define AP_DELIMITER '.' 900d62bc4baSyz147064 90125ec3e3dSEric Cheng /* ARGSUSED */ 902d62bc4baSyz147064 static dladm_status_t 9030dc2366fSVenugopal Iyer check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 904c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 9050dc2366fSVenugopal Iyer datalink_media_t media) 9060ba2cbe9Sxc151355 { 907d62bc4baSyz147064 int i, j; 908c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 909c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 9100ba2cbe9Sxc151355 911d62bc4baSyz147064 for (j = 0; j < val_cnt; j++) { 912d62bc4baSyz147064 for (i = 0; i < pdp->pd_noptval; i++) { 91325ec3e3dSEric Cheng if (strcasecmp(prop_val[j], 914d62bc4baSyz147064 pdp->pd_optval[i].vd_name) == 0) { 9150ba2cbe9Sxc151355 break; 9160ba2cbe9Sxc151355 } 9170ba2cbe9Sxc151355 } 91825ec3e3dSEric Cheng if (i == pdp->pd_noptval) 91925ec3e3dSEric Cheng return (DLADM_STATUS_BADVAL); 9200ba2cbe9Sxc151355 92125ec3e3dSEric Cheng (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); 92225ec3e3dSEric Cheng } 92325ec3e3dSEric Cheng return (DLADM_STATUS_OK); 9240ba2cbe9Sxc151355 } 9250ba2cbe9Sxc151355 9260ba2cbe9Sxc151355 static dladm_status_t 9274ac67f02SAnurag S. Maskey i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, 9284ac67f02SAnurag S. Maskey datalink_class_t class, uint32_t media, prop_desc_t *pdp, char **prop_val, 9294ac67f02SAnurag S. Maskey uint_t val_cnt, uint_t flags) 9300ba2cbe9Sxc151355 { 9310ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 932d62bc4baSyz147064 val_desc_t *vdp = NULL; 933d62bc4baSyz147064 boolean_t needfree = B_FALSE; 934d62bc4baSyz147064 uint_t cnt, i; 9350ba2cbe9Sxc151355 936d62bc4baSyz147064 if (!(pdp->pd_class & class)) 937d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 9380ba2cbe9Sxc151355 939d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 940d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 941d62bc4baSyz147064 942d62bc4baSyz147064 if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY)) 943d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 944d62bc4baSyz147064 945d62bc4baSyz147064 if (!(flags & DLADM_OPT_ACTIVE)) 946d62bc4baSyz147064 return (DLADM_STATUS_OK); 947d62bc4baSyz147064 948d62bc4baSyz147064 if (pdp->pd_set == NULL) 949d62bc4baSyz147064 return (DLADM_STATUS_PROPRDONLY); 950d62bc4baSyz147064 951d62bc4baSyz147064 if (prop_val != NULL) { 9520dc2366fSVenugopal Iyer vdp = calloc(val_cnt, sizeof (val_desc_t)); 953d62bc4baSyz147064 if (vdp == NULL) 954d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 955d62bc4baSyz147064 956d62bc4baSyz147064 if (pdp->pd_check != NULL) { 957da14cebeSEric Cheng needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 9584ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, linkid, prop_val, 959c569ef53SMichael Lim &val_cnt, flags, &vdp, media); 960d62bc4baSyz147064 } else if (pdp->pd_optval != NULL) { 9610dc2366fSVenugopal Iyer status = check_prop(handle, pdp, linkid, prop_val, 962c569ef53SMichael Lim &val_cnt, flags, &vdp, media); 963d62bc4baSyz147064 } else { 964d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 9650ba2cbe9Sxc151355 } 9660ba2cbe9Sxc151355 967d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 968d62bc4baSyz147064 goto done; 969d62bc4baSyz147064 970d62bc4baSyz147064 cnt = val_cnt; 971d62bc4baSyz147064 } else { 972e0a79f29SYuri Pankov boolean_t defval; 973da14cebeSEric Cheng 974d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) 975d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 976d62bc4baSyz147064 9773bc21d0aSAruna Ramakrishna - Sun Microsystems cnt = 1; 978da14cebeSEric Cheng defval = (strlen(pdp->pd_defval.vd_name) > 0); 979e0a79f29SYuri Pankov if ((pdp->pd_flags & PD_CHECK_ALLOC) == 0 && !defval) { 980e0a79f29SYuri Pankov status = i_dladm_getset_defval(handle, pdp, linkid, 981e0a79f29SYuri Pankov media, flags); 982e0a79f29SYuri Pankov return (status); 983e0a79f29SYuri Pankov } 984e0a79f29SYuri Pankov 985e0a79f29SYuri Pankov vdp = calloc(1, sizeof (val_desc_t)); 986e0a79f29SYuri Pankov if (vdp == NULL) 987d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 9883bc21d0aSAruna Ramakrishna - Sun Microsystems 989da14cebeSEric Cheng if (defval) { 990da14cebeSEric Cheng (void) memcpy(vdp, &pdp->pd_defval, 991da14cebeSEric Cheng sizeof (val_desc_t)); 992da14cebeSEric Cheng } else if (pdp->pd_check != NULL) { 993e0a79f29SYuri Pankov needfree = ((pdp->pd_flags & PD_CHECK_ALLOC) != 0); 994e0a79f29SYuri Pankov status = pdp->pd_check(handle, pdp, linkid, prop_val, 995e0a79f29SYuri Pankov &cnt, flags, &vdp, media); 9963bc21d0aSAruna Ramakrishna - Sun Microsystems if (status != DLADM_STATUS_OK) 9973bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 9983bc21d0aSAruna Ramakrishna - Sun Microsystems } 999d62bc4baSyz147064 } 10004eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_AFTER_PERM) 10014eaa4710SRishi Srivatsavai status = (flags & DLADM_OPT_PERSIST) ? DLADM_STATUS_OK : 10024eaa4710SRishi Srivatsavai DLADM_STATUS_PERMONLY; 10034eaa4710SRishi Srivatsavai else 10044eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, vdp, cnt, flags, 10054eaa4710SRishi Srivatsavai media); 1006d62bc4baSyz147064 if (needfree) { 1007d62bc4baSyz147064 for (i = 0; i < cnt; i++) 1008e7801d59Ssowmini free((void *)((val_desc_t *)vdp + i)->vd_val); 1009d62bc4baSyz147064 } 1010d62bc4baSyz147064 done: 1011d62bc4baSyz147064 free(vdp); 1012d62bc4baSyz147064 return (status); 1013d62bc4baSyz147064 } 1014d62bc4baSyz147064 1015d62bc4baSyz147064 static dladm_status_t 10164ac67f02SAnurag S. Maskey i_dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 1017*63cfa7a9SRyan Zezeski const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags, 1018*63cfa7a9SRyan Zezeski datalink_class_t class, uint32_t media) 1019d62bc4baSyz147064 { 1020d62bc4baSyz147064 int i; 1021d62bc4baSyz147064 boolean_t found = B_FALSE; 1022d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1023d62bc4baSyz147064 1024d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 1025d62bc4baSyz147064 prop_desc_t *pdp = &prop_table[i]; 1026d62bc4baSyz147064 dladm_status_t s; 10270ba2cbe9Sxc151355 1028d62bc4baSyz147064 if (prop_name != NULL && 1029d62bc4baSyz147064 (strcasecmp(prop_name, pdp->pd_name) != 0)) 1030d62bc4baSyz147064 continue; 1031d62bc4baSyz147064 found = B_TRUE; 10324ac67f02SAnurag S. Maskey s = i_dladm_set_single_prop(handle, linkid, class, media, pdp, 10334ac67f02SAnurag S. Maskey prop_val, val_cnt, flags); 1034d62bc4baSyz147064 1035d62bc4baSyz147064 if (prop_name != NULL) { 1036d62bc4baSyz147064 status = s; 1037d62bc4baSyz147064 break; 1038d62bc4baSyz147064 } else { 1039*63cfa7a9SRyan Zezeski /* 1040*63cfa7a9SRyan Zezeski * Some consumers of this function pass a 1041*63cfa7a9SRyan Zezeski * prop_name of NULL to indicate that all 1042*63cfa7a9SRyan Zezeski * properties should reset to their default 1043*63cfa7a9SRyan Zezeski * value. Some properties don't support a 1044*63cfa7a9SRyan Zezeski * default value and will return NOTSUP -- for 1045*63cfa7a9SRyan Zezeski * the purpose of resetting property values we 1046*63cfa7a9SRyan Zezeski * treat it the same as success. We need the 1047*63cfa7a9SRyan Zezeski * separate status variable 's' so that we can 1048*63cfa7a9SRyan Zezeski * record any failed calls in 'status' and 1049*63cfa7a9SRyan Zezeski * continue resetting the rest of the 1050*63cfa7a9SRyan Zezeski * properties. 1051*63cfa7a9SRyan Zezeski */ 1052d62bc4baSyz147064 if (s != DLADM_STATUS_OK && 1053d62bc4baSyz147064 s != DLADM_STATUS_NOTSUP) 1054d62bc4baSyz147064 status = s; 1055d62bc4baSyz147064 } 1056d62bc4baSyz147064 } 1057e7801d59Ssowmini if (!found) { 1058e7801d59Ssowmini if (prop_name[0] == '_') { 1059e7801d59Ssowmini /* other private properties */ 10603361618bSRishi Srivatsavai status = i_dladm_set_private_prop(handle, linkid, 10613361618bSRishi Srivatsavai prop_name, prop_val, val_cnt, flags); 1062e7801d59Ssowmini } else { 10630ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 1064e7801d59Ssowmini } 1065e7801d59Ssowmini } 10660ba2cbe9Sxc151355 return (status); 10670ba2cbe9Sxc151355 } 10680ba2cbe9Sxc151355 1069d62bc4baSyz147064 /* 1070d62bc4baSyz147064 * Set/reset link property for specific link 1071d62bc4baSyz147064 */ 1072d62bc4baSyz147064 dladm_status_t 10734ac67f02SAnurag S. Maskey dladm_set_linkprop(dladm_handle_t handle, datalink_id_t linkid, 10744ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 10750ba2cbe9Sxc151355 { 1076d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1077*63cfa7a9SRyan Zezeski datalink_class_t class; 1078*63cfa7a9SRyan Zezeski uint32_t media; 1079*63cfa7a9SRyan Zezeski uint32_t link_flags; 10800ba2cbe9Sxc151355 1081d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) || 1082d62bc4baSyz147064 (prop_val == NULL && val_cnt > 0) || 1083d62bc4baSyz147064 (prop_val != NULL && val_cnt == 0) || 1084d62bc4baSyz147064 (prop_name == NULL && prop_val != NULL)) { 1085d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 10860ba2cbe9Sxc151355 } 10870ba2cbe9Sxc151355 10883361618bSRishi Srivatsavai /* 10893361618bSRishi Srivatsavai * Check for valid link property against the flags passed 10903361618bSRishi Srivatsavai * and set the link property when active flag is passed. 10913361618bSRishi Srivatsavai */ 1092*63cfa7a9SRyan Zezeski status = dladm_datalink_id2info(handle, linkid, &link_flags, &class, 1093*63cfa7a9SRyan Zezeski &media, NULL, 0); 1094*63cfa7a9SRyan Zezeski if (status != DLADM_STATUS_OK) 1095*63cfa7a9SRyan Zezeski return (status); 10964ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop(handle, linkid, prop_name, prop_val, 1097*63cfa7a9SRyan Zezeski val_cnt, flags, class, media); 1098d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1099d62bc4baSyz147064 return (status); 1100d62bc4baSyz147064 1101*63cfa7a9SRyan Zezeski /* 1102*63cfa7a9SRyan Zezeski * Write an entry to the persistent configuration database if 1103*63cfa7a9SRyan Zezeski * and only if the user has requested the property to be 1104*63cfa7a9SRyan Zezeski * persistent and the link is a persistent link. 1105*63cfa7a9SRyan Zezeski */ 1106*63cfa7a9SRyan Zezeski if ((flags & DLADM_OPT_PERSIST) && (link_flags & DLMGMT_PERSIST)) { 11074ac67f02SAnurag S. Maskey status = i_dladm_set_linkprop_db(handle, linkid, prop_name, 1108d62bc4baSyz147064 prop_val, val_cnt); 11094eaa4710SRishi Srivatsavai 11104eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { 11114eaa4710SRishi Srivatsavai prop_desc_t *pdp = prop_table; 11124eaa4710SRishi Srivatsavai int i; 11134eaa4710SRishi Srivatsavai 11144eaa4710SRishi Srivatsavai for (i = 0; i < DLADM_MAX_PROPS; i++, pdp++) { 11154eaa4710SRishi Srivatsavai if (!(pdp->pd_flags & PD_AFTER_PERM)) 11164eaa4710SRishi Srivatsavai continue; 11174eaa4710SRishi Srivatsavai if (prop_name != NULL && 11184eaa4710SRishi Srivatsavai strcasecmp(prop_name, pdp->pd_name) != 0) 11194eaa4710SRishi Srivatsavai continue; 11204eaa4710SRishi Srivatsavai status = pdp->pd_set(handle, pdp, linkid, NULL, 11214eaa4710SRishi Srivatsavai 0, flags, 0); 11224eaa4710SRishi Srivatsavai } 11234eaa4710SRishi Srivatsavai } 1124d62bc4baSyz147064 } 1125d62bc4baSyz147064 return (status); 1126d62bc4baSyz147064 } 1127d62bc4baSyz147064 1128d62bc4baSyz147064 /* 112962ee1d25SArtem Kachitchkine * Walk all link properties of the given specific link. 113062ee1d25SArtem Kachitchkine * 113162ee1d25SArtem Kachitchkine * Note: this function currently lacks the ability to walk _all_ private 113262ee1d25SArtem Kachitchkine * properties if the link, because there is no kernel interface to 113362ee1d25SArtem Kachitchkine * retrieve all known private property names. Once such an interface 113462ee1d25SArtem Kachitchkine * is added, this function should be fixed accordingly. 1135d62bc4baSyz147064 */ 1136d62bc4baSyz147064 dladm_status_t 11374ac67f02SAnurag S. Maskey dladm_walk_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg, 11384ac67f02SAnurag S. Maskey int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 11390ba2cbe9Sxc151355 { 1140d62bc4baSyz147064 dladm_status_t status; 1141d62bc4baSyz147064 datalink_class_t class; 1142d62bc4baSyz147064 uint_t media; 1143d62bc4baSyz147064 int i; 11440ba2cbe9Sxc151355 1145d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || func == NULL) 1146d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 11470ba2cbe9Sxc151355 11484ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 11494ac67f02SAnurag S. Maskey NULL, 0); 1150d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1151d62bc4baSyz147064 return (status); 1152d62bc4baSyz147064 115362ee1d25SArtem Kachitchkine /* public */ 1154d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) { 1155d62bc4baSyz147064 if (!(prop_table[i].pd_class & class)) 1156d62bc4baSyz147064 continue; 1157d62bc4baSyz147064 1158d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media)) 1159d62bc4baSyz147064 continue; 1160d62bc4baSyz147064 11614ac67f02SAnurag S. Maskey if (func(handle, linkid, prop_table[i].pd_name, arg) == 1162d62bc4baSyz147064 DLADM_WALK_TERMINATE) { 1163d62bc4baSyz147064 break; 1164d62bc4baSyz147064 } 1165d62bc4baSyz147064 } 1166d62bc4baSyz147064 116762ee1d25SArtem Kachitchkine /* private */ 116862ee1d25SArtem Kachitchkine status = i_dladm_walk_linkprop_priv_db(handle, linkid, arg, func); 116962ee1d25SArtem Kachitchkine 117062ee1d25SArtem Kachitchkine return (status); 1171d62bc4baSyz147064 } 1172d62bc4baSyz147064 1173d62bc4baSyz147064 /* 1174d62bc4baSyz147064 * Get linkprop of the given specific link. 1175d62bc4baSyz147064 */ 1176d62bc4baSyz147064 dladm_status_t 11774ac67f02SAnurag S. Maskey dladm_get_linkprop(dladm_handle_t handle, datalink_id_t linkid, 11784ac67f02SAnurag S. Maskey dladm_prop_type_t type, const char *prop_name, char **prop_val, 11794ac67f02SAnurag S. Maskey uint_t *val_cntp) 1180d62bc4baSyz147064 { 1181d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 1182d62bc4baSyz147064 datalink_class_t class; 1183d62bc4baSyz147064 uint_t media; 1184d62bc4baSyz147064 prop_desc_t *pdp; 11854045d941Ssowmini uint_t cnt, dld_flags = 0; 1186d62bc4baSyz147064 int i; 1187afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 1188d62bc4baSyz147064 11894045d941Ssowmini if (type == DLADM_PROP_VAL_DEFAULT) 11900dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_DEFAULT; 1191f0f2c3a5SGirish Moodalbail else if (type == DLADM_PROP_VAL_MODIFIABLE) 11920dc2366fSVenugopal Iyer dld_flags |= DLD_PROP_POSSIBLE; 11934045d941Ssowmini 1194d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 1195d62bc4baSyz147064 prop_val == NULL || val_cntp == NULL || *val_cntp == 0) 1196d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1197d62bc4baSyz147064 1198d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROPS; i++) 1199d62bc4baSyz147064 if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) 1200d62bc4baSyz147064 break; 1201d62bc4baSyz147064 1202e7801d59Ssowmini if (i == DLADM_MAX_PROPS) { 1203e7801d59Ssowmini if (prop_name[0] == '_') { 1204e7801d59Ssowmini /* 1205e7801d59Ssowmini * private property. 1206e7801d59Ssowmini */ 120762ee1d25SArtem Kachitchkine if (type == DLADM_PROP_VAL_PERSISTENT) 120862ee1d25SArtem Kachitchkine return (i_dladm_get_linkprop_db(handle, linkid, 120962ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp)); 121062ee1d25SArtem Kachitchkine else 121162ee1d25SArtem Kachitchkine return (i_dladm_get_priv_prop(handle, linkid, 121262ee1d25SArtem Kachitchkine prop_name, prop_val, val_cntp, type, 121362ee1d25SArtem Kachitchkine dld_flags)); 1214e7801d59Ssowmini } else { 1215d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 1216e7801d59Ssowmini } 1217e7801d59Ssowmini } 1218d62bc4baSyz147064 1219d62bc4baSyz147064 pdp = &prop_table[i]; 1220d62bc4baSyz147064 12214ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 12224ac67f02SAnurag S. Maskey NULL, 0); 1223d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1224d62bc4baSyz147064 return (status); 1225d62bc4baSyz147064 1226d62bc4baSyz147064 if (!(pdp->pd_class & class)) 1227d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1228d62bc4baSyz147064 1229d62bc4baSyz147064 if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 1230d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 1231d62bc4baSyz147064 1232d62bc4baSyz147064 switch (type) { 1233d62bc4baSyz147064 case DLADM_PROP_VAL_CURRENT: 12344ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 12354ac67f02SAnurag S. Maskey media, dld_flags, &perm_flags); 1236afdda45fSVasumathi Sundaram - Sun Microsystems break; 1237afdda45fSVasumathi Sundaram - Sun Microsystems 1238afdda45fSVasumathi Sundaram - Sun Microsystems case DLADM_PROP_VAL_PERM: 1239afdda45fSVasumathi Sundaram - Sun Microsystems if (pdp->pd_set == NULL) { 1240afdda45fSVasumathi Sundaram - Sun Microsystems perm_flags = MAC_PROP_PERM_READ; 1241afdda45fSVasumathi Sundaram - Sun Microsystems } else { 12424ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 12434ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 1244afdda45fSVasumathi Sundaram - Sun Microsystems } 1245afdda45fSVasumathi Sundaram - Sun Microsystems 1246afdda45fSVasumathi Sundaram - Sun Microsystems *prop_val[0] = '\0'; 124763a6526dSMichael Lim *val_cntp = 1; 1248da14cebeSEric Cheng if (status == DLADM_STATUS_OK) 1249da14cebeSEric Cheng (void) dladm_perm2str(perm_flags, *prop_val); 1250d62bc4baSyz147064 break; 1251d62bc4baSyz147064 1252d62bc4baSyz147064 case DLADM_PROP_VAL_DEFAULT: 125313a55820Sar224390 /* 125413a55820Sar224390 * If defaults are not defined for the property, 125513a55820Sar224390 * pd_defval.vd_name should be null. If the driver 125613a55820Sar224390 * has to be contacted for the value, vd_name should 125713a55820Sar224390 * be the empty string (""). Otherwise, dladm will 125813a55820Sar224390 * just print whatever is in the table. 125913a55820Sar224390 */ 1260d62bc4baSyz147064 if (pdp->pd_defval.vd_name == NULL) { 1261d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1262d62bc4baSyz147064 break; 1263d62bc4baSyz147064 } 12644045d941Ssowmini 12654045d941Ssowmini if (strlen(pdp->pd_defval.vd_name) == 0) { 12664ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_val, 12674ac67f02SAnurag S. Maskey val_cntp, media, dld_flags, &perm_flags); 12684045d941Ssowmini } else { 1269d62bc4baSyz147064 (void) strcpy(*prop_val, pdp->pd_defval.vd_name); 12704045d941Ssowmini } 1271d62bc4baSyz147064 *val_cntp = 1; 1272d62bc4baSyz147064 break; 1273d62bc4baSyz147064 1274d62bc4baSyz147064 case DLADM_PROP_VAL_MODIFIABLE: 1275d62bc4baSyz147064 if (pdp->pd_getmod != NULL) { 12764ac67f02SAnurag S. Maskey status = pdp->pd_getmod(handle, pdp, linkid, prop_val, 1277afdda45fSVasumathi Sundaram - Sun Microsystems val_cntp, media, dld_flags, &perm_flags); 1278d62bc4baSyz147064 break; 1279d62bc4baSyz147064 } 1280d62bc4baSyz147064 cnt = pdp->pd_noptval; 1281d62bc4baSyz147064 if (cnt == 0) { 1282d62bc4baSyz147064 status = DLADM_STATUS_NOTSUP; 1283d62bc4baSyz147064 } else if (cnt > *val_cntp) { 1284d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 1285d62bc4baSyz147064 } else { 1286d62bc4baSyz147064 for (i = 0; i < cnt; i++) { 1287d62bc4baSyz147064 (void) strcpy(prop_val[i], 1288d62bc4baSyz147064 pdp->pd_optval[i].vd_name); 1289d62bc4baSyz147064 } 1290d62bc4baSyz147064 *val_cntp = cnt; 1291d62bc4baSyz147064 } 1292d62bc4baSyz147064 break; 1293d62bc4baSyz147064 case DLADM_PROP_VAL_PERSISTENT: 1294d62bc4baSyz147064 if (pdp->pd_flags & PD_TEMPONLY) 1295d62bc4baSyz147064 return (DLADM_STATUS_TEMPONLY); 12964ac67f02SAnurag S. Maskey status = i_dladm_get_linkprop_db(handle, linkid, prop_name, 1297d62bc4baSyz147064 prop_val, val_cntp); 1298d62bc4baSyz147064 break; 1299d62bc4baSyz147064 default: 1300d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 1301d62bc4baSyz147064 break; 1302d62bc4baSyz147064 } 1303d62bc4baSyz147064 1304d62bc4baSyz147064 return (status); 1305d62bc4baSyz147064 } 1306d62bc4baSyz147064 13074eaa4710SRishi Srivatsavai /* 13084eaa4710SRishi Srivatsavai * Get linkprop of the given specific link and run any possible conversion 13094eaa4710SRishi Srivatsavai * of the values using the check function for the property. Fails if the 13104eaa4710SRishi Srivatsavai * check function doesn't succeed for the property value. 13114eaa4710SRishi Srivatsavai */ 13124eaa4710SRishi Srivatsavai dladm_status_t 13134eaa4710SRishi Srivatsavai dladm_get_linkprop_values(dladm_handle_t handle, datalink_id_t linkid, 13144eaa4710SRishi Srivatsavai dladm_prop_type_t type, const char *prop_name, uint_t *ret_val, 13154eaa4710SRishi Srivatsavai uint_t *val_cntp) 13164eaa4710SRishi Srivatsavai { 13174eaa4710SRishi Srivatsavai dladm_status_t status; 13184eaa4710SRishi Srivatsavai datalink_class_t class; 13194eaa4710SRishi Srivatsavai uint_t media; 13204eaa4710SRishi Srivatsavai prop_desc_t *pdp; 13214eaa4710SRishi Srivatsavai uint_t dld_flags; 13224eaa4710SRishi Srivatsavai int valc, i; 13234eaa4710SRishi Srivatsavai char **prop_val; 13244eaa4710SRishi Srivatsavai uint_t perm_flags; 13254eaa4710SRishi Srivatsavai 13264eaa4710SRishi Srivatsavai if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL || 13274eaa4710SRishi Srivatsavai ret_val == NULL || val_cntp == NULL || *val_cntp == 0) 13284eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 13294eaa4710SRishi Srivatsavai 13304eaa4710SRishi Srivatsavai for (pdp = prop_table; pdp < prop_table + DLADM_MAX_PROPS; pdp++) 13314eaa4710SRishi Srivatsavai if (strcasecmp(prop_name, pdp->pd_name) == 0) 13324eaa4710SRishi Srivatsavai break; 13334eaa4710SRishi Srivatsavai 13344eaa4710SRishi Srivatsavai if (pdp == prop_table + DLADM_MAX_PROPS) 13354eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 13364eaa4710SRishi Srivatsavai 13374eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_CHECK_ALLOC) 13384eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 13394eaa4710SRishi Srivatsavai 13404eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, NULL, &class, &media, 13414eaa4710SRishi Srivatsavai NULL, 0); 13424eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 13434eaa4710SRishi Srivatsavai return (status); 13444eaa4710SRishi Srivatsavai 13454eaa4710SRishi Srivatsavai if (!(pdp->pd_class & class)) 13464eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 13474eaa4710SRishi Srivatsavai 13484eaa4710SRishi Srivatsavai if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media)) 13494eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADARG); 13504eaa4710SRishi Srivatsavai 13514eaa4710SRishi Srivatsavai prop_val = malloc(*val_cntp * sizeof (*prop_val) + 13524eaa4710SRishi Srivatsavai *val_cntp * DLADM_PROP_VAL_MAX); 13534eaa4710SRishi Srivatsavai if (prop_val == NULL) 13544eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOMEM); 13554eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 13564eaa4710SRishi Srivatsavai prop_val[valc] = (char *)(prop_val + *val_cntp) + 13574eaa4710SRishi Srivatsavai valc * DLADM_PROP_VAL_MAX; 13584eaa4710SRishi Srivatsavai 13590dc2366fSVenugopal Iyer dld_flags = (type == DLADM_PROP_VAL_DEFAULT) ? DLD_PROP_DEFAULT : 0; 13604eaa4710SRishi Srivatsavai 13614eaa4710SRishi Srivatsavai switch (type) { 13624eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_CURRENT: 13634eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 13644eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 13654eaa4710SRishi Srivatsavai break; 13664eaa4710SRishi Srivatsavai 13674eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_DEFAULT: 13684eaa4710SRishi Srivatsavai /* 13694eaa4710SRishi Srivatsavai * If defaults are not defined for the property, 13704eaa4710SRishi Srivatsavai * pd_defval.vd_name should be null. If the driver 13714eaa4710SRishi Srivatsavai * has to be contacted for the value, vd_name should 13724eaa4710SRishi Srivatsavai * be the empty string (""). Otherwise, dladm will 13734eaa4710SRishi Srivatsavai * just print whatever is in the table. 13744eaa4710SRishi Srivatsavai */ 13754eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name == NULL) { 13764eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOTSUP; 13774eaa4710SRishi Srivatsavai break; 13784eaa4710SRishi Srivatsavai } 13794eaa4710SRishi Srivatsavai 13804eaa4710SRishi Srivatsavai if (pdp->pd_defval.vd_name[0] != '\0') { 13814eaa4710SRishi Srivatsavai *val_cntp = 1; 13824eaa4710SRishi Srivatsavai *ret_val = pdp->pd_defval.vd_val; 13834eaa4710SRishi Srivatsavai free(prop_val); 13844eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 13854eaa4710SRishi Srivatsavai } 13864eaa4710SRishi Srivatsavai status = pdp->pd_get(handle, pdp, linkid, prop_val, val_cntp, 13874eaa4710SRishi Srivatsavai media, dld_flags, &perm_flags); 13884eaa4710SRishi Srivatsavai break; 13894eaa4710SRishi Srivatsavai 13904eaa4710SRishi Srivatsavai case DLADM_PROP_VAL_PERSISTENT: 13914eaa4710SRishi Srivatsavai if (pdp->pd_flags & PD_TEMPONLY) 13924eaa4710SRishi Srivatsavai status = DLADM_STATUS_TEMPONLY; 13934eaa4710SRishi Srivatsavai else 13944eaa4710SRishi Srivatsavai status = i_dladm_get_linkprop_db(handle, linkid, 13954eaa4710SRishi Srivatsavai prop_name, prop_val, val_cntp); 13964eaa4710SRishi Srivatsavai break; 13974eaa4710SRishi Srivatsavai 13984eaa4710SRishi Srivatsavai default: 13994eaa4710SRishi Srivatsavai status = DLADM_STATUS_BADARG; 14004eaa4710SRishi Srivatsavai break; 14014eaa4710SRishi Srivatsavai } 14024eaa4710SRishi Srivatsavai 14034eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 14044eaa4710SRishi Srivatsavai if (pdp->pd_check != NULL) { 14054eaa4710SRishi Srivatsavai val_desc_t *vdp; 14064eaa4710SRishi Srivatsavai 14074eaa4710SRishi Srivatsavai vdp = malloc(sizeof (val_desc_t) * *val_cntp); 14084eaa4710SRishi Srivatsavai if (vdp == NULL) 14094eaa4710SRishi Srivatsavai status = DLADM_STATUS_NOMEM; 14104eaa4710SRishi Srivatsavai else 14114eaa4710SRishi Srivatsavai status = pdp->pd_check(handle, pdp, linkid, 1412c569ef53SMichael Lim prop_val, val_cntp, 0, &vdp, media); 14134eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 14144eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) 14154eaa4710SRishi Srivatsavai ret_val[valc] = vdp[valc].vd_val; 14164eaa4710SRishi Srivatsavai } 14174eaa4710SRishi Srivatsavai free(vdp); 14184eaa4710SRishi Srivatsavai } else { 14194eaa4710SRishi Srivatsavai for (valc = 0; valc < *val_cntp; valc++) { 14204eaa4710SRishi Srivatsavai for (i = 0; i < pdp->pd_noptval; i++) { 14214eaa4710SRishi Srivatsavai if (strcmp(pdp->pd_optval[i].vd_name, 14224eaa4710SRishi Srivatsavai prop_val[valc]) == 0) { 14234eaa4710SRishi Srivatsavai ret_val[valc] = 14244eaa4710SRishi Srivatsavai pdp->pd_optval[i].vd_val; 14254eaa4710SRishi Srivatsavai break; 14264eaa4710SRishi Srivatsavai } 14274eaa4710SRishi Srivatsavai } 14284eaa4710SRishi Srivatsavai if (i == pdp->pd_noptval) { 14294eaa4710SRishi Srivatsavai status = DLADM_STATUS_FAILED; 14304eaa4710SRishi Srivatsavai break; 14314eaa4710SRishi Srivatsavai } 14324eaa4710SRishi Srivatsavai } 14334eaa4710SRishi Srivatsavai } 14344eaa4710SRishi Srivatsavai } 14354eaa4710SRishi Srivatsavai 14364eaa4710SRishi Srivatsavai free(prop_val); 14374eaa4710SRishi Srivatsavai 14384eaa4710SRishi Srivatsavai return (status); 14394eaa4710SRishi Srivatsavai } 14404eaa4710SRishi Srivatsavai 1441d62bc4baSyz147064 /*ARGSUSED*/ 1442d62bc4baSyz147064 static int 14434ac67f02SAnurag S. Maskey i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, 14444ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 1445d62bc4baSyz147064 { 1446d62bc4baSyz147064 char *buf, **propvals; 1447d62bc4baSyz147064 uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; 14480dc2366fSVenugopal Iyer dladm_status_t status; 14490dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla = arg; 1450d62bc4baSyz147064 1451d62bc4baSyz147064 if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 1452d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT)) == NULL) { 1453d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1454d62bc4baSyz147064 } 1455d62bc4baSyz147064 1456d62bc4baSyz147064 propvals = (char **)(void *)buf; 1457d62bc4baSyz147064 for (i = 0; i < valcnt; i++) { 1458d62bc4baSyz147064 propvals[i] = buf + 1459d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 1460d62bc4baSyz147064 i * DLADM_PROP_VAL_MAX; 1461d62bc4baSyz147064 } 1462d62bc4baSyz147064 14634ac67f02SAnurag S. Maskey if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 14644ac67f02SAnurag S. Maskey prop_name, propvals, &valcnt) != DLADM_STATUS_OK) { 1465d62bc4baSyz147064 goto done; 1466d62bc4baSyz147064 } 1467d62bc4baSyz147064 14688d4cf8d8S status = dladm_set_linkprop(handle, linkid, prop_name, propvals, 14690dc2366fSVenugopal Iyer valcnt, dla->dla_flags | DLADM_OPT_ACTIVE); 14700dc2366fSVenugopal Iyer 14718d4cf8d8S if (status != DLADM_STATUS_OK) 14720dc2366fSVenugopal Iyer dla->dla_status = status; 1473d62bc4baSyz147064 1474d62bc4baSyz147064 done: 1475d62bc4baSyz147064 if (buf != NULL) 1476d62bc4baSyz147064 free(buf); 1477d62bc4baSyz147064 1478d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 1479d62bc4baSyz147064 } 1480d62bc4baSyz147064 1481d62bc4baSyz147064 /*ARGSUSED*/ 1482d62bc4baSyz147064 static int 14834ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, void *arg) 1484d62bc4baSyz147064 { 1485da14cebeSEric Cheng datalink_class_t class; 1486da14cebeSEric Cheng dladm_status_t status; 1487da14cebeSEric Cheng 14884ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, 14894ac67f02SAnurag S. Maskey NULL, 0); 1490da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1491da14cebeSEric Cheng return (DLADM_WALK_TERMINATE); 1492da14cebeSEric Cheng 1493da14cebeSEric Cheng if ((class & (DATALINK_CLASS_VNIC | DATALINK_CLASS_VLAN)) == 0) 14944ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, B_TRUE); 1495da14cebeSEric Cheng 1496d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 14970ba2cbe9Sxc151355 } 14980ba2cbe9Sxc151355 14990ba2cbe9Sxc151355 dladm_status_t 15004ac67f02SAnurag S. Maskey dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, 15014ac67f02SAnurag S. Maskey boolean_t any_media) 15020ba2cbe9Sxc151355 { 15038d4cf8d8S dladm_status_t status = DLADM_STATUS_OK; 150430890389Sartem datalink_media_t dmedia; 150530890389Sartem uint32_t media; 15060dc2366fSVenugopal Iyer dladm_linkprop_args_t *dla; 150730890389Sartem 150830890389Sartem dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI; 150930890389Sartem 15100dc2366fSVenugopal Iyer dla = malloc(sizeof (dladm_linkprop_args_t)); 15110dc2366fSVenugopal Iyer if (dla == NULL) 15120dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 15130dc2366fSVenugopal Iyer dla->dla_flags = DLADM_OPT_BOOT; 15140dc2366fSVenugopal Iyer dla->dla_status = DLADM_STATUS_OK; 15150dc2366fSVenugopal Iyer 1516d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 15174ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 15184ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST); 15194ac67f02SAnurag S. Maskey } else if (any_media || 15204ac67f02SAnurag S. Maskey ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 15214ac67f02SAnurag S. Maskey 0) == DLADM_STATUS_OK) && 152230890389Sartem DATALINK_MEDIA_ACCEPTED(dmedia, media))) { 15230dc2366fSVenugopal Iyer (void) dladm_walk_linkprop(handle, linkid, (void *)dla, 15244ac67f02SAnurag S. Maskey i_dladm_init_one_prop); 15250dc2366fSVenugopal Iyer status = dla->dla_status; 1526d62bc4baSyz147064 } 15270dc2366fSVenugopal Iyer free(dla); 15288d4cf8d8S return (status); 15290ba2cbe9Sxc151355 } 1530f4b3ec61Sdh155122 1531e7801d59Ssowmini /* ARGSUSED */ 1532f4b3ec61Sdh155122 static dladm_status_t 15330dc2366fSVenugopal Iyer get_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1534da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1535da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1536f4b3ec61Sdh155122 { 1537d62bc4baSyz147064 char zone_name[ZONENAME_MAX]; 1538d62bc4baSyz147064 zoneid_t zid; 1539d62bc4baSyz147064 dladm_status_t status; 1540f4b3ec61Sdh155122 15414045d941Ssowmini if (flags != 0) 15424045d941Ssowmini return (DLADM_STATUS_NOTSUP); 15434045d941Ssowmini 15440dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 15450dc2366fSVenugopal Iyer perm_flags, &zid, sizeof (zid)); 1546d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1547d62bc4baSyz147064 return (status); 1548d62bc4baSyz147064 1549d62bc4baSyz147064 *val_cnt = 1; 1550d62bc4baSyz147064 if (zid != GLOBAL_ZONEID) { 1551afdda45fSVasumathi Sundaram - Sun Microsystems if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) { 1552f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1553afdda45fSVasumathi Sundaram - Sun Microsystems } 1554f4b3ec61Sdh155122 1555d62bc4baSyz147064 (void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX); 155647a01978Sbw } else { 1557d62bc4baSyz147064 *prop_val[0] = '\0'; 155847a01978Sbw } 1559f4b3ec61Sdh155122 1560f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1561f4b3ec61Sdh155122 } 1562f4b3ec61Sdh155122 1563f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t); 1564f4b3ec61Sdh155122 1565f4b3ec61Sdh155122 static int 1566f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen) 1567f4b3ec61Sdh155122 { 1568f4b3ec61Sdh155122 char root[MAXPATHLEN]; 1569f4b3ec61Sdh155122 zone_get_devroot_t real_zone_get_devroot; 1570f4b3ec61Sdh155122 void *dlhandle; 1571f4b3ec61Sdh155122 void *sym; 1572f4b3ec61Sdh155122 int ret; 1573f4b3ec61Sdh155122 1574f4b3ec61Sdh155122 if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL) 1575f4b3ec61Sdh155122 return (-1); 1576f4b3ec61Sdh155122 1577f4b3ec61Sdh155122 if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) { 1578f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1579f4b3ec61Sdh155122 return (-1); 1580f4b3ec61Sdh155122 } 1581f4b3ec61Sdh155122 1582f4b3ec61Sdh155122 real_zone_get_devroot = (zone_get_devroot_t)sym; 1583f4b3ec61Sdh155122 1584f4b3ec61Sdh155122 if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0) 1585f4b3ec61Sdh155122 (void) snprintf(dev, devlen, "%s%s", root, "/dev"); 1586f4b3ec61Sdh155122 (void) dlclose(dlhandle); 1587f4b3ec61Sdh155122 return (ret); 1588f4b3ec61Sdh155122 } 1589f4b3ec61Sdh155122 1590f4b3ec61Sdh155122 static dladm_status_t 15914ac67f02SAnurag S. Maskey i_dladm_update_deventry(dladm_handle_t handle, zoneid_t zid, 15924ac67f02SAnurag S. Maskey datalink_id_t linkid, boolean_t add) 1593f4b3ec61Sdh155122 { 1594f4b3ec61Sdh155122 char path[MAXPATHLEN]; 1595d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1596f4b3ec61Sdh155122 di_prof_t prof = NULL; 1597f4b3ec61Sdh155122 char zone_name[ZONENAME_MAX]; 1598f4b3ec61Sdh155122 dladm_status_t status; 1599d62bc4baSyz147064 int ret; 1600f4b3ec61Sdh155122 1601f4b3ec61Sdh155122 if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) 1602f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1603f4b3ec61Sdh155122 if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0) 1604f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1605f4b3ec61Sdh155122 if (di_prof_init(path, &prof) != 0) 1606f4b3ec61Sdh155122 return (dladm_errno2status(errno)); 1607f4b3ec61Sdh155122 16084ac67f02SAnurag S. Maskey status = dladm_linkid2legacyname(handle, linkid, name, MAXLINKNAMELEN); 1609f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1610d62bc4baSyz147064 goto cleanup; 1611f4b3ec61Sdh155122 1612d62bc4baSyz147064 if (add) 1613d62bc4baSyz147064 ret = di_prof_add_dev(prof, name); 1614d62bc4baSyz147064 else 1615d62bc4baSyz147064 ret = di_prof_add_exclude(prof, name); 1616f4b3ec61Sdh155122 1617d62bc4baSyz147064 if (ret != 0) { 1618d62bc4baSyz147064 status = dladm_errno2status(errno); 1619d62bc4baSyz147064 goto cleanup; 1620f4b3ec61Sdh155122 } 1621f4b3ec61Sdh155122 1622d62bc4baSyz147064 if (di_prof_commit(prof) != 0) 1623d62bc4baSyz147064 status = dladm_errno2status(errno); 1624d62bc4baSyz147064 cleanup: 1625d62bc4baSyz147064 if (prof) 1626d62bc4baSyz147064 di_prof_fini(prof); 1627d62bc4baSyz147064 1628d62bc4baSyz147064 return (status); 1629f4b3ec61Sdh155122 } 1630f4b3ec61Sdh155122 1631e7801d59Ssowmini /* ARGSUSED */ 1632f4b3ec61Sdh155122 static dladm_status_t 16330dc2366fSVenugopal Iyer set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 16344ac67f02SAnurag S. Maskey val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 1635f4b3ec61Sdh155122 { 16363bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 1637f4b3ec61Sdh155122 zoneid_t zid_old, zid_new; 16383bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1639f4b3ec61Sdh155122 1640f4b3ec61Sdh155122 if (val_cnt != 1) 1641f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1642f4b3ec61Sdh155122 16433bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = (dld_ioc_zid_t *)vdp->vd_val; 16443bc21d0aSAruna Ramakrishna - Sun Microsystems 16450dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 16460dc2366fSVenugopal Iyer NULL, &zid_old, sizeof (zid_old)); 1647f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 1648f4b3ec61Sdh155122 return (status); 1649f4b3ec61Sdh155122 16503bc21d0aSAruna Ramakrishna - Sun Microsystems zid_new = dzp->diz_zid; 16513bc21d0aSAruna Ramakrishna - Sun Microsystems if (zid_new == zid_old) 16522b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 16532b24ab6bSSebastien Roy 16540dc2366fSVenugopal Iyer if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, 16552b24ab6bSSebastien Roy flags, media)) != DLADM_STATUS_OK) 16563bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 16573bc21d0aSAruna Ramakrishna - Sun Microsystems 1658d62bc4baSyz147064 /* 16592b24ab6bSSebastien Roy * It is okay to fail to update the /dev entry (some vanity-named 16602b24ab6bSSebastien Roy * links do not have a /dev entry). 1661d62bc4baSyz147064 */ 1662d62bc4baSyz147064 if (zid_old != GLOBAL_ZONEID) { 16634ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_old, linkid, 16644ac67f02SAnurag S. Maskey B_FALSE); 1665d62bc4baSyz147064 } 16662b24ab6bSSebastien Roy if (zid_new != GLOBAL_ZONEID) 16674ac67f02SAnurag S. Maskey (void) i_dladm_update_deventry(handle, zid_new, linkid, B_TRUE); 1668f4b3ec61Sdh155122 1669f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 1670f4b3ec61Sdh155122 } 1671f4b3ec61Sdh155122 1672f4b3ec61Sdh155122 /* ARGSUSED */ 1673f4b3ec61Sdh155122 static dladm_status_t 16740dc2366fSVenugopal Iyer check_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1675c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 16760dc2366fSVenugopal Iyer datalink_media_t media) 1677f4b3ec61Sdh155122 { 16783bc21d0aSAruna Ramakrishna - Sun Microsystems char *zone_name; 16793bc21d0aSAruna Ramakrishna - Sun Microsystems zoneid_t zoneid; 16803bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status = DLADM_STATUS_OK; 16813bc21d0aSAruna Ramakrishna - Sun Microsystems dld_ioc_zid_t *dzp; 1682c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1683c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1684f4b3ec61Sdh155122 1685f4b3ec61Sdh155122 if (val_cnt != 1) 1686f4b3ec61Sdh155122 return (DLADM_STATUS_BADVALCNT); 1687f4b3ec61Sdh155122 16883bc21d0aSAruna Ramakrishna - Sun Microsystems dzp = malloc(sizeof (dld_ioc_zid_t)); 16893bc21d0aSAruna Ramakrishna - Sun Microsystems if (dzp == NULL) 16903bc21d0aSAruna Ramakrishna - Sun Microsystems return (DLADM_STATUS_NOMEM); 1691f4b3ec61Sdh155122 1692da14cebeSEric Cheng zone_name = (prop_val != NULL) ? *prop_val : GLOBAL_ZONENAME; 16933bc21d0aSAruna Ramakrishna - Sun Microsystems if ((zoneid = getzoneidbyname(zone_name)) == -1) { 16943bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 16953bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 16963bc21d0aSAruna Ramakrishna - Sun Microsystems } 16973bc21d0aSAruna Ramakrishna - Sun Microsystems 16983bc21d0aSAruna Ramakrishna - Sun Microsystems if (zoneid != GLOBAL_ZONEID) { 1699f4b3ec61Sdh155122 ushort_t flags; 1700f4b3ec61Sdh155122 17013bc21d0aSAruna Ramakrishna - Sun Microsystems if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 1702f4b3ec61Sdh155122 sizeof (flags)) < 0) { 17033bc21d0aSAruna Ramakrishna - Sun Microsystems status = dladm_errno2status(errno); 17043bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1705f4b3ec61Sdh155122 } 1706f4b3ec61Sdh155122 1707f4b3ec61Sdh155122 if (!(flags & ZF_NET_EXCL)) { 17083bc21d0aSAruna Ramakrishna - Sun Microsystems status = DLADM_STATUS_BADVAL; 17093bc21d0aSAruna Ramakrishna - Sun Microsystems goto done; 1710f4b3ec61Sdh155122 } 1711f4b3ec61Sdh155122 } 1712f4b3ec61Sdh155122 17133bc21d0aSAruna Ramakrishna - Sun Microsystems (void) memset(dzp, 0, sizeof (dld_ioc_zid_t)); 17143bc21d0aSAruna Ramakrishna - Sun Microsystems 17153bc21d0aSAruna Ramakrishna - Sun Microsystems dzp->diz_zid = zoneid; 17162b24ab6bSSebastien Roy dzp->diz_linkid = linkid; 17173bc21d0aSAruna Ramakrishna - Sun Microsystems 17183bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = (uintptr_t)dzp; 1719f4b3ec61Sdh155122 return (DLADM_STATUS_OK); 17203bc21d0aSAruna Ramakrishna - Sun Microsystems done: 17213bc21d0aSAruna Ramakrishna - Sun Microsystems free(dzp); 17223bc21d0aSAruna Ramakrishna - Sun Microsystems return (status); 1723f4b3ec61Sdh155122 } 1724f4b3ec61Sdh155122 1725e7801d59Ssowmini /* ARGSUSED */ 1726f4b3ec61Sdh155122 static dladm_status_t 17270dc2366fSVenugopal Iyer get_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1728da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1729da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1730da14cebeSEric Cheng { 1731da14cebeSEric Cheng mac_resource_props_t mrp; 1732da14cebeSEric Cheng dladm_status_t status; 1733da14cebeSEric Cheng 17340dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 17350dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 17360dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1737da14cebeSEric Cheng return (status); 1738da14cebeSEric Cheng 1739da14cebeSEric Cheng if ((mrp.mrp_mask & MRP_MAXBW) == 0) { 17400dc2366fSVenugopal Iyer *val_cnt = 0; 17410dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 1742da14cebeSEric Cheng } 17430dc2366fSVenugopal Iyer 17440dc2366fSVenugopal Iyer (void) dladm_bw2str(mrp.mrp_maxbw, prop_val[0]); 1745da14cebeSEric Cheng *val_cnt = 1; 1746da14cebeSEric Cheng return (DLADM_STATUS_OK); 1747da14cebeSEric Cheng } 1748da14cebeSEric Cheng 1749da14cebeSEric Cheng /* ARGSUSED */ 1750da14cebeSEric Cheng static dladm_status_t 17510dc2366fSVenugopal Iyer check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1752c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 17530dc2366fSVenugopal Iyer datalink_media_t media) 1754da14cebeSEric Cheng { 1755da14cebeSEric Cheng uint64_t *maxbw; 1756da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 1757c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1758c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1759da14cebeSEric Cheng 1760da14cebeSEric Cheng if (val_cnt != 1) 1761da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 1762da14cebeSEric Cheng 1763da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 1764da14cebeSEric Cheng if (maxbw == NULL) 1765da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 1766da14cebeSEric Cheng 1767da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 1768da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 1769da14cebeSEric Cheng free(maxbw); 1770da14cebeSEric Cheng return (status); 1771da14cebeSEric Cheng } 1772da14cebeSEric Cheng 1773da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 1774da14cebeSEric Cheng free(maxbw); 1775da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 1776da14cebeSEric Cheng } 1777da14cebeSEric Cheng 1778da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 1779da14cebeSEric Cheng return (DLADM_STATUS_OK); 1780da14cebeSEric Cheng } 1781da14cebeSEric Cheng 1782da14cebeSEric Cheng /* ARGSUSED */ 1783da14cebeSEric Cheng dladm_status_t 17840dc2366fSVenugopal Iyer extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) 1785da14cebeSEric Cheng { 178625ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 1787da14cebeSEric Cheng 17880dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 17890dc2366fSVenugopal Iyer mrp->mrp_maxbw = MRP_MAXBW_RESETVAL; 17900dc2366fSVenugopal Iyer } else { 1791da14cebeSEric Cheng bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); 17920dc2366fSVenugopal Iyer } 1793da14cebeSEric Cheng mrp->mrp_mask |= MRP_MAXBW; 1794da14cebeSEric Cheng 1795da14cebeSEric Cheng return (DLADM_STATUS_OK); 1796da14cebeSEric Cheng } 1797da14cebeSEric Cheng 1798da14cebeSEric Cheng /* ARGSUSED */ 1799da14cebeSEric Cheng static dladm_status_t 18000dc2366fSVenugopal Iyer get_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1801da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 1802da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 1803da14cebeSEric Cheng { 18040dc2366fSVenugopal Iyer dladm_status_t status; 1805da14cebeSEric Cheng mac_resource_props_t mrp; 1806c569ef53SMichael Lim mac_propval_range_t *pv_range; 1807c569ef53SMichael Lim int err; 1808da14cebeSEric Cheng 18090dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "cpus-effective") == 0) { 18100dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 18110dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 18120dc2366fSVenugopal Iyer sizeof (mrp)); 18130dc2366fSVenugopal Iyer } else { 18140dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 18150dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 18160dc2366fSVenugopal Iyer } 18170dc2366fSVenugopal Iyer 18180dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 1819da14cebeSEric Cheng return (status); 1820da14cebeSEric Cheng 1821c569ef53SMichael Lim if (mrp.mrp_ncpus > *val_cnt) 1822da14cebeSEric Cheng return (DLADM_STATUS_TOOSMALL); 1823da14cebeSEric Cheng 1824c569ef53SMichael Lim if (mrp.mrp_ncpus == 0) { 18250dc2366fSVenugopal Iyer *val_cnt = 0; 1826da14cebeSEric Cheng return (DLADM_STATUS_OK); 1827da14cebeSEric Cheng } 1828da14cebeSEric Cheng 1829c569ef53SMichael Lim /* Sort CPU list and convert it to a mac_propval_range */ 1830c569ef53SMichael Lim status = dladm_list2range(mrp.mrp_cpu, mrp.mrp_ncpus, 1831c569ef53SMichael Lim MAC_PROPVAL_UINT32, &pv_range); 1832c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1833c569ef53SMichael Lim return (status); 1834c569ef53SMichael Lim 1835c569ef53SMichael Lim /* Write CPU ranges and individual CPUs */ 1836c569ef53SMichael Lim err = dladm_range2strs(pv_range, prop_val); 1837c569ef53SMichael Lim if (err != 0) { 1838c569ef53SMichael Lim free(pv_range); 1839c569ef53SMichael Lim return (dladm_errno2status(err)); 1840da14cebeSEric Cheng } 1841c569ef53SMichael Lim 1842c569ef53SMichael Lim *val_cnt = pv_range->mpr_count; 1843c569ef53SMichael Lim free(pv_range); 1844c569ef53SMichael Lim 1845da14cebeSEric Cheng return (DLADM_STATUS_OK); 1846da14cebeSEric Cheng } 1847da14cebeSEric Cheng 1848da14cebeSEric Cheng /* ARGSUSED */ 1849da14cebeSEric Cheng static dladm_status_t 18500dc2366fSVenugopal Iyer check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 1851c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 18520dc2366fSVenugopal Iyer datalink_media_t media) 1853da14cebeSEric Cheng { 1854da14cebeSEric Cheng int i, j, rc; 1855da14cebeSEric Cheng long nproc = sysconf(_SC_NPROCESSORS_CONF); 18560dc2366fSVenugopal Iyer mac_resource_props_t mrp; 1857c569ef53SMichael Lim mac_propval_range_t *pv_range; 18580dc2366fSVenugopal Iyer uint_t perm_flags; 1859c569ef53SMichael Lim uint32_t ncpus; 1860c569ef53SMichael Lim uint32_t *cpus = mrp.mrp_cpu; 1861c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 1862c569ef53SMichael Lim val_desc_t *newvdp; 1863c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 1864c569ef53SMichael Lim dladm_status_t status = DLADM_STATUS_OK; 1865da14cebeSEric Cheng 18660dc2366fSVenugopal Iyer /* Get the current pool property */ 18670dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 18680dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 18690dc2366fSVenugopal Iyer 18700dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 18710dc2366fSVenugopal Iyer /* Can't set cpus if a pool is set */ 18720dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) != 0) 18730dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 18740dc2366fSVenugopal Iyer } 18750dc2366fSVenugopal Iyer 1876c569ef53SMichael Lim /* Read ranges and convert to mac_propval_range */ 1877c569ef53SMichael Lim status = dladm_strs2range(prop_val, val_cnt, MAC_PROPVAL_UINT32, 1878c569ef53SMichael Lim &pv_range); 1879c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1880c569ef53SMichael Lim goto done1; 1881da14cebeSEric Cheng 1882c569ef53SMichael Lim /* Convert mac_propval_range to a single CPU list */ 1883c569ef53SMichael Lim ncpus = MRP_NCPUS; 1884c569ef53SMichael Lim status = dladm_range2list(pv_range, cpus, &ncpus); 1885c569ef53SMichael Lim if (status != DLADM_STATUS_OK) 1886c569ef53SMichael Lim goto done1; 18870dc2366fSVenugopal Iyer 1888c569ef53SMichael Lim /* 1889c569ef53SMichael Lim * If a range of CPUs was entered, update value count and reallocate 1890c569ef53SMichael Lim * the array of val_desc_t's. The array allocated was sized for 1891c569ef53SMichael Lim * indvidual elements, but needs to be reallocated to accomodate the 1892c569ef53SMichael Lim * expanded list of CPUs. 1893c569ef53SMichael Lim */ 1894c569ef53SMichael Lim if (val_cnt < ncpus) { 1895c569ef53SMichael Lim newvdp = calloc(*val_cntp, sizeof (val_desc_t)); 1896c569ef53SMichael Lim if (newvdp == NULL) { 1897c569ef53SMichael Lim status = DLADM_STATUS_NOMEM; 1898c569ef53SMichael Lim goto done1; 1899c569ef53SMichael Lim } 1900c569ef53SMichael Lim vdp = newvdp; 1901da14cebeSEric Cheng } 1902da14cebeSEric Cheng 1903c569ef53SMichael Lim /* Check if all CPUs in the list are online */ 1904c569ef53SMichael Lim for (i = 0; i < ncpus; i++) { 1905c569ef53SMichael Lim if (cpus[i] >= nproc) { 1906c569ef53SMichael Lim status = DLADM_STATUS_BADCPUID; 1907c569ef53SMichael Lim goto done2; 1908c569ef53SMichael Lim } 1909c569ef53SMichael Lim 1910c569ef53SMichael Lim rc = p_online(cpus[i], P_STATUS); 1911c569ef53SMichael Lim if (rc < 1) { 1912c569ef53SMichael Lim status = DLADM_STATUS_CPUERR; 1913c569ef53SMichael Lim goto done2; 1914c569ef53SMichael Lim } 1915c569ef53SMichael Lim 1916c569ef53SMichael Lim if (rc != P_ONLINE) { 1917c569ef53SMichael Lim status = DLADM_STATUS_CPUNOTONLINE; 1918c569ef53SMichael Lim goto done2; 1919c569ef53SMichael Lim } 1920c569ef53SMichael Lim 1921c569ef53SMichael Lim vdp[i].vd_val = (uintptr_t)cpus[i]; 1922c569ef53SMichael Lim } 1923c569ef53SMichael Lim 1924c569ef53SMichael Lim /* Check for duplicate CPUs */ 1925c569ef53SMichael Lim for (i = 0; i < *val_cntp; i++) { 1926c569ef53SMichael Lim for (j = 0; j < *val_cntp; j++) { 1927c569ef53SMichael Lim if (i != j && vdp[i].vd_val == vdp[j].vd_val) { 1928c569ef53SMichael Lim status = DLADM_STATUS_BADVAL; 1929c569ef53SMichael Lim goto done2; 1930da14cebeSEric Cheng } 1931da14cebeSEric Cheng } 1932c569ef53SMichael Lim } 1933c569ef53SMichael Lim 1934c569ef53SMichael Lim /* Update *val_cntp and *vdpp if everything was OK */ 1935c569ef53SMichael Lim if (val_cnt < ncpus) { 1936c569ef53SMichael Lim *val_cntp = ncpus; 1937c569ef53SMichael Lim free(*vdpp); 1938c569ef53SMichael Lim *vdpp = newvdp; 1939c569ef53SMichael Lim } 1940c569ef53SMichael Lim 1941c569ef53SMichael Lim status = DLADM_STATUS_OK; 1942c569ef53SMichael Lim goto done1; 1943c569ef53SMichael Lim 1944c569ef53SMichael Lim done2: 1945c569ef53SMichael Lim free(newvdp); 1946c569ef53SMichael Lim done1: 1947c569ef53SMichael Lim free(pv_range); 1948c569ef53SMichael Lim return (status); 1949da14cebeSEric Cheng } 19500dc2366fSVenugopal Iyer 19510dc2366fSVenugopal Iyer /* ARGSUSED */ 19520dc2366fSVenugopal Iyer dladm_status_t 19530dc2366fSVenugopal Iyer extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) 19540dc2366fSVenugopal Iyer { 19550dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 19560dc2366fSVenugopal Iyer int i; 19570dc2366fSVenugopal Iyer 19580dc2366fSVenugopal Iyer if (vdp[0].vd_val == RESET_VAL) { 19590dc2366fSVenugopal Iyer bzero(&mrp->mrp_cpus, sizeof (mac_cpus_t)); 19600dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_CPUS; 19610dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 19620dc2366fSVenugopal Iyer } 19630dc2366fSVenugopal Iyer 19640dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) 19650dc2366fSVenugopal Iyer mrp->mrp_cpu[i] = (uint32_t)vdp[i].vd_val; 19660dc2366fSVenugopal Iyer 19670dc2366fSVenugopal Iyer mrp->mrp_ncpus = cnt; 19680dc2366fSVenugopal Iyer mrp->mrp_mask |= (MRP_CPUS|MRP_CPUS_USERSPEC); 19690dc2366fSVenugopal Iyer mrp->mrp_fanout_mode = MCM_CPUS; 19700dc2366fSVenugopal Iyer mrp->mrp_rx_intr_cpu = -1; 19710dc2366fSVenugopal Iyer 19720dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 19730dc2366fSVenugopal Iyer } 19740dc2366fSVenugopal Iyer 19750dc2366fSVenugopal Iyer /* 19760dc2366fSVenugopal Iyer * Get the pool datalink property from the kernel. This is used 19770dc2366fSVenugopal Iyer * for both the user specified pool and effective pool properties. 19780dc2366fSVenugopal Iyer */ 19790dc2366fSVenugopal Iyer /* ARGSUSED */ 19800dc2366fSVenugopal Iyer static dladm_status_t 19810dc2366fSVenugopal Iyer get_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 19820dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 19830dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 19840dc2366fSVenugopal Iyer { 19850dc2366fSVenugopal Iyer mac_resource_props_t mrp; 19860dc2366fSVenugopal Iyer dladm_status_t status; 19870dc2366fSVenugopal Iyer 19880dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "pool-effective") == 0) { 19890dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 19900dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 19910dc2366fSVenugopal Iyer sizeof (mrp)); 19920dc2366fSVenugopal Iyer } else { 19930dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 19940dc2366fSVenugopal Iyer "resource", flags, perm_flags, &mrp, sizeof (mrp)); 19950dc2366fSVenugopal Iyer } 19960dc2366fSVenugopal Iyer 19970dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 19980dc2366fSVenugopal Iyer return (status); 19990dc2366fSVenugopal Iyer 20000dc2366fSVenugopal Iyer if (strlen(mrp.mrp_pool) == 0) { 20010dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 20020dc2366fSVenugopal Iyer } else { 20030dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 20040dc2366fSVenugopal Iyer "%s", mrp.mrp_pool); 20050dc2366fSVenugopal Iyer } 20060dc2366fSVenugopal Iyer *val_cnt = 1; 20070dc2366fSVenugopal Iyer 20080dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 20090dc2366fSVenugopal Iyer } 20100dc2366fSVenugopal Iyer 20110dc2366fSVenugopal Iyer /* ARGSUSED */ 20120dc2366fSVenugopal Iyer static dladm_status_t 20130dc2366fSVenugopal Iyer check_pool(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 2014c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 20150dc2366fSVenugopal Iyer datalink_media_t media) 20160dc2366fSVenugopal Iyer { 20170dc2366fSVenugopal Iyer pool_conf_t *poolconf; 20180dc2366fSVenugopal Iyer pool_t *pool; 20190dc2366fSVenugopal Iyer mac_resource_props_t mrp; 20200dc2366fSVenugopal Iyer dladm_status_t status; 20210dc2366fSVenugopal Iyer uint_t perm_flags; 20220dc2366fSVenugopal Iyer char *poolname; 2023c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 20240dc2366fSVenugopal Iyer 20250dc2366fSVenugopal Iyer /* Get the current cpus property */ 20260dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 0, 20270dc2366fSVenugopal Iyer &perm_flags, &mrp, sizeof (mrp)); 20280dc2366fSVenugopal Iyer 20290dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) { 20300dc2366fSVenugopal Iyer /* Can't set pool if cpus are set */ 20310dc2366fSVenugopal Iyer if (mrp.mrp_ncpus != 0) 20320dc2366fSVenugopal Iyer return (DLADM_STATUS_POOLCPU); 20330dc2366fSVenugopal Iyer } 20340dc2366fSVenugopal Iyer 20350dc2366fSVenugopal Iyer poolname = malloc(sizeof (mrp.mrp_pool)); 20360dc2366fSVenugopal Iyer if (poolname == NULL) 20370dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 20380dc2366fSVenugopal Iyer 20390dc2366fSVenugopal Iyer /* Check for pool's availability if not booting */ 20400dc2366fSVenugopal Iyer if ((flags & DLADM_OPT_BOOT) == 0) { 20410dc2366fSVenugopal Iyer 20420dc2366fSVenugopal Iyer /* Allocate and open pool configuration */ 20430dc2366fSVenugopal Iyer if ((poolconf = pool_conf_alloc()) == NULL) 20440dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20450dc2366fSVenugopal Iyer 20460dc2366fSVenugopal Iyer if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) 20470dc2366fSVenugopal Iyer != PO_SUCCESS) { 20480dc2366fSVenugopal Iyer pool_conf_free(poolconf); 20490dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20500dc2366fSVenugopal Iyer } 20510dc2366fSVenugopal Iyer 20520dc2366fSVenugopal Iyer /* Look for pool name */ 20530dc2366fSVenugopal Iyer if ((pool = pool_get_pool(poolconf, *prop_val)) == NULL) { 20540dc2366fSVenugopal Iyer pool_conf_free(poolconf); 20550dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 20560dc2366fSVenugopal Iyer } 20570dc2366fSVenugopal Iyer 20580dc2366fSVenugopal Iyer pool_conf_free(poolconf); 20590dc2366fSVenugopal Iyer free(pool); 20600dc2366fSVenugopal Iyer } 20610dc2366fSVenugopal Iyer 20620dc2366fSVenugopal Iyer (void) strlcpy(poolname, *prop_val, sizeof (mrp.mrp_pool)); 20630dc2366fSVenugopal Iyer vdp->vd_val = (uintptr_t)poolname; 2064da14cebeSEric Cheng 2065da14cebeSEric Cheng return (DLADM_STATUS_OK); 2066da14cebeSEric Cheng } 2067da14cebeSEric Cheng 2068da14cebeSEric Cheng /* ARGSUSED */ 2069da14cebeSEric Cheng dladm_status_t 20700dc2366fSVenugopal Iyer extract_pool(val_desc_t *vdp, uint_t cnt, void *arg) 2071da14cebeSEric Cheng { 20720dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 2073da14cebeSEric Cheng 20740dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) { 20750dc2366fSVenugopal Iyer bzero(&mrp->mrp_pool, sizeof (mrp->mrp_pool)); 20760dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 20770dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 2078da14cebeSEric Cheng } 20790dc2366fSVenugopal Iyer 20800dc2366fSVenugopal Iyer (void) strlcpy(mrp->mrp_pool, (char *)vdp->vd_val, 20810dc2366fSVenugopal Iyer sizeof (mrp->mrp_pool)); 20820dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_POOL; 20830dc2366fSVenugopal Iyer /* 20840dc2366fSVenugopal Iyer * Use MCM_CPUS since the fanout count is not user specified 20850dc2366fSVenugopal Iyer * and will be determined by the cpu list generated from the 20860dc2366fSVenugopal Iyer * pool. 20870dc2366fSVenugopal Iyer */ 2088da14cebeSEric Cheng mrp->mrp_fanout_mode = MCM_CPUS; 2089da14cebeSEric Cheng 2090da14cebeSEric Cheng return (DLADM_STATUS_OK); 2091da14cebeSEric Cheng } 2092da14cebeSEric Cheng 2093da14cebeSEric Cheng /* ARGSUSED */ 2094da14cebeSEric Cheng static dladm_status_t 20950dc2366fSVenugopal Iyer get_priority(dladm_handle_t handle, prop_desc_t *pdp, 209662ee1d25SArtem Kachitchkine datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 209762ee1d25SArtem Kachitchkine datalink_media_t media, uint_t flags, uint_t *perm_flags) 2098da14cebeSEric Cheng { 2099da14cebeSEric Cheng mac_resource_props_t mrp; 2100da14cebeSEric Cheng mac_priority_level_t pri; 2101da14cebeSEric Cheng dladm_status_t status; 2102da14cebeSEric Cheng 21030dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 21040dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 21050dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 2106da14cebeSEric Cheng return (status); 2107da14cebeSEric Cheng 2108da14cebeSEric Cheng pri = ((mrp.mrp_mask & MRP_PRIORITY) == 0) ? MPL_HIGH : 2109da14cebeSEric Cheng mrp.mrp_priority; 2110da14cebeSEric Cheng 2111da14cebeSEric Cheng (void) dladm_pri2str(pri, prop_val[0]); 2112da14cebeSEric Cheng *val_cnt = 1; 2113da14cebeSEric Cheng return (DLADM_STATUS_OK); 2114da14cebeSEric Cheng } 2115da14cebeSEric Cheng 2116da14cebeSEric Cheng /* ARGSUSED */ 2117da14cebeSEric Cheng dladm_status_t 21180dc2366fSVenugopal Iyer extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) 2119da14cebeSEric Cheng { 212025ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 2121da14cebeSEric Cheng 21220dc2366fSVenugopal Iyer if (cnt != 1) 21230dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 21240dc2366fSVenugopal Iyer 21250dc2366fSVenugopal Iyer mrp->mrp_priority = (mac_priority_level_t)vdp->vd_val; 2126da14cebeSEric Cheng mrp->mrp_mask |= MRP_PRIORITY; 2127da14cebeSEric Cheng 2128da14cebeSEric Cheng return (DLADM_STATUS_OK); 2129da14cebeSEric Cheng } 2130da14cebeSEric Cheng 21310dc2366fSVenugopal Iyer /* 21320dc2366fSVenugopal Iyer * Determines the size of the structure that needs to be sent to drivers 21330dc2366fSVenugopal Iyer * for retrieving the property range values. 21340dc2366fSVenugopal Iyer */ 21350dc2366fSVenugopal Iyer static int 21360591ddd0SPrakash Jalan i_dladm_range_size(mac_propval_range_t *r, size_t *sz, uint_t *rcount) 21370dc2366fSVenugopal Iyer { 21380dc2366fSVenugopal Iyer uint_t count = r->mpr_count; 21390dc2366fSVenugopal Iyer 21400dc2366fSVenugopal Iyer *sz = sizeof (mac_propval_range_t); 21410591ddd0SPrakash Jalan *rcount = count; 21420dc2366fSVenugopal Iyer --count; 21430dc2366fSVenugopal Iyer 21440dc2366fSVenugopal Iyer switch (r->mpr_type) { 21450dc2366fSVenugopal Iyer case MAC_PROPVAL_UINT32: 21460dc2366fSVenugopal Iyer *sz += (count * sizeof (mac_propval_uint32_range_t)); 21470dc2366fSVenugopal Iyer return (0); 21480dc2366fSVenugopal Iyer default: 21490dc2366fSVenugopal Iyer break; 21500dc2366fSVenugopal Iyer } 21510dc2366fSVenugopal Iyer *sz = 0; 21520591ddd0SPrakash Jalan *rcount = 0; 21530dc2366fSVenugopal Iyer return (EINVAL); 21540dc2366fSVenugopal Iyer } 21550dc2366fSVenugopal Iyer 21560dc2366fSVenugopal Iyer 2157da14cebeSEric Cheng /* ARGSUSED */ 2158da14cebeSEric Cheng static dladm_status_t 21590dc2366fSVenugopal Iyer check_rings(dladm_handle_t handle, prop_desc_t *pdp, 2160c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 2161c569ef53SMichael Lim val_desc_t **vp, datalink_media_t media) 21620dc2366fSVenugopal Iyer { 2163c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2164c569ef53SMichael Lim val_desc_t *v = *vp; 2165c569ef53SMichael Lim 21660dc2366fSVenugopal Iyer if (val_cnt != 1) 21670dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 21680dc2366fSVenugopal Iyer if (strncasecmp(prop_val[0], "hw", strlen("hw")) == 0) { 21690dc2366fSVenugopal Iyer v->vd_val = UNSPEC_VAL; 21700dc2366fSVenugopal Iyer } else if (strncasecmp(prop_val[0], "sw", strlen("sw")) == 0) { 21710dc2366fSVenugopal Iyer v->vd_val = 0; 21720dc2366fSVenugopal Iyer } else { 21730dc2366fSVenugopal Iyer v->vd_val = strtoul(prop_val[0], NULL, 0); 21740dc2366fSVenugopal Iyer if (v->vd_val == 0) 21750dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVAL); 21760dc2366fSVenugopal Iyer } 21770dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 21780dc2366fSVenugopal Iyer } 21790dc2366fSVenugopal Iyer 21800dc2366fSVenugopal Iyer /* ARGSUSED */ 21810dc2366fSVenugopal Iyer static dladm_status_t 21820dc2366fSVenugopal Iyer get_rings_range(dladm_handle_t handle, prop_desc_t *pdp, 21830dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 21840dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 21850dc2366fSVenugopal Iyer { 21860dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 21870dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 21880dc2366fSVenugopal Iyer mac_propval_range_t *rangep; 21890dc2366fSVenugopal Iyer size_t sz; 21900dc2366fSVenugopal Iyer mac_propval_uint32_range_t *ur; 21910dc2366fSVenugopal Iyer 21920dc2366fSVenugopal Iyer sz = sizeof (mac_propval_range_t); 21930dc2366fSVenugopal Iyer 21940dc2366fSVenugopal Iyer if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 21950dc2366fSVenugopal Iyer &status)) == NULL) 21960dc2366fSVenugopal Iyer return (status); 21970dc2366fSVenugopal Iyer 21980dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 21990dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 22000dc2366fSVenugopal Iyer return (status); 22010dc2366fSVenugopal Iyer 22020dc2366fSVenugopal Iyer rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 22030dc2366fSVenugopal Iyer *val_cnt = 1; 22040dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 22050dc2366fSVenugopal Iyer /* This is the case where the dev doesn't have any rings/groups */ 22060dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 22070dc2366fSVenugopal Iyer (*prop_val)[0] = '\0'; 22080dc2366fSVenugopal Iyer /* 22090dc2366fSVenugopal Iyer * This is the case where the dev supports rings, but static 22100dc2366fSVenugopal Iyer * grouping. 22110dc2366fSVenugopal Iyer */ 22120dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max && 22130dc2366fSVenugopal Iyer ur->mpur_max == 0) { 22140dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw"); 22150dc2366fSVenugopal Iyer /* 22160dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 22170dc2366fSVenugopal Iyer * grouping, but has only one value (say 2 rings and 2 groups). 22180dc2366fSVenugopal Iyer */ 22190dc2366fSVenugopal Iyer } else if (ur->mpur_min == ur->mpur_max) { 22200dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "sw,hw,%d", 22210dc2366fSVenugopal Iyer ur->mpur_min); 22220dc2366fSVenugopal Iyer /* 22230dc2366fSVenugopal Iyer * This is the case where the dev supports rings and dynamic 22240dc2366fSVenugopal Iyer * grouping and has a range of rings. 22250dc2366fSVenugopal Iyer */ 22260dc2366fSVenugopal Iyer } else { 22270dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, 22280dc2366fSVenugopal Iyer "sw,hw,<%ld-%ld>", ur->mpur_min, ur->mpur_max); 22290dc2366fSVenugopal Iyer } 22300dc2366fSVenugopal Iyer free(dip); 22310dc2366fSVenugopal Iyer return (status); 22320dc2366fSVenugopal Iyer } 22330dc2366fSVenugopal Iyer 22340dc2366fSVenugopal Iyer 22350dc2366fSVenugopal Iyer /* ARGSUSED */ 22360dc2366fSVenugopal Iyer static dladm_status_t 22370dc2366fSVenugopal Iyer get_rxrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 22380dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 22390dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 22400dc2366fSVenugopal Iyer { 22410dc2366fSVenugopal Iyer mac_resource_props_t mrp; 22420dc2366fSVenugopal Iyer dladm_status_t status; 22430dc2366fSVenugopal Iyer uint32_t nrings = 0; 22440dc2366fSVenugopal Iyer 22450dc2366fSVenugopal Iyer /* 22460dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 22470dc2366fSVenugopal Iyer */ 22480dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "rxrings-effective") == 0) { 22490dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 22500dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 22510dc2366fSVenugopal Iyer sizeof (mrp)); 22520dc2366fSVenugopal Iyer } else { 22530dc2366fSVenugopal Iyer /* 22540dc2366fSVenugopal Iyer * Get the permissions from the "rxrings" property. 22550dc2366fSVenugopal Iyer */ 22560dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "rxrings", 22570dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 22580dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 22590dc2366fSVenugopal Iyer return (status); 22600dc2366fSVenugopal Iyer 22610dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 22620dc2366fSVenugopal Iyer "resource", flags, NULL, &mrp, sizeof (mrp)); 22630dc2366fSVenugopal Iyer } 22640dc2366fSVenugopal Iyer 22650dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 22660dc2366fSVenugopal Iyer return (status); 22670dc2366fSVenugopal Iyer 22680dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_RX_RINGS) == 0) { 22690dc2366fSVenugopal Iyer *val_cnt = 0; 22700dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22710dc2366fSVenugopal Iyer } 22720dc2366fSVenugopal Iyer nrings = mrp.mrp_nrxrings; 22730dc2366fSVenugopal Iyer *val_cnt = 1; 22740dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_RXRINGS_UNSPEC) 22750dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 22760dc2366fSVenugopal Iyer else if (nrings == 0) 22770dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 22780dc2366fSVenugopal Iyer else 22790dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 22800dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22810dc2366fSVenugopal Iyer } 22820dc2366fSVenugopal Iyer 22830dc2366fSVenugopal Iyer /* ARGSUSED */ 22840dc2366fSVenugopal Iyer dladm_status_t 22850dc2366fSVenugopal Iyer extract_rxrings(val_desc_t *vdp, uint_t cnt, void *arg) 22860dc2366fSVenugopal Iyer { 22870dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 22880dc2366fSVenugopal Iyer 22890dc2366fSVenugopal Iyer mrp->mrp_nrxrings = 0; 22900dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 22910dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 22920dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 22930dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RXRINGS_UNSPEC; 22940dc2366fSVenugopal Iyer else 22950dc2366fSVenugopal Iyer mrp->mrp_nrxrings = vdp->vd_val; 22960dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_RX_RINGS; 22970dc2366fSVenugopal Iyer 22980dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 22990dc2366fSVenugopal Iyer } 23000dc2366fSVenugopal Iyer 23010dc2366fSVenugopal Iyer /* ARGSUSED */ 23020dc2366fSVenugopal Iyer static dladm_status_t 23030dc2366fSVenugopal Iyer get_txrings(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 23040dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, 23050dc2366fSVenugopal Iyer uint_t flags, uint_t *perm_flags) 23060dc2366fSVenugopal Iyer { 23070dc2366fSVenugopal Iyer mac_resource_props_t mrp; 23080dc2366fSVenugopal Iyer dladm_status_t status; 23090dc2366fSVenugopal Iyer uint32_t nrings = 0; 23100dc2366fSVenugopal Iyer 23110dc2366fSVenugopal Iyer 23120dc2366fSVenugopal Iyer /* 23130dc2366fSVenugopal Iyer * Get the number of (effective-)rings from the resource property. 23140dc2366fSVenugopal Iyer */ 23150dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, "txrings-effective") == 0) { 23160dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, 23170dc2366fSVenugopal Iyer "resource-effective", flags, perm_flags, &mrp, 23180dc2366fSVenugopal Iyer sizeof (mrp)); 23190dc2366fSVenugopal Iyer } else { 23200dc2366fSVenugopal Iyer /* 23210dc2366fSVenugopal Iyer * Get the permissions from the "txrings" property. 23220dc2366fSVenugopal Iyer */ 23230dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "txrings", 23240dc2366fSVenugopal Iyer flags, perm_flags, NULL, 0); 23250dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 23260dc2366fSVenugopal Iyer return (status); 23270dc2366fSVenugopal Iyer 23280dc2366fSVenugopal Iyer /* 23290dc2366fSVenugopal Iyer * Get the number of rings from the "resource" property. 23300dc2366fSVenugopal Iyer */ 23310dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", 23320dc2366fSVenugopal Iyer flags, NULL, &mrp, sizeof (mrp)); 23330dc2366fSVenugopal Iyer } 23340dc2366fSVenugopal Iyer 23350dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 23360dc2366fSVenugopal Iyer return (status); 23370dc2366fSVenugopal Iyer 23380dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_TX_RINGS) == 0) { 23390dc2366fSVenugopal Iyer *val_cnt = 0; 23400dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23410dc2366fSVenugopal Iyer } 23420dc2366fSVenugopal Iyer nrings = mrp.mrp_ntxrings; 23430dc2366fSVenugopal Iyer *val_cnt = 1; 23440dc2366fSVenugopal Iyer if (mrp.mrp_mask & MRP_TXRINGS_UNSPEC) 23450dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "hw"); 23460dc2366fSVenugopal Iyer else if (nrings == 0) 23470dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "sw"); 23480dc2366fSVenugopal Iyer else 23490dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", nrings); 23500dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23510dc2366fSVenugopal Iyer } 23520dc2366fSVenugopal Iyer 23530dc2366fSVenugopal Iyer /* ARGSUSED */ 23540dc2366fSVenugopal Iyer dladm_status_t 23550dc2366fSVenugopal Iyer extract_txrings(val_desc_t *vdp, uint_t cnt, void *arg) 23560dc2366fSVenugopal Iyer { 23570dc2366fSVenugopal Iyer mac_resource_props_t *mrp = (mac_resource_props_t *)arg; 23580dc2366fSVenugopal Iyer 23590dc2366fSVenugopal Iyer mrp->mrp_ntxrings = 0; 23600dc2366fSVenugopal Iyer if (vdp->vd_val == RESET_VAL) 23610dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_RINGS_RESET; 23620dc2366fSVenugopal Iyer else if (vdp->vd_val == UNSPEC_VAL) 23630dc2366fSVenugopal Iyer mrp->mrp_mask = MRP_TXRINGS_UNSPEC; 23640dc2366fSVenugopal Iyer else 23650dc2366fSVenugopal Iyer mrp->mrp_ntxrings = vdp->vd_val; 23660dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_TX_RINGS; 23670dc2366fSVenugopal Iyer 23680dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 23690dc2366fSVenugopal Iyer } 23700dc2366fSVenugopal Iyer 23710dc2366fSVenugopal Iyer /* ARGSUSED */ 23720dc2366fSVenugopal Iyer static dladm_status_t 23730dc2366fSVenugopal Iyer get_cntavail(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 23740dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 23750dc2366fSVenugopal Iyer uint_t *perm_flags) 23760dc2366fSVenugopal Iyer { 23770dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 23780dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTDEFINED); 23790dc2366fSVenugopal Iyer 23800dc2366fSVenugopal Iyer return (get_uint32(handle, pdp, linkid, prop_val, val_cnt, media, 23810dc2366fSVenugopal Iyer flags, perm_flags)); 23820dc2366fSVenugopal Iyer } 23830dc2366fSVenugopal Iyer 23840dc2366fSVenugopal Iyer /* ARGSUSED */ 23850dc2366fSVenugopal Iyer static dladm_status_t 23860dc2366fSVenugopal Iyer set_resource(dladm_handle_t handle, prop_desc_t *pdp, 238725ec3e3dSEric Cheng datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, 238825ec3e3dSEric Cheng uint_t flags, datalink_media_t media) 238925ec3e3dSEric Cheng { 239025ec3e3dSEric Cheng mac_resource_props_t mrp; 239125ec3e3dSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 239225ec3e3dSEric Cheng dld_ioc_macprop_t *dip; 23930dc2366fSVenugopal Iyer int i; 239425ec3e3dSEric Cheng 239525ec3e3dSEric Cheng bzero(&mrp, sizeof (mac_resource_props_t)); 23960dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, "resource", 239725ec3e3dSEric Cheng flags, &status); 239825ec3e3dSEric Cheng 239925ec3e3dSEric Cheng if (dip == NULL) 240025ec3e3dSEric Cheng return (status); 240125ec3e3dSEric Cheng 24020dc2366fSVenugopal Iyer for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 24030dc2366fSVenugopal Iyer resource_prop_t *rp = &rsrc_prop_table[i]; 24040dc2366fSVenugopal Iyer 24050dc2366fSVenugopal Iyer if (strcmp(pdp->pd_name, rp->rp_name) != 0) 24060dc2366fSVenugopal Iyer continue; 24070dc2366fSVenugopal Iyer 24080dc2366fSVenugopal Iyer status = rp->rp_extract(vdp, val_cnt, &mrp); 240925ec3e3dSEric Cheng if (status != DLADM_STATUS_OK) 241025ec3e3dSEric Cheng goto done; 241125ec3e3dSEric Cheng 24120dc2366fSVenugopal Iyer break; 241325ec3e3dSEric Cheng } 241425ec3e3dSEric Cheng 241525ec3e3dSEric Cheng (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); 241625ec3e3dSEric Cheng status = i_dladm_macprop(handle, dip, B_TRUE); 241725ec3e3dSEric Cheng 241825ec3e3dSEric Cheng done: 241925ec3e3dSEric Cheng free(dip); 242025ec3e3dSEric Cheng return (status); 242125ec3e3dSEric Cheng } 242225ec3e3dSEric Cheng 242325ec3e3dSEric Cheng /* ARGSUSED */ 242425ec3e3dSEric Cheng static dladm_status_t 24250dc2366fSVenugopal Iyer get_protection(dladm_handle_t handle, prop_desc_t *pdp, 242625ec3e3dSEric Cheng datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 242725ec3e3dSEric Cheng datalink_media_t media, uint_t flags, uint_t *perm_flags) 242825ec3e3dSEric Cheng { 242925ec3e3dSEric Cheng mac_resource_props_t mrp; 243025ec3e3dSEric Cheng mac_protect_t *p; 243125ec3e3dSEric Cheng dladm_status_t status; 24320dc2366fSVenugopal Iyer uint32_t i, cnt = 0, setbits[32]; 243325ec3e3dSEric Cheng 24340dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 24350dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 24360dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 243725ec3e3dSEric Cheng return (status); 243825ec3e3dSEric Cheng 243925ec3e3dSEric Cheng p = &mrp.mrp_protect; 24400dc2366fSVenugopal Iyer if ((mrp.mrp_mask & MRP_PROTECT) == 0) { 24410dc2366fSVenugopal Iyer *val_cnt = 0; 24420dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 24430dc2366fSVenugopal Iyer } 244425ec3e3dSEric Cheng dladm_find_setbits32(p->mp_types, setbits, &cnt); 244525ec3e3dSEric Cheng if (cnt > *val_cnt) 244625ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 244725ec3e3dSEric Cheng 244825ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 244925ec3e3dSEric Cheng (void) dladm_protect2str(setbits[i], prop_val[i]); 245025ec3e3dSEric Cheng 245125ec3e3dSEric Cheng *val_cnt = cnt; 245225ec3e3dSEric Cheng return (DLADM_STATUS_OK); 245325ec3e3dSEric Cheng } 245425ec3e3dSEric Cheng 24550dc2366fSVenugopal Iyer /* ARGSUSED */ 24560dc2366fSVenugopal Iyer static dladm_status_t 24570dc2366fSVenugopal Iyer get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 24580dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 24590dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 24600dc2366fSVenugopal Iyer { 24610dc2366fSVenugopal Iyer mac_resource_props_t mrp; 24620dc2366fSVenugopal Iyer mac_protect_t *p; 24630dc2366fSVenugopal Iyer dladm_status_t status; 24640dc2366fSVenugopal Iyer int i; 24650dc2366fSVenugopal Iyer 24660dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 24670dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 24680dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 24690dc2366fSVenugopal Iyer return (status); 24700dc2366fSVenugopal Iyer 24710dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 24720dc2366fSVenugopal Iyer if (p->mp_ipaddrcnt == 0) { 24730dc2366fSVenugopal Iyer *val_cnt = 0; 24740dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 24750dc2366fSVenugopal Iyer } 247625ec3e3dSEric Cheng if (p->mp_ipaddrcnt > *val_cnt) 247725ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 247825ec3e3dSEric Cheng 247925ec3e3dSEric Cheng for (i = 0; i < p->mp_ipaddrcnt; i++) { 2480e03914f9SRobert Mustacchi int len; 24810dc2366fSVenugopal Iyer if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { 24820dc2366fSVenugopal Iyer ipaddr_t v4addr; 24830dc2366fSVenugopal Iyer 24840dc2366fSVenugopal Iyer v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); 24850dc2366fSVenugopal Iyer (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); 24860dc2366fSVenugopal Iyer } else { 24870dc2366fSVenugopal Iyer (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, 248825ec3e3dSEric Cheng prop_val[i]); 248925ec3e3dSEric Cheng } 2490e03914f9SRobert Mustacchi len = strlen(prop_val[i]); 2491e03914f9SRobert Mustacchi (void) sprintf(prop_val[i] + len, "/%d", 2492e03914f9SRobert Mustacchi p->mp_ipaddrs[i].ip_netmask); 24930dc2366fSVenugopal Iyer } 249425ec3e3dSEric Cheng *val_cnt = p->mp_ipaddrcnt; 249525ec3e3dSEric Cheng return (DLADM_STATUS_OK); 249625ec3e3dSEric Cheng } 249725ec3e3dSEric Cheng 249825ec3e3dSEric Cheng dladm_status_t 24990dc2366fSVenugopal Iyer extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) 250025ec3e3dSEric Cheng { 250125ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 250225ec3e3dSEric Cheng uint32_t types = 0; 250325ec3e3dSEric Cheng int i; 250425ec3e3dSEric Cheng 250525ec3e3dSEric Cheng for (i = 0; i < cnt; i++) 250625ec3e3dSEric Cheng types |= (uint32_t)vdp[i].vd_val; 250725ec3e3dSEric Cheng 250825ec3e3dSEric Cheng mrp->mrp_protect.mp_types = types; 250925ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 251025ec3e3dSEric Cheng return (DLADM_STATUS_OK); 251125ec3e3dSEric Cheng } 251225ec3e3dSEric Cheng 251325ec3e3dSEric Cheng dladm_status_t 25140dc2366fSVenugopal Iyer extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) 251525ec3e3dSEric Cheng { 251625ec3e3dSEric Cheng mac_resource_props_t *mrp = arg; 251725ec3e3dSEric Cheng mac_protect_t *p = &mrp->mrp_protect; 251825ec3e3dSEric Cheng int i; 251925ec3e3dSEric Cheng 252025ec3e3dSEric Cheng if (vdp->vd_val == 0) { 252125ec3e3dSEric Cheng cnt = (uint_t)-1; 252225ec3e3dSEric Cheng } else { 25230dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 25240dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_ipaddrs[i], 25250dc2366fSVenugopal Iyer sizeof (mac_ipaddr_t)); 25260dc2366fSVenugopal Iyer } 252725ec3e3dSEric Cheng } 252825ec3e3dSEric Cheng p->mp_ipaddrcnt = cnt; 252925ec3e3dSEric Cheng mrp->mrp_mask |= MRP_PROTECT; 253025ec3e3dSEric Cheng return (DLADM_STATUS_OK); 253125ec3e3dSEric Cheng } 253225ec3e3dSEric Cheng 25330dc2366fSVenugopal Iyer static dladm_status_t 25340dc2366fSVenugopal Iyer check_single_ip(char *buf, mac_ipaddr_t *addr) 25350dc2366fSVenugopal Iyer { 25360dc2366fSVenugopal Iyer dladm_status_t status; 25370dc2366fSVenugopal Iyer ipaddr_t v4addr; 25380dc2366fSVenugopal Iyer in6_addr_t v6addr; 25390dc2366fSVenugopal Iyer boolean_t isv4 = B_TRUE; 2540e03914f9SRobert Mustacchi char *p; 2541e03914f9SRobert Mustacchi uint32_t mask = 0; 2542e03914f9SRobert Mustacchi 2543e03914f9SRobert Mustacchi /* 2544e03914f9SRobert Mustacchi * If the IP address is in CIDR format, parse the bits component 2545e03914f9SRobert Mustacchi * seperately. An address in this style will be used to indicate an 2546e03914f9SRobert Mustacchi * entire subnet, so it must be a network number with no host address. 2547e03914f9SRobert Mustacchi */ 2548e03914f9SRobert Mustacchi if ((p = strchr(buf, '/')) != NULL) { 2549e03914f9SRobert Mustacchi char *end = NULL; 2550e03914f9SRobert Mustacchi 2551e03914f9SRobert Mustacchi *p++ = '\0'; 2552e03914f9SRobert Mustacchi if (!isdigit(*p)) 2553e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2554e03914f9SRobert Mustacchi mask = strtol(p, &end, 10); 2555e03914f9SRobert Mustacchi if (end != NULL && *end != '\0') 2556e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2557e03914f9SRobert Mustacchi if (mask > 128|| mask < 1) 2558e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2559e03914f9SRobert Mustacchi } 25600dc2366fSVenugopal Iyer 25610dc2366fSVenugopal Iyer status = dladm_str2ipv4addr(buf, &v4addr); 25620dc2366fSVenugopal Iyer if (status == DLADM_STATUS_INVALID_IP) { 25630dc2366fSVenugopal Iyer status = dladm_str2ipv6addr(buf, &v6addr); 25640dc2366fSVenugopal Iyer if (status == DLADM_STATUS_OK) 25650dc2366fSVenugopal Iyer isv4 = B_FALSE; 25660dc2366fSVenugopal Iyer } 25670dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 25680dc2366fSVenugopal Iyer return (status); 25690dc2366fSVenugopal Iyer 25700dc2366fSVenugopal Iyer if (isv4) { 25710dc2366fSVenugopal Iyer if (v4addr == INADDR_ANY) 25720dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 25730dc2366fSVenugopal Iyer 25740dc2366fSVenugopal Iyer IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); 25750dc2366fSVenugopal Iyer addr->ip_version = IPV4_VERSION; 2576e03914f9SRobert Mustacchi if (p != NULL) { 2577e03914f9SRobert Mustacchi uint32_t smask; 2578e03914f9SRobert Mustacchi 2579e03914f9SRobert Mustacchi /* 2580e03914f9SRobert Mustacchi * Validate the netmask is in the proper range for v4 2581e03914f9SRobert Mustacchi */ 2582e03914f9SRobert Mustacchi if (mask > 32 || mask < 1) 2583e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2584e03914f9SRobert Mustacchi 2585e03914f9SRobert Mustacchi /* 2586e03914f9SRobert Mustacchi * We have a CIDR style address, confirm that only the 2587e03914f9SRobert Mustacchi * network number is set. 2588e03914f9SRobert Mustacchi */ 2589e03914f9SRobert Mustacchi smask = 0xFFFFFFFFu << (32 - mask); 2590e03914f9SRobert Mustacchi if (htonl(v4addr) & ~smask) 2591e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2592e03914f9SRobert Mustacchi } else { 2593e03914f9SRobert Mustacchi mask = 32; 2594e03914f9SRobert Mustacchi } 2595e03914f9SRobert Mustacchi addr->ip_netmask = mask; 25960dc2366fSVenugopal Iyer } else { 25970dc2366fSVenugopal Iyer if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) 25980dc2366fSVenugopal Iyer return (DLADM_STATUS_INVALID_IP); 25990dc2366fSVenugopal Iyer 2600e03914f9SRobert Mustacchi if (IN6_IS_ADDR_V4MAPPED_ANY(&v6addr)) 2601e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2602e03914f9SRobert Mustacchi 2603e03914f9SRobert Mustacchi if (p != NULL) { 2604e03914f9SRobert Mustacchi int i, off, high; 2605e03914f9SRobert Mustacchi 2606e03914f9SRobert Mustacchi /* 2607e03914f9SRobert Mustacchi * Note that the address in our buffer is stored in 2608e03914f9SRobert Mustacchi * network byte order. 2609e03914f9SRobert Mustacchi */ 2610e03914f9SRobert Mustacchi off = 0; 2611e03914f9SRobert Mustacchi for (i = 3; i >= 0; i--) { 2612e03914f9SRobert Mustacchi high = ffsl(ntohl(v6addr._S6_un._S6_u32[i])); 2613e03914f9SRobert Mustacchi if (high != 0) 2614e03914f9SRobert Mustacchi break; 2615e03914f9SRobert Mustacchi off += 32; 2616e03914f9SRobert Mustacchi } 2617e03914f9SRobert Mustacchi off += high; 2618e03914f9SRobert Mustacchi if (128 - off >= mask) 2619e03914f9SRobert Mustacchi return (DLADM_STATUS_INVALID_IP); 2620e03914f9SRobert Mustacchi } else { 2621e03914f9SRobert Mustacchi mask = 128; 2622e03914f9SRobert Mustacchi } 2623e03914f9SRobert Mustacchi 26240dc2366fSVenugopal Iyer addr->ip_addr = v6addr; 26250dc2366fSVenugopal Iyer addr->ip_version = IPV6_VERSION; 2626e03914f9SRobert Mustacchi addr->ip_netmask = mask; 26270dc2366fSVenugopal Iyer } 26280dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 26290dc2366fSVenugopal Iyer } 26300dc2366fSVenugopal Iyer 263125ec3e3dSEric Cheng /* ARGSUSED */ 263225ec3e3dSEric Cheng static dladm_status_t 26330dc2366fSVenugopal Iyer check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, 2634c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 2635c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 263625ec3e3dSEric Cheng { 263725ec3e3dSEric Cheng dladm_status_t status; 26380dc2366fSVenugopal Iyer mac_ipaddr_t *addr; 263925ec3e3dSEric Cheng int i; 2640c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2641c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 264225ec3e3dSEric Cheng 264325ec3e3dSEric Cheng if (val_cnt > MPT_MAXIPADDR) 264425ec3e3dSEric Cheng return (DLADM_STATUS_BADVALCNT); 264525ec3e3dSEric Cheng 264625ec3e3dSEric Cheng for (i = 0; i < val_cnt; i++) { 26470dc2366fSVenugopal Iyer if ((addr = calloc(1, sizeof (mac_ipaddr_t))) == NULL) { 26480dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 26490dc2366fSVenugopal Iyer goto fail; 265025ec3e3dSEric Cheng } 26510dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)addr; 26520dc2366fSVenugopal Iyer 26530dc2366fSVenugopal Iyer status = check_single_ip(prop_val[i], addr); 26540dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 26550dc2366fSVenugopal Iyer goto fail; 26560dc2366fSVenugopal Iyer } 26570dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 26580dc2366fSVenugopal Iyer 26590dc2366fSVenugopal Iyer fail: 26600dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 26610dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 26620dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 26630dc2366fSVenugopal Iyer } 26640dc2366fSVenugopal Iyer return (status); 26650dc2366fSVenugopal Iyer } 26660dc2366fSVenugopal Iyer 26670dc2366fSVenugopal Iyer static void 26680dc2366fSVenugopal Iyer dladm_cid2str(mac_dhcpcid_t *cid, char *buf) 26690dc2366fSVenugopal Iyer { 26700dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 26710dc2366fSVenugopal Iyer uint_t hexlen; 26720dc2366fSVenugopal Iyer 26730dc2366fSVenugopal Iyer switch (cid->dc_form) { 26740dc2366fSVenugopal Iyer case CIDFORM_TYPED: { 26750dc2366fSVenugopal Iyer uint16_t duidtype, hwtype; 26760dc2366fSVenugopal Iyer uint32_t timestamp, ennum; 26770dc2366fSVenugopal Iyer char *lladdr; 26780dc2366fSVenugopal Iyer 26790dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (duidtype)) 26800dc2366fSVenugopal Iyer goto fail; 26810dc2366fSVenugopal Iyer 26820dc2366fSVenugopal Iyer bcopy(cid->dc_id, &duidtype, sizeof (duidtype)); 26830dc2366fSVenugopal Iyer duidtype = ntohs(duidtype); 26840dc2366fSVenugopal Iyer switch (duidtype) { 26850dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 26860dc2366fSVenugopal Iyer duid_llt_t llt; 26870dc2366fSVenugopal Iyer 26880dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (llt)) 26890dc2366fSVenugopal Iyer goto fail; 26900dc2366fSVenugopal Iyer 26910dc2366fSVenugopal Iyer bcopy(cid->dc_id, &llt, sizeof (llt)); 26920dc2366fSVenugopal Iyer hwtype = ntohs(llt.dllt_hwtype); 26930dc2366fSVenugopal Iyer timestamp = ntohl(llt.dllt_time); 26940dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (llt), 26950dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (llt), IFT_OTHER); 26960dc2366fSVenugopal Iyer if (lladdr == NULL) 26970dc2366fSVenugopal Iyer goto fail; 26980dc2366fSVenugopal Iyer 26990dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%d.%s", 27000dc2366fSVenugopal Iyer duidtype, hwtype, timestamp, lladdr); 27010dc2366fSVenugopal Iyer free(lladdr); 27020dc2366fSVenugopal Iyer break; 27030dc2366fSVenugopal Iyer } 27040dc2366fSVenugopal Iyer case DHCPV6_DUID_EN: { 27050dc2366fSVenugopal Iyer duid_en_t en; 27060dc2366fSVenugopal Iyer 27070dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (en)) 27080dc2366fSVenugopal Iyer goto fail; 27090dc2366fSVenugopal Iyer 27100dc2366fSVenugopal Iyer bcopy(cid->dc_id, &en, sizeof (en)); 27110dc2366fSVenugopal Iyer ennum = DHCPV6_GET_ENTNUM(&en); 27120dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 27130dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (en), 27140dc2366fSVenugopal Iyer cid->dc_len - sizeof (en), tmp_buf, &hexlen) != 0) 27150dc2366fSVenugopal Iyer goto fail; 27160dc2366fSVenugopal Iyer 27170dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 27180dc2366fSVenugopal Iyer duidtype, ennum, tmp_buf); 27190dc2366fSVenugopal Iyer break; 27200dc2366fSVenugopal Iyer } 27210dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 27220dc2366fSVenugopal Iyer duid_ll_t ll; 27230dc2366fSVenugopal Iyer 27240dc2366fSVenugopal Iyer if (cid->dc_len < sizeof (ll)) 27250dc2366fSVenugopal Iyer goto fail; 27260dc2366fSVenugopal Iyer 27270dc2366fSVenugopal Iyer bcopy(cid->dc_id, &ll, sizeof (ll)); 27280dc2366fSVenugopal Iyer hwtype = ntohs(ll.dll_hwtype); 27290dc2366fSVenugopal Iyer lladdr = _link_ntoa(cid->dc_id + sizeof (ll), 27300dc2366fSVenugopal Iyer NULL, cid->dc_len - sizeof (ll), IFT_OTHER); 27310dc2366fSVenugopal Iyer if (lladdr == NULL) 27320dc2366fSVenugopal Iyer goto fail; 27330dc2366fSVenugopal Iyer 27340dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%d.%s", 27350dc2366fSVenugopal Iyer duidtype, hwtype, lladdr); 27360dc2366fSVenugopal Iyer free(lladdr); 27370dc2366fSVenugopal Iyer break; 27380dc2366fSVenugopal Iyer } 27390dc2366fSVenugopal Iyer default: { 27400dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 27410dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id + sizeof (duidtype), 27420dc2366fSVenugopal Iyer cid->dc_len - sizeof (duidtype), 27430dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 27440dc2366fSVenugopal Iyer goto fail; 27450dc2366fSVenugopal Iyer 27460dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%d.%s", 27470dc2366fSVenugopal Iyer duidtype, tmp_buf); 27480dc2366fSVenugopal Iyer } 27490dc2366fSVenugopal Iyer } 27500dc2366fSVenugopal Iyer break; 27510dc2366fSVenugopal Iyer } 27520dc2366fSVenugopal Iyer case CIDFORM_HEX: { 27530dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 27540dc2366fSVenugopal Iyer if (octet_to_hexascii(cid->dc_id, cid->dc_len, 27550dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 27560dc2366fSVenugopal Iyer goto fail; 27570dc2366fSVenugopal Iyer 27580dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "0x%s", tmp_buf); 27590dc2366fSVenugopal Iyer break; 27600dc2366fSVenugopal Iyer } 27610dc2366fSVenugopal Iyer case CIDFORM_STR: { 27620dc2366fSVenugopal Iyer int i; 27630dc2366fSVenugopal Iyer 27640dc2366fSVenugopal Iyer for (i = 0; i < cid->dc_len; i++) { 27650dc2366fSVenugopal Iyer if (!isprint(cid->dc_id[i])) 27660dc2366fSVenugopal Iyer goto fail; 27670dc2366fSVenugopal Iyer } 27680dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "%s", cid->dc_id); 27690dc2366fSVenugopal Iyer break; 27700dc2366fSVenugopal Iyer } 27710dc2366fSVenugopal Iyer default: 27720dc2366fSVenugopal Iyer goto fail; 27730dc2366fSVenugopal Iyer } 27740dc2366fSVenugopal Iyer return; 27750dc2366fSVenugopal Iyer 27760dc2366fSVenugopal Iyer fail: 27770dc2366fSVenugopal Iyer (void) snprintf(buf, DLADM_STRSIZE, "<unknown>"); 27780dc2366fSVenugopal Iyer } 27790dc2366fSVenugopal Iyer 27800dc2366fSVenugopal Iyer static dladm_status_t 27810dc2366fSVenugopal Iyer dladm_str2cid(char *buf, mac_dhcpcid_t *cid) 27820dc2366fSVenugopal Iyer { 27830dc2366fSVenugopal Iyer char *ptr = buf; 27840dc2366fSVenugopal Iyer char tmp_buf[DLADM_STRSIZE]; 27850dc2366fSVenugopal Iyer uint_t hexlen, cidlen; 27860dc2366fSVenugopal Iyer 27870dc2366fSVenugopal Iyer bzero(cid, sizeof (*cid)); 27880dc2366fSVenugopal Iyer if (isdigit(*ptr) && 27890dc2366fSVenugopal Iyer ptr[strspn(ptr, "0123456789")] == '.') { 27900dc2366fSVenugopal Iyer char *cp; 27910dc2366fSVenugopal Iyer ulong_t duidtype; 27920dc2366fSVenugopal Iyer ulong_t subtype; 27930dc2366fSVenugopal Iyer ulong_t timestamp; 27940dc2366fSVenugopal Iyer uchar_t *lladdr; 27950dc2366fSVenugopal Iyer int addrlen; 27960dc2366fSVenugopal Iyer 27970dc2366fSVenugopal Iyer errno = 0; 27980dc2366fSVenugopal Iyer duidtype = strtoul(ptr, &cp, 0); 27990dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.' || 28000dc2366fSVenugopal Iyer duidtype > USHRT_MAX) 28010dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28020dc2366fSVenugopal Iyer ptr = cp + 1; 28030dc2366fSVenugopal Iyer 28040dc2366fSVenugopal Iyer if (duidtype != 0 && duidtype <= DHCPV6_DUID_LL) { 28050dc2366fSVenugopal Iyer errno = 0; 28060dc2366fSVenugopal Iyer subtype = strtoul(ptr, &cp, 0); 28070dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 28080dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28090dc2366fSVenugopal Iyer ptr = cp + 1; 28100dc2366fSVenugopal Iyer } 28110dc2366fSVenugopal Iyer switch (duidtype) { 28120dc2366fSVenugopal Iyer case DHCPV6_DUID_LLT: { 28130dc2366fSVenugopal Iyer duid_llt_t llt; 28140dc2366fSVenugopal Iyer 28150dc2366fSVenugopal Iyer errno = 0; 28160dc2366fSVenugopal Iyer timestamp = strtoul(ptr, &cp, 0); 28170dc2366fSVenugopal Iyer if (ptr == cp || errno != 0 || *cp != '.') 28180dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28190dc2366fSVenugopal Iyer 28200dc2366fSVenugopal Iyer ptr = cp + 1; 28210dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 28220dc2366fSVenugopal Iyer if (lladdr == NULL) 28230dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28240dc2366fSVenugopal Iyer 28250dc2366fSVenugopal Iyer cidlen = sizeof (llt) + addrlen; 28260dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 28270dc2366fSVenugopal Iyer free(lladdr); 28280dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 28290dc2366fSVenugopal Iyer } 28300dc2366fSVenugopal Iyer llt.dllt_dutype = htons(duidtype); 28310dc2366fSVenugopal Iyer llt.dllt_hwtype = htons(subtype); 28320dc2366fSVenugopal Iyer llt.dllt_time = htonl(timestamp); 28330dc2366fSVenugopal Iyer bcopy(&llt, cid->dc_id, sizeof (llt)); 28340dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (llt), addrlen); 28350dc2366fSVenugopal Iyer free(lladdr); 28360dc2366fSVenugopal Iyer break; 28370dc2366fSVenugopal Iyer } 28380dc2366fSVenugopal Iyer case DHCPV6_DUID_LL: { 28390dc2366fSVenugopal Iyer duid_ll_t ll; 28400dc2366fSVenugopal Iyer 28410dc2366fSVenugopal Iyer lladdr = _link_aton(ptr, &addrlen); 28420dc2366fSVenugopal Iyer if (lladdr == NULL) 28430dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28440dc2366fSVenugopal Iyer 28450dc2366fSVenugopal Iyer cidlen = sizeof (ll) + addrlen; 28460dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) { 28470dc2366fSVenugopal Iyer free(lladdr); 28480dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 28490dc2366fSVenugopal Iyer } 28500dc2366fSVenugopal Iyer ll.dll_dutype = htons(duidtype); 28510dc2366fSVenugopal Iyer ll.dll_hwtype = htons(subtype); 28520dc2366fSVenugopal Iyer bcopy(&ll, cid->dc_id, sizeof (ll)); 28530dc2366fSVenugopal Iyer bcopy(lladdr, cid->dc_id + sizeof (ll), addrlen); 28540dc2366fSVenugopal Iyer free(lladdr); 28550dc2366fSVenugopal Iyer break; 28560dc2366fSVenugopal Iyer } 28570dc2366fSVenugopal Iyer default: { 28580dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 28590dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), 28600dc2366fSVenugopal Iyer tmp_buf, &hexlen) != 0) 28610dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28620dc2366fSVenugopal Iyer 28630dc2366fSVenugopal Iyer if (duidtype == DHCPV6_DUID_EN) { 28640dc2366fSVenugopal Iyer duid_en_t en; 28650dc2366fSVenugopal Iyer 28660dc2366fSVenugopal Iyer en.den_dutype = htons(duidtype); 28670dc2366fSVenugopal Iyer DHCPV6_SET_ENTNUM(&en, subtype); 28680dc2366fSVenugopal Iyer 28690dc2366fSVenugopal Iyer cidlen = sizeof (en) + hexlen; 28700dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 28710dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 28720dc2366fSVenugopal Iyer 28730dc2366fSVenugopal Iyer bcopy(&en, cid->dc_id, sizeof (en)); 28740dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (en), 28750dc2366fSVenugopal Iyer hexlen); 28760dc2366fSVenugopal Iyer } else { 28770dc2366fSVenugopal Iyer uint16_t dutype = htons(duidtype); 28780dc2366fSVenugopal Iyer 28790dc2366fSVenugopal Iyer cidlen = sizeof (dutype) + hexlen; 28800dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 28810dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 28820dc2366fSVenugopal Iyer 28830dc2366fSVenugopal Iyer bcopy(&dutype, cid->dc_id, sizeof (dutype)); 28840dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id + sizeof (dutype), 28850dc2366fSVenugopal Iyer hexlen); 28860dc2366fSVenugopal Iyer } 28870dc2366fSVenugopal Iyer break; 28880dc2366fSVenugopal Iyer } 28890dc2366fSVenugopal Iyer } 28900dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_TYPED; 28910dc2366fSVenugopal Iyer } else if (strncasecmp("0x", ptr, 2) == 0 && ptr[2] != '\0') { 28920dc2366fSVenugopal Iyer ptr += 2; 28930dc2366fSVenugopal Iyer hexlen = sizeof (tmp_buf); 28940dc2366fSVenugopal Iyer if (hexascii_to_octet(ptr, strlen(ptr), tmp_buf, 28950dc2366fSVenugopal Iyer &hexlen) != 0) { 28960dc2366fSVenugopal Iyer return (DLADM_STATUS_BADARG); 28970dc2366fSVenugopal Iyer } 28980dc2366fSVenugopal Iyer cidlen = hexlen; 28990dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 29000dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 29010dc2366fSVenugopal Iyer 29020dc2366fSVenugopal Iyer bcopy(tmp_buf, cid->dc_id, cidlen); 29030dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_HEX; 29040dc2366fSVenugopal Iyer } else { 29050dc2366fSVenugopal Iyer cidlen = strlen(ptr); 29060dc2366fSVenugopal Iyer if (cidlen > sizeof (cid->dc_id)) 29070dc2366fSVenugopal Iyer return (DLADM_STATUS_TOOSMALL); 29080dc2366fSVenugopal Iyer 29090dc2366fSVenugopal Iyer bcopy(ptr, cid->dc_id, cidlen); 29100dc2366fSVenugopal Iyer cid->dc_form = CIDFORM_STR; 29110dc2366fSVenugopal Iyer } 29120dc2366fSVenugopal Iyer cid->dc_len = cidlen; 291325ec3e3dSEric Cheng return (DLADM_STATUS_OK); 291425ec3e3dSEric Cheng } 291525ec3e3dSEric Cheng 291625ec3e3dSEric Cheng /* ARGSUSED */ 291725ec3e3dSEric Cheng static dladm_status_t 29180dc2366fSVenugopal Iyer get_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 29190dc2366fSVenugopal Iyer datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 29200dc2366fSVenugopal Iyer datalink_media_t media, uint_t flags, uint_t *perm_flags) 29210dc2366fSVenugopal Iyer { 29220dc2366fSVenugopal Iyer mac_resource_props_t mrp; 29230dc2366fSVenugopal Iyer mac_protect_t *p; 29240dc2366fSVenugopal Iyer dladm_status_t status; 29250dc2366fSVenugopal Iyer int i; 29260dc2366fSVenugopal Iyer 29270dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, "resource", flags, 29280dc2366fSVenugopal Iyer perm_flags, &mrp, sizeof (mrp)); 29290dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 29300dc2366fSVenugopal Iyer return (status); 29310dc2366fSVenugopal Iyer 29320dc2366fSVenugopal Iyer p = &mrp.mrp_protect; 29330dc2366fSVenugopal Iyer if (p->mp_cidcnt == 0) { 29340dc2366fSVenugopal Iyer *val_cnt = 0; 29350dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 29360dc2366fSVenugopal Iyer } 29370dc2366fSVenugopal Iyer if (p->mp_cidcnt > *val_cnt) 29380dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 29390dc2366fSVenugopal Iyer 29400dc2366fSVenugopal Iyer for (i = 0; i < p->mp_cidcnt; i++) { 29410dc2366fSVenugopal Iyer mac_dhcpcid_t *cid = &p->mp_cids[i]; 29420dc2366fSVenugopal Iyer 29430dc2366fSVenugopal Iyer dladm_cid2str(cid, prop_val[i]); 29440dc2366fSVenugopal Iyer } 29450dc2366fSVenugopal Iyer *val_cnt = p->mp_cidcnt; 29460dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 29470dc2366fSVenugopal Iyer } 29480dc2366fSVenugopal Iyer 29490dc2366fSVenugopal Iyer dladm_status_t 29500dc2366fSVenugopal Iyer extract_allowedcids(val_desc_t *vdp, uint_t cnt, void *arg) 29510dc2366fSVenugopal Iyer { 29520dc2366fSVenugopal Iyer mac_resource_props_t *mrp = arg; 29530dc2366fSVenugopal Iyer mac_protect_t *p = &mrp->mrp_protect; 29540dc2366fSVenugopal Iyer int i; 29550dc2366fSVenugopal Iyer 29560dc2366fSVenugopal Iyer if (vdp->vd_val == 0) { 29570dc2366fSVenugopal Iyer cnt = (uint_t)-1; 29580dc2366fSVenugopal Iyer } else { 29590dc2366fSVenugopal Iyer for (i = 0; i < cnt; i++) { 29600dc2366fSVenugopal Iyer bcopy((void *)vdp[i].vd_val, &p->mp_cids[i], 29610dc2366fSVenugopal Iyer sizeof (mac_dhcpcid_t)); 29620dc2366fSVenugopal Iyer } 29630dc2366fSVenugopal Iyer } 29640dc2366fSVenugopal Iyer p->mp_cidcnt = cnt; 29650dc2366fSVenugopal Iyer mrp->mrp_mask |= MRP_PROTECT; 29660dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 29670dc2366fSVenugopal Iyer } 29680dc2366fSVenugopal Iyer 29690dc2366fSVenugopal Iyer /* ARGSUSED */ 29700dc2366fSVenugopal Iyer static dladm_status_t 29710dc2366fSVenugopal Iyer check_allowedcids(dladm_handle_t handle, prop_desc_t *pdp, 2972c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, 2973c569ef53SMichael Lim uint_t flags, val_desc_t **vdpp, datalink_media_t media) 29740dc2366fSVenugopal Iyer { 29750dc2366fSVenugopal Iyer dladm_status_t status; 29760dc2366fSVenugopal Iyer mac_dhcpcid_t *cid; 29770dc2366fSVenugopal Iyer int i; 2978c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 2979c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 29800dc2366fSVenugopal Iyer 29810dc2366fSVenugopal Iyer if (val_cnt > MPT_MAXCID) 29820dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 29830dc2366fSVenugopal Iyer 29840dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 29850dc2366fSVenugopal Iyer if ((cid = calloc(1, sizeof (mac_dhcpcid_t))) == NULL) { 29860dc2366fSVenugopal Iyer status = DLADM_STATUS_NOMEM; 29870dc2366fSVenugopal Iyer goto fail; 29880dc2366fSVenugopal Iyer } 29890dc2366fSVenugopal Iyer vdp[i].vd_val = (uintptr_t)cid; 29900dc2366fSVenugopal Iyer 29910dc2366fSVenugopal Iyer status = dladm_str2cid(prop_val[i], cid); 29920dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 29930dc2366fSVenugopal Iyer goto fail; 29940dc2366fSVenugopal Iyer } 29950dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 29960dc2366fSVenugopal Iyer 29970dc2366fSVenugopal Iyer fail: 29980dc2366fSVenugopal Iyer for (i = 0; i < val_cnt; i++) { 29990dc2366fSVenugopal Iyer free((void *)vdp[i].vd_val); 30000dc2366fSVenugopal Iyer vdp[i].vd_val = NULL; 30010dc2366fSVenugopal Iyer } 30020dc2366fSVenugopal Iyer return (status); 30030dc2366fSVenugopal Iyer } 30040dc2366fSVenugopal Iyer 30050dc2366fSVenugopal Iyer /* ARGSUSED */ 30060dc2366fSVenugopal Iyer static dladm_status_t 30071a41ca23SJerry Jelinek get_secondary_macs(dladm_handle_t handle, prop_desc_t *pdp, 30081a41ca23SJerry Jelinek datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 30091a41ca23SJerry Jelinek datalink_media_t media, uint_t flags, uint_t *perm_flags) 30101a41ca23SJerry Jelinek { 30111a41ca23SJerry Jelinek mac_secondary_addr_t sa; 30121a41ca23SJerry Jelinek dladm_status_t status; 30131a41ca23SJerry Jelinek int i; 30141a41ca23SJerry Jelinek 30151a41ca23SJerry Jelinek status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 30161a41ca23SJerry Jelinek perm_flags, &sa, sizeof (sa)); 30171a41ca23SJerry Jelinek if (status != DLADM_STATUS_OK) 30181a41ca23SJerry Jelinek return (status); 30191a41ca23SJerry Jelinek 30201a41ca23SJerry Jelinek if (sa.ms_addrcnt > *val_cnt) 30211a41ca23SJerry Jelinek return (DLADM_STATUS_BADVALCNT); 30221a41ca23SJerry Jelinek 30231a41ca23SJerry Jelinek for (i = 0; i < sa.ms_addrcnt; i++) { 30241a41ca23SJerry Jelinek if (dladm_aggr_macaddr2str( 30251a41ca23SJerry Jelinek (const unsigned char *)&sa.ms_addrs[i], prop_val[i]) == 30261a41ca23SJerry Jelinek NULL) { 30271a41ca23SJerry Jelinek *val_cnt = i; 30281a41ca23SJerry Jelinek return (DLADM_STATUS_NOMEM); 30291a41ca23SJerry Jelinek } 30301a41ca23SJerry Jelinek } 30311a41ca23SJerry Jelinek *val_cnt = sa.ms_addrcnt; 30321a41ca23SJerry Jelinek return (DLADM_STATUS_OK); 30331a41ca23SJerry Jelinek } 30341a41ca23SJerry Jelinek 30351a41ca23SJerry Jelinek /* ARGSUSED */ 30361a41ca23SJerry Jelinek static dladm_status_t 30371a41ca23SJerry Jelinek check_secondary_macs(dladm_handle_t handle, prop_desc_t *pdp, 30381a41ca23SJerry Jelinek datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 30391a41ca23SJerry Jelinek val_desc_t **vdpp, datalink_media_t media) 30401a41ca23SJerry Jelinek { 30411a41ca23SJerry Jelinek dladm_status_t status; 30421a41ca23SJerry Jelinek uchar_t *addr; 30431a41ca23SJerry Jelinek uint_t len = 0; 30441a41ca23SJerry Jelinek int i; 30451a41ca23SJerry Jelinek uint_t val_cnt = *val_cntp; 30461a41ca23SJerry Jelinek val_desc_t *vdp = *vdpp; 30471a41ca23SJerry Jelinek 30481a41ca23SJerry Jelinek if (val_cnt >= MPT_MAXMACADDR) 30491a41ca23SJerry Jelinek return (DLADM_STATUS_BADVALCNT); 30501a41ca23SJerry Jelinek 30511a41ca23SJerry Jelinek for (i = 0; i < val_cnt; i++) { 30521a41ca23SJerry Jelinek addr = _link_aton(prop_val[i], (int *)&len); 30531a41ca23SJerry Jelinek if (addr == NULL) { 30541a41ca23SJerry Jelinek if (len == (uint_t)-1) 30551a41ca23SJerry Jelinek status = DLADM_STATUS_MACADDRINVAL; 30561a41ca23SJerry Jelinek else 30571a41ca23SJerry Jelinek status = DLADM_STATUS_NOMEM; 30581a41ca23SJerry Jelinek goto fail; 30591a41ca23SJerry Jelinek } 30601a41ca23SJerry Jelinek 30611a41ca23SJerry Jelinek vdp[i].vd_val = (uintptr_t)addr; 30621a41ca23SJerry Jelinek } 30631a41ca23SJerry Jelinek return (DLADM_STATUS_OK); 30641a41ca23SJerry Jelinek 30651a41ca23SJerry Jelinek fail: 30661a41ca23SJerry Jelinek for (i = 0; i < val_cnt; i++) { 30671a41ca23SJerry Jelinek free((void *)vdp[i].vd_val); 30681a41ca23SJerry Jelinek vdp[i].vd_val = NULL; 30691a41ca23SJerry Jelinek } 30701a41ca23SJerry Jelinek return (status); 30711a41ca23SJerry Jelinek } 30721a41ca23SJerry Jelinek 30731a41ca23SJerry Jelinek /* ARGSUSED */ 30741a41ca23SJerry Jelinek static dladm_status_t 30751a41ca23SJerry Jelinek set_secondary_macs(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 30761a41ca23SJerry Jelinek val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 30771a41ca23SJerry Jelinek { 30781a41ca23SJerry Jelinek dladm_status_t status; 30791a41ca23SJerry Jelinek dld_ioc_macprop_t *dip; 30801a41ca23SJerry Jelinek int i; 30811a41ca23SJerry Jelinek mac_secondary_addr_t msa; 30821a41ca23SJerry Jelinek 30831a41ca23SJerry Jelinek dip = i_dladm_buf_alloc_by_name(0, linkid, "secondary-macs", 0, 30841a41ca23SJerry Jelinek &status); 30851a41ca23SJerry Jelinek if (dip == NULL) 30861a41ca23SJerry Jelinek return (status); 30871a41ca23SJerry Jelinek 30881a41ca23SJerry Jelinek if (vdp->vd_val == 0) { 30891a41ca23SJerry Jelinek val_cnt = (uint_t)-1; 30901a41ca23SJerry Jelinek } else { 30911a41ca23SJerry Jelinek for (i = 0; i < val_cnt; i++) { 30921a41ca23SJerry Jelinek bcopy((void *)vdp[i].vd_val, msa.ms_addrs[i], 30931a41ca23SJerry Jelinek MAXMACADDRLEN); 30941a41ca23SJerry Jelinek } 30951a41ca23SJerry Jelinek } 30961a41ca23SJerry Jelinek msa.ms_addrcnt = val_cnt; 30971a41ca23SJerry Jelinek bcopy(&msa, dip->pr_val, dip->pr_valsize); 30981a41ca23SJerry Jelinek 30991a41ca23SJerry Jelinek status = i_dladm_macprop(handle, dip, B_TRUE); 31001a41ca23SJerry Jelinek 31011a41ca23SJerry Jelinek free(dip); 31021a41ca23SJerry Jelinek return (status); 31031a41ca23SJerry Jelinek } 31041a41ca23SJerry Jelinek 31051a41ca23SJerry Jelinek /* ARGSUSED */ 31061a41ca23SJerry Jelinek static dladm_status_t 31070dc2366fSVenugopal Iyer get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3108da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3109da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3110d62bc4baSyz147064 { 31113bc21d0aSAruna Ramakrishna - Sun Microsystems struct dlautopush dlap; 31123bc21d0aSAruna Ramakrishna - Sun Microsystems int i, len; 31133bc21d0aSAruna Ramakrishna - Sun Microsystems dladm_status_t status; 3114d62bc4baSyz147064 31150dc2366fSVenugopal Iyer if (flags & DLD_PROP_DEFAULT) 3116149b7eb2SSowmini Varadhan return (DLADM_STATUS_NOTDEFINED); 31174045d941Ssowmini 31180dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 31190dc2366fSVenugopal Iyer perm_flags, &dlap, sizeof (dlap)); 31200dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 31210dc2366fSVenugopal Iyer return (status); 31220dc2366fSVenugopal Iyer 31230dc2366fSVenugopal Iyer if (dlap.dap_npush == 0) { 31240dc2366fSVenugopal Iyer *val_cnt = 0; 3125da14cebeSEric Cheng return (DLADM_STATUS_OK); 3126d62bc4baSyz147064 } 31273bc21d0aSAruna Ramakrishna - Sun Microsystems for (i = 0, len = 0; i < dlap.dap_npush; i++) { 3128d62bc4baSyz147064 if (i != 0) { 3129d62bc4baSyz147064 (void) snprintf(*prop_val + len, 3130d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER); 3131d62bc4baSyz147064 len += 1; 3132d62bc4baSyz147064 } 3133d62bc4baSyz147064 (void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len, 31343bc21d0aSAruna Ramakrishna - Sun Microsystems "%s", dlap.dap_aplist[i]); 31353bc21d0aSAruna Ramakrishna - Sun Microsystems len += strlen(dlap.dap_aplist[i]); 31363bc21d0aSAruna Ramakrishna - Sun Microsystems if (dlap.dap_anchor - 1 == i) { 3137d62bc4baSyz147064 (void) snprintf(*prop_val + len, 3138d62bc4baSyz147064 DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER, 3139d62bc4baSyz147064 AP_ANCHOR); 3140d62bc4baSyz147064 len += (strlen(AP_ANCHOR) + 1); 3141d62bc4baSyz147064 } 3142d62bc4baSyz147064 } 31430dc2366fSVenugopal Iyer *val_cnt = 1; 3144d62bc4baSyz147064 return (DLADM_STATUS_OK); 3145d62bc4baSyz147064 } 3146d62bc4baSyz147064 3147d62bc4baSyz147064 /* 3148d62bc4baSyz147064 * Add the specified module to the dlautopush structure; returns a 3149d62bc4baSyz147064 * DLADM_STATUS_* code. 3150d62bc4baSyz147064 */ 3151d62bc4baSyz147064 dladm_status_t 3152d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap) 3153d62bc4baSyz147064 { 3154d62bc4baSyz147064 if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ)) 3155d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 3156d62bc4baSyz147064 3157d62bc4baSyz147064 if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) { 3158d62bc4baSyz147064 /* 3159d62bc4baSyz147064 * We don't allow multiple anchors, and the anchor must 3160d62bc4baSyz147064 * be after at least one module. 3161d62bc4baSyz147064 */ 3162d62bc4baSyz147064 if (dlap->dap_anchor != 0) 3163d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 3164d62bc4baSyz147064 if (dlap->dap_npush == 0) 3165d62bc4baSyz147064 return (DLADM_STATUS_BADVAL); 3166d62bc4baSyz147064 3167d62bc4baSyz147064 dlap->dap_anchor = dlap->dap_npush; 3168d62bc4baSyz147064 return (DLADM_STATUS_OK); 3169d62bc4baSyz147064 } 3170285e94f9SMichael Lim if (dlap->dap_npush >= MAXAPUSH) 3171d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3172d62bc4baSyz147064 3173d62bc4baSyz147064 (void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module, 3174d62bc4baSyz147064 FMNAMESZ + 1); 3175d62bc4baSyz147064 3176d62bc4baSyz147064 return (DLADM_STATUS_OK); 3177d62bc4baSyz147064 } 3178d62bc4baSyz147064 3179d62bc4baSyz147064 /* 3180d62bc4baSyz147064 * Currently, both '.' and ' '(space) can be used as the delimiters between 3181d62bc4baSyz147064 * autopush modules. The former is used in dladm set-linkprop, and the 3182d62bc4baSyz147064 * latter is used in the autopush(1M) file. 3183d62bc4baSyz147064 */ 3184d62bc4baSyz147064 /* ARGSUSED */ 3185d62bc4baSyz147064 static dladm_status_t 31860dc2366fSVenugopal Iyer check_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3187c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 31880dc2366fSVenugopal Iyer datalink_media_t media) 3189d62bc4baSyz147064 { 3190d62bc4baSyz147064 char *module; 3191d62bc4baSyz147064 struct dlautopush *dlap; 3192d62bc4baSyz147064 dladm_status_t status; 3193d62bc4baSyz147064 char val[DLADM_PROP_VAL_MAX]; 3194d62bc4baSyz147064 char delimiters[4]; 3195c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3196c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 3197d62bc4baSyz147064 3198d62bc4baSyz147064 if (val_cnt != 1) 3199d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3200d62bc4baSyz147064 32013bc21d0aSAruna Ramakrishna - Sun Microsystems if (prop_val != NULL) { 3202d62bc4baSyz147064 dlap = malloc(sizeof (struct dlautopush)); 3203d62bc4baSyz147064 if (dlap == NULL) 3204d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 3205d62bc4baSyz147064 3206d62bc4baSyz147064 (void) memset(dlap, 0, sizeof (struct dlautopush)); 3207d62bc4baSyz147064 (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER); 3208d62bc4baSyz147064 bcopy(*prop_val, val, DLADM_PROP_VAL_MAX); 3209d62bc4baSyz147064 module = strtok(val, delimiters); 3210d62bc4baSyz147064 while (module != NULL) { 3211d62bc4baSyz147064 status = i_dladm_add_ap_module(module, dlap); 3212d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3213d62bc4baSyz147064 return (status); 3214d62bc4baSyz147064 module = strtok(NULL, delimiters); 3215d62bc4baSyz147064 } 3216d62bc4baSyz147064 3217d62bc4baSyz147064 vdp->vd_val = (uintptr_t)dlap; 32183bc21d0aSAruna Ramakrishna - Sun Microsystems } else { 32193bc21d0aSAruna Ramakrishna - Sun Microsystems vdp->vd_val = 0; 32203bc21d0aSAruna Ramakrishna - Sun Microsystems } 3221d62bc4baSyz147064 return (DLADM_STATUS_OK); 3222d62bc4baSyz147064 } 3223d62bc4baSyz147064 3224bcb5c89dSSowmini Varadhan #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) 3225bcb5c89dSSowmini Varadhan 3226e7801d59Ssowmini /* ARGSUSED */ 3227d62bc4baSyz147064 static dladm_status_t 32280dc2366fSVenugopal Iyer get_rate_common(dladm_handle_t handle, prop_desc_t *pdp, 32294ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, uint_t id, 32304ac67f02SAnurag S. Maskey uint_t *perm_flags) 3231d62bc4baSyz147064 { 3232d62bc4baSyz147064 wl_rates_t *wrp; 3233d62bc4baSyz147064 uint_t i; 3234d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 3235d62bc4baSyz147064 3236bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 3237bcb5c89dSSowmini Varadhan if (wrp == NULL) 3238bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 3239d62bc4baSyz147064 32404ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, id, WLDP_BUFSIZE, 32414ac67f02SAnurag S. Maskey B_FALSE); 3242d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3243d62bc4baSyz147064 goto done; 3244d62bc4baSyz147064 3245d62bc4baSyz147064 if (wrp->wl_rates_num > *val_cnt) { 3246d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 3247d62bc4baSyz147064 goto done; 3248d62bc4baSyz147064 } 3249d62bc4baSyz147064 3250d62bc4baSyz147064 if (wrp->wl_rates_rates[0] == 0) { 3251d62bc4baSyz147064 prop_val[0][0] = '\0'; 3252d62bc4baSyz147064 *val_cnt = 1; 3253d62bc4baSyz147064 goto done; 3254d62bc4baSyz147064 } 3255d62bc4baSyz147064 3256d62bc4baSyz147064 for (i = 0; i < wrp->wl_rates_num; i++) { 3257d62bc4baSyz147064 (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", 3258d62bc4baSyz147064 wrp->wl_rates_rates[i] % 2, 3259d62bc4baSyz147064 (float)wrp->wl_rates_rates[i] / 2); 3260d62bc4baSyz147064 } 3261d62bc4baSyz147064 *val_cnt = wrp->wl_rates_num; 3262da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_RW; 3263d62bc4baSyz147064 3264d62bc4baSyz147064 done: 3265bcb5c89dSSowmini Varadhan free(wrp); 3266d62bc4baSyz147064 return (status); 3267d62bc4baSyz147064 } 3268d62bc4baSyz147064 3269d62bc4baSyz147064 static dladm_status_t 32700dc2366fSVenugopal Iyer get_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3271da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3272da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3273d62bc4baSyz147064 { 3274afdda45fSVasumathi Sundaram - Sun Microsystems if (media != DL_WIFI) { 32750dc2366fSVenugopal Iyer return (get_speed(handle, pdp, linkid, prop_val, 32760dc2366fSVenugopal Iyer val_cnt, media, flags, perm_flags)); 3277afdda45fSVasumathi Sundaram - Sun Microsystems } 32786b9e797cSsowmini 32790dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, val_cnt, 3280da14cebeSEric Cheng MAC_PROP_WL_DESIRED_RATES, perm_flags)); 3281d62bc4baSyz147064 } 3282d62bc4baSyz147064 32834045d941Ssowmini /* ARGSUSED */ 3284d62bc4baSyz147064 static dladm_status_t 32850dc2366fSVenugopal Iyer get_rate_mod(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3286da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3287da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3288d62bc4baSyz147064 { 32896b9e797cSsowmini switch (media) { 32906b9e797cSsowmini case DL_ETHER: 32914045d941Ssowmini /* 32924045d941Ssowmini * Speed for ethernet links is unbounded. E.g., 802.11b 32934045d941Ssowmini * links can have a speed of 5.5 Gbps. 32944045d941Ssowmini */ 32954045d941Ssowmini return (DLADM_STATUS_NOTSUP); 32966b9e797cSsowmini 32976b9e797cSsowmini case DL_WIFI: 32980dc2366fSVenugopal Iyer return (get_rate_common(handle, pdp, linkid, prop_val, 32994ac67f02SAnurag S. Maskey val_cnt, MAC_PROP_WL_SUPPORTED_RATES, perm_flags)); 33006b9e797cSsowmini default: 33016b9e797cSsowmini return (DLADM_STATUS_BADARG); 33026b9e797cSsowmini } 3303d62bc4baSyz147064 } 3304d62bc4baSyz147064 3305d62bc4baSyz147064 static dladm_status_t 33060dc2366fSVenugopal Iyer set_wlan_rate(dladm_handle_t handle, datalink_id_t linkid, 33074ac67f02SAnurag S. Maskey dladm_wlan_rates_t *rates) 3308f4b3ec61Sdh155122 { 3309f4b3ec61Sdh155122 int i; 3310d62bc4baSyz147064 uint_t len; 3311d62bc4baSyz147064 wl_rates_t *wrp; 3312d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 3313d62bc4baSyz147064 3314bcb5c89dSSowmini Varadhan wrp = malloc(WLDP_BUFSIZE); 3315bcb5c89dSSowmini Varadhan if (wrp == NULL) 3316d62bc4baSyz147064 return (DLADM_STATUS_NOMEM); 3317d62bc4baSyz147064 3318bcb5c89dSSowmini Varadhan bzero(wrp, WLDP_BUFSIZE); 3319d62bc4baSyz147064 for (i = 0; i < rates->wr_cnt; i++) 3320d62bc4baSyz147064 wrp->wl_rates_rates[i] = rates->wr_rates[i]; 3321d62bc4baSyz147064 wrp->wl_rates_num = rates->wr_cnt; 3322d62bc4baSyz147064 3323d62bc4baSyz147064 len = offsetof(wl_rates_t, wl_rates_rates) + 3324d62bc4baSyz147064 (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; 33254ac67f02SAnurag S. Maskey status = i_dladm_wlan_param(handle, linkid, wrp, 33264ac67f02SAnurag S. Maskey MAC_PROP_WL_DESIRED_RATES, len, B_TRUE); 3327d62bc4baSyz147064 3328bcb5c89dSSowmini Varadhan free(wrp); 3329d62bc4baSyz147064 return (status); 3330d62bc4baSyz147064 } 3331d62bc4baSyz147064 3332e7801d59Ssowmini /* ARGSUSED */ 3333d62bc4baSyz147064 static dladm_status_t 33340dc2366fSVenugopal Iyer set_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 33356b9e797cSsowmini val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3336d62bc4baSyz147064 { 3337d62bc4baSyz147064 dladm_wlan_rates_t rates; 3338f4b3ec61Sdh155122 dladm_status_t status; 3339f4b3ec61Sdh155122 33406b9e797cSsowmini /* 33416b9e797cSsowmini * can currently set rate on WIFI links only. 33426b9e797cSsowmini */ 33436b9e797cSsowmini if (media != DL_WIFI) 33446b9e797cSsowmini return (DLADM_STATUS_PROPRDONLY); 33456b9e797cSsowmini 3346d62bc4baSyz147064 if (val_cnt != 1) 3347d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3348f4b3ec61Sdh155122 3349d62bc4baSyz147064 rates.wr_cnt = 1; 3350d62bc4baSyz147064 rates.wr_rates[0] = vdp[0].vd_val; 3351f4b3ec61Sdh155122 33520dc2366fSVenugopal Iyer status = set_wlan_rate(handle, linkid, &rates); 3353f4b3ec61Sdh155122 3354d62bc4baSyz147064 return (status); 3355d62bc4baSyz147064 } 3356d62bc4baSyz147064 3357d62bc4baSyz147064 /* ARGSUSED */ 3358d62bc4baSyz147064 static dladm_status_t 33590dc2366fSVenugopal Iyer check_rate(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3360c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 33610dc2366fSVenugopal Iyer datalink_media_t media) 3362d62bc4baSyz147064 { 3363d62bc4baSyz147064 int i; 3364d62bc4baSyz147064 uint_t modval_cnt = MAX_SUPPORT_RATES; 3365d62bc4baSyz147064 char *buf, **modval; 3366d62bc4baSyz147064 dladm_status_t status; 3367afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 3368c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3369c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 3370d62bc4baSyz147064 3371d62bc4baSyz147064 if (val_cnt != 1) 3372d62bc4baSyz147064 return (DLADM_STATUS_BADVALCNT); 3373d62bc4baSyz147064 3374d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_STRSIZE) * 3375d62bc4baSyz147064 MAX_SUPPORT_RATES); 3376d62bc4baSyz147064 if (buf == NULL) { 3377d62bc4baSyz147064 status = DLADM_STATUS_NOMEM; 3378d62bc4baSyz147064 goto done; 3379d62bc4baSyz147064 } 3380d62bc4baSyz147064 3381d62bc4baSyz147064 modval = (char **)(void *)buf; 3382d62bc4baSyz147064 for (i = 0; i < MAX_SUPPORT_RATES; i++) { 3383d62bc4baSyz147064 modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + 3384d62bc4baSyz147064 i * DLADM_STRSIZE; 3385d62bc4baSyz147064 } 3386d62bc4baSyz147064 33870dc2366fSVenugopal Iyer status = get_rate_mod(handle, NULL, linkid, modval, &modval_cnt, 33884ac67f02SAnurag S. Maskey media, 0, &perm_flags); 3389d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3390d62bc4baSyz147064 goto done; 3391d62bc4baSyz147064 3392d62bc4baSyz147064 for (i = 0; i < modval_cnt; i++) { 3393d62bc4baSyz147064 if (strcasecmp(*prop_val, modval[i]) == 0) { 3394e7801d59Ssowmini vdp->vd_val = (uintptr_t)(uint_t) 3395e7801d59Ssowmini (atof(*prop_val) * 2); 3396f4b3ec61Sdh155122 status = DLADM_STATUS_OK; 3397f4b3ec61Sdh155122 break; 3398f4b3ec61Sdh155122 } 3399d62bc4baSyz147064 } 3400d62bc4baSyz147064 if (i == modval_cnt) 3401d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 3402d62bc4baSyz147064 done: 3403d62bc4baSyz147064 free(buf); 3404d62bc4baSyz147064 return (status); 3405d62bc4baSyz147064 } 3406f4b3ec61Sdh155122 3407d62bc4baSyz147064 static dladm_status_t 34080dc2366fSVenugopal Iyer get_phyconf(dladm_handle_t handle, datalink_id_t linkid, void *buf, 34094ac67f02SAnurag S. Maskey int buflen) 3410d62bc4baSyz147064 { 34114ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG, 3412bcb5c89dSSowmini Varadhan buflen, B_FALSE)); 3413d62bc4baSyz147064 } 3414d62bc4baSyz147064 3415e7801d59Ssowmini /* ARGSUSED */ 3416d62bc4baSyz147064 static dladm_status_t 34170dc2366fSVenugopal Iyer get_channel(dladm_handle_t handle, prop_desc_t *pdp, 34184ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 34194ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3420d62bc4baSyz147064 { 3421d62bc4baSyz147064 uint32_t channel; 3422bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 34230dc2366fSVenugopal Iyer dladm_status_t status; 3424bcb5c89dSSowmini Varadhan wl_phy_conf_t wl_phy_conf; 3425d62bc4baSyz147064 34260dc2366fSVenugopal Iyer if ((status = get_phyconf(handle, linkid, buf, sizeof (buf))) 3427bcb5c89dSSowmini Varadhan != DLADM_STATUS_OK) 34280dc2366fSVenugopal Iyer return (status); 3429d62bc4baSyz147064 3430bcb5c89dSSowmini Varadhan (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); 34310dc2366fSVenugopal Iyer if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) 34320dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3433d62bc4baSyz147064 3434d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); 3435d62bc4baSyz147064 *val_cnt = 1; 3436da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 34370dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3438d62bc4baSyz147064 } 3439d62bc4baSyz147064 3440e7801d59Ssowmini /* ARGSUSED */ 3441d62bc4baSyz147064 static dladm_status_t 34420dc2366fSVenugopal Iyer get_powermode(dladm_handle_t handle, prop_desc_t *pdp, 34434ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 34444ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3445d62bc4baSyz147064 { 3446bcb5c89dSSowmini Varadhan wl_ps_mode_t mode; 3447d62bc4baSyz147064 const char *s; 3448bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 34490dc2366fSVenugopal Iyer dladm_status_t status; 3450d62bc4baSyz147064 34510dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 34520dc2366fSVenugopal Iyer MAC_PROP_WL_POWER_MODE, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 34530dc2366fSVenugopal Iyer return (status); 3454d62bc4baSyz147064 3455bcb5c89dSSowmini Varadhan (void) memcpy(&mode, buf, sizeof (mode)); 3456bcb5c89dSSowmini Varadhan switch (mode.wl_ps_mode) { 3457d62bc4baSyz147064 case WL_PM_AM: 3458d62bc4baSyz147064 s = "off"; 3459f4b3ec61Sdh155122 break; 3460d62bc4baSyz147064 case WL_PM_MPS: 3461d62bc4baSyz147064 s = "max"; 3462d62bc4baSyz147064 break; 3463d62bc4baSyz147064 case WL_PM_FAST: 3464d62bc4baSyz147064 s = "fast"; 3465f4b3ec61Sdh155122 break; 3466f4b3ec61Sdh155122 default: 34670dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3468f4b3ec61Sdh155122 } 3469d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3470d62bc4baSyz147064 *val_cnt = 1; 3471afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 34720dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3473d62bc4baSyz147064 } 3474d62bc4baSyz147064 34750dc2366fSVenugopal Iyer /* ARGSUSED */ 3476d62bc4baSyz147064 static dladm_status_t 34770dc2366fSVenugopal Iyer set_powermode(dladm_handle_t handle, prop_desc_t *pdp, 34780dc2366fSVenugopal Iyer datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 34790dc2366fSVenugopal Iyer datalink_media_t media) 3480d62bc4baSyz147064 { 34810dc2366fSVenugopal Iyer dladm_wlan_powermode_t powermode = vdp->vd_val; 3482d62bc4baSyz147064 wl_ps_mode_t ps_mode; 3483d62bc4baSyz147064 34840dc2366fSVenugopal Iyer if (val_cnt != 1) 34850dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 34860dc2366fSVenugopal Iyer 3487d62bc4baSyz147064 (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); 3488d62bc4baSyz147064 34890dc2366fSVenugopal Iyer switch (powermode) { 3490d62bc4baSyz147064 case DLADM_WLAN_PM_OFF: 3491d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_AM; 3492d62bc4baSyz147064 break; 3493d62bc4baSyz147064 case DLADM_WLAN_PM_MAX: 3494d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_MPS; 3495d62bc4baSyz147064 break; 3496d62bc4baSyz147064 case DLADM_WLAN_PM_FAST: 3497d62bc4baSyz147064 ps_mode.wl_ps_mode = WL_PM_FAST; 3498d62bc4baSyz147064 break; 3499d62bc4baSyz147064 default: 3500d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3501d62bc4baSyz147064 } 35024ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &ps_mode, 35034ac67f02SAnurag S. Maskey MAC_PROP_WL_POWER_MODE, sizeof (ps_mode), B_TRUE)); 3504d62bc4baSyz147064 } 3505d62bc4baSyz147064 3506d62bc4baSyz147064 /* ARGSUSED */ 3507d62bc4baSyz147064 static dladm_status_t 35080dc2366fSVenugopal Iyer get_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3509da14cebeSEric Cheng char **prop_val, uint_t *val_cnt, datalink_media_t media, 3510da14cebeSEric Cheng uint_t flags, uint_t *perm_flags) 3511d62bc4baSyz147064 { 3512d62bc4baSyz147064 wl_radio_t radio; 3513d62bc4baSyz147064 const char *s; 3514bcb5c89dSSowmini Varadhan char buf[WLDP_BUFSIZE]; 35150dc2366fSVenugopal Iyer dladm_status_t status; 3516d62bc4baSyz147064 35170dc2366fSVenugopal Iyer if ((status = i_dladm_wlan_param(handle, linkid, buf, 35180dc2366fSVenugopal Iyer MAC_PROP_WL_RADIO, sizeof (buf), B_FALSE)) != DLADM_STATUS_OK) 35190dc2366fSVenugopal Iyer return (status); 3520d62bc4baSyz147064 3521bcb5c89dSSowmini Varadhan (void) memcpy(&radio, buf, sizeof (radio)); 3522d62bc4baSyz147064 switch (radio) { 3523d62bc4baSyz147064 case B_TRUE: 3524d62bc4baSyz147064 s = "on"; 3525d62bc4baSyz147064 break; 3526d62bc4baSyz147064 case B_FALSE: 3527d62bc4baSyz147064 s = "off"; 3528d62bc4baSyz147064 break; 3529d62bc4baSyz147064 default: 35300dc2366fSVenugopal Iyer return (DLADM_STATUS_NOTFOUND); 3531d62bc4baSyz147064 } 3532d62bc4baSyz147064 (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); 3533d62bc4baSyz147064 *val_cnt = 1; 3534afdda45fSVasumathi Sundaram - Sun Microsystems *perm_flags = MAC_PROP_PERM_RW; 35350dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3536d62bc4baSyz147064 } 3537d62bc4baSyz147064 35380dc2366fSVenugopal Iyer /* ARGSUSED */ 3539d62bc4baSyz147064 static dladm_status_t 35400dc2366fSVenugopal Iyer set_radio(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 35410dc2366fSVenugopal Iyer val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 3542d62bc4baSyz147064 { 35430dc2366fSVenugopal Iyer dladm_wlan_radio_t radio = vdp->vd_val; 3544d62bc4baSyz147064 wl_radio_t r; 3545d62bc4baSyz147064 35460dc2366fSVenugopal Iyer if (val_cnt != 1) 35470dc2366fSVenugopal Iyer return (DLADM_STATUS_BADVALCNT); 35480dc2366fSVenugopal Iyer 35490dc2366fSVenugopal Iyer switch (radio) { 3550d62bc4baSyz147064 case DLADM_WLAN_RADIO_ON: 3551d62bc4baSyz147064 r = B_TRUE; 3552d62bc4baSyz147064 break; 3553d62bc4baSyz147064 case DLADM_WLAN_RADIO_OFF: 3554d62bc4baSyz147064 r = B_FALSE; 3555d62bc4baSyz147064 break; 3556d62bc4baSyz147064 default: 3557d62bc4baSyz147064 return (DLADM_STATUS_NOTSUP); 3558d62bc4baSyz147064 } 35594ac67f02SAnurag S. Maskey return (i_dladm_wlan_param(handle, linkid, &r, MAC_PROP_WL_RADIO, 3560bcb5c89dSSowmini Varadhan sizeof (r), B_TRUE)); 3561d62bc4baSyz147064 } 3562d62bc4baSyz147064 3563d62bc4baSyz147064 /* ARGSUSED */ 3564d62bc4baSyz147064 static dladm_status_t 35650dc2366fSVenugopal Iyer check_hoplimit(dladm_handle_t handle, prop_desc_t *pdp, 3566c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 3567c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 35682b24ab6bSSebastien Roy { 35692b24ab6bSSebastien Roy int32_t hlim; 35702b24ab6bSSebastien Roy char *ep; 3571c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3572c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 35732b24ab6bSSebastien Roy 35742b24ab6bSSebastien Roy if (val_cnt != 1) 35752b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 35762b24ab6bSSebastien Roy 35772b24ab6bSSebastien Roy errno = 0; 35782b24ab6bSSebastien Roy hlim = strtol(*prop_val, &ep, 10); 35792b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || hlim < 1 || 35802b24ab6bSSebastien Roy hlim > (int32_t)UINT8_MAX) 35812b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 35822b24ab6bSSebastien Roy vdp->vd_val = hlim; 35832b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 35842b24ab6bSSebastien Roy } 35852b24ab6bSSebastien Roy 35862b24ab6bSSebastien Roy /* ARGSUSED */ 35872b24ab6bSSebastien Roy static dladm_status_t 35880dc2366fSVenugopal Iyer check_encaplim(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 3589c569ef53SMichael Lim char **prop_val, uint_t *val_cntp, uint_t flags, val_desc_t **vdpp, 35900dc2366fSVenugopal Iyer datalink_media_t media) 35912b24ab6bSSebastien Roy { 35922b24ab6bSSebastien Roy int32_t elim; 35932b24ab6bSSebastien Roy char *ep; 3594c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3595c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 35962b24ab6bSSebastien Roy 35972b24ab6bSSebastien Roy if (media != DL_IPV6) 35982b24ab6bSSebastien Roy return (DLADM_STATUS_BADARG); 35992b24ab6bSSebastien Roy 36002b24ab6bSSebastien Roy if (val_cnt != 1) 36012b24ab6bSSebastien Roy return (DLADM_STATUS_BADVALCNT); 36022b24ab6bSSebastien Roy 36032b24ab6bSSebastien Roy errno = 0; 36042b24ab6bSSebastien Roy elim = strtol(*prop_val, &ep, 10); 36052b24ab6bSSebastien Roy if (errno != 0 || ep == *prop_val || elim < 0 || 36062b24ab6bSSebastien Roy elim > (int32_t)UINT8_MAX) 36072b24ab6bSSebastien Roy return (DLADM_STATUS_BADVAL); 36082b24ab6bSSebastien Roy vdp->vd_val = elim; 36092b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 36102b24ab6bSSebastien Roy } 36112b24ab6bSSebastien Roy 3612d62bc4baSyz147064 static dladm_status_t 36134ac67f02SAnurag S. Maskey i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 36144ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 3615d62bc4baSyz147064 { 3616d62bc4baSyz147064 char buf[MAXLINELEN]; 3617d62bc4baSyz147064 int i; 3618d62bc4baSyz147064 dladm_conf_t conf; 3619d62bc4baSyz147064 dladm_status_t status; 3620d62bc4baSyz147064 362132715170SCathy Zhou status = dladm_open_conf(handle, linkid, &conf); 3622f4b3ec61Sdh155122 if (status != DLADM_STATUS_OK) 3623f4b3ec61Sdh155122 return (status); 3624f4b3ec61Sdh155122 3625d62bc4baSyz147064 /* 3626d62bc4baSyz147064 * reset case. 3627d62bc4baSyz147064 */ 3628d62bc4baSyz147064 if (val_cnt == 0) { 36294ac67f02SAnurag S. Maskey status = dladm_unset_conf_field(handle, conf, prop_name); 3630d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 36314ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3632d62bc4baSyz147064 goto done; 3633f4b3ec61Sdh155122 } 3634f4b3ec61Sdh155122 3635d62bc4baSyz147064 buf[0] = '\0'; 3636d62bc4baSyz147064 for (i = 0; i < val_cnt; i++) { 3637d62bc4baSyz147064 (void) strlcat(buf, prop_val[i], MAXLINELEN); 3638d62bc4baSyz147064 if (i != val_cnt - 1) 3639d62bc4baSyz147064 (void) strlcat(buf, ",", MAXLINELEN); 3640d62bc4baSyz147064 } 3641f4b3ec61Sdh155122 36424ac67f02SAnurag S. Maskey status = dladm_set_conf_field(handle, conf, prop_name, DLADM_TYPE_STR, 36434ac67f02SAnurag S. Maskey buf); 3644d62bc4baSyz147064 if (status == DLADM_STATUS_OK) 36454ac67f02SAnurag S. Maskey status = dladm_write_conf(handle, conf); 3646d62bc4baSyz147064 3647d62bc4baSyz147064 done: 36484ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3649f4b3ec61Sdh155122 return (status); 3650f4b3ec61Sdh155122 } 3651f4b3ec61Sdh155122 3652f4b3ec61Sdh155122 static dladm_status_t 36534ac67f02SAnurag S. Maskey i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, 36544ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 3655f4b3ec61Sdh155122 { 3656d62bc4baSyz147064 char buf[MAXLINELEN], *str; 3657d62bc4baSyz147064 uint_t cnt = 0; 3658d62bc4baSyz147064 dladm_conf_t conf; 3659d62bc4baSyz147064 dladm_status_t status; 3660f4b3ec61Sdh155122 366132715170SCathy Zhou status = dladm_getsnap_conf(handle, linkid, &conf); 3662d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3663f4b3ec61Sdh155122 return (status); 3664d62bc4baSyz147064 36654ac67f02SAnurag S. Maskey status = dladm_get_conf_field(handle, conf, prop_name, buf, MAXLINELEN); 3666d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3667d62bc4baSyz147064 goto done; 3668d62bc4baSyz147064 3669d62bc4baSyz147064 str = strtok(buf, ","); 3670d62bc4baSyz147064 while (str != NULL) { 3671d62bc4baSyz147064 if (cnt == *val_cntp) { 3672d62bc4baSyz147064 status = DLADM_STATUS_TOOSMALL; 3673d62bc4baSyz147064 goto done; 3674d62bc4baSyz147064 } 3675d62bc4baSyz147064 (void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX); 3676d62bc4baSyz147064 str = strtok(NULL, ","); 3677f4b3ec61Sdh155122 } 3678f4b3ec61Sdh155122 3679d62bc4baSyz147064 *val_cntp = cnt; 3680f4b3ec61Sdh155122 3681d62bc4baSyz147064 done: 36824ac67f02SAnurag S. Maskey dladm_destroy_conf(handle, conf); 3683d62bc4baSyz147064 return (status); 3684f4b3ec61Sdh155122 } 3685e7801d59Ssowmini 368662ee1d25SArtem Kachitchkine /* 368762ee1d25SArtem Kachitchkine * Walk persistent private link properties of a link. 368862ee1d25SArtem Kachitchkine */ 368962ee1d25SArtem Kachitchkine static dladm_status_t 369062ee1d25SArtem Kachitchkine i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, 369162ee1d25SArtem Kachitchkine void *arg, int (*func)(dladm_handle_t, datalink_id_t, const char *, void *)) 369262ee1d25SArtem Kachitchkine { 369362ee1d25SArtem Kachitchkine dladm_status_t status; 369462ee1d25SArtem Kachitchkine dladm_conf_t conf; 369562ee1d25SArtem Kachitchkine char last_attr[MAXLINKATTRLEN]; 369662ee1d25SArtem Kachitchkine char attr[MAXLINKATTRLEN]; 369762ee1d25SArtem Kachitchkine char attrval[MAXLINKATTRVALLEN]; 369862ee1d25SArtem Kachitchkine size_t attrsz; 369962ee1d25SArtem Kachitchkine 370062ee1d25SArtem Kachitchkine if (linkid == DATALINK_INVALID_LINKID || func == NULL) 370162ee1d25SArtem Kachitchkine return (DLADM_STATUS_BADARG); 370262ee1d25SArtem Kachitchkine 370332715170SCathy Zhou status = dladm_getsnap_conf(handle, linkid, &conf); 370462ee1d25SArtem Kachitchkine if (status != DLADM_STATUS_OK) 370562ee1d25SArtem Kachitchkine return (status); 370662ee1d25SArtem Kachitchkine 370762ee1d25SArtem Kachitchkine last_attr[0] = '\0'; 370862ee1d25SArtem Kachitchkine while ((status = dladm_getnext_conf_linkprop(handle, conf, last_attr, 370962ee1d25SArtem Kachitchkine attr, attrval, MAXLINKATTRVALLEN, &attrsz)) == DLADM_STATUS_OK) { 371062ee1d25SArtem Kachitchkine if (attr[0] == '_') { 371162ee1d25SArtem Kachitchkine if (func(handle, linkid, attr, arg) == 371262ee1d25SArtem Kachitchkine DLADM_WALK_TERMINATE) 371362ee1d25SArtem Kachitchkine break; 371462ee1d25SArtem Kachitchkine } 371562ee1d25SArtem Kachitchkine (void) strlcpy(last_attr, attr, MAXLINKATTRLEN); 371662ee1d25SArtem Kachitchkine } 371762ee1d25SArtem Kachitchkine 371862ee1d25SArtem Kachitchkine dladm_destroy_conf(handle, conf); 371962ee1d25SArtem Kachitchkine return (DLADM_STATUS_OK); 372062ee1d25SArtem Kachitchkine } 372162ee1d25SArtem Kachitchkine 3722bcb5c89dSSowmini Varadhan static link_attr_t * 3723e7801d59Ssowmini dladm_name2prop(const char *prop_name) 3724e7801d59Ssowmini { 3725bcb5c89dSSowmini Varadhan link_attr_t *p; 3726e7801d59Ssowmini 3727bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3728e7801d59Ssowmini if (strcmp(p->pp_name, prop_name) == 0) 3729e7801d59Ssowmini break; 3730e7801d59Ssowmini } 3731e7801d59Ssowmini return (p); 3732e7801d59Ssowmini } 3733e7801d59Ssowmini 3734bcb5c89dSSowmini Varadhan static link_attr_t * 3735bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid) 3736bcb5c89dSSowmini Varadhan { 3737bcb5c89dSSowmini Varadhan link_attr_t *p; 3738bcb5c89dSSowmini Varadhan 3739bcb5c89dSSowmini Varadhan for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { 3740bcb5c89dSSowmini Varadhan if (p->pp_id == propid) 3741bcb5c89dSSowmini Varadhan break; 3742bcb5c89dSSowmini Varadhan } 3743bcb5c89dSSowmini Varadhan return (p); 3744bcb5c89dSSowmini Varadhan } 3745e7801d59Ssowmini 37463fd94f8cSam223141 static dld_ioc_macprop_t * 3747bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, 3748bcb5c89dSSowmini Varadhan const char *prop_name, mac_prop_id_t propid, uint_t flags, 3749bcb5c89dSSowmini Varadhan dladm_status_t *status) 3750e7801d59Ssowmini { 3751e7801d59Ssowmini int dsize; 37523fd94f8cSam223141 dld_ioc_macprop_t *dip; 3753e7801d59Ssowmini 3754e7801d59Ssowmini *status = DLADM_STATUS_OK; 37553fd94f8cSam223141 dsize = MAC_PROP_BUFSIZE(valsize); 3756e7801d59Ssowmini dip = malloc(dsize); 3757e7801d59Ssowmini if (dip == NULL) { 3758e7801d59Ssowmini *status = DLADM_STATUS_NOMEM; 3759e7801d59Ssowmini return (NULL); 3760e7801d59Ssowmini } 3761e7801d59Ssowmini bzero(dip, dsize); 3762e7801d59Ssowmini dip->pr_valsize = valsize; 37634045d941Ssowmini (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); 37646b9e797cSsowmini dip->pr_linkid = linkid; 3765bcb5c89dSSowmini Varadhan dip->pr_num = propid; 37664045d941Ssowmini dip->pr_flags = flags; 3767e7801d59Ssowmini return (dip); 3768e7801d59Ssowmini } 3769e7801d59Ssowmini 3770bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3771bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, 3772bcb5c89dSSowmini Varadhan const char *prop_name, uint_t flags, dladm_status_t *status) 3773bcb5c89dSSowmini Varadhan { 3774bcb5c89dSSowmini Varadhan link_attr_t *p; 3775bcb5c89dSSowmini Varadhan 3776bcb5c89dSSowmini Varadhan p = dladm_name2prop(prop_name); 3777bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3778bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, 3779bcb5c89dSSowmini Varadhan flags, status)); 3780bcb5c89dSSowmini Varadhan } 3781bcb5c89dSSowmini Varadhan 3782bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t * 3783bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, 3784bcb5c89dSSowmini Varadhan mac_prop_id_t propid, uint_t flags, dladm_status_t *status) 3785bcb5c89dSSowmini Varadhan { 3786bcb5c89dSSowmini Varadhan link_attr_t *p; 3787bcb5c89dSSowmini Varadhan 3788bcb5c89dSSowmini Varadhan p = dladm_id2prop(propid); 3789bcb5c89dSSowmini Varadhan valsize = MAX(p->pp_valsize, valsize); 3790bcb5c89dSSowmini Varadhan return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, 3791bcb5c89dSSowmini Varadhan flags, status)); 3792bcb5c89dSSowmini Varadhan } 3793bcb5c89dSSowmini Varadhan 3794e7801d59Ssowmini /* ARGSUSED */ 3795e7801d59Ssowmini static dladm_status_t 37960dc2366fSVenugopal Iyer set_public_prop(dladm_handle_t handle, prop_desc_t *pdp, 37974ac67f02SAnurag S. Maskey datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 37984ac67f02SAnurag S. Maskey datalink_media_t media) 3799e7801d59Ssowmini { 38003fd94f8cSam223141 dld_ioc_macprop_t *dip; 3801e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 3802e7801d59Ssowmini uint8_t u8; 3803e7801d59Ssowmini uint16_t u16; 3804e7801d59Ssowmini uint32_t u32; 3805e7801d59Ssowmini void *val; 3806e7801d59Ssowmini 3807da14cebeSEric Cheng dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 0, &status); 3808e7801d59Ssowmini if (dip == NULL) 3809e7801d59Ssowmini return (status); 3810e7801d59Ssowmini 3811da14cebeSEric Cheng if (pdp->pd_flags & PD_CHECK_ALLOC) 3812e7801d59Ssowmini val = (void *)vdp->vd_val; 3813e7801d59Ssowmini else { 3814e7801d59Ssowmini /* 3815e7801d59Ssowmini * Currently all 1/2/4-byte size properties are byte/word/int. 3816e7801d59Ssowmini * No need (yet) to distinguish these from arrays of same size. 3817e7801d59Ssowmini */ 3818e7801d59Ssowmini switch (dip->pr_valsize) { 3819e7801d59Ssowmini case 1: 3820e7801d59Ssowmini u8 = vdp->vd_val; 3821e7801d59Ssowmini val = &u8; 3822e7801d59Ssowmini break; 3823e7801d59Ssowmini case 2: 3824e7801d59Ssowmini u16 = vdp->vd_val; 3825e7801d59Ssowmini val = &u16; 3826e7801d59Ssowmini break; 3827e7801d59Ssowmini case 4: 3828e7801d59Ssowmini u32 = vdp->vd_val; 3829e7801d59Ssowmini val = &u32; 3830e7801d59Ssowmini break; 3831e7801d59Ssowmini default: 3832e7801d59Ssowmini val = &vdp->vd_val; 3833e7801d59Ssowmini break; 3834e7801d59Ssowmini } 3835e7801d59Ssowmini } 3836e7801d59Ssowmini 38373bc21d0aSAruna Ramakrishna - Sun Microsystems if (val != NULL) 3838e7801d59Ssowmini (void) memcpy(dip->pr_val, val, dip->pr_valsize); 38393bc21d0aSAruna Ramakrishna - Sun Microsystems else 38403bc21d0aSAruna Ramakrishna - Sun Microsystems dip->pr_valsize = 0; 38413bc21d0aSAruna Ramakrishna - Sun Microsystems 38424ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_TRUE); 3843bcb5c89dSSowmini Varadhan 3844bcb5c89dSSowmini Varadhan done: 3845bcb5c89dSSowmini Varadhan free(dip); 3846bcb5c89dSSowmini Varadhan return (status); 3847bcb5c89dSSowmini Varadhan } 3848bcb5c89dSSowmini Varadhan 3849bcb5c89dSSowmini Varadhan dladm_status_t 38504ac67f02SAnurag S. Maskey i_dladm_macprop(dladm_handle_t handle, void *dip, boolean_t set) 3851bcb5c89dSSowmini Varadhan { 3852bcb5c89dSSowmini Varadhan dladm_status_t status = DLADM_STATUS_OK; 3853bcb5c89dSSowmini Varadhan 38544ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), 38554ac67f02SAnurag S. Maskey (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) 3856e7801d59Ssowmini status = dladm_errno2status(errno); 3857e7801d59Ssowmini 3858e7801d59Ssowmini return (status); 3859e7801d59Ssowmini } 3860e7801d59Ssowmini 38610dc2366fSVenugopal Iyer static dladm_status_t 38624ac67f02SAnurag S. Maskey i_dladm_get_public_prop(dladm_handle_t handle, datalink_id_t linkid, 38630dc2366fSVenugopal Iyer char *prop_name, uint_t flags, uint_t *perm_flags, void *arg, size_t size) 3864e7801d59Ssowmini { 38650dc2366fSVenugopal Iyer dld_ioc_macprop_t *dip; 38660dc2366fSVenugopal Iyer dladm_status_t status; 38674045d941Ssowmini 38680dc2366fSVenugopal Iyer dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, &status); 38694045d941Ssowmini if (dip == NULL) 38700dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 3871e7801d59Ssowmini 38720dc2366fSVenugopal Iyer status = i_dladm_macprop(handle, dip, B_FALSE); 38730dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) { 38744045d941Ssowmini free(dip); 38750dc2366fSVenugopal Iyer return (status); 38764045d941Ssowmini } 38770dc2366fSVenugopal Iyer 3878da14cebeSEric Cheng if (perm_flags != NULL) 3879da14cebeSEric Cheng *perm_flags = dip->pr_perm_flags; 3880da14cebeSEric Cheng 38810dc2366fSVenugopal Iyer if (arg != NULL) 38820dc2366fSVenugopal Iyer (void) memcpy(arg, dip->pr_val, size); 38830dc2366fSVenugopal Iyer free(dip); 38840dc2366fSVenugopal Iyer return (DLADM_STATUS_OK); 3885e7801d59Ssowmini } 3886e7801d59Ssowmini 3887e7801d59Ssowmini /* ARGSUSED */ 3888e7801d59Ssowmini static dladm_status_t 38890dc2366fSVenugopal Iyer check_uint32(dladm_handle_t handle, prop_desc_t *pdp, 3890c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 3891c569ef53SMichael Lim val_desc_t **vp, datalink_media_t media) 3892e7801d59Ssowmini { 3893c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 3894c569ef53SMichael Lim val_desc_t *v = *vp; 3895c569ef53SMichael Lim 3896e7801d59Ssowmini if (val_cnt != 1) 3897e7801d59Ssowmini return (DLADM_STATUS_BADVAL); 38984eaa4710SRishi Srivatsavai v->vd_val = strtoul(prop_val[0], NULL, 0); 3899e7801d59Ssowmini return (DLADM_STATUS_OK); 3900e7801d59Ssowmini } 3901e7801d59Ssowmini 3902e7801d59Ssowmini /* ARGSUSED */ 3903e7801d59Ssowmini static dladm_status_t 39040dc2366fSVenugopal Iyer get_duplex(dladm_handle_t handle, prop_desc_t *pdp, 39054ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 39064ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3907e7801d59Ssowmini { 3908e7801d59Ssowmini link_duplex_t link_duplex; 3909e7801d59Ssowmini dladm_status_t status; 3910e7801d59Ssowmini 39114ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 3912e7801d59Ssowmini KSTAT_DATA_UINT32, &link_duplex)) != 0) 3913e7801d59Ssowmini return (status); 3914e7801d59Ssowmini 3915e7801d59Ssowmini switch (link_duplex) { 3916e7801d59Ssowmini case LINK_DUPLEX_FULL: 3917e7801d59Ssowmini (void) strcpy(*prop_val, "full"); 3918e7801d59Ssowmini break; 3919e7801d59Ssowmini case LINK_DUPLEX_HALF: 3920e7801d59Ssowmini (void) strcpy(*prop_val, "half"); 3921e7801d59Ssowmini break; 3922e7801d59Ssowmini default: 3923e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3924e7801d59Ssowmini break; 3925e7801d59Ssowmini } 3926e7801d59Ssowmini *val_cnt = 1; 3927e7801d59Ssowmini return (DLADM_STATUS_OK); 3928e7801d59Ssowmini } 3929e7801d59Ssowmini 3930e7801d59Ssowmini /* ARGSUSED */ 3931e7801d59Ssowmini static dladm_status_t 39320dc2366fSVenugopal Iyer get_speed(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, 39330dc2366fSVenugopal Iyer char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 39340dc2366fSVenugopal Iyer uint_t *perm_flags) 3935e7801d59Ssowmini { 3936e7801d59Ssowmini uint64_t ifspeed = 0; 3937e7801d59Ssowmini dladm_status_t status; 3938e7801d59Ssowmini 39394ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 3940e7801d59Ssowmini KSTAT_DATA_UINT64, &ifspeed)) != 0) 3941e7801d59Ssowmini return (status); 39424045d941Ssowmini 39436b9e797cSsowmini if ((ifspeed % 1000000) != 0) { 39446b9e797cSsowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 39456b9e797cSsowmini "%llf", ifspeed / (float)1000000); /* Mbps */ 39466b9e797cSsowmini } else { 3947e7801d59Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, 3948e7801d59Ssowmini "%llu", ifspeed / 1000000); /* Mbps */ 39496b9e797cSsowmini } 3950e7801d59Ssowmini *val_cnt = 1; 3951da14cebeSEric Cheng *perm_flags = MAC_PROP_PERM_READ; 3952e7801d59Ssowmini return (DLADM_STATUS_OK); 3953e7801d59Ssowmini } 3954e7801d59Ssowmini 3955e7801d59Ssowmini /* ARGSUSED */ 3956e7801d59Ssowmini static dladm_status_t 39570dc2366fSVenugopal Iyer get_link_state(dladm_handle_t handle, prop_desc_t *pdp, 39584ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 39594ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3960e7801d59Ssowmini { 3961e7801d59Ssowmini link_state_t link_state; 3962e7801d59Ssowmini dladm_status_t status; 3963e7801d59Ssowmini 39640dc2366fSVenugopal Iyer status = dladm_get_state(handle, linkid, &link_state); 39654045d941Ssowmini if (status != DLADM_STATUS_OK) 3966e7801d59Ssowmini return (status); 3967da14cebeSEric Cheng 3968e7801d59Ssowmini switch (link_state) { 3969e7801d59Ssowmini case LINK_STATE_UP: 3970e7801d59Ssowmini (void) strcpy(*prop_val, "up"); 3971e7801d59Ssowmini break; 3972e7801d59Ssowmini case LINK_STATE_DOWN: 3973e7801d59Ssowmini (void) strcpy(*prop_val, "down"); 3974e7801d59Ssowmini break; 3975e7801d59Ssowmini default: 3976e7801d59Ssowmini (void) strcpy(*prop_val, "unknown"); 3977e7801d59Ssowmini break; 3978e7801d59Ssowmini } 3979e7801d59Ssowmini *val_cnt = 1; 39804784fcbdSSowmini Varadhan *perm_flags = MAC_PROP_PERM_READ; 3981e7801d59Ssowmini return (DLADM_STATUS_OK); 3982e7801d59Ssowmini } 3983e7801d59Ssowmini 3984e7801d59Ssowmini /* ARGSUSED */ 3985e7801d59Ssowmini static dladm_status_t 39860dc2366fSVenugopal Iyer get_binary(dladm_handle_t handle, prop_desc_t *pdp, 39874ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 39884ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 3989e7801d59Ssowmini { 3990e7801d59Ssowmini dladm_status_t status; 39910dc2366fSVenugopal Iyer uint_t v = 0; 3992e7801d59Ssowmini 39930dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 39940dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 39950dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 3996e7801d59Ssowmini return (status); 3997da14cebeSEric Cheng 39980dc2366fSVenugopal Iyer (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%d", (uint_t)(v > 0)); 3999e7801d59Ssowmini *val_cnt = 1; 4000e7801d59Ssowmini return (DLADM_STATUS_OK); 4001e7801d59Ssowmini } 4002e7801d59Ssowmini 40036b9e797cSsowmini /* ARGSUSED */ 4004e7801d59Ssowmini static dladm_status_t 40050dc2366fSVenugopal Iyer get_uint32(dladm_handle_t handle, prop_desc_t *pdp, 40064ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 40074ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 4008e7801d59Ssowmini { 40090dc2366fSVenugopal Iyer dladm_status_t status; 40104045d941Ssowmini uint32_t v = 0; 4011e7801d59Ssowmini 40120dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 40130dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 40140dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 4015e7801d59Ssowmini return (status); 4016da14cebeSEric Cheng 40174045d941Ssowmini (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v); 4018e7801d59Ssowmini *val_cnt = 1; 4019e7801d59Ssowmini return (DLADM_STATUS_OK); 4020e7801d59Ssowmini } 4021e7801d59Ssowmini 4022f0f2c3a5SGirish Moodalbail /* ARGSUSED */ 4023f0f2c3a5SGirish Moodalbail static dladm_status_t 40240dc2366fSVenugopal Iyer get_range(dladm_handle_t handle, prop_desc_t *pdp, 4025f0f2c3a5SGirish Moodalbail datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 4026f0f2c3a5SGirish Moodalbail datalink_media_t media, uint_t flags, uint_t *perm_flags) 4027f0f2c3a5SGirish Moodalbail { 4028f0f2c3a5SGirish Moodalbail dld_ioc_macprop_t *dip; 4029f0f2c3a5SGirish Moodalbail dladm_status_t status = DLADM_STATUS_OK; 4030f0f2c3a5SGirish Moodalbail size_t sz; 40310591ddd0SPrakash Jalan uint_t rcount; 4032f0f2c3a5SGirish Moodalbail mac_propval_range_t *rangep; 4033f0f2c3a5SGirish Moodalbail 4034f0f2c3a5SGirish Moodalbail /* 4035f0f2c3a5SGirish Moodalbail * As caller we don't know number of value ranges, the driver 4036f0f2c3a5SGirish Moodalbail * supports. To begin with we assume that number to be 1. If the 4037f0f2c3a5SGirish Moodalbail * buffer size is insufficient, driver returns back with the 4038f0f2c3a5SGirish Moodalbail * actual count of value ranges. See mac.h for more details. 4039f0f2c3a5SGirish Moodalbail */ 40400591ddd0SPrakash Jalan sz = sizeof (mac_propval_range_t); 40410591ddd0SPrakash Jalan rcount = 1; 4042f0f2c3a5SGirish Moodalbail retry: 4043f0f2c3a5SGirish Moodalbail if ((dip = i_dladm_buf_alloc_by_name(sz, linkid, pdp->pd_name, flags, 4044f0f2c3a5SGirish Moodalbail &status)) == NULL) 4045f0f2c3a5SGirish Moodalbail return (status); 4046f0f2c3a5SGirish Moodalbail 40470591ddd0SPrakash Jalan rangep = (mac_propval_range_t *)(void *)&dip->pr_val; 40480591ddd0SPrakash Jalan rangep->mpr_count = rcount; 40490591ddd0SPrakash Jalan 4050f0f2c3a5SGirish Moodalbail status = i_dladm_macprop(handle, dip, B_FALSE); 4051f0f2c3a5SGirish Moodalbail if (status != DLADM_STATUS_OK) { 4052f0f2c3a5SGirish Moodalbail if (status == DLADM_STATUS_TOOSMALL) { 4053f0f2c3a5SGirish Moodalbail int err; 4054f0f2c3a5SGirish Moodalbail 40550591ddd0SPrakash Jalan if ((err = i_dladm_range_size(rangep, &sz, &rcount)) 40560591ddd0SPrakash Jalan == 0) { 4057f0f2c3a5SGirish Moodalbail free(dip); 4058f0f2c3a5SGirish Moodalbail goto retry; 4059f0f2c3a5SGirish Moodalbail } else { 4060f0f2c3a5SGirish Moodalbail status = dladm_errno2status(err); 4061f0f2c3a5SGirish Moodalbail } 4062f0f2c3a5SGirish Moodalbail } 4063f0f2c3a5SGirish Moodalbail free(dip); 4064f0f2c3a5SGirish Moodalbail return (status); 4065f0f2c3a5SGirish Moodalbail } 40660dc2366fSVenugopal Iyer 40670dc2366fSVenugopal Iyer if (rangep->mpr_count == 0) { 40680dc2366fSVenugopal Iyer *val_cnt = 1; 40690dc2366fSVenugopal Iyer (void) snprintf(prop_val[0], DLADM_PROP_VAL_MAX, "--"); 40700dc2366fSVenugopal Iyer goto done; 40710dc2366fSVenugopal Iyer } 4072f0f2c3a5SGirish Moodalbail 4073f0f2c3a5SGirish Moodalbail switch (rangep->mpr_type) { 4074f0f2c3a5SGirish Moodalbail case MAC_PROPVAL_UINT32: { 4075f0f2c3a5SGirish Moodalbail mac_propval_uint32_range_t *ur; 4076f0f2c3a5SGirish Moodalbail uint_t count = rangep->mpr_count, i; 4077f0f2c3a5SGirish Moodalbail 40780dc2366fSVenugopal Iyer ur = &rangep->mpr_range_uint32[0]; 4079f0f2c3a5SGirish Moodalbail 4080f0f2c3a5SGirish Moodalbail for (i = 0; i < count; i++, ur++) { 4081f0f2c3a5SGirish Moodalbail if (ur->mpur_min == ur->mpur_max) { 4082f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 4083f0f2c3a5SGirish Moodalbail "%ld", ur->mpur_min); 4084f0f2c3a5SGirish Moodalbail } else { 4085f0f2c3a5SGirish Moodalbail (void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX, 4086f0f2c3a5SGirish Moodalbail "%ld-%ld", ur->mpur_min, ur->mpur_max); 4087f0f2c3a5SGirish Moodalbail } 4088f0f2c3a5SGirish Moodalbail } 4089f0f2c3a5SGirish Moodalbail *val_cnt = count; 4090f0f2c3a5SGirish Moodalbail break; 4091f0f2c3a5SGirish Moodalbail } 4092f0f2c3a5SGirish Moodalbail default: 4093f0f2c3a5SGirish Moodalbail status = DLADM_STATUS_BADARG; 4094f0f2c3a5SGirish Moodalbail break; 4095f0f2c3a5SGirish Moodalbail } 40960dc2366fSVenugopal Iyer done: 4097f0f2c3a5SGirish Moodalbail free(dip); 4098f0f2c3a5SGirish Moodalbail return (status); 4099f0f2c3a5SGirish Moodalbail } 4100f0f2c3a5SGirish Moodalbail 41016b9e797cSsowmini /* ARGSUSED */ 4102e7801d59Ssowmini static dladm_status_t 41030dc2366fSVenugopal Iyer get_tagmode(dladm_handle_t handle, prop_desc_t *pdp, 4104e75f0919SSebastien Roy datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 4105e75f0919SSebastien Roy datalink_media_t media, uint_t flags, uint_t *perm_flags) 4106e75f0919SSebastien Roy { 4107e75f0919SSebastien Roy link_tagmode_t mode; 4108e75f0919SSebastien Roy dladm_status_t status; 4109e75f0919SSebastien Roy 41100dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 41110dc2366fSVenugopal Iyer perm_flags, &mode, sizeof (mode)); 41120dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 4113e75f0919SSebastien Roy return (status); 4114e75f0919SSebastien Roy 4115e75f0919SSebastien Roy switch (mode) { 4116e75f0919SSebastien Roy case LINK_TAGMODE_NORMAL: 4117e75f0919SSebastien Roy (void) strlcpy(*prop_val, "normal", DLADM_PROP_VAL_MAX); 4118e75f0919SSebastien Roy break; 4119e75f0919SSebastien Roy case LINK_TAGMODE_VLANONLY: 4120e75f0919SSebastien Roy (void) strlcpy(*prop_val, "vlanonly", DLADM_PROP_VAL_MAX); 4121e75f0919SSebastien Roy break; 4122e75f0919SSebastien Roy default: 4123e75f0919SSebastien Roy (void) strlcpy(*prop_val, "unknown", DLADM_PROP_VAL_MAX); 4124e75f0919SSebastien Roy } 4125e75f0919SSebastien Roy *val_cnt = 1; 4126e75f0919SSebastien Roy return (DLADM_STATUS_OK); 4127e75f0919SSebastien Roy } 4128e75f0919SSebastien Roy 4129e75f0919SSebastien Roy /* ARGSUSED */ 4130e75f0919SSebastien Roy static dladm_status_t 41310dc2366fSVenugopal Iyer get_flowctl(dladm_handle_t handle, prop_desc_t *pdp, 41324ac67f02SAnurag S. Maskey datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 41334ac67f02SAnurag S. Maskey datalink_media_t media, uint_t flags, uint_t *perm_flags) 4134e7801d59Ssowmini { 4135e7801d59Ssowmini link_flowctrl_t v; 4136e7801d59Ssowmini dladm_status_t status; 4137e7801d59Ssowmini 41380dc2366fSVenugopal Iyer status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 41390dc2366fSVenugopal Iyer perm_flags, &v, sizeof (v)); 41400dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 4141e7801d59Ssowmini return (status); 4142da14cebeSEric Cheng 4143e7801d59Ssowmini switch (v) { 4144e7801d59Ssowmini case LINK_FLOWCTRL_NONE: 4145e7801d59Ssowmini (void) sprintf(*prop_val, "no"); 4146e7801d59Ssowmini break; 4147e7801d59Ssowmini case LINK_FLOWCTRL_RX: 4148e7801d59Ssowmini (void) sprintf(*prop_val, "rx"); 4149e7801d59Ssowmini break; 4150e7801d59Ssowmini case LINK_FLOWCTRL_TX: 4151e7801d59Ssowmini (void) sprintf(*prop_val, "tx"); 4152e7801d59Ssowmini break; 4153e7801d59Ssowmini case LINK_FLOWCTRL_BI: 4154e7801d59Ssowmini (void) sprintf(*prop_val, "bi"); 4155e7801d59Ssowmini break; 4156e7801d59Ssowmini } 4157e7801d59Ssowmini *val_cnt = 1; 4158e7801d59Ssowmini return (DLADM_STATUS_OK); 4159e7801d59Ssowmini } 4160e7801d59Ssowmini 4161e7801d59Ssowmini 4162e7801d59Ssowmini /* ARGSUSED */ 4163e7801d59Ssowmini static dladm_status_t 41643361618bSRishi Srivatsavai i_dladm_set_private_prop(dladm_handle_t handle, datalink_id_t linkid, 41654ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) 4166e7801d59Ssowmini { 4167bcb5c89dSSowmini Varadhan int i, slen; 4168eae72b5bSSebastien Roy int bufsize = 0; 41693fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 4170e7801d59Ssowmini uchar_t *dp; 4171bcb5c89dSSowmini Varadhan link_attr_t *p; 41724045d941Ssowmini dladm_status_t status = DLADM_STATUS_OK; 4173e7801d59Ssowmini 4174e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 4175e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 4176e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4177e7801d59Ssowmini p = dladm_name2prop(prop_name); 41783fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 4179e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4180e7801d59Ssowmini 41813361618bSRishi Srivatsavai if (!(flags & DLADM_OPT_ACTIVE)) 41823361618bSRishi Srivatsavai return (DLADM_STATUS_OK); 41833361618bSRishi Srivatsavai 4184e7801d59Ssowmini /* 4185e7801d59Ssowmini * private properties: all parsing is done in the kernel. 4186e7801d59Ssowmini * allocate a enough space for each property + its separator (','). 4187e7801d59Ssowmini */ 4188e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 4189e7801d59Ssowmini bufsize += strlen(prop_val[i]) + 1; 4190e7801d59Ssowmini } 41914045d941Ssowmini 41924045d941Ssowmini if (prop_val == NULL) { 41934045d941Ssowmini /* 41944045d941Ssowmini * getting default value. so use more buffer space. 41954045d941Ssowmini */ 4196bcb5c89dSSowmini Varadhan bufsize += DLADM_PROP_BUF_CHUNK; 41974045d941Ssowmini } 41984045d941Ssowmini 4199bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, 42000dc2366fSVenugopal Iyer (prop_val != NULL ? 0 : DLD_PROP_DEFAULT), &status); 4201e7801d59Ssowmini if (dip == NULL) 4202e7801d59Ssowmini return (status); 4203e7801d59Ssowmini 4204e7801d59Ssowmini dp = (uchar_t *)dip->pr_val; 4205e7801d59Ssowmini slen = 0; 4206bcb5c89dSSowmini Varadhan 42074045d941Ssowmini if (prop_val == NULL) { 42084ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, B_FALSE); 420962ee1d25SArtem Kachitchkine dip->pr_flags = 0; 42104045d941Ssowmini } else { 4211e7801d59Ssowmini for (i = 0; i < val_cnt; i++) { 4212e7801d59Ssowmini int plen = 0; 4213e7801d59Ssowmini 4214e7801d59Ssowmini plen = strlen(prop_val[i]); 4215e7801d59Ssowmini bcopy(prop_val[i], dp, plen); 4216e7801d59Ssowmini slen += plen; 4217e7801d59Ssowmini /* 4218e7801d59Ssowmini * add a "," separator and update dp. 4219e7801d59Ssowmini */ 4220e7801d59Ssowmini if (i != (val_cnt -1)) 4221e7801d59Ssowmini dp[slen++] = ','; 4222e7801d59Ssowmini dp += (plen + 1); 4223e7801d59Ssowmini } 4224e7801d59Ssowmini } 422562ee1d25SArtem Kachitchkine if (status == DLADM_STATUS_OK) 422662ee1d25SArtem Kachitchkine status = i_dladm_macprop(handle, dip, B_TRUE); 42274045d941Ssowmini 4228e7801d59Ssowmini free(dip); 4229e7801d59Ssowmini return (status); 4230e7801d59Ssowmini } 4231e7801d59Ssowmini 4232e7801d59Ssowmini static dladm_status_t 423362ee1d25SArtem Kachitchkine i_dladm_get_priv_prop(dladm_handle_t handle, datalink_id_t linkid, 42344ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cnt, 42354ac67f02SAnurag S. Maskey dladm_prop_type_t type, uint_t dld_flags) 4236e7801d59Ssowmini { 4237e7801d59Ssowmini dladm_status_t status = DLADM_STATUS_OK; 42383fd94f8cSam223141 dld_ioc_macprop_t *dip = NULL; 4239bcb5c89dSSowmini Varadhan link_attr_t *p; 4240e7801d59Ssowmini 4241e7801d59Ssowmini if ((prop_name == NULL && prop_val != NULL) || 4242e7801d59Ssowmini (prop_val != NULL && val_cnt == 0)) 4243e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4244e7801d59Ssowmini 4245e7801d59Ssowmini p = dladm_name2prop(prop_name); 42463fd94f8cSam223141 if (p->pp_id != MAC_PROP_PRIVATE) 4247e7801d59Ssowmini return (DLADM_STATUS_BADARG); 4248e7801d59Ssowmini 4249e7801d59Ssowmini /* 4250e7801d59Ssowmini * private properties: all parsing is done in the kernel. 4251e7801d59Ssowmini */ 4252bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, 4253bcb5c89dSSowmini Varadhan dld_flags, &status); 4254e7801d59Ssowmini if (dip == NULL) 4255e7801d59Ssowmini return (status); 4256e7801d59Ssowmini 42574ac67f02SAnurag S. Maskey if ((status = i_dladm_macprop(handle, dip, B_FALSE)) == 42584ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 4259afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_PERM) { 4260da14cebeSEric Cheng (void) dladm_perm2str(dip->pr_perm_flags, *prop_val); 426162ee1d25SArtem Kachitchkine } else if (type == DLADM_PROP_VAL_MODIFIABLE) { 426262ee1d25SArtem Kachitchkine *prop_val[0] = '\0'; 4263afdda45fSVasumathi Sundaram - Sun Microsystems } else { 4264afdda45fSVasumathi Sundaram - Sun Microsystems (void) strncpy(*prop_val, dip->pr_val, 4265afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_MAX); 4266afdda45fSVasumathi Sundaram - Sun Microsystems } 4267e7801d59Ssowmini *val_cnt = 1; 426862ee1d25SArtem Kachitchkine } else if ((status == DLADM_STATUS_NOTSUP) && 426962ee1d25SArtem Kachitchkine (type == DLADM_PROP_VAL_CURRENT)) { 427062ee1d25SArtem Kachitchkine status = DLADM_STATUS_NOTFOUND; 4271e7801d59Ssowmini } 42724045d941Ssowmini free(dip); 42734045d941Ssowmini return (status); 42744045d941Ssowmini } 42754045d941Ssowmini 42764045d941Ssowmini 42774045d941Ssowmini static dladm_status_t 42784ac67f02SAnurag S. Maskey i_dladm_getset_defval(dladm_handle_t handle, prop_desc_t *pdp, 42794ac67f02SAnurag S. Maskey datalink_id_t linkid, datalink_media_t media, uint_t flags) 42804045d941Ssowmini { 42814045d941Ssowmini dladm_status_t status; 42824045d941Ssowmini char **prop_vals = NULL, *buf; 42834045d941Ssowmini size_t bufsize; 42844045d941Ssowmini uint_t cnt; 42854045d941Ssowmini int i; 4286afdda45fSVasumathi Sundaram - Sun Microsystems uint_t perm_flags; 42874045d941Ssowmini 42884045d941Ssowmini /* 42894045d941Ssowmini * Allocate buffer needed for prop_vals array. We can have at most 42904045d941Ssowmini * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where 42914045d941Ssowmini * each entry has max size DLADM_PROP_VAL_MAX 42924045d941Ssowmini */ 42934045d941Ssowmini bufsize = 42944045d941Ssowmini (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 42954045d941Ssowmini buf = malloc(bufsize); 42964045d941Ssowmini prop_vals = (char **)(void *)buf; 42974045d941Ssowmini for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 42984045d941Ssowmini prop_vals[i] = buf + 42994045d941Ssowmini sizeof (char *) * DLADM_MAX_PROP_VALCNT + 43004045d941Ssowmini i * DLADM_PROP_VAL_MAX; 43014045d941Ssowmini } 430213a55820Sar224390 430313a55820Sar224390 /* 43043bc21d0aSAruna Ramakrishna - Sun Microsystems * For properties which have pdp->pd_defval.vd_name as a non-empty 43053bc21d0aSAruna Ramakrishna - Sun Microsystems * string, the "" itself is used to reset the property (exceptions 43063bc21d0aSAruna Ramakrishna - Sun Microsystems * are zone and autopush, which populate vdp->vd_val). So 43073bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm can copy pdp->pd_defval over to the val_desc_t passed 43083bc21d0aSAruna Ramakrishna - Sun Microsystems * down on the setprop using the global values in the table. For 43093bc21d0aSAruna Ramakrishna - Sun Microsystems * other cases (vd_name is ""), doing reset-linkprop will cause 43103bc21d0aSAruna Ramakrishna - Sun Microsystems * libdladm to do a getprop to find the default value and then do 43113bc21d0aSAruna Ramakrishna - Sun Microsystems * a setprop to reset the value to default. 431213a55820Sar224390 */ 43134ac67f02SAnurag S. Maskey status = pdp->pd_get(handle, pdp, linkid, prop_vals, &cnt, media, 43140dc2366fSVenugopal Iyer DLD_PROP_DEFAULT, &perm_flags); 43154045d941Ssowmini if (status == DLADM_STATUS_OK) { 4316afdda45fSVasumathi Sundaram - Sun Microsystems if (perm_flags == MAC_PROP_PERM_RW) { 43174ac67f02SAnurag S. Maskey status = i_dladm_set_single_prop(handle, linkid, 43184ac67f02SAnurag S. Maskey pdp->pd_class, media, pdp, prop_vals, cnt, flags); 43194045d941Ssowmini } 4320afdda45fSVasumathi Sundaram - Sun Microsystems else 4321afdda45fSVasumathi Sundaram - Sun Microsystems status = DLADM_STATUS_NOTSUP; 4322afdda45fSVasumathi Sundaram - Sun Microsystems } 43234045d941Ssowmini free(buf); 4324e7801d59Ssowmini return (status); 4325e7801d59Ssowmini } 4326bcb5c89dSSowmini Varadhan 43274eaa4710SRishi Srivatsavai /* ARGSUSED */ 43284eaa4710SRishi Srivatsavai static dladm_status_t 43290dc2366fSVenugopal Iyer get_stp(dladm_handle_t handle, struct prop_desc *pd, datalink_id_t linkid, 43304eaa4710SRishi Srivatsavai char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, 43314eaa4710SRishi Srivatsavai uint_t *perm_flags) 43324eaa4710SRishi Srivatsavai { 43334eaa4710SRishi Srivatsavai const bridge_public_prop_t *bpp; 43344eaa4710SRishi Srivatsavai dladm_status_t retv; 43354eaa4710SRishi Srivatsavai int val, i; 43364eaa4710SRishi Srivatsavai 43374eaa4710SRishi Srivatsavai if (flags != 0) 43384eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 43394eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 43404eaa4710SRishi Srivatsavai *val_cnt = 1; 43414eaa4710SRishi Srivatsavai for (bpp = bridge_prop; bpp->bpp_name != NULL; bpp++) 43424eaa4710SRishi Srivatsavai if (strcmp(bpp->bpp_name, pd->pd_name) == 0) 43434eaa4710SRishi Srivatsavai break; 43444eaa4710SRishi Srivatsavai retv = dladm_bridge_get_port_cfg(handle, linkid, bpp->bpp_code, &val); 43454eaa4710SRishi Srivatsavai /* If the daemon isn't running, then return the persistent value */ 43464eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 43474eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 43484eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 43494eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 43504eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 43514eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43524eaa4710SRishi Srivatsavai } 43534eaa4710SRishi Srivatsavai if (retv != DLADM_STATUS_OK) { 43544eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 43554eaa4710SRishi Srivatsavai return (retv); 43564eaa4710SRishi Srivatsavai } 43574eaa4710SRishi Srivatsavai if (val == pd->pd_defval.vd_val && pd->pd_defval.vd_name[0] != '\0') { 43584eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 43594eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 43604eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43614eaa4710SRishi Srivatsavai } 43624eaa4710SRishi Srivatsavai for (i = 0; i < pd->pd_noptval; i++) { 43634eaa4710SRishi Srivatsavai if (val == pd->pd_optval[i].vd_val) { 43644eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_optval[i].vd_name, 43654eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 43664eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43674eaa4710SRishi Srivatsavai } 43684eaa4710SRishi Srivatsavai } 43694eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", (unsigned)val); 43704eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43714eaa4710SRishi Srivatsavai } 43724eaa4710SRishi Srivatsavai 43734eaa4710SRishi Srivatsavai /* ARGSUSED1 */ 43744eaa4710SRishi Srivatsavai static dladm_status_t 43754eaa4710SRishi Srivatsavai set_stp_prop(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 43764eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 43774eaa4710SRishi Srivatsavai { 43784eaa4710SRishi Srivatsavai /* 43794eaa4710SRishi Srivatsavai * Special case for mcheck: the daemon resets the value to zero, and we 43804eaa4710SRishi Srivatsavai * don't want the daemon to refresh itself; it leads to deadlock. 43814eaa4710SRishi Srivatsavai */ 43824eaa4710SRishi Srivatsavai if (flags & DLADM_OPT_NOREFRESH) 43834eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 43844eaa4710SRishi Srivatsavai 43854eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 43864eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 43874eaa4710SRishi Srivatsavai } 43884eaa4710SRishi Srivatsavai 43894eaa4710SRishi Srivatsavai /* 43904eaa4710SRishi Srivatsavai * This is used only for stp_priority, stp_cost, and stp_mcheck. 43914eaa4710SRishi Srivatsavai */ 43924eaa4710SRishi Srivatsavai /* ARGSUSED */ 43934eaa4710SRishi Srivatsavai static dladm_status_t 43944eaa4710SRishi Srivatsavai check_stp_prop(dladm_handle_t handle, struct prop_desc *pd, 4395c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 4396c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 43974eaa4710SRishi Srivatsavai { 43984eaa4710SRishi Srivatsavai char *cp; 43994eaa4710SRishi Srivatsavai boolean_t iscost; 4400c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 4401c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 44024eaa4710SRishi Srivatsavai 44034eaa4710SRishi Srivatsavai if (val_cnt != 1) 44044eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 44054eaa4710SRishi Srivatsavai 44064eaa4710SRishi Srivatsavai if (prop_val == NULL) { 44074eaa4710SRishi Srivatsavai vdp->vd_val = 0; 44084eaa4710SRishi Srivatsavai } else { 44094eaa4710SRishi Srivatsavai /* Only stp_priority and stp_cost use this function */ 44104eaa4710SRishi Srivatsavai iscost = strcmp(pd->pd_name, "stp_cost") == 0; 44114eaa4710SRishi Srivatsavai 44124eaa4710SRishi Srivatsavai if (iscost && strcmp(prop_val[0], "auto") == 0) { 44134eaa4710SRishi Srivatsavai /* Illegal value 0 is allowed to mean "automatic" */ 44144eaa4710SRishi Srivatsavai vdp->vd_val = 0; 44154eaa4710SRishi Srivatsavai } else { 44164eaa4710SRishi Srivatsavai errno = 0; 44174eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 44184eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 44194eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 44204eaa4710SRishi Srivatsavai } 44214eaa4710SRishi Srivatsavai } 44224eaa4710SRishi Srivatsavai 44234eaa4710SRishi Srivatsavai if (iscost) { 44244eaa4710SRishi Srivatsavai return (vdp->vd_val > 65535 ? DLADM_STATUS_BADVAL : 44254eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 44264eaa4710SRishi Srivatsavai } else { 44274eaa4710SRishi Srivatsavai if (vdp->vd_val > 255) 44284eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 44294eaa4710SRishi Srivatsavai /* 44304eaa4710SRishi Srivatsavai * If the user is setting stp_mcheck non-zero, then (per the 44314eaa4710SRishi Srivatsavai * IEEE management standards and UNH testing) we need to check 44324eaa4710SRishi Srivatsavai * whether this link is part of a bridge that is running RSTP. 44334eaa4710SRishi Srivatsavai * If it's not, then setting the flag is an error. Note that 44344eaa4710SRishi Srivatsavai * errors are intentionally discarded here; it's the value 44354eaa4710SRishi Srivatsavai * that's the problem -- it's not a bad value, merely one that 44364eaa4710SRishi Srivatsavai * can't be used now. 44374eaa4710SRishi Srivatsavai */ 44384eaa4710SRishi Srivatsavai if (strcmp(pd->pd_name, "stp_mcheck") == 0 && 44394eaa4710SRishi Srivatsavai vdp->vd_val != 0) { 44404eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 44414eaa4710SRishi Srivatsavai UID_STP_CFG_T cfg; 44424eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot; 44434eaa4710SRishi Srivatsavai 44444eaa4710SRishi Srivatsavai if (dladm_bridge_getlink(handle, linkid, bridge, 44454eaa4710SRishi Srivatsavai sizeof (bridge)) != DLADM_STATUS_OK || 44464eaa4710SRishi Srivatsavai dladm_bridge_get_properties(bridge, &cfg, 44474eaa4710SRishi Srivatsavai &brprot) != DLADM_STATUS_OK) 44484eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 44494eaa4710SRishi Srivatsavai if (cfg.force_version <= 1) 44504eaa4710SRishi Srivatsavai return (DLADM_STATUS_FAILED); 44514eaa4710SRishi Srivatsavai } 44524eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 44534eaa4710SRishi Srivatsavai } 44544eaa4710SRishi Srivatsavai } 44554eaa4710SRishi Srivatsavai 44564eaa4710SRishi Srivatsavai /* ARGSUSED */ 44574eaa4710SRishi Srivatsavai static dladm_status_t 44584eaa4710SRishi Srivatsavai get_bridge_forward(dladm_handle_t handle, struct prop_desc *pd, 44594eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 44604eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 44614eaa4710SRishi Srivatsavai { 44624eaa4710SRishi Srivatsavai dladm_status_t retv; 44634eaa4710SRishi Srivatsavai uint_t val; 44644eaa4710SRishi Srivatsavai 44654eaa4710SRishi Srivatsavai if (flags != 0) 44664eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 44674eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 44684eaa4710SRishi Srivatsavai *val_cnt = 1; 44694eaa4710SRishi Srivatsavai retv = dladm_bridge_get_forwarding(handle, linkid, &val); 44704eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_NOTFOUND) { 44714eaa4710SRishi Srivatsavai if (i_dladm_get_linkprop_db(handle, linkid, pd->pd_name, 44724eaa4710SRishi Srivatsavai prop_val, val_cnt) != DLADM_STATUS_OK) 44734eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, pd->pd_defval.vd_name, 44744eaa4710SRishi Srivatsavai DLADM_PROP_VAL_MAX); 44754eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 44764eaa4710SRishi Srivatsavai } 44774eaa4710SRishi Srivatsavai if (retv == DLADM_STATUS_OK) 44784eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", val); 44794eaa4710SRishi Srivatsavai else 44804eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 44814eaa4710SRishi Srivatsavai return (retv); 44824eaa4710SRishi Srivatsavai } 44834eaa4710SRishi Srivatsavai 44844eaa4710SRishi Srivatsavai /* ARGSUSED */ 44854eaa4710SRishi Srivatsavai static dladm_status_t 44864eaa4710SRishi Srivatsavai set_bridge_forward(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 44874eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 44884eaa4710SRishi Srivatsavai { 44894eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 44904eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 44914eaa4710SRishi Srivatsavai } 44924eaa4710SRishi Srivatsavai 44934eaa4710SRishi Srivatsavai /* ARGSUSED */ 44944eaa4710SRishi Srivatsavai static dladm_status_t 44954eaa4710SRishi Srivatsavai get_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 44964eaa4710SRishi Srivatsavai datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 44974eaa4710SRishi Srivatsavai datalink_media_t media, uint_t flags, uint_t *perm_flags) 44984eaa4710SRishi Srivatsavai { 44994eaa4710SRishi Srivatsavai dladm_status_t status; 45004eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 45014eaa4710SRishi Srivatsavai uint16_t pvid; 45024eaa4710SRishi Srivatsavai 45034eaa4710SRishi Srivatsavai if (flags != 0) 45044eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTSUP); 45054eaa4710SRishi Srivatsavai *perm_flags = MAC_PROP_PERM_RW; 45064eaa4710SRishi Srivatsavai *val_cnt = 1; 45074eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 45084eaa4710SRishi Srivatsavai 0, &status); 45094eaa4710SRishi Srivatsavai if (dip == NULL) 45104eaa4710SRishi Srivatsavai return (status); 45114eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_FALSE); 45124eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 45134eaa4710SRishi Srivatsavai (void) memcpy(&pvid, dip->pr_val, sizeof (pvid)); 45144eaa4710SRishi Srivatsavai (void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%u", pvid); 45154eaa4710SRishi Srivatsavai } else { 45164eaa4710SRishi Srivatsavai (void) strlcpy(*prop_val, "?", DLADM_PROP_VAL_MAX); 45174eaa4710SRishi Srivatsavai } 45184eaa4710SRishi Srivatsavai free(dip); 45194eaa4710SRishi Srivatsavai return (status); 45204eaa4710SRishi Srivatsavai } 45214eaa4710SRishi Srivatsavai 45224eaa4710SRishi Srivatsavai /* ARGSUSED */ 45234eaa4710SRishi Srivatsavai static dladm_status_t 45244eaa4710SRishi Srivatsavai set_bridge_pvid(dladm_handle_t handle, prop_desc_t *pd, datalink_id_t linkid, 45254eaa4710SRishi Srivatsavai val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) 45264eaa4710SRishi Srivatsavai { 45274eaa4710SRishi Srivatsavai dladm_status_t status; 45284eaa4710SRishi Srivatsavai dld_ioc_macprop_t *dip; 45294eaa4710SRishi Srivatsavai uint16_t pvid; 45304eaa4710SRishi Srivatsavai 45314eaa4710SRishi Srivatsavai dip = i_dladm_buf_alloc_by_id(sizeof (uint16_t), linkid, MAC_PROP_PVID, 45324eaa4710SRishi Srivatsavai 0, &status); 45334eaa4710SRishi Srivatsavai if (dip == NULL) 45344eaa4710SRishi Srivatsavai return (status); 45354eaa4710SRishi Srivatsavai pvid = vdp->vd_val; 45364eaa4710SRishi Srivatsavai (void) memcpy(dip->pr_val, &pvid, sizeof (pvid)); 45374eaa4710SRishi Srivatsavai status = i_dladm_macprop(handle, dip, B_TRUE); 45384eaa4710SRishi Srivatsavai free(dip); 45394eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 45404eaa4710SRishi Srivatsavai return (status); 45414eaa4710SRishi Srivatsavai 45424eaa4710SRishi Srivatsavai /* Tell the running daemon, if any */ 45434eaa4710SRishi Srivatsavai return (dladm_bridge_refresh(handle, linkid)); 45444eaa4710SRishi Srivatsavai } 45454eaa4710SRishi Srivatsavai 45464eaa4710SRishi Srivatsavai /* ARGSUSED */ 45474eaa4710SRishi Srivatsavai static dladm_status_t 45484eaa4710SRishi Srivatsavai check_bridge_pvid(dladm_handle_t handle, struct prop_desc *pd, 4549c569ef53SMichael Lim datalink_id_t linkid, char **prop_val, uint_t *val_cntp, uint_t flags, 4550c569ef53SMichael Lim val_desc_t **vdpp, datalink_media_t media) 45514eaa4710SRishi Srivatsavai { 45524eaa4710SRishi Srivatsavai char *cp; 4553c569ef53SMichael Lim uint_t val_cnt = *val_cntp; 4554c569ef53SMichael Lim val_desc_t *vdp = *vdpp; 45554eaa4710SRishi Srivatsavai 45564eaa4710SRishi Srivatsavai if (val_cnt != 1) 45574eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVALCNT); 45584eaa4710SRishi Srivatsavai 45594eaa4710SRishi Srivatsavai if (prop_val == NULL) { 45604eaa4710SRishi Srivatsavai vdp->vd_val = 1; 45614eaa4710SRishi Srivatsavai } else { 45624eaa4710SRishi Srivatsavai errno = 0; 45634eaa4710SRishi Srivatsavai vdp->vd_val = strtoul(prop_val[0], &cp, 0); 45644eaa4710SRishi Srivatsavai if (errno != 0 || *cp != '\0') 45654eaa4710SRishi Srivatsavai return (DLADM_STATUS_BADVAL); 45664eaa4710SRishi Srivatsavai } 45674eaa4710SRishi Srivatsavai 45684eaa4710SRishi Srivatsavai return (vdp->vd_val > VLAN_ID_MAX ? DLADM_STATUS_BADVAL : 45694eaa4710SRishi Srivatsavai DLADM_STATUS_OK); 45704eaa4710SRishi Srivatsavai } 45714eaa4710SRishi Srivatsavai 4572bcb5c89dSSowmini Varadhan dladm_status_t 45734ac67f02SAnurag S. Maskey i_dladm_wlan_param(dladm_handle_t handle, datalink_id_t linkid, void *buf, 45744ac67f02SAnurag S. Maskey mac_prop_id_t cmd, size_t len, boolean_t set) 4575bcb5c89dSSowmini Varadhan { 4576bcb5c89dSSowmini Varadhan uint32_t flags; 4577bcb5c89dSSowmini Varadhan dladm_status_t status; 4578bcb5c89dSSowmini Varadhan uint32_t media; 4579bcb5c89dSSowmini Varadhan dld_ioc_macprop_t *dip; 4580bcb5c89dSSowmini Varadhan void *dp; 4581bcb5c89dSSowmini Varadhan 45824ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 45834ac67f02SAnurag S. Maskey &media, NULL, 0)) != DLADM_STATUS_OK) { 4584bcb5c89dSSowmini Varadhan return (status); 4585bcb5c89dSSowmini Varadhan } 4586bcb5c89dSSowmini Varadhan 4587bcb5c89dSSowmini Varadhan if (media != DL_WIFI) 4588bcb5c89dSSowmini Varadhan return (DLADM_STATUS_BADARG); 4589bcb5c89dSSowmini Varadhan 4590bcb5c89dSSowmini Varadhan if (!(flags & DLADM_OPT_ACTIVE)) 4591bcb5c89dSSowmini Varadhan return (DLADM_STATUS_TEMPONLY); 4592bcb5c89dSSowmini Varadhan 4593bcb5c89dSSowmini Varadhan if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) 4594bcb5c89dSSowmini Varadhan len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; 4595bcb5c89dSSowmini Varadhan 4596bcb5c89dSSowmini Varadhan dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); 4597bcb5c89dSSowmini Varadhan if (dip == NULL) 4598bcb5c89dSSowmini Varadhan return (DLADM_STATUS_NOMEM); 4599bcb5c89dSSowmini Varadhan 4600bcb5c89dSSowmini Varadhan dp = (uchar_t *)dip->pr_val; 4601bcb5c89dSSowmini Varadhan if (set) 4602bcb5c89dSSowmini Varadhan (void) memcpy(dp, buf, len); 4603bcb5c89dSSowmini Varadhan 46044ac67f02SAnurag S. Maskey status = i_dladm_macprop(handle, dip, set); 46050b8f0546SSowmini Varadhan if (status == DLADM_STATUS_OK) { 4606bcb5c89dSSowmini Varadhan if (!set) 4607bcb5c89dSSowmini Varadhan (void) memcpy(buf, dp, len); 4608bcb5c89dSSowmini Varadhan } 4609bcb5c89dSSowmini Varadhan 4610bcb5c89dSSowmini Varadhan free(dip); 4611bcb5c89dSSowmini Varadhan return (status); 4612bcb5c89dSSowmini Varadhan } 4613bcb5c89dSSowmini Varadhan 4614da14cebeSEric Cheng dladm_status_t 4615da14cebeSEric Cheng dladm_parse_link_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 4616da14cebeSEric Cheng { 461762ee1d25SArtem Kachitchkine return (dladm_parse_args(str, listp, novalues)); 4618da14cebeSEric Cheng } 4619da14cebeSEric Cheng 4620da14cebeSEric Cheng /* 4621da14cebeSEric Cheng * Retrieve the one link property from the database 4622da14cebeSEric Cheng */ 4623da14cebeSEric Cheng /*ARGSUSED*/ 4624da14cebeSEric Cheng static int 46254ac67f02SAnurag S. Maskey i_dladm_get_one_prop(dladm_handle_t handle, datalink_id_t linkid, 46264ac67f02SAnurag S. Maskey const char *prop_name, void *arg) 4627da14cebeSEric Cheng { 4628da14cebeSEric Cheng dladm_arg_list_t *proplist = arg; 4629da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4630da14cebeSEric Cheng 4631da14cebeSEric Cheng aip = &proplist->al_info[proplist->al_count]; 4632da14cebeSEric Cheng /* 4633da14cebeSEric Cheng * it is fine to point to prop_name since prop_name points to the 4634da14cebeSEric Cheng * prop_table[n].pd_name. 4635da14cebeSEric Cheng */ 4636da14cebeSEric Cheng aip->ai_name = prop_name; 4637da14cebeSEric Cheng 46384ac67f02SAnurag S. Maskey (void) dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_PERSISTENT, 46394ac67f02SAnurag S. Maskey prop_name, aip->ai_val, &aip->ai_count); 4640da14cebeSEric Cheng 4641da14cebeSEric Cheng if (aip->ai_count != 0) 4642da14cebeSEric Cheng proplist->al_count++; 4643da14cebeSEric Cheng 4644da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 4645da14cebeSEric Cheng } 4646da14cebeSEric Cheng 4647da14cebeSEric Cheng 4648da14cebeSEric Cheng /* 4649da14cebeSEric Cheng * Retrieve all link properties for a link from the database and 4650da14cebeSEric Cheng * return a property list. 4651da14cebeSEric Cheng */ 4652da14cebeSEric Cheng dladm_status_t 46534ac67f02SAnurag S. Maskey dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, 46544ac67f02SAnurag S. Maskey dladm_arg_list_t **listp) 4655da14cebeSEric Cheng { 4656da14cebeSEric Cheng dladm_arg_list_t *list; 4657da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 4658da14cebeSEric Cheng 4659da14cebeSEric Cheng list = calloc(1, sizeof (dladm_arg_list_t)); 4660da14cebeSEric Cheng if (list == NULL) 4661da14cebeSEric Cheng return (dladm_errno2status(errno)); 4662da14cebeSEric Cheng 46634ac67f02SAnurag S. Maskey status = dladm_walk_linkprop(handle, linkid, list, 46644ac67f02SAnurag S. Maskey i_dladm_get_one_prop); 4665da14cebeSEric Cheng 4666da14cebeSEric Cheng *listp = list; 4667da14cebeSEric Cheng return (status); 4668da14cebeSEric Cheng } 4669da14cebeSEric Cheng 4670da14cebeSEric Cheng /* 4671da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 4672da14cebeSEric Cheng * convert to a kernel structure. 4673da14cebeSEric Cheng */ 4674da14cebeSEric Cheng static dladm_status_t 46754ac67f02SAnurag S. Maskey i_dladm_link_proplist_extract_one(dladm_handle_t handle, 46760dc2366fSVenugopal Iyer dladm_arg_list_t *proplist, const char *name, uint_t flags, void *arg) 4677da14cebeSEric Cheng { 4678da14cebeSEric Cheng dladm_status_t status; 4679da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 4680da14cebeSEric Cheng int i, j; 4681da14cebeSEric Cheng 4682da14cebeSEric Cheng /* Find named property in proplist */ 4683da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 4684da14cebeSEric Cheng aip = &proplist->al_info[i]; 4685da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 4686da14cebeSEric Cheng break; 4687da14cebeSEric Cheng } 4688da14cebeSEric Cheng 4689da14cebeSEric Cheng /* Property not in list */ 4690da14cebeSEric Cheng if (i == proplist->al_count) 4691da14cebeSEric Cheng return (DLADM_STATUS_OK); 4692da14cebeSEric Cheng 4693da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_PROPS; i++) { 4694da14cebeSEric Cheng prop_desc_t *pdp = &prop_table[i]; 4695da14cebeSEric Cheng val_desc_t *vdp; 4696da14cebeSEric Cheng 4697da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 4698da14cebeSEric Cheng if (vdp == NULL) 4699da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 4700da14cebeSEric Cheng 4701da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 4702da14cebeSEric Cheng continue; 4703da14cebeSEric Cheng 4704da14cebeSEric Cheng if (aip->ai_val == NULL) 4705da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 4706da14cebeSEric Cheng 4707da14cebeSEric Cheng /* Check property value */ 4708da14cebeSEric Cheng if (pdp->pd_check != NULL) { 47094ac67f02SAnurag S. Maskey status = pdp->pd_check(handle, pdp, 0, aip->ai_val, 4710c569ef53SMichael Lim &(aip->ai_count), flags, &vdp, 0); 4711da14cebeSEric Cheng } else { 4712da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4713da14cebeSEric Cheng } 4714da14cebeSEric Cheng 4715da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4716da14cebeSEric Cheng return (status); 4717da14cebeSEric Cheng 4718da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 4719da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 4720da14cebeSEric Cheng 4721da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 4722da14cebeSEric Cheng continue; 4723da14cebeSEric Cheng 4724da14cebeSEric Cheng /* Extract kernel structure */ 4725da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 472625ec3e3dSEric Cheng status = rpp->rp_extract(vdp, 472725ec3e3dSEric Cheng aip->ai_count, arg); 4728da14cebeSEric Cheng } else { 4729da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 4730da14cebeSEric Cheng } 4731da14cebeSEric Cheng break; 4732da14cebeSEric Cheng } 4733da14cebeSEric Cheng 4734da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4735da14cebeSEric Cheng return (status); 4736da14cebeSEric Cheng 4737da14cebeSEric Cheng break; 4738da14cebeSEric Cheng } 4739da14cebeSEric Cheng return (status); 4740da14cebeSEric Cheng } 4741da14cebeSEric Cheng 4742da14cebeSEric Cheng /* 4743da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 4744da14cebeSEric Cheng */ 4745da14cebeSEric Cheng dladm_status_t 47464ac67f02SAnurag S. Maskey dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, 47470dc2366fSVenugopal Iyer mac_resource_props_t *mrp, uint_t flags) 4748da14cebeSEric Cheng { 474925ec3e3dSEric Cheng dladm_status_t status; 475025ec3e3dSEric Cheng int i; 4751da14cebeSEric Cheng 475225ec3e3dSEric Cheng for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { 475325ec3e3dSEric Cheng status = i_dladm_link_proplist_extract_one(handle, 47540dc2366fSVenugopal Iyer proplist, rsrc_prop_table[i].rp_name, flags, mrp); 4755da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4756da14cebeSEric Cheng return (status); 475725ec3e3dSEric Cheng } 4758da14cebeSEric Cheng return (status); 4759da14cebeSEric Cheng } 4760da14cebeSEric Cheng 4761da14cebeSEric Cheng static const char * 4762da14cebeSEric Cheng dladm_perm2str(uint_t perm, char *buf) 4763da14cebeSEric Cheng { 4764da14cebeSEric Cheng (void) snprintf(buf, DLADM_STRSIZE, "%c%c", 4765da14cebeSEric Cheng ((perm & MAC_PROP_PERM_READ) != 0) ? 'r' : '-', 4766da14cebeSEric Cheng ((perm & MAC_PROP_PERM_WRITE) != 0) ? 'w' : '-'); 4767da14cebeSEric Cheng return (buf); 4768da14cebeSEric Cheng } 47694784fcbdSSowmini Varadhan 47704784fcbdSSowmini Varadhan dladm_status_t 47710dc2366fSVenugopal Iyer dladm_get_state(dladm_handle_t handle, datalink_id_t linkid, 47724ac67f02SAnurag S. Maskey link_state_t *state) 47734784fcbdSSowmini Varadhan { 47744784fcbdSSowmini Varadhan uint_t perms; 47754784fcbdSSowmini Varadhan 47760dc2366fSVenugopal Iyer return (i_dladm_get_public_prop(handle, linkid, "state", 0, 47770dc2366fSVenugopal Iyer &perms, state, sizeof (*state))); 47784784fcbdSSowmini Varadhan } 477962ee1d25SArtem Kachitchkine 478062ee1d25SArtem Kachitchkine boolean_t 478162ee1d25SArtem Kachitchkine dladm_attr_is_linkprop(const char *name) 478262ee1d25SArtem Kachitchkine { 478362ee1d25SArtem Kachitchkine /* non-property attribute names */ 478462ee1d25SArtem Kachitchkine const char *nonprop[] = { 478562ee1d25SArtem Kachitchkine /* dlmgmtd core attributes */ 478662ee1d25SArtem Kachitchkine "name", 478762ee1d25SArtem Kachitchkine "class", 478862ee1d25SArtem Kachitchkine "media", 478962ee1d25SArtem Kachitchkine FPHYMAJ, 479062ee1d25SArtem Kachitchkine FPHYINST, 479162ee1d25SArtem Kachitchkine FDEVNAME, 479262ee1d25SArtem Kachitchkine 479362ee1d25SArtem Kachitchkine /* other attributes for vlan, aggr, etc */ 479462ee1d25SArtem Kachitchkine DLADM_ATTR_NAMES 479562ee1d25SArtem Kachitchkine }; 479662ee1d25SArtem Kachitchkine boolean_t is_nonprop = B_FALSE; 479762ee1d25SArtem Kachitchkine int i; 479862ee1d25SArtem Kachitchkine 479962ee1d25SArtem Kachitchkine for (i = 0; i < sizeof (nonprop) / sizeof (nonprop[0]); i++) { 480062ee1d25SArtem Kachitchkine if (strcmp(name, nonprop[i]) == 0) { 480162ee1d25SArtem Kachitchkine is_nonprop = B_TRUE; 480262ee1d25SArtem Kachitchkine break; 480362ee1d25SArtem Kachitchkine } 480462ee1d25SArtem Kachitchkine } 480562ee1d25SArtem Kachitchkine 480662ee1d25SArtem Kachitchkine return (!is_nonprop); 480762ee1d25SArtem Kachitchkine } 48080dc2366fSVenugopal Iyer 48090dc2366fSVenugopal Iyer dladm_status_t 48100dc2366fSVenugopal Iyer dladm_linkprop_is_set(dladm_handle_t handle, datalink_id_t linkid, 48110dc2366fSVenugopal Iyer dladm_prop_type_t type, const char *prop_name, boolean_t *is_set) 48120dc2366fSVenugopal Iyer { 48130dc2366fSVenugopal Iyer char *buf, **propvals; 48140dc2366fSVenugopal Iyer uint_t valcnt = DLADM_MAX_PROP_VALCNT; 48150dc2366fSVenugopal Iyer int i; 48160dc2366fSVenugopal Iyer dladm_status_t status = DLADM_STATUS_OK; 4817550b6e40SSowmini Varadhan size_t bufsize; 48180dc2366fSVenugopal Iyer 48190dc2366fSVenugopal Iyer *is_set = B_FALSE; 48200dc2366fSVenugopal Iyer 4821550b6e40SSowmini Varadhan bufsize = (sizeof (char *) + DLADM_PROP_VAL_MAX) * 4822550b6e40SSowmini Varadhan DLADM_MAX_PROP_VALCNT; 4823550b6e40SSowmini Varadhan if ((buf = calloc(1, bufsize)) == NULL) 48240dc2366fSVenugopal Iyer return (DLADM_STATUS_NOMEM); 48250dc2366fSVenugopal Iyer 48260dc2366fSVenugopal Iyer propvals = (char **)(void *)buf; 48270dc2366fSVenugopal Iyer for (i = 0; i < valcnt; i++) { 48280dc2366fSVenugopal Iyer propvals[i] = buf + 48290dc2366fSVenugopal Iyer sizeof (char *) * DLADM_MAX_PROP_VALCNT + 48300dc2366fSVenugopal Iyer i * DLADM_PROP_VAL_MAX; 48310dc2366fSVenugopal Iyer } 48320dc2366fSVenugopal Iyer 48330dc2366fSVenugopal Iyer if (dladm_get_linkprop(handle, linkid, type, prop_name, propvals, 48340dc2366fSVenugopal Iyer &valcnt) != DLADM_STATUS_OK) { 48350dc2366fSVenugopal Iyer goto done; 48360dc2366fSVenugopal Iyer } 48370dc2366fSVenugopal Iyer 4838550b6e40SSowmini Varadhan /* 4839550b6e40SSowmini Varadhan * valcnt is always set to 1 by get_pool(), hence we need to check 48401a41ca23SJerry Jelinek * for a non-null string to see if it is set. For protection, 48411a41ca23SJerry Jelinek * secondary-macs and allowed-ips, we can check either the *propval 48421a41ca23SJerry Jelinek * or the valcnt. 4843550b6e40SSowmini Varadhan */ 4844550b6e40SSowmini Varadhan if ((strcmp(prop_name, "pool") == 0 || 4845550b6e40SSowmini Varadhan strcmp(prop_name, "protection") == 0 || 48461a41ca23SJerry Jelinek strcmp(prop_name, "secondary-macs") == 0 || 4847550b6e40SSowmini Varadhan strcmp(prop_name, "allowed-ips") == 0) && 4848550b6e40SSowmini Varadhan (strlen(*propvals) != 0)) { 48490dc2366fSVenugopal Iyer *is_set = B_TRUE; 48500dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "cpus") == 0) && (valcnt != 0)) { 48510dc2366fSVenugopal Iyer *is_set = B_TRUE; 48520dc2366fSVenugopal Iyer } else if ((strcmp(prop_name, "_softmac") == 0) && (valcnt != 0) && 48530dc2366fSVenugopal Iyer (strcmp(propvals[0], "true") == 0)) { 48540dc2366fSVenugopal Iyer *is_set = B_TRUE; 48550dc2366fSVenugopal Iyer } 48560dc2366fSVenugopal Iyer 48570dc2366fSVenugopal Iyer done: 48580dc2366fSVenugopal Iyer if (buf != NULL) 48590dc2366fSVenugopal Iyer free(buf); 48600dc2366fSVenugopal Iyer return (status); 48610dc2366fSVenugopal Iyer } 48621cfa752fSRamaswamy Tummala 48631cfa752fSRamaswamy Tummala /* ARGSUSED */ 48641cfa752fSRamaswamy Tummala static dladm_status_t 48651cfa752fSRamaswamy Tummala get_linkmode_prop(dladm_handle_t handle, prop_desc_t *pdp, 48661cfa752fSRamaswamy Tummala datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 48671cfa752fSRamaswamy Tummala datalink_media_t media, uint_t flags, uint_t *perm_flags) 48681cfa752fSRamaswamy Tummala { 48691cfa752fSRamaswamy Tummala char *s; 48701cfa752fSRamaswamy Tummala uint32_t v; 48711cfa752fSRamaswamy Tummala dladm_status_t status; 48721cfa752fSRamaswamy Tummala 48731cfa752fSRamaswamy Tummala status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 48741cfa752fSRamaswamy Tummala perm_flags, &v, sizeof (v)); 48751cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 48761cfa752fSRamaswamy Tummala return (status); 48771cfa752fSRamaswamy Tummala 48781cfa752fSRamaswamy Tummala switch (v) { 4879c87dd6b7SRajkumar Sivaprakasam case DLADM_PART_CM_MODE: 48801cfa752fSRamaswamy Tummala s = "cm"; 48811cfa752fSRamaswamy Tummala break; 4882c87dd6b7SRajkumar Sivaprakasam case DLADM_PART_UD_MODE: 48831cfa752fSRamaswamy Tummala s = "ud"; 48841cfa752fSRamaswamy Tummala break; 48851cfa752fSRamaswamy Tummala default: 48861cfa752fSRamaswamy Tummala s = ""; 48871cfa752fSRamaswamy Tummala break; 48881cfa752fSRamaswamy Tummala } 48891cfa752fSRamaswamy Tummala (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); 48901cfa752fSRamaswamy Tummala 48911cfa752fSRamaswamy Tummala *val_cnt = 1; 48921cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 48931cfa752fSRamaswamy Tummala } 4894098d2c75SRobert Mustacchi 4895098d2c75SRobert Mustacchi /*ARGSUSED*/ 4896098d2c75SRobert Mustacchi static dladm_status_t 4897098d2c75SRobert Mustacchi get_promisc_filtered(dladm_handle_t handle, prop_desc_t *pdp, 4898098d2c75SRobert Mustacchi datalink_id_t linkid, char **prop_val, uint_t *val_cnt, 4899098d2c75SRobert Mustacchi datalink_media_t media, uint_t flags, uint_t *perm_flags) 4900098d2c75SRobert Mustacchi { 4901098d2c75SRobert Mustacchi char *s; 4902098d2c75SRobert Mustacchi dladm_status_t status; 4903098d2c75SRobert Mustacchi boolean_t filt; 4904098d2c75SRobert Mustacchi 4905098d2c75SRobert Mustacchi status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, 4906098d2c75SRobert Mustacchi perm_flags, &filt, sizeof (filt)); 4907098d2c75SRobert Mustacchi if (status != DLADM_STATUS_OK) 4908098d2c75SRobert Mustacchi return (status); 4909098d2c75SRobert Mustacchi 4910098d2c75SRobert Mustacchi if (filt != 0) 4911098d2c75SRobert Mustacchi s = link_promisc_filtered_vals[1].vd_name; 4912098d2c75SRobert Mustacchi else 4913098d2c75SRobert Mustacchi s = link_promisc_filtered_vals[0].vd_name; 4914098d2c75SRobert Mustacchi (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); 4915098d2c75SRobert Mustacchi 4916098d2c75SRobert Mustacchi *val_cnt = 1; 4917098d2c75SRobert Mustacchi return (DLADM_STATUS_OK); 4918098d2c75SRobert Mustacchi } 4919098d2c75SRobert Mustacchi 4920098d2c75SRobert Mustacchi /* ARGSUSED */ 4921098d2c75SRobert Mustacchi static dladm_status_t 4922098d2c75SRobert Mustacchi set_promisc_filtered(dladm_handle_t handle, prop_desc_t *pdp, 4923098d2c75SRobert Mustacchi datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, 4924098d2c75SRobert Mustacchi datalink_media_t media) 4925098d2c75SRobert Mustacchi { 4926098d2c75SRobert Mustacchi dld_ioc_macprop_t *dip; 4927098d2c75SRobert Mustacchi dladm_status_t status = DLADM_STATUS_OK; 4928098d2c75SRobert Mustacchi 4929098d2c75SRobert Mustacchi dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, 4930098d2c75SRobert Mustacchi 0, &status); 4931098d2c75SRobert Mustacchi 4932098d2c75SRobert Mustacchi if (dip == NULL) 4933098d2c75SRobert Mustacchi return (status); 4934098d2c75SRobert Mustacchi 4935098d2c75SRobert Mustacchi (void) memcpy(dip->pr_val, &vdp->vd_val, dip->pr_valsize); 4936098d2c75SRobert Mustacchi status = i_dladm_macprop(handle, dip, B_TRUE); 4937098d2c75SRobert Mustacchi 4938098d2c75SRobert Mustacchi free(dip); 4939098d2c75SRobert Mustacchi return (status); 4940098d2c75SRobert Mustacchi } 4941