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