15895Syz147064 /* 25895Syz147064 * CDDL HEADER START 35895Syz147064 * 45895Syz147064 * The contents of this file are subject to the terms of the 55895Syz147064 * Common Development and Distribution License (the "License"). 65895Syz147064 * You may not use this file except in compliance with the License. 75895Syz147064 * 85895Syz147064 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95895Syz147064 * or http://www.opensolaris.org/os/licensing. 105895Syz147064 * See the License for the specific language governing permissions 115895Syz147064 * and limitations under the License. 125895Syz147064 * 135895Syz147064 * When distributing Covered Code, include this CDDL HEADER in each 145895Syz147064 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155895Syz147064 * If applicable, add the following below this CDDL HEADER, with the 165895Syz147064 * fields enclosed by brackets "[]" replaced with your own identifying 175895Syz147064 * information: Portions Copyright [yyyy] [name of copyright owner] 185895Syz147064 * 195895Syz147064 * CDDL HEADER END 205895Syz147064 */ 215895Syz147064 /* 22*12824SCathy.Zhou@Sun.COM * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 235895Syz147064 */ 245895Syz147064 255895Syz147064 #include <door.h> 265895Syz147064 #include <errno.h> 275895Syz147064 #include <assert.h> 285895Syz147064 #include <stdio.h> 295895Syz147064 #include <stdlib.h> 305895Syz147064 #include <unistd.h> 315895Syz147064 #include <string.h> 325895Syz147064 #include <strings.h> 3310616SSebastien.Roy@Sun.COM #include <zone.h> 345895Syz147064 #include <sys/types.h> 355895Syz147064 #include <sys/stat.h> 365895Syz147064 #include <sys/aggr.h> 379107Sjames.d.carlson@sun.com #include <sys/mman.h> 385895Syz147064 #include <fcntl.h> 395895Syz147064 #include <libdladm.h> 405895Syz147064 #include <libdladm_impl.h> 415895Syz147064 #include <libdllink.h> 425895Syz147064 #include <libdlmgmt.h> 435895Syz147064 445895Syz147064 /* 455895Syz147064 * Table of data type sizes indexed by dladm_datatype_t. 465895Syz147064 */ 475895Syz147064 static size_t dladm_datatype_size[] = { 485895Syz147064 0, /* DLADM_TYPE_STR, use strnlen() */ 495895Syz147064 sizeof (boolean_t), /* DLADM_TYPE_BOOLEAN */ 505895Syz147064 sizeof (uint64_t) /* DLADM_TYPE_UINT64 */ 515895Syz147064 }; 525895Syz147064 535895Syz147064 static dladm_status_t 548453SAnurag.Maskey@Sun.COM dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf, 55*12824SCathy.Zhou@Sun.COM size_t *rsizep) 565895Syz147064 { 575895Syz147064 door_arg_t darg; 588453SAnurag.Maskey@Sun.COM int door_fd; 595895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 605895Syz147064 615895Syz147064 darg.data_ptr = arg; 625895Syz147064 darg.data_size = asize; 635895Syz147064 darg.desc_ptr = NULL; 645895Syz147064 darg.desc_num = 0; 655895Syz147064 darg.rbuf = rbuf; 66*12824SCathy.Zhou@Sun.COM darg.rsize = *rsizep; 675895Syz147064 688453SAnurag.Maskey@Sun.COM /* The door descriptor is opened if it isn't already */ 698453SAnurag.Maskey@Sun.COM if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK) 708453SAnurag.Maskey@Sun.COM return (status); 718453SAnurag.Maskey@Sun.COM if (door_call(door_fd, &darg) == -1) 725895Syz147064 status = dladm_errno2status(errno); 735895Syz147064 if (status != DLADM_STATUS_OK) 745895Syz147064 return (status); 755895Syz147064 765895Syz147064 if (darg.rbuf != rbuf) { 775895Syz147064 /* 785895Syz147064 * The size of the input rbuf is not big enough so that 79*12824SCathy.Zhou@Sun.COM * the door allocate the rbuf itself. In this case, return 80*12824SCathy.Zhou@Sun.COM * the required size to the caller. 815895Syz147064 */ 825895Syz147064 (void) munmap(darg.rbuf, darg.rsize); 83*12824SCathy.Zhou@Sun.COM *rsizep = darg.rsize; 845895Syz147064 return (DLADM_STATUS_TOOSMALL); 85*12824SCathy.Zhou@Sun.COM } else if (darg.rsize != *rsizep) { 86*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_FAILED); 875895Syz147064 } 885895Syz147064 896263Sseb return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err)); 905895Syz147064 } 915895Syz147064 925895Syz147064 /* 935895Syz147064 * Allocate a new linkid with the given name. Return the new linkid. 945895Syz147064 */ 955895Syz147064 dladm_status_t 968453SAnurag.Maskey@Sun.COM dladm_create_datalink_id(dladm_handle_t handle, const char *link, 978453SAnurag.Maskey@Sun.COM datalink_class_t class, uint32_t media, uint32_t flags, 988453SAnurag.Maskey@Sun.COM datalink_id_t *linkidp) 995895Syz147064 { 1006263Sseb dlmgmt_door_createid_t createid; 1015895Syz147064 dlmgmt_createid_retval_t retval; 1026263Sseb uint32_t dlmgmt_flags; 1036263Sseb dladm_status_t status; 104*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 1055895Syz147064 1066263Sseb if (link == NULL || class == DATALINK_CLASS_ALL || 1075895Syz147064 !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) || 1085895Syz147064 linkidp == NULL) { 1095895Syz147064 return (DLADM_STATUS_BADARG); 1105895Syz147064 } 1115895Syz147064 1125895Syz147064 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 1135895Syz147064 dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0; 1145895Syz147064 1155895Syz147064 (void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN); 1165895Syz147064 createid.ld_class = class; 1175895Syz147064 createid.ld_media = media; 1185895Syz147064 createid.ld_flags = dlmgmt_flags; 1195895Syz147064 createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID; 1205895Syz147064 createid.ld_prefix = (flags & DLADM_OPT_PREFIX); 1215895Syz147064 1228453SAnurag.Maskey@Sun.COM if ((status = dladm_door_call(handle, &createid, sizeof (createid), 123*12824SCathy.Zhou@Sun.COM &retval, &sz)) == DLADM_STATUS_OK) { 1246263Sseb *linkidp = retval.lr_linkid; 1256263Sseb } 1266263Sseb return (status); 1275895Syz147064 } 1285895Syz147064 1295895Syz147064 /* 1305895Syz147064 * Destroy the given link ID. 1315895Syz147064 */ 1325895Syz147064 dladm_status_t 1338453SAnurag.Maskey@Sun.COM dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid, 1348453SAnurag.Maskey@Sun.COM uint32_t flags) 1355895Syz147064 { 1365895Syz147064 dlmgmt_door_destroyid_t destroyid; 1375895Syz147064 dlmgmt_destroyid_retval_t retval; 1385895Syz147064 uint32_t dlmgmt_flags; 139*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 1405895Syz147064 1415895Syz147064 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 1425895Syz147064 dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); 1435895Syz147064 1445895Syz147064 destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID; 1455895Syz147064 destroyid.ld_linkid = linkid; 1465895Syz147064 destroyid.ld_flags = dlmgmt_flags; 1475895Syz147064 148*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &destroyid, sizeof (destroyid), 149*12824SCathy.Zhou@Sun.COM &retval, &sz)); 1505895Syz147064 } 1515895Syz147064 1525895Syz147064 /* 1535895Syz147064 * Remap a given link ID to a new name. 1545895Syz147064 */ 1555895Syz147064 dladm_status_t 1568453SAnurag.Maskey@Sun.COM dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid, 1578453SAnurag.Maskey@Sun.COM const char *link) 1585895Syz147064 { 1595895Syz147064 dlmgmt_door_remapid_t remapid; 1605895Syz147064 dlmgmt_remapid_retval_t retval; 161*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 1625895Syz147064 1635895Syz147064 remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID; 1645895Syz147064 remapid.ld_linkid = linkid; 1655895Syz147064 (void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN); 1665895Syz147064 167*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &remapid, sizeof (remapid), 168*12824SCathy.Zhou@Sun.COM &retval, &sz)); 1695895Syz147064 } 1705895Syz147064 1715895Syz147064 /* 1725895Syz147064 * Make a given link ID active. 1735895Syz147064 */ 1745895Syz147064 dladm_status_t 1758453SAnurag.Maskey@Sun.COM dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid) 1765895Syz147064 { 1776263Sseb dlmgmt_door_upid_t upid; 1786263Sseb dlmgmt_upid_retval_t retval; 179*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 1805895Syz147064 1815895Syz147064 upid.ld_cmd = DLMGMT_CMD_UP_LINKID; 1825895Syz147064 upid.ld_linkid = linkid; 1835895Syz147064 184*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &upid, sizeof (upid), &retval, &sz)); 1855895Syz147064 } 1865895Syz147064 1875895Syz147064 /* 1885895Syz147064 * Create a new link with the given name. Return the new link's handle 1895895Syz147064 */ 1905895Syz147064 dladm_status_t 1918453SAnurag.Maskey@Sun.COM dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid, 1925895Syz147064 datalink_class_t class, uint32_t media, dladm_conf_t *confp) 1935895Syz147064 { 1946263Sseb dlmgmt_door_createconf_t createconf; 1956263Sseb dlmgmt_createconf_retval_t retval; 1966263Sseb dladm_status_t status; 197*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 1985895Syz147064 1996263Sseb if (link == NULL || confp == NULL) 2005895Syz147064 return (DLADM_STATUS_BADARG); 2015895Syz147064 2025895Syz147064 (void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN); 2035895Syz147064 createconf.ld_class = class; 2045895Syz147064 createconf.ld_media = media; 2055895Syz147064 createconf.ld_linkid = linkid; 2065895Syz147064 createconf.ld_cmd = DLMGMT_CMD_CREATECONF; 207*12824SCathy.Zhou@Sun.COM confp->ds_confid = DLADM_INVALID_CONF; 2085895Syz147064 2098453SAnurag.Maskey@Sun.COM if ((status = dladm_door_call(handle, &createconf, sizeof (createconf), 210*12824SCathy.Zhou@Sun.COM &retval, &sz)) == DLADM_STATUS_OK) { 211*12824SCathy.Zhou@Sun.COM confp->ds_readonly = B_FALSE; 212*12824SCathy.Zhou@Sun.COM confp->ds_confid = retval.lr_confid; 2136263Sseb } 2146263Sseb return (status); 2155895Syz147064 } 2165895Syz147064 2175895Syz147064 /* 2185895Syz147064 * An active physical link reported by the dlmgmtd daemon might not be active 2195895Syz147064 * anymore as this link might be removed during system shutdown. Check its 2205895Syz147064 * real status by calling dladm_phys_info(). 2215895Syz147064 */ 2225895Syz147064 dladm_status_t 2238453SAnurag.Maskey@Sun.COM i_dladm_phys_status(dladm_handle_t handle, datalink_id_t linkid, 2248453SAnurag.Maskey@Sun.COM uint32_t *flagsp) 2255895Syz147064 { 2265895Syz147064 dladm_phys_attr_t dpa; 2275895Syz147064 dladm_status_t status; 2285895Syz147064 2295895Syz147064 assert((*flagsp) & DLMGMT_ACTIVE); 2305895Syz147064 2318453SAnurag.Maskey@Sun.COM status = dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE); 2325895Syz147064 if (status == DLADM_STATUS_NOTFOUND) { 2335895Syz147064 /* 2345895Syz147064 * No active status, this link was removed. Update its status 2355895Syz147064 * in the daemon and delete all active linkprops. 2368120SCathy.Zhou@Sun.COM * 2378120SCathy.Zhou@Sun.COM * Note that the operation could fail. If it does, return 2388120SCathy.Zhou@Sun.COM * failure now since otherwise dladm_set_linkprop() might 2398120SCathy.Zhou@Sun.COM * call back to i_dladm_phys_status() recursively. 2405895Syz147064 */ 2418453SAnurag.Maskey@Sun.COM if ((status = dladm_destroy_datalink_id(handle, linkid, 2428453SAnurag.Maskey@Sun.COM DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) 2438120SCathy.Zhou@Sun.COM return (status); 2448120SCathy.Zhou@Sun.COM 2458453SAnurag.Maskey@Sun.COM (void) dladm_set_linkprop(handle, linkid, NULL, NULL, 0, 2465895Syz147064 DLADM_OPT_ACTIVE); 2475895Syz147064 2485895Syz147064 (*flagsp) &= ~DLMGMT_ACTIVE; 2495895Syz147064 status = DLADM_STATUS_OK; 2505895Syz147064 } 2515895Syz147064 return (status); 2525895Syz147064 } 2535895Syz147064 2545895Syz147064 /* 2555895Syz147064 * Walk each entry in the data link configuration repository and 2565895Syz147064 * call fn on the linkid and arg. 2575895Syz147064 */ 2585895Syz147064 dladm_status_t 2598453SAnurag.Maskey@Sun.COM dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *), 2608453SAnurag.Maskey@Sun.COM dladm_handle_t handle, void *argp, datalink_class_t class, 2618453SAnurag.Maskey@Sun.COM datalink_media_t dmedia, uint32_t flags) 2625895Syz147064 { 2635895Syz147064 dlmgmt_door_getnext_t getnext; 2645895Syz147064 dlmgmt_getnext_retval_t retval; 2655895Syz147064 uint32_t dlmgmt_flags; 2665895Syz147064 datalink_id_t linkid = DATALINK_INVALID_LINKID; 2675895Syz147064 dladm_status_t status = DLADM_STATUS_OK; 268*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 2695895Syz147064 2705895Syz147064 if (fn == NULL) 2715895Syz147064 return (DLADM_STATUS_BADARG); 2725895Syz147064 2735895Syz147064 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 2745895Syz147064 dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); 2755895Syz147064 2765895Syz147064 getnext.ld_cmd = DLMGMT_CMD_GETNEXT; 2775895Syz147064 getnext.ld_class = class; 2785895Syz147064 getnext.ld_dmedia = dmedia; 2795895Syz147064 getnext.ld_flags = dlmgmt_flags; 2805895Syz147064 2815895Syz147064 do { 2825895Syz147064 getnext.ld_linkid = linkid; 2838453SAnurag.Maskey@Sun.COM if ((status = dladm_door_call(handle, &getnext, 284*12824SCathy.Zhou@Sun.COM sizeof (getnext), &retval, &sz)) != DLADM_STATUS_OK) { 2855895Syz147064 /* 28611009SCathy.Zhou@Sun.COM * Done with walking. If no next datalink is found, 28711009SCathy.Zhou@Sun.COM * return success. 2885895Syz147064 */ 28911009SCathy.Zhou@Sun.COM if (status == DLADM_STATUS_NOTFOUND) 29011009SCathy.Zhou@Sun.COM status = DLADM_STATUS_OK; 2915895Syz147064 break; 2925895Syz147064 } 2935895Syz147064 2945895Syz147064 linkid = retval.lr_linkid; 2955895Syz147064 if ((retval.lr_class == DATALINK_CLASS_PHYS) && 2965895Syz147064 (retval.lr_flags & DLMGMT_ACTIVE)) { 2975895Syz147064 /* 2985895Syz147064 * An active physical link reported by the dlmgmtd 2995895Syz147064 * daemon might not be active anymore. Check its 3005895Syz147064 * real status. 3015895Syz147064 */ 3028453SAnurag.Maskey@Sun.COM if (i_dladm_phys_status(handle, linkid, 3038453SAnurag.Maskey@Sun.COM &retval.lr_flags) != DLADM_STATUS_OK) { 3045895Syz147064 continue; 3055895Syz147064 } 3065895Syz147064 3075895Syz147064 if (!(dlmgmt_flags & retval.lr_flags)) 3085895Syz147064 continue; 3095895Syz147064 } 3105895Syz147064 3118453SAnurag.Maskey@Sun.COM if (fn(handle, linkid, argp) == DLADM_WALK_TERMINATE) 3125895Syz147064 break; 3135895Syz147064 } while (linkid != DATALINK_INVALID_LINKID); 3145895Syz147064 3155895Syz147064 return (status); 3165895Syz147064 } 3175895Syz147064 3185895Syz147064 /* 319*12824SCathy.Zhou@Sun.COM * Get a handle of a copy of the link configuration (kept in the daemon) 320*12824SCathy.Zhou@Sun.COM * for the given link so it can be updated later by dladm_write_conf(). 3215895Syz147064 */ 3225895Syz147064 dladm_status_t 323*12824SCathy.Zhou@Sun.COM dladm_open_conf(dladm_handle_t handle, datalink_id_t linkid, 3248453SAnurag.Maskey@Sun.COM dladm_conf_t *confp) 3255895Syz147064 { 326*12824SCathy.Zhou@Sun.COM dlmgmt_door_openconf_t openconf; 327*12824SCathy.Zhou@Sun.COM dlmgmt_openconf_retval_t retval; 3285895Syz147064 dladm_status_t status; 329*12824SCathy.Zhou@Sun.COM size_t sz; 3305895Syz147064 3315895Syz147064 if (linkid == DATALINK_INVALID_LINKID || confp == NULL) 3325895Syz147064 return (DLADM_STATUS_BADARG); 3335895Syz147064 334*12824SCathy.Zhou@Sun.COM sz = sizeof (retval); 335*12824SCathy.Zhou@Sun.COM openconf.ld_linkid = linkid; 336*12824SCathy.Zhou@Sun.COM openconf.ld_cmd = DLMGMT_CMD_OPENCONF; 337*12824SCathy.Zhou@Sun.COM confp->ds_confid = DLADM_INVALID_CONF; 338*12824SCathy.Zhou@Sun.COM if ((status = dladm_door_call(handle, &openconf, 339*12824SCathy.Zhou@Sun.COM sizeof (openconf), &retval, &sz)) == DLADM_STATUS_OK) { 340*12824SCathy.Zhou@Sun.COM confp->ds_readonly = B_FALSE; 341*12824SCathy.Zhou@Sun.COM confp->ds_confid = retval.lr_confid; 342*12824SCathy.Zhou@Sun.COM } 343*12824SCathy.Zhou@Sun.COM 344*12824SCathy.Zhou@Sun.COM return (status); 345*12824SCathy.Zhou@Sun.COM } 346*12824SCathy.Zhou@Sun.COM 347*12824SCathy.Zhou@Sun.COM /* 348*12824SCathy.Zhou@Sun.COM * Get the handle of a local snapshot of the link configuration. Note that 349*12824SCathy.Zhou@Sun.COM * any operations with this handle are read-only, i.e., one can not update 350*12824SCathy.Zhou@Sun.COM * the configuration with this handle. 351*12824SCathy.Zhou@Sun.COM */ 352*12824SCathy.Zhou@Sun.COM dladm_status_t 353*12824SCathy.Zhou@Sun.COM dladm_getsnap_conf(dladm_handle_t handle, datalink_id_t linkid, 354*12824SCathy.Zhou@Sun.COM dladm_conf_t *confp) 355*12824SCathy.Zhou@Sun.COM { 356*12824SCathy.Zhou@Sun.COM dlmgmt_door_getconfsnapshot_t snapshot; 357*12824SCathy.Zhou@Sun.COM dlmgmt_getconfsnapshot_retval_t *retvalp; 358*12824SCathy.Zhou@Sun.COM char *nvlbuf; 359*12824SCathy.Zhou@Sun.COM dladm_status_t status; 360*12824SCathy.Zhou@Sun.COM int err; 361*12824SCathy.Zhou@Sun.COM size_t sz; 3625895Syz147064 363*12824SCathy.Zhou@Sun.COM if (linkid == DATALINK_INVALID_LINKID || confp == NULL) 364*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_BADARG); 365*12824SCathy.Zhou@Sun.COM 366*12824SCathy.Zhou@Sun.COM sz = sizeof (dlmgmt_getconfsnapshot_retval_t); 367*12824SCathy.Zhou@Sun.COM snapshot.ld_linkid = linkid; 368*12824SCathy.Zhou@Sun.COM snapshot.ld_cmd = DLMGMT_CMD_GETCONFSNAPSHOT; 369*12824SCathy.Zhou@Sun.COM again: 370*12824SCathy.Zhou@Sun.COM if ((retvalp = malloc(sz)) == NULL) 371*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_NOMEM); 372*12824SCathy.Zhou@Sun.COM 373*12824SCathy.Zhou@Sun.COM if ((status = dladm_door_call(handle, &snapshot, sizeof (snapshot), 374*12824SCathy.Zhou@Sun.COM retvalp, &sz)) == DLADM_STATUS_TOOSMALL) { 375*12824SCathy.Zhou@Sun.COM free(retvalp); 376*12824SCathy.Zhou@Sun.COM goto again; 3776263Sseb } 378*12824SCathy.Zhou@Sun.COM 379*12824SCathy.Zhou@Sun.COM if (status != DLADM_STATUS_OK) { 380*12824SCathy.Zhou@Sun.COM free(retvalp); 381*12824SCathy.Zhou@Sun.COM return (status); 382*12824SCathy.Zhou@Sun.COM } 383*12824SCathy.Zhou@Sun.COM 384*12824SCathy.Zhou@Sun.COM confp->ds_readonly = B_TRUE; 385*12824SCathy.Zhou@Sun.COM nvlbuf = (char *)retvalp + sizeof (dlmgmt_getconfsnapshot_retval_t); 386*12824SCathy.Zhou@Sun.COM if ((err = nvlist_unpack(nvlbuf, retvalp->lr_nvlsz, 387*12824SCathy.Zhou@Sun.COM &(confp->ds_nvl), NV_ENCODE_NATIVE)) != 0) { 388*12824SCathy.Zhou@Sun.COM status = dladm_errno2status(err); 389*12824SCathy.Zhou@Sun.COM } 390*12824SCathy.Zhou@Sun.COM free(retvalp); 3916263Sseb return (status); 3925895Syz147064 } 3935895Syz147064 3945895Syz147064 /* 3955895Syz147064 * Commit the given link to the data link configuration repository so 3965895Syz147064 * that it will persist across reboots. 3975895Syz147064 */ 3985895Syz147064 dladm_status_t 3998453SAnurag.Maskey@Sun.COM dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf) 4005895Syz147064 { 4015895Syz147064 dlmgmt_door_writeconf_t writeconf; 4025895Syz147064 dlmgmt_writeconf_retval_t retval; 403*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 4045895Syz147064 405*12824SCathy.Zhou@Sun.COM if (conf.ds_confid == DLADM_INVALID_CONF) 4065895Syz147064 return (DLADM_STATUS_BADARG); 4075895Syz147064 408*12824SCathy.Zhou@Sun.COM if (conf.ds_readonly) 409*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_DENIED); 410*12824SCathy.Zhou@Sun.COM 4115895Syz147064 writeconf.ld_cmd = DLMGMT_CMD_WRITECONF; 412*12824SCathy.Zhou@Sun.COM writeconf.ld_confid = conf.ds_confid; 4135895Syz147064 414*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &writeconf, sizeof (writeconf), 415*12824SCathy.Zhou@Sun.COM &retval, &sz)); 4165895Syz147064 } 4175895Syz147064 4185895Syz147064 /* 419*12824SCathy.Zhou@Sun.COM * Given a dladm_conf_t, get the specific configuration field 420*12824SCathy.Zhou@Sun.COM * 421*12824SCathy.Zhou@Sun.COM * If the specified dladm_conf_t is a read-only snapshot of the configuration, 422*12824SCathy.Zhou@Sun.COM * get a specific link propertie from that snapshot (nvl), otherwise, get 423*12824SCathy.Zhou@Sun.COM * the link protperty from the dlmgmtd daemon using the given confid. 4245895Syz147064 */ 4255895Syz147064 dladm_status_t 4268453SAnurag.Maskey@Sun.COM dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, 4278453SAnurag.Maskey@Sun.COM void *attrval, size_t attrsz) 4285895Syz147064 { 429*12824SCathy.Zhou@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 430*12824SCathy.Zhou@Sun.COM 431*12824SCathy.Zhou@Sun.COM if (attrval == NULL || attrsz == 0 || attr == NULL) 432*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_BADARG); 4335895Syz147064 434*12824SCathy.Zhou@Sun.COM if (conf.ds_readonly) { 435*12824SCathy.Zhou@Sun.COM uchar_t *oattrval; 436*12824SCathy.Zhou@Sun.COM uint32_t oattrsz; 437*12824SCathy.Zhou@Sun.COM int err; 438*12824SCathy.Zhou@Sun.COM 439*12824SCathy.Zhou@Sun.COM if ((err = nvlist_lookup_byte_array(conf.ds_nvl, (char *)attr, 440*12824SCathy.Zhou@Sun.COM &oattrval, &oattrsz)) != 0) { 441*12824SCathy.Zhou@Sun.COM return (dladm_errno2status(err)); 442*12824SCathy.Zhou@Sun.COM } 443*12824SCathy.Zhou@Sun.COM if (oattrsz > attrsz) 444*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_TOOSMALL); 4455895Syz147064 446*12824SCathy.Zhou@Sun.COM bcopy(oattrval, attrval, oattrsz); 447*12824SCathy.Zhou@Sun.COM } else { 448*12824SCathy.Zhou@Sun.COM dlmgmt_door_getattr_t getattr; 449*12824SCathy.Zhou@Sun.COM dlmgmt_getattr_retval_t retval; 450*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 451*12824SCathy.Zhou@Sun.COM 452*12824SCathy.Zhou@Sun.COM if (conf.ds_confid == DLADM_INVALID_CONF) 453*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_BADARG); 4545895Syz147064 455*12824SCathy.Zhou@Sun.COM getattr.ld_cmd = DLMGMT_CMD_GETATTR; 456*12824SCathy.Zhou@Sun.COM getattr.ld_confid = conf.ds_confid; 457*12824SCathy.Zhou@Sun.COM (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN); 4585895Syz147064 459*12824SCathy.Zhou@Sun.COM if ((status = dladm_door_call(handle, &getattr, 460*12824SCathy.Zhou@Sun.COM sizeof (getattr), &retval, &sz)) != DLADM_STATUS_OK) { 461*12824SCathy.Zhou@Sun.COM return (status); 462*12824SCathy.Zhou@Sun.COM } 4635895Syz147064 464*12824SCathy.Zhou@Sun.COM if (retval.lr_attrsz > attrsz) 465*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_TOOSMALL); 466*12824SCathy.Zhou@Sun.COM 467*12824SCathy.Zhou@Sun.COM bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); 468*12824SCathy.Zhou@Sun.COM } 469*12824SCathy.Zhou@Sun.COM return (status); 4705895Syz147064 } 4715895Syz147064 4725895Syz147064 /* 4738460SArtem.Kachitchkin@Sun.COM * Get next property attribute from data link configuration repository. 474*12824SCathy.Zhou@Sun.COM * If last_attr is "", return the first property. 4758460SArtem.Kachitchkin@Sun.COM */ 476*12824SCathy.Zhou@Sun.COM /* ARGSUSED */ 4778460SArtem.Kachitchkin@Sun.COM dladm_status_t 4788460SArtem.Kachitchkin@Sun.COM dladm_getnext_conf_linkprop(dladm_handle_t handle, dladm_conf_t conf, 4798460SArtem.Kachitchkin@Sun.COM const char *last_attr, char *attr, void *attrval, size_t attrsz, 4808460SArtem.Kachitchkin@Sun.COM size_t *attrszp) 4818460SArtem.Kachitchkin@Sun.COM { 482*12824SCathy.Zhou@Sun.COM nvlist_t *nvl = conf.ds_nvl; 483*12824SCathy.Zhou@Sun.COM nvpair_t *last = NULL, *nvp; 484*12824SCathy.Zhou@Sun.COM uchar_t *oattrval; 485*12824SCathy.Zhou@Sun.COM uint32_t oattrsz; 486*12824SCathy.Zhou@Sun.COM int err; 4878460SArtem.Kachitchkin@Sun.COM 488*12824SCathy.Zhou@Sun.COM if (nvl == NULL || attrval == NULL || attrsz == 0 || attr == NULL || 489*12824SCathy.Zhou@Sun.COM !conf.ds_readonly) 4908460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_BADARG); 491*12824SCathy.Zhou@Sun.COM 492*12824SCathy.Zhou@Sun.COM while ((nvp = nvlist_next_nvpair(nvl, last)) != NULL) { 493*12824SCathy.Zhou@Sun.COM if (last_attr[0] == '\0') 494*12824SCathy.Zhou@Sun.COM break; 495*12824SCathy.Zhou@Sun.COM if (last != NULL && strcmp(last_attr, nvpair_name(last)) == 0) 496*12824SCathy.Zhou@Sun.COM break; 497*12824SCathy.Zhou@Sun.COM last = nvp; 4988460SArtem.Kachitchkin@Sun.COM } 4998460SArtem.Kachitchkin@Sun.COM 500*12824SCathy.Zhou@Sun.COM if (nvp == NULL) 501*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_NOTFOUND); 5028460SArtem.Kachitchkin@Sun.COM 503*12824SCathy.Zhou@Sun.COM if ((err = nvpair_value_byte_array(nvp, (uchar_t **)&oattrval, 504*12824SCathy.Zhou@Sun.COM &oattrsz)) != NULL) { 505*12824SCathy.Zhou@Sun.COM return (dladm_errno2status(err)); 5068460SArtem.Kachitchkin@Sun.COM } 5078460SArtem.Kachitchkin@Sun.COM 508*12824SCathy.Zhou@Sun.COM *attrszp = oattrsz; 509*12824SCathy.Zhou@Sun.COM if (oattrsz > attrsz) 5108460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_TOOSMALL); 5118460SArtem.Kachitchkin@Sun.COM 512*12824SCathy.Zhou@Sun.COM (void) strlcpy(attr, nvpair_name(nvp), MAXLINKATTRLEN); 513*12824SCathy.Zhou@Sun.COM bcopy(oattrval, attrval, oattrsz); 5148460SArtem.Kachitchkin@Sun.COM return (DLADM_STATUS_OK); 5158460SArtem.Kachitchkin@Sun.COM } 5168460SArtem.Kachitchkin@Sun.COM 5178460SArtem.Kachitchkin@Sun.COM /* 5185895Syz147064 * Get the link ID that is associated with the given name. 5195895Syz147064 */ 5205895Syz147064 dladm_status_t 5218453SAnurag.Maskey@Sun.COM dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp, 5228453SAnurag.Maskey@Sun.COM uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap) 5235895Syz147064 { 5245895Syz147064 dlmgmt_door_getlinkid_t getlinkid; 5255895Syz147064 dlmgmt_getlinkid_retval_t retval; 5265895Syz147064 datalink_id_t linkid; 5275895Syz147064 dladm_status_t status; 528*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 5295895Syz147064 5305895Syz147064 getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; 5315895Syz147064 (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); 5325895Syz147064 5338453SAnurag.Maskey@Sun.COM if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid), 534*12824SCathy.Zhou@Sun.COM &retval, &sz)) != DLADM_STATUS_OK) { 5355895Syz147064 return (status); 5366263Sseb } 5375895Syz147064 5385895Syz147064 linkid = retval.lr_linkid; 5395895Syz147064 if (retval.lr_class == DATALINK_CLASS_PHYS && 5405895Syz147064 retval.lr_flags & DLMGMT_ACTIVE) { 5415895Syz147064 /* 5425895Syz147064 * An active physical link reported by the dlmgmtd daemon 5435895Syz147064 * might not be active anymore. Check and set its real status. 5445895Syz147064 */ 5458453SAnurag.Maskey@Sun.COM status = i_dladm_phys_status(handle, linkid, &retval.lr_flags); 5465895Syz147064 if (status != DLADM_STATUS_OK) 5475895Syz147064 return (status); 5485895Syz147064 } 5495895Syz147064 5505895Syz147064 if (linkidp != NULL) 5515895Syz147064 *linkidp = linkid; 5525895Syz147064 if (flagp != NULL) { 5535895Syz147064 *flagp = retval.lr_flags & DLMGMT_ACTIVE ? DLADM_OPT_ACTIVE : 0; 5545895Syz147064 *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ? 5555895Syz147064 DLADM_OPT_PERSIST : 0; 5565895Syz147064 } 5575895Syz147064 if (classp != NULL) 5585895Syz147064 *classp = retval.lr_class; 5595895Syz147064 if (mediap != NULL) 5605895Syz147064 *mediap = retval.lr_media; 5615895Syz147064 5625895Syz147064 return (DLADM_STATUS_OK); 5635895Syz147064 } 5645895Syz147064 5655895Syz147064 /* 5665895Syz147064 * Get the link name that is associated with the given id. 5675895Syz147064 */ 5685895Syz147064 dladm_status_t 5698453SAnurag.Maskey@Sun.COM dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid, 5708453SAnurag.Maskey@Sun.COM uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap, char *link, 5718453SAnurag.Maskey@Sun.COM size_t len) 5725895Syz147064 { 5736263Sseb dlmgmt_door_getname_t getname; 5746263Sseb dlmgmt_getname_retval_t retval; 5756263Sseb dladm_status_t status; 576*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 5775895Syz147064 5785895Syz147064 if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) || 5795895Syz147064 (link == NULL && len != 0)) { 5805895Syz147064 return (DLADM_STATUS_BADARG); 5815895Syz147064 } 5825895Syz147064 5835895Syz147064 getname.ld_cmd = DLMGMT_CMD_GETNAME; 5845895Syz147064 getname.ld_linkid = linkid; 5858453SAnurag.Maskey@Sun.COM if ((status = dladm_door_call(handle, &getname, sizeof (getname), 586*12824SCathy.Zhou@Sun.COM &retval, &sz)) != DLADM_STATUS_OK) { 5875895Syz147064 return (status); 5886263Sseb } 5895895Syz147064 5906263Sseb if (len != 0 && (strlen(retval.lr_link) + 1 > len)) 5915895Syz147064 return (DLADM_STATUS_TOOSMALL); 5925895Syz147064 5935895Syz147064 if (retval.lr_class == DATALINK_CLASS_PHYS && 5945895Syz147064 retval.lr_flags & DLMGMT_ACTIVE) { 5955895Syz147064 /* 5965895Syz147064 * An active physical link reported by the dlmgmtd daemon 5975895Syz147064 * might not be active anymore. Check and set its real status. 5985895Syz147064 */ 5998453SAnurag.Maskey@Sun.COM status = i_dladm_phys_status(handle, linkid, &retval.lr_flags); 6005895Syz147064 if (status != DLADM_STATUS_OK) 6015895Syz147064 return (status); 6025895Syz147064 } 6035895Syz147064 6045895Syz147064 if (link != NULL) 6055895Syz147064 (void) strlcpy(link, retval.lr_link, len); 6065895Syz147064 if (classp != NULL) 6075895Syz147064 *classp = retval.lr_class; 6085895Syz147064 if (mediap != NULL) 6095895Syz147064 *mediap = retval.lr_media; 6105895Syz147064 if (flagp != NULL) { 6115895Syz147064 *flagp = retval.lr_flags & DLMGMT_ACTIVE ? 6125895Syz147064 DLADM_OPT_ACTIVE : 0; 6135895Syz147064 *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ? 6145895Syz147064 DLADM_OPT_PERSIST : 0; 6155895Syz147064 } 6165895Syz147064 return (DLADM_STATUS_OK); 6175895Syz147064 } 6185895Syz147064 6195895Syz147064 /* 6205895Syz147064 * Set the given attr with the given attrval for the given link. 6215895Syz147064 */ 6225895Syz147064 dladm_status_t 6238453SAnurag.Maskey@Sun.COM dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, 6245895Syz147064 dladm_datatype_t type, const void *attrval) 6255895Syz147064 { 6266263Sseb dlmgmt_door_setattr_t setattr; 6276263Sseb dlmgmt_setattr_retval_t retval; 6286263Sseb size_t attrsz; 629*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 6305895Syz147064 6316263Sseb if (attr == NULL || attrval == NULL) 6325895Syz147064 return (DLADM_STATUS_BADARG); 6335895Syz147064 634*12824SCathy.Zhou@Sun.COM if (conf.ds_readonly) 635*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_DENIED); 636*12824SCathy.Zhou@Sun.COM 6375895Syz147064 if (type == DLADM_TYPE_STR) 6385895Syz147064 attrsz = strlen(attrval) + 1; 6395895Syz147064 else 6405895Syz147064 attrsz = dladm_datatype_size[type]; 6415895Syz147064 6426263Sseb if (attrsz > MAXLINKATTRVALLEN) 6436263Sseb return (DLADM_STATUS_TOOSMALL); 6445895Syz147064 6456263Sseb setattr.ld_cmd = DLMGMT_CMD_SETATTR; 646*12824SCathy.Zhou@Sun.COM setattr.ld_confid = conf.ds_confid; 6476263Sseb (void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN); 6486263Sseb setattr.ld_attrsz = attrsz; 6496263Sseb setattr.ld_type = type; 6506263Sseb bcopy(attrval, &setattr.ld_attrval, attrsz); 6515895Syz147064 652*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &setattr, sizeof (setattr), 653*12824SCathy.Zhou@Sun.COM &retval, &sz)); 6545895Syz147064 } 6555895Syz147064 6565895Syz147064 /* 6575895Syz147064 * Unset the given attr the given link. 6585895Syz147064 */ 6595895Syz147064 dladm_status_t 6608453SAnurag.Maskey@Sun.COM dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf, 6618453SAnurag.Maskey@Sun.COM const char *attr) 6625895Syz147064 { 6635895Syz147064 dlmgmt_door_unsetattr_t unsetattr; 6645895Syz147064 dlmgmt_unsetattr_retval_t retval; 665*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 6665895Syz147064 6676263Sseb if (attr == NULL) 6685895Syz147064 return (DLADM_STATUS_BADARG); 6695895Syz147064 670*12824SCathy.Zhou@Sun.COM if (conf.ds_readonly) 671*12824SCathy.Zhou@Sun.COM return (DLADM_STATUS_DENIED); 672*12824SCathy.Zhou@Sun.COM 6735895Syz147064 unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR; 674*12824SCathy.Zhou@Sun.COM unsetattr.ld_confid = conf.ds_confid; 6755895Syz147064 (void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN); 6765895Syz147064 677*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr), 678*12824SCathy.Zhou@Sun.COM &retval, &sz)); 6795895Syz147064 } 6805895Syz147064 6815895Syz147064 /* 6825895Syz147064 * Remove the given link ID and its entry from the data link configuration 6835895Syz147064 * repository. 6845895Syz147064 */ 6855895Syz147064 dladm_status_t 6868453SAnurag.Maskey@Sun.COM dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid) 6875895Syz147064 { 6885895Syz147064 dlmgmt_door_removeconf_t removeconf; 6895895Syz147064 dlmgmt_removeconf_retval_t retval; 690*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 6915895Syz147064 6925895Syz147064 removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF; 6935895Syz147064 removeconf.ld_linkid = linkid; 6945895Syz147064 6958453SAnurag.Maskey@Sun.COM return (dladm_door_call(handle, &removeconf, sizeof (removeconf), 696*12824SCathy.Zhou@Sun.COM &retval, &sz)); 6975895Syz147064 } 6985895Syz147064 6995895Syz147064 /* 7005895Syz147064 * Free the contents of the link structure. 7015895Syz147064 */ 7025895Syz147064 void 7038453SAnurag.Maskey@Sun.COM dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf) 7045895Syz147064 { 705*12824SCathy.Zhou@Sun.COM dlmgmt_door_destroyconf_t dconf; 7065895Syz147064 dlmgmt_destroyconf_retval_t retval; 707*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 7085895Syz147064 709*12824SCathy.Zhou@Sun.COM if (conf.ds_readonly) { 710*12824SCathy.Zhou@Sun.COM nvlist_free(conf.ds_nvl); 711*12824SCathy.Zhou@Sun.COM } else { 712*12824SCathy.Zhou@Sun.COM if (conf.ds_confid == DLADM_INVALID_CONF) 713*12824SCathy.Zhou@Sun.COM return; 7145895Syz147064 715*12824SCathy.Zhou@Sun.COM dconf.ld_cmd = DLMGMT_CMD_DESTROYCONF; 716*12824SCathy.Zhou@Sun.COM dconf.ld_confid = conf.ds_confid; 717*12824SCathy.Zhou@Sun.COM 718*12824SCathy.Zhou@Sun.COM (void) dladm_door_call(handle, &dconf, sizeof (dconf), 719*12824SCathy.Zhou@Sun.COM &retval, &sz); 720*12824SCathy.Zhou@Sun.COM } 7215895Syz147064 } 72210616SSebastien.Roy@Sun.COM 72310616SSebastien.Roy@Sun.COM dladm_status_t 72410616SSebastien.Roy@Sun.COM dladm_zone_boot(dladm_handle_t handle, zoneid_t zoneid) 72510616SSebastien.Roy@Sun.COM { 72610616SSebastien.Roy@Sun.COM dlmgmt_door_zoneboot_t zoneboot; 72710616SSebastien.Roy@Sun.COM dlmgmt_zoneboot_retval_t retval; 728*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 72910616SSebastien.Roy@Sun.COM 73010616SSebastien.Roy@Sun.COM zoneboot.ld_cmd = DLMGMT_CMD_ZONEBOOT; 73110616SSebastien.Roy@Sun.COM zoneboot.ld_zoneid = zoneid; 732*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &zoneboot, sizeof (zoneboot), 733*12824SCathy.Zhou@Sun.COM &retval, &sz)); 73410616SSebastien.Roy@Sun.COM } 73510616SSebastien.Roy@Sun.COM 73610616SSebastien.Roy@Sun.COM dladm_status_t 73710616SSebastien.Roy@Sun.COM dladm_zone_halt(dladm_handle_t handle, zoneid_t zoneid) 73810616SSebastien.Roy@Sun.COM { 73910616SSebastien.Roy@Sun.COM dlmgmt_door_zonehalt_t zonehalt; 74010616SSebastien.Roy@Sun.COM dlmgmt_zonehalt_retval_t retval; 741*12824SCathy.Zhou@Sun.COM size_t sz = sizeof (retval); 74210616SSebastien.Roy@Sun.COM 74310616SSebastien.Roy@Sun.COM zonehalt.ld_cmd = DLMGMT_CMD_ZONEHALT; 74410616SSebastien.Roy@Sun.COM zonehalt.ld_zoneid = zoneid; 745*12824SCathy.Zhou@Sun.COM return (dladm_door_call(handle, &zonehalt, sizeof (zonehalt), 746*12824SCathy.Zhou@Sun.COM &retval, &sz)); 74710616SSebastien.Roy@Sun.COM } 748