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