1d62bc4baSyz147064 /* 2d62bc4baSyz147064 * CDDL HEADER START 3d62bc4baSyz147064 * 4d62bc4baSyz147064 * The contents of this file are subject to the terms of the 5d62bc4baSyz147064 * Common Development and Distribution License (the "License"). 6d62bc4baSyz147064 * You may not use this file except in compliance with the License. 7d62bc4baSyz147064 * 8d62bc4baSyz147064 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d62bc4baSyz147064 * or http://www.opensolaris.org/os/licensing. 10d62bc4baSyz147064 * See the License for the specific language governing permissions 11d62bc4baSyz147064 * and limitations under the License. 12d62bc4baSyz147064 * 13d62bc4baSyz147064 * When distributing Covered Code, include this CDDL HEADER in each 14d62bc4baSyz147064 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d62bc4baSyz147064 * If applicable, add the following below this CDDL HEADER, with the 16d62bc4baSyz147064 * fields enclosed by brackets "[]" replaced with your own identifying 17d62bc4baSyz147064 * information: Portions Copyright [yyyy] [name of copyright owner] 18d62bc4baSyz147064 * 19d62bc4baSyz147064 * CDDL HEADER END 20d62bc4baSyz147064 */ 21d62bc4baSyz147064 /* 22d62bc4baSyz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23d62bc4baSyz147064 * Use is subject to license terms. 24d62bc4baSyz147064 */ 25d62bc4baSyz147064 26d62bc4baSyz147064 #include <door.h> 27d62bc4baSyz147064 #include <errno.h> 28d62bc4baSyz147064 #include <assert.h> 29d62bc4baSyz147064 #include <stdio.h> 30d62bc4baSyz147064 #include <stdlib.h> 31d62bc4baSyz147064 #include <unistd.h> 32d62bc4baSyz147064 #include <string.h> 33d62bc4baSyz147064 #include <strings.h> 34d62bc4baSyz147064 #include <sys/types.h> 35d62bc4baSyz147064 #include <sys/stat.h> 36d62bc4baSyz147064 #include <sys/aggr.h> 37d62bc4baSyz147064 #include <fcntl.h> 38d62bc4baSyz147064 #include <libdladm.h> 39d62bc4baSyz147064 #include <libdladm_impl.h> 40d62bc4baSyz147064 #include <libdllink.h> 41d62bc4baSyz147064 #include <libdlmgmt.h> 42d62bc4baSyz147064 43d62bc4baSyz147064 /* 44d62bc4baSyz147064 * Table of data type sizes indexed by dladm_datatype_t. 45d62bc4baSyz147064 */ 46d62bc4baSyz147064 static size_t dladm_datatype_size[] = { 47d62bc4baSyz147064 0, /* DLADM_TYPE_STR, use strnlen() */ 48d62bc4baSyz147064 sizeof (boolean_t), /* DLADM_TYPE_BOOLEAN */ 49d62bc4baSyz147064 sizeof (uint64_t) /* DLADM_TYPE_UINT64 */ 50d62bc4baSyz147064 }; 51d62bc4baSyz147064 52d62bc4baSyz147064 static dladm_status_t 53024b0a25Sseb dladm_door_call(void *arg, size_t asize, void *rbuf, size_t rsize) 54d62bc4baSyz147064 { 55d62bc4baSyz147064 door_arg_t darg; 56d62bc4baSyz147064 int fd; 57d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 58d62bc4baSyz147064 59d62bc4baSyz147064 if ((fd = open(DLMGMT_DOOR, O_RDONLY)) == -1) 60d62bc4baSyz147064 return (dladm_errno2status(errno)); 61d62bc4baSyz147064 62d62bc4baSyz147064 darg.data_ptr = arg; 63d62bc4baSyz147064 darg.data_size = asize; 64d62bc4baSyz147064 darg.desc_ptr = NULL; 65d62bc4baSyz147064 darg.desc_num = 0; 66d62bc4baSyz147064 darg.rbuf = rbuf; 67024b0a25Sseb darg.rsize = rsize; 68d62bc4baSyz147064 69d62bc4baSyz147064 if (door_call(fd, &darg) == -1) 70d62bc4baSyz147064 status = dladm_errno2status(errno); 71d62bc4baSyz147064 (void) close(fd); 72d62bc4baSyz147064 73d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 74d62bc4baSyz147064 return (status); 75d62bc4baSyz147064 76d62bc4baSyz147064 if (darg.rbuf != rbuf) { 77d62bc4baSyz147064 /* 78d62bc4baSyz147064 * The size of the input rbuf is not big enough so that 79d62bc4baSyz147064 * the door allocate the rbuf itself. In this case, simply 80d62bc4baSyz147064 * think something wrong with the door call. 81d62bc4baSyz147064 */ 82d62bc4baSyz147064 (void) munmap(darg.rbuf, darg.rsize); 83d62bc4baSyz147064 return (DLADM_STATUS_TOOSMALL); 84d62bc4baSyz147064 } 85024b0a25Sseb if (darg.rsize != rsize) 86d62bc4baSyz147064 return (DLADM_STATUS_FAILED); 87d62bc4baSyz147064 88024b0a25Sseb return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err)); 89d62bc4baSyz147064 } 90d62bc4baSyz147064 91d62bc4baSyz147064 /* 92d62bc4baSyz147064 * Allocate a new linkid with the given name. Return the new linkid. 93d62bc4baSyz147064 */ 94d62bc4baSyz147064 dladm_status_t 95d62bc4baSyz147064 dladm_create_datalink_id(const char *link, datalink_class_t class, 96d62bc4baSyz147064 uint32_t media, uint32_t flags, datalink_id_t *linkidp) 97d62bc4baSyz147064 { 98d62bc4baSyz147064 dlmgmt_door_createid_t createid; 99d62bc4baSyz147064 dlmgmt_createid_retval_t retval; 100d62bc4baSyz147064 uint32_t dlmgmt_flags; 101d62bc4baSyz147064 dladm_status_t status; 102d62bc4baSyz147064 103024b0a25Sseb if (link == NULL || class == DATALINK_CLASS_ALL || 104d62bc4baSyz147064 !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) || 105d62bc4baSyz147064 linkidp == NULL) { 106d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 107d62bc4baSyz147064 } 108d62bc4baSyz147064 109d62bc4baSyz147064 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 110d62bc4baSyz147064 dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0; 111d62bc4baSyz147064 112d62bc4baSyz147064 (void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN); 113d62bc4baSyz147064 createid.ld_class = class; 114d62bc4baSyz147064 createid.ld_media = media; 115d62bc4baSyz147064 createid.ld_flags = dlmgmt_flags; 116d62bc4baSyz147064 createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID; 117d62bc4baSyz147064 createid.ld_prefix = (flags & DLADM_OPT_PREFIX); 118d62bc4baSyz147064 119024b0a25Sseb if ((status = dladm_door_call(&createid, sizeof (createid), &retval, 120024b0a25Sseb sizeof (retval))) == DLADM_STATUS_OK) { 121d62bc4baSyz147064 *linkidp = retval.lr_linkid; 122024b0a25Sseb } 123024b0a25Sseb return (status); 124d62bc4baSyz147064 } 125d62bc4baSyz147064 126d62bc4baSyz147064 /* 127d62bc4baSyz147064 * Destroy the given link ID. 128d62bc4baSyz147064 */ 129d62bc4baSyz147064 dladm_status_t 130d62bc4baSyz147064 dladm_destroy_datalink_id(datalink_id_t linkid, uint32_t flags) 131d62bc4baSyz147064 { 132d62bc4baSyz147064 dlmgmt_door_destroyid_t destroyid; 133d62bc4baSyz147064 dlmgmt_destroyid_retval_t retval; 134d62bc4baSyz147064 uint32_t dlmgmt_flags; 135d62bc4baSyz147064 136d62bc4baSyz147064 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 137d62bc4baSyz147064 dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); 138d62bc4baSyz147064 139d62bc4baSyz147064 destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID; 140d62bc4baSyz147064 destroyid.ld_linkid = linkid; 141d62bc4baSyz147064 destroyid.ld_flags = dlmgmt_flags; 142d62bc4baSyz147064 143024b0a25Sseb return (dladm_door_call(&destroyid, sizeof (destroyid), 144024b0a25Sseb &retval, sizeof (retval))); 145d62bc4baSyz147064 } 146d62bc4baSyz147064 147d62bc4baSyz147064 /* 148d62bc4baSyz147064 * Remap a given link ID to a new name. 149d62bc4baSyz147064 */ 150d62bc4baSyz147064 dladm_status_t 151d62bc4baSyz147064 dladm_remap_datalink_id(datalink_id_t linkid, const char *link) 152d62bc4baSyz147064 { 153d62bc4baSyz147064 dlmgmt_door_remapid_t remapid; 154d62bc4baSyz147064 dlmgmt_remapid_retval_t retval; 155d62bc4baSyz147064 156d62bc4baSyz147064 remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID; 157d62bc4baSyz147064 remapid.ld_linkid = linkid; 158d62bc4baSyz147064 (void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN); 159d62bc4baSyz147064 160024b0a25Sseb return (dladm_door_call(&remapid, sizeof (remapid), 161024b0a25Sseb &retval, sizeof (retval))); 162d62bc4baSyz147064 } 163d62bc4baSyz147064 164d62bc4baSyz147064 /* 165d62bc4baSyz147064 * Make a given link ID active. 166d62bc4baSyz147064 */ 167d62bc4baSyz147064 dladm_status_t 168d62bc4baSyz147064 dladm_up_datalink_id(datalink_id_t linkid) 169d62bc4baSyz147064 { 170d62bc4baSyz147064 dlmgmt_door_upid_t upid; 171d62bc4baSyz147064 dlmgmt_upid_retval_t retval; 172d62bc4baSyz147064 173d62bc4baSyz147064 upid.ld_cmd = DLMGMT_CMD_UP_LINKID; 174d62bc4baSyz147064 upid.ld_linkid = linkid; 175d62bc4baSyz147064 176024b0a25Sseb return (dladm_door_call(&upid, sizeof (upid), 177024b0a25Sseb &retval, sizeof (retval))); 178d62bc4baSyz147064 } 179d62bc4baSyz147064 180d62bc4baSyz147064 /* 181d62bc4baSyz147064 * Create a new link with the given name. Return the new link's handle 182d62bc4baSyz147064 */ 183d62bc4baSyz147064 dladm_status_t 184d62bc4baSyz147064 dladm_create_conf(const char *link, datalink_id_t linkid, 185d62bc4baSyz147064 datalink_class_t class, uint32_t media, dladm_conf_t *confp) 186d62bc4baSyz147064 { 187d62bc4baSyz147064 dlmgmt_door_createconf_t createconf; 188d62bc4baSyz147064 dlmgmt_createconf_retval_t retval; 189d62bc4baSyz147064 dladm_status_t status; 190d62bc4baSyz147064 191024b0a25Sseb if (link == NULL || confp == NULL) 192d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 193d62bc4baSyz147064 194d62bc4baSyz147064 (void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN); 195d62bc4baSyz147064 createconf.ld_class = class; 196d62bc4baSyz147064 createconf.ld_media = media; 197d62bc4baSyz147064 createconf.ld_linkid = linkid; 198d62bc4baSyz147064 createconf.ld_cmd = DLMGMT_CMD_CREATECONF; 199d62bc4baSyz147064 200024b0a25Sseb if ((status = dladm_door_call(&createconf, sizeof (createconf), 201024b0a25Sseb &retval, sizeof (retval))) == DLADM_STATUS_OK) { 202d62bc4baSyz147064 *confp = retval.lr_conf; 203024b0a25Sseb } 204024b0a25Sseb return (status); 205d62bc4baSyz147064 } 206d62bc4baSyz147064 207d62bc4baSyz147064 /* 208d62bc4baSyz147064 * An active physical link reported by the dlmgmtd daemon might not be active 209d62bc4baSyz147064 * anymore as this link might be removed during system shutdown. Check its 210d62bc4baSyz147064 * real status by calling dladm_phys_info(). 211d62bc4baSyz147064 */ 212d62bc4baSyz147064 dladm_status_t 213d62bc4baSyz147064 i_dladm_phys_status(datalink_id_t linkid, uint32_t *flagsp) 214d62bc4baSyz147064 { 215d62bc4baSyz147064 dladm_phys_attr_t dpa; 216d62bc4baSyz147064 dladm_status_t status; 217d62bc4baSyz147064 218d62bc4baSyz147064 assert((*flagsp) & DLMGMT_ACTIVE); 219d62bc4baSyz147064 220d62bc4baSyz147064 status = dladm_phys_info(linkid, &dpa, DLADM_OPT_ACTIVE); 221d62bc4baSyz147064 if (status == DLADM_STATUS_NOTFOUND) { 222d62bc4baSyz147064 /* 223d62bc4baSyz147064 * No active status, this link was removed. Update its status 224d62bc4baSyz147064 * in the daemon and delete all active linkprops. 225*2d4eecfaSCathy Zhou * 226*2d4eecfaSCathy Zhou * Note that the operation could fail. If it does, return 227*2d4eecfaSCathy Zhou * failure now since otherwise dladm_set_linkprop() might 228*2d4eecfaSCathy Zhou * call back to i_dladm_phys_status() recursively. 229d62bc4baSyz147064 */ 230*2d4eecfaSCathy Zhou status = dladm_destroy_datalink_id(linkid, DLADM_OPT_ACTIVE); 231*2d4eecfaSCathy Zhou if (status != DLADM_STATUS_OK) 232*2d4eecfaSCathy Zhou return (status); 233*2d4eecfaSCathy Zhou 234d62bc4baSyz147064 (void) dladm_set_linkprop(linkid, NULL, NULL, 0, 235d62bc4baSyz147064 DLADM_OPT_ACTIVE); 236d62bc4baSyz147064 237d62bc4baSyz147064 (*flagsp) &= ~DLMGMT_ACTIVE; 238d62bc4baSyz147064 status = DLADM_STATUS_OK; 239d62bc4baSyz147064 } 240d62bc4baSyz147064 return (status); 241d62bc4baSyz147064 } 242d62bc4baSyz147064 243d62bc4baSyz147064 /* 244d62bc4baSyz147064 * Walk each entry in the data link configuration repository and 245d62bc4baSyz147064 * call fn on the linkid and arg. 246d62bc4baSyz147064 */ 247d62bc4baSyz147064 dladm_status_t 248d62bc4baSyz147064 dladm_walk_datalink_id(int (*fn)(datalink_id_t, void *), void *argp, 249d62bc4baSyz147064 datalink_class_t class, datalink_media_t dmedia, uint32_t flags) 250d62bc4baSyz147064 { 251d62bc4baSyz147064 dlmgmt_door_getnext_t getnext; 252d62bc4baSyz147064 dlmgmt_getnext_retval_t retval; 253d62bc4baSyz147064 uint32_t dlmgmt_flags; 254d62bc4baSyz147064 datalink_id_t linkid = DATALINK_INVALID_LINKID; 255d62bc4baSyz147064 dladm_status_t status = DLADM_STATUS_OK; 256d62bc4baSyz147064 257d62bc4baSyz147064 if (fn == NULL) 258d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 259d62bc4baSyz147064 260d62bc4baSyz147064 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 261d62bc4baSyz147064 dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); 262d62bc4baSyz147064 263d62bc4baSyz147064 getnext.ld_cmd = DLMGMT_CMD_GETNEXT; 264d62bc4baSyz147064 getnext.ld_class = class; 265d62bc4baSyz147064 getnext.ld_dmedia = dmedia; 266d62bc4baSyz147064 getnext.ld_flags = dlmgmt_flags; 267d62bc4baSyz147064 268d62bc4baSyz147064 do { 269d62bc4baSyz147064 getnext.ld_linkid = linkid; 270024b0a25Sseb if ((status = dladm_door_call(&getnext, sizeof (getnext), 271024b0a25Sseb &retval, sizeof (retval))) != DLADM_STATUS_OK) { 272d62bc4baSyz147064 /* 273d62bc4baSyz147064 * done with walking 274d62bc4baSyz147064 */ 275d62bc4baSyz147064 break; 276d62bc4baSyz147064 } 277d62bc4baSyz147064 278d62bc4baSyz147064 linkid = retval.lr_linkid; 279d62bc4baSyz147064 if ((retval.lr_class == DATALINK_CLASS_PHYS) && 280d62bc4baSyz147064 (retval.lr_flags & DLMGMT_ACTIVE)) { 281d62bc4baSyz147064 /* 282d62bc4baSyz147064 * An active physical link reported by the dlmgmtd 283d62bc4baSyz147064 * daemon might not be active anymore. Check its 284d62bc4baSyz147064 * real status. 285d62bc4baSyz147064 */ 286d62bc4baSyz147064 if (i_dladm_phys_status(linkid, &retval.lr_flags) != 287d62bc4baSyz147064 DLADM_STATUS_OK) { 288d62bc4baSyz147064 continue; 289d62bc4baSyz147064 } 290d62bc4baSyz147064 291d62bc4baSyz147064 if (!(dlmgmt_flags & retval.lr_flags)) 292d62bc4baSyz147064 continue; 293d62bc4baSyz147064 } 294d62bc4baSyz147064 295d62bc4baSyz147064 if (fn(linkid, argp) == DLADM_WALK_TERMINATE) 296d62bc4baSyz147064 break; 297d62bc4baSyz147064 } while (linkid != DATALINK_INVALID_LINKID); 298d62bc4baSyz147064 299d62bc4baSyz147064 return (status); 300d62bc4baSyz147064 } 301d62bc4baSyz147064 302d62bc4baSyz147064 /* 303d62bc4baSyz147064 * Get the link properties structure for the given link. 304d62bc4baSyz147064 */ 305d62bc4baSyz147064 dladm_status_t 306d62bc4baSyz147064 dladm_read_conf(datalink_id_t linkid, dladm_conf_t *confp) 307d62bc4baSyz147064 { 308d62bc4baSyz147064 dlmgmt_door_readconf_t readconf; 309d62bc4baSyz147064 dlmgmt_readconf_retval_t retval; 310d62bc4baSyz147064 dladm_status_t status; 311d62bc4baSyz147064 312d62bc4baSyz147064 if (linkid == DATALINK_INVALID_LINKID || confp == NULL) 313d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 314d62bc4baSyz147064 315d62bc4baSyz147064 readconf.ld_linkid = linkid; 316d62bc4baSyz147064 readconf.ld_cmd = DLMGMT_CMD_READCONF; 317d62bc4baSyz147064 318024b0a25Sseb if ((status = dladm_door_call(&readconf, sizeof (readconf), 319024b0a25Sseb &retval, sizeof (retval))) == DLADM_STATUS_OK) { 320d62bc4baSyz147064 *confp = retval.lr_conf; 321024b0a25Sseb } 322024b0a25Sseb return (status); 323d62bc4baSyz147064 } 324d62bc4baSyz147064 325d62bc4baSyz147064 /* 326d62bc4baSyz147064 * Commit the given link to the data link configuration repository so 327d62bc4baSyz147064 * that it will persist across reboots. 328d62bc4baSyz147064 */ 329d62bc4baSyz147064 dladm_status_t 330d62bc4baSyz147064 dladm_write_conf(dladm_conf_t conf) 331d62bc4baSyz147064 { 332d62bc4baSyz147064 dlmgmt_door_writeconf_t writeconf; 333d62bc4baSyz147064 dlmgmt_writeconf_retval_t retval; 334d62bc4baSyz147064 335d62bc4baSyz147064 if (conf == DLADM_INVALID_CONF) 336d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 337d62bc4baSyz147064 338d62bc4baSyz147064 writeconf.ld_cmd = DLMGMT_CMD_WRITECONF; 339d62bc4baSyz147064 writeconf.ld_conf = conf; 340d62bc4baSyz147064 341024b0a25Sseb return (dladm_door_call(&writeconf, sizeof (writeconf), 342024b0a25Sseb &retval, sizeof (retval))); 343d62bc4baSyz147064 } 344d62bc4baSyz147064 345d62bc4baSyz147064 /* 346d62bc4baSyz147064 * Given a link ID and a key, get the matching information from 347d62bc4baSyz147064 * data link configuration repository. 348d62bc4baSyz147064 */ 349d62bc4baSyz147064 dladm_status_t 350d62bc4baSyz147064 dladm_get_conf_field(dladm_conf_t conf, const char *attr, void *attrval, 351d62bc4baSyz147064 size_t attrsz) 352d62bc4baSyz147064 { 353d62bc4baSyz147064 dlmgmt_door_getattr_t getattr; 354024b0a25Sseb dlmgmt_getattr_retval_t retval; 355024b0a25Sseb dladm_status_t status; 356d62bc4baSyz147064 357d62bc4baSyz147064 if (conf == DLADM_INVALID_CONF || attrval == NULL || 358024b0a25Sseb attrsz == 0 || attr == NULL) { 359d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 360d62bc4baSyz147064 } 361d62bc4baSyz147064 362d62bc4baSyz147064 getattr.ld_cmd = DLMGMT_CMD_GETATTR; 363d62bc4baSyz147064 getattr.ld_conf = conf; 364d62bc4baSyz147064 (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN); 365d62bc4baSyz147064 366024b0a25Sseb if ((status = dladm_door_call(&getattr, sizeof (getattr), &retval, 367024b0a25Sseb sizeof (retval))) != DLADM_STATUS_OK) { 368d62bc4baSyz147064 return (status); 369d62bc4baSyz147064 } 370d62bc4baSyz147064 371024b0a25Sseb if (retval.lr_attrsz > attrsz) 372024b0a25Sseb return (DLADM_STATUS_TOOSMALL); 373024b0a25Sseb 374024b0a25Sseb bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); 375024b0a25Sseb return (DLADM_STATUS_OK); 376024b0a25Sseb } 377024b0a25Sseb 378d62bc4baSyz147064 /* 379d62bc4baSyz147064 * Get the link ID that is associated with the given name. 380d62bc4baSyz147064 */ 381d62bc4baSyz147064 dladm_status_t 382d62bc4baSyz147064 dladm_name2info(const char *link, datalink_id_t *linkidp, uint32_t *flagp, 383d62bc4baSyz147064 datalink_class_t *classp, uint32_t *mediap) 384d62bc4baSyz147064 { 385d62bc4baSyz147064 dlmgmt_door_getlinkid_t getlinkid; 386d62bc4baSyz147064 dlmgmt_getlinkid_retval_t retval; 387d62bc4baSyz147064 datalink_id_t linkid; 388d62bc4baSyz147064 dladm_status_t status; 389d62bc4baSyz147064 390d62bc4baSyz147064 getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; 391d62bc4baSyz147064 (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); 392d62bc4baSyz147064 393024b0a25Sseb if ((status = dladm_door_call(&getlinkid, sizeof (getlinkid), 394024b0a25Sseb &retval, sizeof (retval))) != DLADM_STATUS_OK) { 395d62bc4baSyz147064 return (status); 396024b0a25Sseb } 397d62bc4baSyz147064 398d62bc4baSyz147064 linkid = retval.lr_linkid; 399d62bc4baSyz147064 if (retval.lr_class == DATALINK_CLASS_PHYS && 400d62bc4baSyz147064 retval.lr_flags & DLMGMT_ACTIVE) { 401d62bc4baSyz147064 /* 402d62bc4baSyz147064 * An active physical link reported by the dlmgmtd daemon 403d62bc4baSyz147064 * might not be active anymore. Check and set its real status. 404d62bc4baSyz147064 */ 405d62bc4baSyz147064 status = i_dladm_phys_status(linkid, &retval.lr_flags); 406d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 407d62bc4baSyz147064 return (status); 408d62bc4baSyz147064 } 409d62bc4baSyz147064 410d62bc4baSyz147064 if (linkidp != NULL) 411d62bc4baSyz147064 *linkidp = linkid; 412d62bc4baSyz147064 if (flagp != NULL) { 413d62bc4baSyz147064 *flagp = retval.lr_flags & DLMGMT_ACTIVE ? DLADM_OPT_ACTIVE : 0; 414d62bc4baSyz147064 *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ? 415d62bc4baSyz147064 DLADM_OPT_PERSIST : 0; 416d62bc4baSyz147064 } 417d62bc4baSyz147064 if (classp != NULL) 418d62bc4baSyz147064 *classp = retval.lr_class; 419d62bc4baSyz147064 if (mediap != NULL) 420d62bc4baSyz147064 *mediap = retval.lr_media; 421d62bc4baSyz147064 422d62bc4baSyz147064 return (DLADM_STATUS_OK); 423d62bc4baSyz147064 } 424d62bc4baSyz147064 425d62bc4baSyz147064 /* 426d62bc4baSyz147064 * Get the link name that is associated with the given id. 427d62bc4baSyz147064 */ 428d62bc4baSyz147064 dladm_status_t 429d62bc4baSyz147064 dladm_datalink_id2info(datalink_id_t linkid, uint32_t *flagp, 430d62bc4baSyz147064 datalink_class_t *classp, uint32_t *mediap, char *link, size_t len) 431d62bc4baSyz147064 { 432d62bc4baSyz147064 dlmgmt_door_getname_t getname; 433d62bc4baSyz147064 dlmgmt_getname_retval_t retval; 434d62bc4baSyz147064 dladm_status_t status; 435d62bc4baSyz147064 436d62bc4baSyz147064 if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) || 437d62bc4baSyz147064 (link == NULL && len != 0)) { 438d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 439d62bc4baSyz147064 } 440d62bc4baSyz147064 441d62bc4baSyz147064 getname.ld_cmd = DLMGMT_CMD_GETNAME; 442d62bc4baSyz147064 getname.ld_linkid = linkid; 443024b0a25Sseb if ((status = dladm_door_call(&getname, sizeof (getname), &retval, 444024b0a25Sseb sizeof (retval))) != DLADM_STATUS_OK) { 445d62bc4baSyz147064 return (status); 446d62bc4baSyz147064 } 447d62bc4baSyz147064 448024b0a25Sseb if (len != 0 && (strlen(retval.lr_link) + 1 > len)) 449024b0a25Sseb return (DLADM_STATUS_TOOSMALL); 450024b0a25Sseb 451d62bc4baSyz147064 if (retval.lr_class == DATALINK_CLASS_PHYS && 452d62bc4baSyz147064 retval.lr_flags & DLMGMT_ACTIVE) { 453d62bc4baSyz147064 /* 454d62bc4baSyz147064 * An active physical link reported by the dlmgmtd daemon 455d62bc4baSyz147064 * might not be active anymore. Check and set its real status. 456d62bc4baSyz147064 */ 457d62bc4baSyz147064 status = i_dladm_phys_status(linkid, &retval.lr_flags); 458d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 459d62bc4baSyz147064 return (status); 460d62bc4baSyz147064 } 461d62bc4baSyz147064 462d62bc4baSyz147064 if (link != NULL) 463d62bc4baSyz147064 (void) strlcpy(link, retval.lr_link, len); 464d62bc4baSyz147064 if (classp != NULL) 465d62bc4baSyz147064 *classp = retval.lr_class; 466d62bc4baSyz147064 if (mediap != NULL) 467d62bc4baSyz147064 *mediap = retval.lr_media; 468d62bc4baSyz147064 if (flagp != NULL) { 469d62bc4baSyz147064 *flagp = retval.lr_flags & DLMGMT_ACTIVE ? 470d62bc4baSyz147064 DLADM_OPT_ACTIVE : 0; 471d62bc4baSyz147064 *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ? 472d62bc4baSyz147064 DLADM_OPT_PERSIST : 0; 473d62bc4baSyz147064 } 474d62bc4baSyz147064 return (DLADM_STATUS_OK); 475d62bc4baSyz147064 } 476d62bc4baSyz147064 477d62bc4baSyz147064 /* 478d62bc4baSyz147064 * Set the given attr with the given attrval for the given link. 479d62bc4baSyz147064 */ 480d62bc4baSyz147064 dladm_status_t 481d62bc4baSyz147064 dladm_set_conf_field(dladm_conf_t conf, const char *attr, 482d62bc4baSyz147064 dladm_datatype_t type, const void *attrval) 483d62bc4baSyz147064 { 484024b0a25Sseb dlmgmt_door_setattr_t setattr; 485d62bc4baSyz147064 dlmgmt_setattr_retval_t retval; 486024b0a25Sseb size_t attrsz; 487d62bc4baSyz147064 488024b0a25Sseb if (attr == NULL || attrval == NULL) 489d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 490d62bc4baSyz147064 491d62bc4baSyz147064 if (type == DLADM_TYPE_STR) 492d62bc4baSyz147064 attrsz = strlen(attrval) + 1; 493d62bc4baSyz147064 else 494d62bc4baSyz147064 attrsz = dladm_datatype_size[type]; 495d62bc4baSyz147064 496024b0a25Sseb if (attrsz > MAXLINKATTRVALLEN) 497024b0a25Sseb return (DLADM_STATUS_TOOSMALL); 498d62bc4baSyz147064 499024b0a25Sseb setattr.ld_cmd = DLMGMT_CMD_SETATTR; 500024b0a25Sseb setattr.ld_conf = conf; 501024b0a25Sseb (void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN); 502024b0a25Sseb setattr.ld_attrsz = attrsz; 503024b0a25Sseb setattr.ld_type = type; 504024b0a25Sseb bcopy(attrval, &setattr.ld_attrval, attrsz); 505d62bc4baSyz147064 506024b0a25Sseb return (dladm_door_call(&setattr, sizeof (setattr), 507024b0a25Sseb &retval, sizeof (retval))); 508d62bc4baSyz147064 } 509d62bc4baSyz147064 510d62bc4baSyz147064 /* 511d62bc4baSyz147064 * Unset the given attr the given link. 512d62bc4baSyz147064 */ 513d62bc4baSyz147064 dladm_status_t 514d62bc4baSyz147064 dladm_unset_conf_field(dladm_conf_t conf, const char *attr) 515d62bc4baSyz147064 { 516d62bc4baSyz147064 dlmgmt_door_unsetattr_t unsetattr; 517d62bc4baSyz147064 dlmgmt_unsetattr_retval_t retval; 518d62bc4baSyz147064 519024b0a25Sseb if (attr == NULL) 520d62bc4baSyz147064 return (DLADM_STATUS_BADARG); 521d62bc4baSyz147064 522d62bc4baSyz147064 unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR; 523d62bc4baSyz147064 unsetattr.ld_conf = conf; 524d62bc4baSyz147064 (void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN); 525d62bc4baSyz147064 526024b0a25Sseb return (dladm_door_call(&unsetattr, sizeof (unsetattr), 527024b0a25Sseb &retval, sizeof (retval))); 528d62bc4baSyz147064 } 529d62bc4baSyz147064 530d62bc4baSyz147064 /* 531d62bc4baSyz147064 * Remove the given link ID and its entry from the data link configuration 532d62bc4baSyz147064 * repository. 533d62bc4baSyz147064 */ 534d62bc4baSyz147064 dladm_status_t 535d62bc4baSyz147064 dladm_remove_conf(datalink_id_t linkid) 536d62bc4baSyz147064 { 537d62bc4baSyz147064 dlmgmt_door_removeconf_t removeconf; 538d62bc4baSyz147064 dlmgmt_removeconf_retval_t retval; 539d62bc4baSyz147064 540d62bc4baSyz147064 removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF; 541d62bc4baSyz147064 removeconf.ld_linkid = linkid; 542d62bc4baSyz147064 543024b0a25Sseb return (dladm_door_call(&removeconf, sizeof (removeconf), 544024b0a25Sseb &retval, sizeof (retval))); 545d62bc4baSyz147064 } 546d62bc4baSyz147064 547d62bc4baSyz147064 /* 548d62bc4baSyz147064 * Free the contents of the link structure. 549d62bc4baSyz147064 */ 550d62bc4baSyz147064 void 551d62bc4baSyz147064 dladm_destroy_conf(dladm_conf_t conf) 552d62bc4baSyz147064 { 553d62bc4baSyz147064 dlmgmt_door_destroyconf_t destroyconf; 554d62bc4baSyz147064 dlmgmt_destroyconf_retval_t retval; 555d62bc4baSyz147064 556d62bc4baSyz147064 if (conf == DLADM_INVALID_CONF) 557d62bc4baSyz147064 return; 558d62bc4baSyz147064 559d62bc4baSyz147064 destroyconf.ld_cmd = DLMGMT_CMD_DESTROYCONF; 560d62bc4baSyz147064 destroyconf.ld_conf = conf; 561d62bc4baSyz147064 562024b0a25Sseb (void) dladm_door_call(&destroyconf, sizeof (destroyconf), 563024b0a25Sseb &retval, sizeof (retval)); 564d62bc4baSyz147064 } 565