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