libdllink.c revision 811fc8e17e28618ca5149abc18f576709fc5875b
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * CDDL HEADER START
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * The contents of this file are subject to the terms of the
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Common Development and Distribution License (the "License").
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * You may not use this file except in compliance with the License.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * See the License for the specific language governing permissions
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * and limitations under the License.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * When distributing Covered Code, include this CDDL HEADER in each
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * If applicable, add the following below this CDDL HEADER, with the
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * CDDL HEADER END
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Use is subject to license terms.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#pragma ident "%Z%%M% %I% %E% SMI"
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Return the attributes of the specified datalink from the DLD driver.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowei_dladm_info(int fd, const datalink_id_t linkid, dladm_attr_t *dap)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (i_dladm_ioctl(fd, DLDIOC_ATTR, &dia, sizeof (dia)) < 0)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (dladm_datalink_id2info(linkid, NULL, NULL, NULL, link,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Walk all datalinks.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedladm_walk(dladm_walkcb_t *fn, void *arg, datalink_class_t class,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return (dladm_walk_datalink_id(i_dladm_walk, &walk_arg,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * These routines are used by administration tools such as dladm(1M) to
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * iterate through the list of MAC interfaces
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowetypedef struct dladm_mac_dev {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowetypedef struct macadm_walk {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Local callback invoked for each DDI_NT_NET node.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/* ARGSUSED */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowei_dladm_mac_walk(di_node_t node, di_minor_t minor, void *arg)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe dladm_mac_dev_t **last_dmdp = &dmwp->dmd_dev_list;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Skip aggregations.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Skip softmacs.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (strcmp("softmac", di_driver_name(node)) == 0)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Skip duplicates.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (void) strlcpy(dmdp->dm_name, mac, MAXNAMELEN);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Invoke the specified callback for each DDI_NT_NET node.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedladm_mac_walk(int (*fn)(const char *, void *arg), void *arg)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &dmw,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe for (dmdp = dmw.dmd_dev_list; dmdp != NULL; dmdp = next) {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe ((*fn)(dmdp->dm_name, arg) == DLADM_WALK_TERMINATE)) {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Get the current attributes of the specified datalink.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedladm_info(datalink_id_t linkid, dladm_attr_t *dap)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedladm_linkstate2str(link_state_t state, char *buf)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe const char *s;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe s = "unknown";
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedladm_linkduplex2str(link_duplex_t duplex, char *buf)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe const char *s;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe s = "unknown";
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Set zoneid of a given link. Note that this function takes a link name
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * argument instead of a linkid, because a data-link (and its linkid) could
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * be created implicitly as the result of this function. For example, a VLAN
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * could be created if a VLAN PPA hack name is assigned to an exclusive
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * non-global zone.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (void) strlcpy(dis.dis_link, link, MAXLINKNAMELEN);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (i_dladm_ioctl(fd, DLDIOC_SETZID, &dis, sizeof (dis)) < 0)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Get zoneid of a given link
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedladm_getzid(datalink_id_t linkid, zoneid_t *zoneidp)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (i_dladm_ioctl(fd, DLDIOC_GETZID, &dig, sizeof (dig)) < 0)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Case 1: rename an existing link1 to a link2 that does not exist.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Result: <linkid1, link2>
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowei_dladm_rename_link_c1(datalink_id_t linkid1, const char *link1,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Link is currently available. Check to see whether anything is
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * holding this link to prevent a rename operation.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (void) strlcpy(dir.dir_link, link2, MAXLINKNAMELEN);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (i_dladm_ioctl(fd, DLDIOC_RENAME, &dir, sizeof (dir)) < 0) {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe status = dladm_remap_datalink_id(linkid1, link2);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Flush the current mapping to persistent configuration.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (((status = dladm_read_conf(linkid1, &conf)) != DLADM_STATUS_OK) ||
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe ((status = dladm_write_conf(conf)) != DLADM_STATUS_OK))) {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (void) dladm_remap_datalink_id(linkid1, link1);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe (void) strlcpy(dir.dir_link, link1, MAXLINKNAMELEN);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowetypedef struct link_hold_arg_s {
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowei_dladm_aggr_link_hold(datalink_id_t aggrid, void *arg)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe status = dladm_aggr_info(aggrid, &ginfo, hold_arg->flags);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_TERMINATE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_TERMINATE);
return (DLADM_WALK_CONTINUE);
static dladm_status_t
int fd;
return (DLADM_STATUS_LINKBUSY);
return (DLADM_STATUS_LINKBUSY);
return (status);
return (status);
goto done;
goto done;
RCM_SUCCESS) {
done:
return (status);
static dladm_status_t
return (DLADM_STATUS_LINKINVAL);
goto done;
done:
return (status);
flags1);
} else if (remphy2) {
linkid2);
} else if (remphy2) {
return (status);
typedef struct consumer_del_phys_arg_s {
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
typedef struct del_phys_arg_s {
goto done;
goto done;
done:
return (DLADM_WALK_CONTINUE);
return (DLADM_STATUS_OK);
switch (flags) {
case DLADM_OPT_PERSIST: {
return (status);
return (status);
case DLADM_OPT_ACTIVE: {
int fd;
return (status);
return (DLADM_STATUS_OK);
return (DLADM_STATUS_BADARG);
typedef struct i_walk_dev_state_s {
const char *devname;
return (DLADM_WALK_TERMINATE);
return (DLADM_WALK_CONTINUE);
return (DLADM_STATUS_OK);
int len;
return (EINVAL);
return (EINVAL);
goto done;
goto done;
goto done;
switch (class) {
case DATALINK_CLASS_AGGR: {
goto done;
goto done;
case DATALINK_CLASS_PHYS: {
goto done;
goto done;
goto done;
done:
return (status);
void *val)
return (status);
return (DLADM_STATUS_LINKINVAL);
return (status);
return (status);
goto bail;
goto bail;
goto bail;
return (DLADM_STATUS_OK);
bail:
switch (type) {
case KSTAT_DATA_UINT64:
case KSTAT_DATA_UINT32:
return (DLADM_STATUS_LINKINVAL);
return (DLADM_STATUS_OK);