1d62bc4baSyz /* 2d62bc4baSyz * CDDL HEADER START 3d62bc4baSyz * 4d62bc4baSyz * The contents of this file are subject to the terms of the 5d62bc4baSyz * Common Development and Distribution License (the "License"). 6d62bc4baSyz * You may not use this file except in compliance with the License. 7d62bc4baSyz * 8d62bc4baSyz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d62bc4baSyz * or http://www.opensolaris.org/os/licensing. 10d62bc4baSyz * See the License for the specific language governing permissions 11d62bc4baSyz * and limitations under the License. 12d62bc4baSyz * 13d62bc4baSyz * When distributing Covered Code, include this CDDL HEADER in each 14d62bc4baSyz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d62bc4baSyz * If applicable, add the following below this CDDL HEADER, with the 16d62bc4baSyz * fields enclosed by brackets "[]" replaced with your own identifying 17d62bc4baSyz * information: Portions Copyright [yyyy] [name of copyright owner] 18d62bc4baSyz * 19d62bc4baSyz * CDDL HEADER END 20d62bc4baSyz */ 21d62bc4baSyz /* 22*82a2fc47SJames Carlson * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23d62bc4baSyz * Use is subject to license terms. 24d62bc4baSyz */ 25d62bc4baSyz 26d62bc4baSyz #include <door.h> 27d62bc4baSyz #include <errno.h> 28d62bc4baSyz #include <assert.h> 29d62bc4baSyz #include <stdio.h> 30d62bc4baSyz #include <stdlib.h> 31d62bc4baSyz #include <unistd.h> 32d62bc4baSyz #include <string.h> 33d62bc4baSyz #include <strings.h> 34d62bc4baSyz #include <sys/types.h> 35d62bc4baSyz #include <sys/stat.h> 36d62bc4baSyz #include <sys/aggr.h> 37*82a2fc47SJames Carlson #include <sys/mman.h> 38d62bc4baSyz #include <fcntl.h> 39d62bc4baSyz #include <libdladm.h> 40d62bc4baSyz #include <libdladm_impl.h> 41d62bc4baSyz #include <libdllink.h> 42d62bc4baSyz #include <libdlmgmt.h> 43d62bc4baSyz 44d62bc4baSyz /* 45d62bc4baSyz * Table of data type sizes indexed by dladm_datatype_t. 46d62bc4baSyz */ 47d62bc4baSyz static size_t dladm_datatype_size[] = { 48d62bc4baSyz 0, /* DLADM_TYPE_STR, use strnlen() */ 49d62bc4baSyz sizeof (boolean_t), /* DLADM_TYPE_BOOLEAN */ 50d62bc4baSyz sizeof (uint64_t) /* DLADM_TYPE_UINT64 */ 51d62bc4baSyz }; 52d62bc4baSyz 53d62bc4baSyz static dladm_status_t 544ac67f02SAnurag S. Maskey dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf, 554ac67f02SAnurag S. Maskey size_t rsize) 56d62bc4baSyz { 57d62bc4baSyz door_arg_t darg; 584ac67f02SAnurag S. Maskey int door_fd; 59d62bc4baSyz dladm_status_t status = DLADM_STATUS_OK; 60d62bc4baSyz 61d62bc4baSyz darg.data_ptr = arg; 62d62bc4baSyz darg.data_size = asize; 63d62bc4baSyz darg.desc_ptr = NULL; 64d62bc4baSyz darg.desc_num = 0; 65d62bc4baSyz darg.rbuf = rbuf; 66024b0a25Sseb darg.rsize = rsize; 67d62bc4baSyz 684ac67f02SAnurag S. Maskey /* The door descriptor is opened if it isn't already */ 694ac67f02SAnurag S. Maskey if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK) 704ac67f02SAnurag S. Maskey return (status); 714ac67f02SAnurag S. Maskey if (door_call(door_fd, &darg) == -1) 72d62bc4baSyz status = dladm_errno2status(errno); 73d62bc4baSyz if (status != DLADM_STATUS_OK) 74d62bc4baSyz return (status); 75d62bc4baSyz 76d62bc4baSyz if (darg.rbuf != rbuf) { 77d62bc4baSyz /* 78d62bc4baSyz * The size of the input rbuf is not big enough so that 79d62bc4baSyz * the door allocate the rbuf itself. In this case, simply 80d62bc4baSyz * think something wrong with the door call. 81d62bc4baSyz */ 82d62bc4baSyz (void) munmap(darg.rbuf, darg.rsize); 83d62bc4baSyz return (DLADM_STATUS_TOOSMALL); 84d62bc4baSyz } 85024b0a25Sseb if (darg.rsize != rsize) 86d62bc4baSyz return (DLADM_STATUS_FAILED); 87d62bc4baSyz 88024b0a25Sseb return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err)); 89d62bc4baSyz } 90d62bc4baSyz 91d62bc4baSyz /* 92d62bc4baSyz * Allocate a new linkid with the given name. Return the new linkid. 93d62bc4baSyz */ 94d62bc4baSyz dladm_status_t 954ac67f02SAnurag S. Maskey dladm_create_datalink_id(dladm_handle_t handle, const char *link, 964ac67f02SAnurag S. Maskey datalink_class_t class, uint32_t media, uint32_t flags, 974ac67f02SAnurag S. Maskey datalink_id_t *linkidp) 98d62bc4baSyz { 99024b0a25Sseb dlmgmt_door_createid_t createid; 100d62bc4baSyz dlmgmt_createid_retval_t retval; 101024b0a25Sseb uint32_t dlmgmt_flags; 102024b0a25Sseb dladm_status_t status; 103d62bc4baSyz 104024b0a25Sseb if (link == NULL || class == DATALINK_CLASS_ALL || 105d62bc4baSyz !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) || 106d62bc4baSyz linkidp == NULL) { 107d62bc4baSyz return (DLADM_STATUS_BADARG); 108d62bc4baSyz } 109d62bc4baSyz 110d62bc4baSyz dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 111d62bc4baSyz dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0; 112d62bc4baSyz 113d62bc4baSyz (void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN); 114d62bc4baSyz createid.ld_class = class; 115d62bc4baSyz createid.ld_media = media; 116d62bc4baSyz createid.ld_flags = dlmgmt_flags; 117d62bc4baSyz createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID; 118d62bc4baSyz createid.ld_prefix = (flags & DLADM_OPT_PREFIX); 119d62bc4baSyz 1204ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &createid, sizeof (createid), 1214ac67f02SAnurag S. Maskey &retval, sizeof (retval))) == DLADM_STATUS_OK) { 122024b0a25Sseb *linkidp = retval.lr_linkid; 123024b0a25Sseb } 124024b0a25Sseb return (status); 125d62bc4baSyz } 126d62bc4baSyz 127d62bc4baSyz /* 128d62bc4baSyz * Destroy the given link ID. 129d62bc4baSyz */ 130d62bc4baSyz dladm_status_t 1314ac67f02SAnurag S. Maskey dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid, 1324ac67f02SAnurag S. Maskey uint32_t flags) 133d62bc4baSyz { 134d62bc4baSyz dlmgmt_door_destroyid_t destroyid; 135d62bc4baSyz dlmgmt_destroyid_retval_t retval; 136d62bc4baSyz uint32_t dlmgmt_flags; 137d62bc4baSyz 138d62bc4baSyz dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 139d62bc4baSyz dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); 140d62bc4baSyz 141d62bc4baSyz destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID; 142d62bc4baSyz destroyid.ld_linkid = linkid; 143d62bc4baSyz destroyid.ld_flags = dlmgmt_flags; 144d62bc4baSyz 1454ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &destroyid, sizeof (destroyid), &retval, 1464ac67f02SAnurag S. Maskey sizeof (retval))); 147d62bc4baSyz } 148d62bc4baSyz 149d62bc4baSyz /* 150d62bc4baSyz * Remap a given link ID to a new name. 151d62bc4baSyz */ 152d62bc4baSyz dladm_status_t 1534ac67f02SAnurag S. Maskey dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid, 1544ac67f02SAnurag S. Maskey const char *link) 155d62bc4baSyz { 156d62bc4baSyz dlmgmt_door_remapid_t remapid; 157d62bc4baSyz dlmgmt_remapid_retval_t retval; 158d62bc4baSyz 159d62bc4baSyz remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID; 160d62bc4baSyz remapid.ld_linkid = linkid; 161d62bc4baSyz (void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN); 162d62bc4baSyz 1634ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &remapid, sizeof (remapid), &retval, 1644ac67f02SAnurag S. Maskey sizeof (retval))); 165d62bc4baSyz } 166d62bc4baSyz 167d62bc4baSyz /* 168d62bc4baSyz * Make a given link ID active. 169d62bc4baSyz */ 170d62bc4baSyz dladm_status_t 1714ac67f02SAnurag S. Maskey dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid) 172d62bc4baSyz { 173024b0a25Sseb dlmgmt_door_upid_t upid; 174024b0a25Sseb dlmgmt_upid_retval_t retval; 175d62bc4baSyz 176d62bc4baSyz upid.ld_cmd = DLMGMT_CMD_UP_LINKID; 177d62bc4baSyz upid.ld_linkid = linkid; 178d62bc4baSyz 1794ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &upid, sizeof (upid), &retval, 1804ac67f02SAnurag S. Maskey sizeof (retval))); 181d62bc4baSyz } 182d62bc4baSyz 183d62bc4baSyz /* 184d62bc4baSyz * Create a new link with the given name. Return the new link's handle 185d62bc4baSyz */ 186d62bc4baSyz dladm_status_t 1874ac67f02SAnurag S. Maskey dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid, 188d62bc4baSyz datalink_class_t class, uint32_t media, dladm_conf_t *confp) 189d62bc4baSyz { 190024b0a25Sseb dlmgmt_door_createconf_t createconf; 191024b0a25Sseb dlmgmt_createconf_retval_t retval; 192024b0a25Sseb dladm_status_t status; 193d62bc4baSyz 194024b0a25Sseb if (link == NULL || confp == NULL) 195d62bc4baSyz return (DLADM_STATUS_BADARG); 196d62bc4baSyz 197d62bc4baSyz (void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN); 198d62bc4baSyz createconf.ld_class = class; 199d62bc4baSyz createconf.ld_media = media; 200d62bc4baSyz createconf.ld_linkid = linkid; 201d62bc4baSyz createconf.ld_cmd = DLMGMT_CMD_CREATECONF; 202d62bc4baSyz 2034ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &createconf, sizeof (createconf), 204024b0a25Sseb &retval, sizeof (retval))) == DLADM_STATUS_OK) { 205024b0a25Sseb *confp = retval.lr_conf; 206024b0a25Sseb } 207024b0a25Sseb return (status); 208d62bc4baSyz } 209d62bc4baSyz 210d62bc4baSyz /* 211d62bc4baSyz * An active physical link reported by the dlmgmtd daemon might not be active 212d62bc4baSyz * anymore as this link might be removed during system shutdown. Check its 213d62bc4baSyz * real status by calling dladm_phys_info(). 214d62bc4baSyz */ 215d62bc4baSyz dladm_status_t 2164ac67f02SAnurag S. Maskey i_dladm_phys_status(dladm_handle_t handle, datalink_id_t linkid, 2174ac67f02SAnurag S. Maskey uint32_t *flagsp) 218d62bc4baSyz { 219d62bc4baSyz dladm_phys_attr_t dpa; 220d62bc4baSyz dladm_status_t status; 221d62bc4baSyz 222d62bc4baSyz assert((*flagsp) & DLMGMT_ACTIVE); 223d62bc4baSyz 2244ac67f02SAnurag S. Maskey status = dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE); 225d62bc4baSyz if (status == DLADM_STATUS_NOTFOUND) { 226d62bc4baSyz /* 227d62bc4baSyz * No active status, this link was removed. Update its status 228d62bc4baSyz * in the daemon and delete all active linkprops. 2292d4eecfaSCathy Zhou * 2302d4eecfaSCathy Zhou * Note that the operation could fail. If it does, return 2312d4eecfaSCathy Zhou * failure now since otherwise dladm_set_linkprop() might 2322d4eecfaSCathy Zhou * call back to i_dladm_phys_status() recursively. 233d62bc4baSyz */ 2344ac67f02SAnurag S. Maskey if ((status = dladm_destroy_datalink_id(handle, linkid, 2354ac67f02SAnurag S. Maskey DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) 2362d4eecfaSCathy Zhou return (status); 2372d4eecfaSCathy Zhou 2384ac67f02SAnurag S. Maskey (void) dladm_set_linkprop(handle, linkid, NULL, NULL, 0, 239d62bc4baSyz DLADM_OPT_ACTIVE); 240d62bc4baSyz 241d62bc4baSyz (*flagsp) &= ~DLMGMT_ACTIVE; 242d62bc4baSyz status = DLADM_STATUS_OK; 243d62bc4baSyz } 244d62bc4baSyz return (status); 245d62bc4baSyz } 246d62bc4baSyz 247d62bc4baSyz /* 248d62bc4baSyz * Walk each entry in the data link configuration repository and 249d62bc4baSyz * call fn on the linkid and arg. 250d62bc4baSyz */ 251d62bc4baSyz dladm_status_t 2524ac67f02SAnurag S. Maskey dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *), 2534ac67f02SAnurag S. Maskey dladm_handle_t handle, void *argp, datalink_class_t class, 2544ac67f02SAnurag S. Maskey datalink_media_t dmedia, uint32_t flags) 255d62bc4baSyz { 256d62bc4baSyz dlmgmt_door_getnext_t getnext; 257d62bc4baSyz dlmgmt_getnext_retval_t retval; 258d62bc4baSyz uint32_t dlmgmt_flags; 259d62bc4baSyz datalink_id_t linkid = DATALINK_INVALID_LINKID; 260d62bc4baSyz dladm_status_t status = DLADM_STATUS_OK; 261d62bc4baSyz 262d62bc4baSyz if (fn == NULL) 263d62bc4baSyz return (DLADM_STATUS_BADARG); 264d62bc4baSyz 265d62bc4baSyz dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; 266d62bc4baSyz dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); 267d62bc4baSyz 268d62bc4baSyz getnext.ld_cmd = DLMGMT_CMD_GETNEXT; 269d62bc4baSyz getnext.ld_class = class; 270d62bc4baSyz getnext.ld_dmedia = dmedia; 271d62bc4baSyz getnext.ld_flags = dlmgmt_flags; 272d62bc4baSyz 273d62bc4baSyz do { 274d62bc4baSyz getnext.ld_linkid = linkid; 2754ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &getnext, 2764ac67f02SAnurag S. Maskey sizeof (getnext), &retval, sizeof (retval))) != 2774ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 278d62bc4baSyz /* 279d62bc4baSyz * done with walking 280d62bc4baSyz */ 281d62bc4baSyz break; 282d62bc4baSyz } 283d62bc4baSyz 284d62bc4baSyz linkid = retval.lr_linkid; 285d62bc4baSyz if ((retval.lr_class == DATALINK_CLASS_PHYS) && 286d62bc4baSyz (retval.lr_flags & DLMGMT_ACTIVE)) { 287d62bc4baSyz /* 288d62bc4baSyz * An active physical link reported by the dlmgmtd 289d62bc4baSyz * daemon might not be active anymore. Check its 290d62bc4baSyz * real status. 291d62bc4baSyz */ 2924ac67f02SAnurag S. Maskey if (i_dladm_phys_status(handle, linkid, 2934ac67f02SAnurag S. Maskey &retval.lr_flags) != DLADM_STATUS_OK) { 294d62bc4baSyz continue; 295d62bc4baSyz } 296d62bc4baSyz 297d62bc4baSyz if (!(dlmgmt_flags & retval.lr_flags)) 298d62bc4baSyz continue; 299d62bc4baSyz } 300d62bc4baSyz 3014ac67f02SAnurag S. Maskey if (fn(handle, linkid, argp) == DLADM_WALK_TERMINATE) 302d62bc4baSyz break; 303d62bc4baSyz } while (linkid != DATALINK_INVALID_LINKID); 304d62bc4baSyz 305d62bc4baSyz return (status); 306d62bc4baSyz } 307d62bc4baSyz 308d62bc4baSyz /* 309d62bc4baSyz * Get the link properties structure for the given link. 310d62bc4baSyz */ 311d62bc4baSyz dladm_status_t 3124ac67f02SAnurag S. Maskey dladm_read_conf(dladm_handle_t handle, datalink_id_t linkid, 3134ac67f02SAnurag S. Maskey dladm_conf_t *confp) 314d62bc4baSyz { 315024b0a25Sseb dlmgmt_door_readconf_t readconf; 316d62bc4baSyz dlmgmt_readconf_retval_t retval; 317d62bc4baSyz dladm_status_t status; 318d62bc4baSyz 319d62bc4baSyz if (linkid == DATALINK_INVALID_LINKID || confp == NULL) 320d62bc4baSyz return (DLADM_STATUS_BADARG); 321d62bc4baSyz 322d62bc4baSyz readconf.ld_linkid = linkid; 323d62bc4baSyz readconf.ld_cmd = DLMGMT_CMD_READCONF; 324d62bc4baSyz 3254ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &readconf, sizeof (readconf), 326024b0a25Sseb &retval, sizeof (retval))) == DLADM_STATUS_OK) { 327024b0a25Sseb *confp = retval.lr_conf; 328024b0a25Sseb } 329024b0a25Sseb return (status); 330d62bc4baSyz } 331d62bc4baSyz 332d62bc4baSyz /* 333d62bc4baSyz * Commit the given link to the data link configuration repository so 334d62bc4baSyz * that it will persist across reboots. 335d62bc4baSyz */ 336d62bc4baSyz dladm_status_t 3374ac67f02SAnurag S. Maskey dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf) 338d62bc4baSyz { 339d62bc4baSyz dlmgmt_door_writeconf_t writeconf; 340d62bc4baSyz dlmgmt_writeconf_retval_t retval; 341d62bc4baSyz 342d62bc4baSyz if (conf == DLADM_INVALID_CONF) 343d62bc4baSyz return (DLADM_STATUS_BADARG); 344d62bc4baSyz 345d62bc4baSyz writeconf.ld_cmd = DLMGMT_CMD_WRITECONF; 346d62bc4baSyz writeconf.ld_conf = conf; 347d62bc4baSyz 3484ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &writeconf, sizeof (writeconf), &retval, 3494ac67f02SAnurag S. Maskey sizeof (retval))); 350d62bc4baSyz } 351d62bc4baSyz 352d62bc4baSyz /* 353d62bc4baSyz * Given a link ID and a key, get the matching information from 354d62bc4baSyz * data link configuration repository. 355d62bc4baSyz */ 356d62bc4baSyz dladm_status_t 3574ac67f02SAnurag S. Maskey dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, 3584ac67f02SAnurag S. Maskey void *attrval, size_t attrsz) 359d62bc4baSyz { 360024b0a25Sseb dlmgmt_door_getattr_t getattr; 361024b0a25Sseb dlmgmt_getattr_retval_t retval; 362024b0a25Sseb dladm_status_t status; 363d62bc4baSyz 364d62bc4baSyz if (conf == DLADM_INVALID_CONF || attrval == NULL || 365024b0a25Sseb attrsz == 0 || attr == NULL) { 366d62bc4baSyz return (DLADM_STATUS_BADARG); 367d62bc4baSyz } 368d62bc4baSyz 369d62bc4baSyz getattr.ld_cmd = DLMGMT_CMD_GETATTR; 370d62bc4baSyz getattr.ld_conf = conf; 371d62bc4baSyz (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN); 372d62bc4baSyz 3734ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &getattr, sizeof (getattr), 3744ac67f02SAnurag S. Maskey &retval, sizeof (retval))) != DLADM_STATUS_OK) { 375024b0a25Sseb return (status); 376024b0a25Sseb } 377d62bc4baSyz 378024b0a25Sseb if (retval.lr_attrsz > attrsz) 379024b0a25Sseb return (DLADM_STATUS_TOOSMALL); 380d62bc4baSyz 38162ee1d25SArtem Kachitchkine bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); 38262ee1d25SArtem Kachitchkine return (DLADM_STATUS_OK); 38362ee1d25SArtem Kachitchkine } 38462ee1d25SArtem Kachitchkine 38562ee1d25SArtem Kachitchkine /* 38662ee1d25SArtem Kachitchkine * Get next property attribute from data link configuration repository. 38762ee1d25SArtem Kachitchkine */ 38862ee1d25SArtem Kachitchkine dladm_status_t 38962ee1d25SArtem Kachitchkine dladm_getnext_conf_linkprop(dladm_handle_t handle, dladm_conf_t conf, 39062ee1d25SArtem Kachitchkine const char *last_attr, char *attr, void *attrval, size_t attrsz, 39162ee1d25SArtem Kachitchkine size_t *attrszp) 39262ee1d25SArtem Kachitchkine { 39362ee1d25SArtem Kachitchkine dlmgmt_door_linkprop_getnext_t getnext; 39462ee1d25SArtem Kachitchkine dlmgmt_linkprop_getnext_retval_t retval; 39562ee1d25SArtem Kachitchkine dladm_status_t status; 39662ee1d25SArtem Kachitchkine 39762ee1d25SArtem Kachitchkine if (conf == DLADM_INVALID_CONF || attrval == NULL || 39862ee1d25SArtem Kachitchkine attrsz == 0 || attr == NULL) { 39962ee1d25SArtem Kachitchkine return (DLADM_STATUS_BADARG); 40062ee1d25SArtem Kachitchkine } 40162ee1d25SArtem Kachitchkine 40262ee1d25SArtem Kachitchkine getnext.ld_cmd = DLMGMT_CMD_LINKPROP_GETNEXT; 40362ee1d25SArtem Kachitchkine getnext.ld_conf = conf; 40462ee1d25SArtem Kachitchkine (void) strlcpy(getnext.ld_last_attr, last_attr, MAXLINKATTRLEN); 40562ee1d25SArtem Kachitchkine 40662ee1d25SArtem Kachitchkine if ((status = dladm_door_call(handle, &getnext, sizeof (getnext), 40762ee1d25SArtem Kachitchkine &retval, sizeof (retval))) != DLADM_STATUS_OK) { 40862ee1d25SArtem Kachitchkine return (status); 40962ee1d25SArtem Kachitchkine } 41062ee1d25SArtem Kachitchkine 41162ee1d25SArtem Kachitchkine *attrszp = retval.lr_attrsz; 41262ee1d25SArtem Kachitchkine if (retval.lr_attrsz > attrsz) { 41362ee1d25SArtem Kachitchkine return (DLADM_STATUS_TOOSMALL); 41462ee1d25SArtem Kachitchkine } 41562ee1d25SArtem Kachitchkine 41662ee1d25SArtem Kachitchkine (void) strlcpy(attr, retval.lr_attr, MAXLINKATTRLEN); 417024b0a25Sseb bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); 418024b0a25Sseb return (DLADM_STATUS_OK); 419d62bc4baSyz } 420d62bc4baSyz 421d62bc4baSyz /* 422d62bc4baSyz * Get the link ID that is associated with the given name. 423d62bc4baSyz */ 424d62bc4baSyz dladm_status_t 4254ac67f02SAnurag S. Maskey dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp, 4264ac67f02SAnurag S. Maskey uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap) 427d62bc4baSyz { 428d62bc4baSyz dlmgmt_door_getlinkid_t getlinkid; 429d62bc4baSyz dlmgmt_getlinkid_retval_t retval; 430d62bc4baSyz datalink_id_t linkid; 431d62bc4baSyz dladm_status_t status; 432d62bc4baSyz 433d62bc4baSyz getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; 434d62bc4baSyz (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); 435d62bc4baSyz 4364ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid), 437024b0a25Sseb &retval, sizeof (retval))) != DLADM_STATUS_OK) { 438d62bc4baSyz return (status); 439024b0a25Sseb } 440d62bc4baSyz 441d62bc4baSyz linkid = retval.lr_linkid; 442d62bc4baSyz if (retval.lr_class == DATALINK_CLASS_PHYS && 443d62bc4baSyz retval.lr_flags & DLMGMT_ACTIVE) { 444d62bc4baSyz /* 445d62bc4baSyz * An active physical link reported by the dlmgmtd daemon 446d62bc4baSyz * might not be active anymore. Check and set its real status. 447d62bc4baSyz */ 4484ac67f02SAnurag S. Maskey status = i_dladm_phys_status(handle, linkid, &retval.lr_flags); 449d62bc4baSyz if (status != DLADM_STATUS_OK) 450d62bc4baSyz return (status); 451d62bc4baSyz } 452d62bc4baSyz 453d62bc4baSyz if (linkidp != NULL) 454d62bc4baSyz *linkidp = linkid; 455d62bc4baSyz if (flagp != NULL) { 456d62bc4baSyz *flagp = retval.lr_flags & DLMGMT_ACTIVE ? DLADM_OPT_ACTIVE : 0; 457d62bc4baSyz *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ? 458d62bc4baSyz DLADM_OPT_PERSIST : 0; 459d62bc4baSyz } 460d62bc4baSyz if (classp != NULL) 461d62bc4baSyz *classp = retval.lr_class; 462d62bc4baSyz if (mediap != NULL) 463d62bc4baSyz *mediap = retval.lr_media; 464d62bc4baSyz 465d62bc4baSyz return (DLADM_STATUS_OK); 466d62bc4baSyz } 467d62bc4baSyz 468d62bc4baSyz /* 469d62bc4baSyz * Get the link name that is associated with the given id. 470d62bc4baSyz */ 471d62bc4baSyz dladm_status_t 4724ac67f02SAnurag S. Maskey dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid, 4734ac67f02SAnurag S. Maskey uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap, char *link, 4744ac67f02SAnurag S. Maskey size_t len) 475d62bc4baSyz { 476024b0a25Sseb dlmgmt_door_getname_t getname; 477024b0a25Sseb dlmgmt_getname_retval_t retval; 478024b0a25Sseb dladm_status_t status; 479d62bc4baSyz 480d62bc4baSyz if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) || 481d62bc4baSyz (link == NULL && len != 0)) { 482d62bc4baSyz return (DLADM_STATUS_BADARG); 483d62bc4baSyz } 484d62bc4baSyz 485d62bc4baSyz getname.ld_cmd = DLMGMT_CMD_GETNAME; 486d62bc4baSyz getname.ld_linkid = linkid; 4874ac67f02SAnurag S. Maskey if ((status = dladm_door_call(handle, &getname, sizeof (getname), 4884ac67f02SAnurag S. Maskey &retval, sizeof (retval))) != DLADM_STATUS_OK) { 489d62bc4baSyz return (status); 490024b0a25Sseb } 491d62bc4baSyz 492024b0a25Sseb if (len != 0 && (strlen(retval.lr_link) + 1 > len)) 493d62bc4baSyz return (DLADM_STATUS_TOOSMALL); 494d62bc4baSyz 495d62bc4baSyz if (retval.lr_class == DATALINK_CLASS_PHYS && 496d62bc4baSyz retval.lr_flags & DLMGMT_ACTIVE) { 497d62bc4baSyz /* 498d62bc4baSyz * An active physical link reported by the dlmgmtd daemon 499d62bc4baSyz * might not be active anymore. Check and set its real status. 500d62bc4baSyz */ 5014ac67f02SAnurag S. Maskey status = i_dladm_phys_status(handle, linkid, &retval.lr_flags); 502d62bc4baSyz if (status != DLADM_STATUS_OK) 503d62bc4baSyz return (status); 504d62bc4baSyz } 505d62bc4baSyz 506d62bc4baSyz if (link != NULL) 507d62bc4baSyz (void) strlcpy(link, retval.lr_link, len); 508d62bc4baSyz if (classp != NULL) 509d62bc4baSyz *classp = retval.lr_class; 510d62bc4baSyz if (mediap != NULL) 511d62bc4baSyz *mediap = retval.lr_media; 512d62bc4baSyz if (flagp != NULL) { 513d62bc4baSyz *flagp = retval.lr_flags & DLMGMT_ACTIVE ? 514d62bc4baSyz DLADM_OPT_ACTIVE : 0; 515d62bc4baSyz *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ? 516d62bc4baSyz DLADM_OPT_PERSIST : 0; 517d62bc4baSyz } 518d62bc4baSyz return (DLADM_STATUS_OK); 519d62bc4baSyz } 520d62bc4baSyz 521d62bc4baSyz /* 522d62bc4baSyz * Set the given attr with the given attrval for the given link. 523d62bc4baSyz */ 524d62bc4baSyz dladm_status_t 5254ac67f02SAnurag S. Maskey dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, 526d62bc4baSyz dladm_datatype_t type, const void *attrval) 527d62bc4baSyz { 528024b0a25Sseb dlmgmt_door_setattr_t setattr; 529024b0a25Sseb dlmgmt_setattr_retval_t retval; 530024b0a25Sseb size_t attrsz; 531d62bc4baSyz 532024b0a25Sseb if (attr == NULL || attrval == NULL) 533d62bc4baSyz return (DLADM_STATUS_BADARG); 534d62bc4baSyz 535d62bc4baSyz if (type == DLADM_TYPE_STR) 536d62bc4baSyz attrsz = strlen(attrval) + 1; 537d62bc4baSyz else 538d62bc4baSyz attrsz = dladm_datatype_size[type]; 539d62bc4baSyz 540024b0a25Sseb if (attrsz > MAXLINKATTRVALLEN) 541024b0a25Sseb return (DLADM_STATUS_TOOSMALL); 542d62bc4baSyz 543024b0a25Sseb setattr.ld_cmd = DLMGMT_CMD_SETATTR; 544024b0a25Sseb setattr.ld_conf = conf; 545024b0a25Sseb (void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN); 546024b0a25Sseb setattr.ld_attrsz = attrsz; 547024b0a25Sseb setattr.ld_type = type; 548024b0a25Sseb bcopy(attrval, &setattr.ld_attrval, attrsz); 549d62bc4baSyz 5504ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &setattr, sizeof (setattr), &retval, 5514ac67f02SAnurag S. Maskey sizeof (retval))); 552d62bc4baSyz } 553d62bc4baSyz 554d62bc4baSyz /* 555d62bc4baSyz * Unset the given attr the given link. 556d62bc4baSyz */ 557d62bc4baSyz dladm_status_t 5584ac67f02SAnurag S. Maskey dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf, 5594ac67f02SAnurag S. Maskey const char *attr) 560d62bc4baSyz { 561d62bc4baSyz dlmgmt_door_unsetattr_t unsetattr; 562d62bc4baSyz dlmgmt_unsetattr_retval_t retval; 563d62bc4baSyz 564024b0a25Sseb if (attr == NULL) 565d62bc4baSyz return (DLADM_STATUS_BADARG); 566d62bc4baSyz 567d62bc4baSyz unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR; 568d62bc4baSyz unsetattr.ld_conf = conf; 569d62bc4baSyz (void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN); 570d62bc4baSyz 5714ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr), &retval, 5724ac67f02SAnurag S. Maskey sizeof (retval))); 573d62bc4baSyz } 574d62bc4baSyz 575d62bc4baSyz /* 576d62bc4baSyz * Remove the given link ID and its entry from the data link configuration 577d62bc4baSyz * repository. 578d62bc4baSyz */ 579d62bc4baSyz dladm_status_t 5804ac67f02SAnurag S. Maskey dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid) 581d62bc4baSyz { 582d62bc4baSyz dlmgmt_door_removeconf_t removeconf; 583d62bc4baSyz dlmgmt_removeconf_retval_t retval; 584d62bc4baSyz 585d62bc4baSyz removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF; 586d62bc4baSyz removeconf.ld_linkid = linkid; 587d62bc4baSyz 5884ac67f02SAnurag S. Maskey return (dladm_door_call(handle, &removeconf, sizeof (removeconf), 589024b0a25Sseb &retval, sizeof (retval))); 590d62bc4baSyz } 591d62bc4baSyz 592d62bc4baSyz /* 593d62bc4baSyz * Free the contents of the link structure. 594d62bc4baSyz */ 595d62bc4baSyz void 5964ac67f02SAnurag S. Maskey dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf) 597d62bc4baSyz { 598d62bc4baSyz dlmgmt_door_destroyconf_t destroyconf; 599d62bc4baSyz dlmgmt_destroyconf_retval_t retval; 600d62bc4baSyz 601d62bc4baSyz if (conf == DLADM_INVALID_CONF) 602d62bc4baSyz return; 603d62bc4baSyz 604d62bc4baSyz destroyconf.ld_cmd = DLMGMT_CMD_DESTROYCONF; 605d62bc4baSyz destroyconf.ld_conf = conf; 606d62bc4baSyz 6074ac67f02SAnurag S. Maskey (void) dladm_door_call(handle, &destroyconf, sizeof (destroyconf), 608024b0a25Sseb &retval, sizeof (retval)); 609d62bc4baSyz } 610