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